diff -u --recursive --new-file linux-1.1.55/arch/i386/config.in linux/arch/i386/config.in --- linux-1.1.55/arch/i386/config.in Thu Oct 20 15:14:23 1994 +++ linux/arch/i386/config.in Thu Oct 20 17:09:39 1994 @@ -5,10 +5,11 @@ comment 'General setup' -bool 'Kernel math emulation' CONFIG_MATH_EMULATION n +bool 'Kernel math emulation' CONFIG_MATH_EMULATION y bool 'Normal harddisk support' CONFIG_BLK_DEV_HD y bool 'XT harddisk support' CONFIG_BLK_DEV_XD n bool 'Networking support' CONFIG_NET y +bool 'Filesystem quota support' CONFIG_QUOTA n bool 'Limit memory to low 16MB' CONFIG_MAX_16M n bool 'System V IPC' CONFIG_SYSVIPC y bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y @@ -31,7 +32,7 @@ comment 'SCSI support' -bool 'SCSI support?' CONFIG_SCSI n +bool 'SCSI support?' CONFIG_SCSI y if [ "$CONFIG_SCSI" = "n" ]; then @@ -42,25 +43,25 @@ comment 'SCSI support type (disk, tape, CDrom)' bool 'Scsi disk support' CONFIG_BLK_DEV_SD y -bool 'Scsi tape support' CONFIG_CHR_DEV_ST n -bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR n +bool 'Scsi tape support' CONFIG_CHR_DEV_ST y +bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR y bool 'Scsi generic support' CONFIG_CHR_DEV_SG n comment 'SCSI low-level drivers' -bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n +bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X y bool 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 y -bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n -bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n -bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n -bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n -bool 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx n +bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 y +bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC y +bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN y +bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 y +bool 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx y #bool 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 n -bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n -bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n -bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 n -bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n -bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST n +bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 y +bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE y +bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 y +bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR y +bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST y #bool 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n fi @@ -76,56 +77,56 @@ else bool 'Dummy net driver support' CONFIG_DUMMY n -bool 'SLIP (serial line) support' CONFIG_SLIP n +bool 'SLIP (serial line) support' CONFIG_SLIP y if [ "$CONFIG_SLIP" = "y" ]; then bool ' CSLIP compressed headers' SL_COMPRESSED y # bool ' SLIP debugging on' SL_DUMP y fi -bool 'PPP (point-to-point) support' CONFIG_PPP n +bool 'PPP (point-to-point) support' CONFIG_PPP y bool 'PLIP (parallel port) support' CONFIG_PLIP n bool 'Load balancing support (experimental)' CONFIG_SLAVE_BALANCING n -bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA n -bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC n +bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA y +bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC y if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then - bool 'WD80*3 support' CONFIG_WD80x3 n - bool 'SMC Ultra support' CONFIG_ULTRA n + bool 'WD80*3 support' CONFIG_WD80x3 y + bool 'SMC Ultra support' CONFIG_ULTRA y fi bool '3COM cards' CONFIG_NET_VENDOR_3COM y if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then - bool '3c501 support' CONFIG_EL1 n - bool '3c503 support' CONFIG_EL2 n + bool '3c501 support' CONFIG_EL1 y + bool '3c503 support' CONFIG_EL2 y if [ "$CONFIG_NET_ALPHA" = "y" ]; then - bool '3c505 support' CONFIG_ELPLUS n - bool '3c507 support' CONFIG_EL16 n + bool '3c505 support' CONFIG_ELPLUS y + bool '3c507 support' CONFIG_EL16 y fi bool '3c509/3c579 support' CONFIG_EL3 y fi -bool 'Other ISA cards' CONFIG_NET_ISA n +bool 'Other ISA cards' CONFIG_NET_ISA y if [ "$CONFIG_NET_ISA" = "y" ]; then - bool 'AT1500 and NE2100 (LANCE and PCnet-ISA) support' CONFIG_LANCE n - bool 'Cabletron E21xx support (not recommended)' CONFIG_E2100 n - bool 'DEPCA support' CONFIG_DEPCA n + bool 'AT1500 and NE2100 (LANCE and PCnet-ISA) support' CONFIG_LANCE y + bool 'Cabletron E21xx support (not recommended)' CONFIG_E2100 y + bool 'DEPCA support' CONFIG_DEPCA y if [ "$CONFIG_NET_ALPHA" = "y" ]; then - bool 'EtherExpress support' CONFIG_EEXPRESS n - bool 'AT1700 support' CONFIG_AT1700 n - bool 'NI5210 support' CONFIG_NI52 n - bool 'NI6510 support' CONFIG_NI65 n + bool 'EtherExpress support' CONFIG_EEXPRESS y + bool 'AT1700 support' CONFIG_AT1700 y + bool 'NI5210 support' CONFIG_NI52 y + bool 'NI6510 support' CONFIG_NI65 y fi - bool 'HP PCLAN support' CONFIG_HPLAN n + bool 'HP PCLAN support' CONFIG_HPLAN y bool 'NE2000/NE1000 support' CONFIG_NE2000 y - bool 'SK_G16 support' CONFIG_SK_G16 n + bool 'SK_G16 support' CONFIG_SK_G16 y fi -bool 'EISA and on board controllers' CONFIG_NET_EISA n +bool 'EISA and on board controllers' CONFIG_NET_EISA y if [ "$CONFIG_NET_ALPHA" = "y" ]; then - bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n + bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 y fi - bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n -bool 'Pocket and portable adaptors' CONFIG_NET_POCKET n + bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT y +bool 'Pocket and portable adaptors' CONFIG_NET_POCKET y if [ "$CONFIG_NET_POCKET" = "y" ]; then - bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n - bool 'D-Link DE620 pocket adaptor support' CONFIG_DE620 n - bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n - bool 'Zenith Z-Note support' CONFIG_ZNET n + bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 y + bool 'D-Link DE620 pocket adaptor support' CONFIG_DE620 y + bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP y + bool 'Zenith Z-Note support' CONFIG_ZNET y fi fi fi @@ -150,30 +151,30 @@ bool 'Standard (minix) fs support' CONFIG_MINIX_FS y bool 'Extended fs support' CONFIG_EXT_FS n bool 'Second extended fs support' CONFIG_EXT2_FS y -bool 'xiafs filesystem support' CONFIG_XIA_FS n +bool 'xiafs filesystem support' CONFIG_XIA_FS y bool 'msdos fs support' CONFIG_MSDOS_FS y if [ "$CONFIG_MSDOS_FS" = "y" ]; then -bool 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS n +bool 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS y fi bool '/proc filesystem support' CONFIG_PROC_FS y if [ "$CONFIG_INET" = "y" ]; then bool 'NFS filesystem support' CONFIG_NFS_FS y fi -bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS n -bool 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS n +bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y +bool 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS y bool 'System V and Coherent filesystem support' CONFIG_SYSV_FS n comment 'character devices' -bool 'Parallel printer support' CONFIG_PRINTER n +bool 'Parallel printer support' CONFIG_PRINTER y bool 'Logitech busmouse support' CONFIG_BUSMOUSE n -bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE n +bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE y if [ "$CONFIG_PSMOUSE" = "y" ]; then bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE y fi bool 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n bool 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n -bool 'Selection (cut and paste for virtual consoles)' CONFIG_SELECTION n +bool 'Selection (cut and paste for virtual consoles)' CONFIG_SELECTION y bool 'QIC-02 tape support' CONFIG_QIC02_TAPE n if [ "$CONFIG_QIC02_TAPE" = "y" ]; then @@ -190,7 +191,7 @@ fi fi -bool 'QIC-117 tape support' CONFIG_FTAPE n +bool 'QIC-117 tape support' CONFIG_FTAPE y if [ "$CONFIG_FTAPE" = "y" ]; then int ' number of ftape buffers' NR_FTAPE_BUFFERS 3 fi @@ -204,5 +205,5 @@ #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC n bool 'Kernel profiling support' CONFIG_PROFILE n if [ "$CONFIG_SCSI" = "y" ]; then -bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS y +bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS n fi diff -u --recursive --new-file linux-1.1.55/config.in linux/config.in --- linux-1.1.55/config.in Sat Sep 17 21:48:10 1994 +++ linux/config.in Thu Oct 20 17:09:26 1994 @@ -5,12 +5,14 @@ comment 'General setup' -bool 'Kernel math emulation' CONFIG_MATH_EMULATION n +bool 'Kernel math emulation' CONFIG_MATH_EMULATION y bool 'Normal harddisk support' CONFIG_BLK_DEV_HD y bool 'XT harddisk support' CONFIG_BLK_DEV_XD n bool 'Networking support' CONFIG_NET y +bool 'Filesystem quota support' CONFIG_QUOTA n bool 'Limit memory to low 16MB' CONFIG_MAX_16M n bool 'System V IPC' CONFIG_SYSVIPC y +bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 y if [ "$CONFIG_NET" = "y" ]; then @@ -24,13 +26,13 @@ bool 'Assume subnets are local' CONFIG_INET_SNARL y bool 'Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n fi -bool 'The IPX protocol' CONFIG_IPX y +bool 'The IPX protocol' CONFIG_IPX n #bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n fi comment 'SCSI support' -bool 'SCSI support?' CONFIG_SCSI n +bool 'SCSI support?' CONFIG_SCSI y if [ "$CONFIG_SCSI" = "n" ]; then @@ -41,25 +43,25 @@ comment 'SCSI support type (disk, tape, CDrom)' bool 'Scsi disk support' CONFIG_BLK_DEV_SD y -bool 'Scsi tape support' CONFIG_CHR_DEV_ST n -bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR n +bool 'Scsi tape support' CONFIG_CHR_DEV_ST y +bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR y bool 'Scsi generic support' CONFIG_CHR_DEV_SG n comment 'SCSI low-level drivers' -bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n +bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X y bool 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 y -bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n -bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n -bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n -bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n -bool 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx n +bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 y +bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC y +bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN y +bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 y +bool 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx y #bool 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 n -bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n -bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n -bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 n -bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n -bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST n +bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 y +bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE y +bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 y +bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR y +bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST y #bool 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n fi @@ -75,56 +77,56 @@ else bool 'Dummy net driver support' CONFIG_DUMMY n -bool 'SLIP (serial line) support' CONFIG_SLIP n +bool 'SLIP (serial line) support' CONFIG_SLIP y if [ "$CONFIG_SLIP" = "y" ]; then bool ' CSLIP compressed headers' SL_COMPRESSED y # bool ' SLIP debugging on' SL_DUMP y fi -bool 'PPP (point-to-point) support' CONFIG_PPP n +bool 'PPP (point-to-point) support' CONFIG_PPP y bool 'PLIP (parallel port) support' CONFIG_PLIP n bool 'Load balancing support (experimental)' CONFIG_SLAVE_BALANCING n -bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA n -bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC n +bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA y +bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC y if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then - bool 'WD80*3 support' CONFIG_WD80x3 n - bool 'SMC Ultra support' CONFIG_ULTRA n + bool 'WD80*3 support' CONFIG_WD80x3 y + bool 'SMC Ultra support' CONFIG_ULTRA y fi bool '3COM cards' CONFIG_NET_VENDOR_3COM y if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then - bool '3c501 support' CONFIG_EL1 n - bool '3c503 support' CONFIG_EL2 n + bool '3c501 support' CONFIG_EL1 y + bool '3c503 support' CONFIG_EL2 y if [ "$CONFIG_NET_ALPHA" = "y" ]; then - bool '3c505 support' CONFIG_ELPLUS n - bool '3c507 support' CONFIG_EL16 n + bool '3c505 support' CONFIG_ELPLUS y + bool '3c507 support' CONFIG_EL16 y fi bool '3c509/3c579 support' CONFIG_EL3 y fi -bool 'Other ISA cards' CONFIG_NET_ISA n +bool 'Other ISA cards' CONFIG_NET_ISA y if [ "$CONFIG_NET_ISA" = "y" ]; then - bool 'AT1500 and NE2100 (LANCE and PCnet-ISA) support' CONFIG_LANCE n - bool 'Cabletron E21xx support (not recommended)' CONFIG_E2100 n - bool 'DEPCA support' CONFIG_DEPCA n + bool 'AT1500 and NE2100 (LANCE and PCnet-ISA) support' CONFIG_LANCE y + bool 'Cabletron E21xx support (not recommended)' CONFIG_E2100 y + bool 'DEPCA support' CONFIG_DEPCA y if [ "$CONFIG_NET_ALPHA" = "y" ]; then - bool 'EtherExpress support' CONFIG_EEXPRESS n - bool 'AT1700 support' CONFIG_AT1700 n + bool 'EtherExpress support' CONFIG_EEXPRESS y + bool 'AT1700 support' CONFIG_AT1700 y + bool 'NI5210 support' CONFIG_NI52 y + bool 'NI6510 support' CONFIG_NI65 y fi - bool 'HP PCLAN support' CONFIG_HPLAN n + bool 'HP PCLAN support' CONFIG_HPLAN y bool 'NE2000/NE1000 support' CONFIG_NE2000 y - bool 'SK_G16 support' CONFIG_SK_G16 n + bool 'SK_G16 support' CONFIG_SK_G16 y fi -bool 'EISA and on board controllers' CONFIG_NET_EISA n +bool 'EISA and on board controllers' CONFIG_NET_EISA y if [ "$CONFIG_NET_ALPHA" = "y" ]; then - bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n + bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 y fi - bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n -#bool 'NI52EE support' CONFIG_NI52 n -#bool 'NI65EE support' CONFIG_NI65 n -bool 'Pocket and portable adaptors' CONFIG_NET_POCKET n + bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT y +bool 'Pocket and portable adaptors' CONFIG_NET_POCKET y if [ "$CONFIG_NET_POCKET" = "y" ]; then - bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n - bool 'D-Link DE620 pocket adaptor support' CONFIG_DE620 n - bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n - bool 'Zenith Z-Note support' CONFIG_ZNET n + bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 y + bool 'D-Link DE620 pocket adaptor support' CONFIG_DE620 y + bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP y + bool 'Zenith Z-Note support' CONFIG_ZNET y fi fi fi @@ -149,30 +151,30 @@ bool 'Standard (minix) fs support' CONFIG_MINIX_FS y bool 'Extended fs support' CONFIG_EXT_FS n bool 'Second extended fs support' CONFIG_EXT2_FS y -bool 'xiafs filesystem support' CONFIG_XIA_FS n +bool 'xiafs filesystem support' CONFIG_XIA_FS y bool 'msdos fs support' CONFIG_MSDOS_FS y if [ "$CONFIG_MSDOS_FS" = "y" ]; then -bool 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS n +bool 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS y fi bool '/proc filesystem support' CONFIG_PROC_FS y if [ "$CONFIG_INET" = "y" ]; then bool 'NFS filesystem support' CONFIG_NFS_FS y fi -bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS n -bool 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS n +bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y +bool 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS y bool 'System V and Coherent filesystem support' CONFIG_SYSV_FS n comment 'character devices' -bool 'Parallel printer support' CONFIG_PRINTER n +bool 'Parallel printer support' CONFIG_PRINTER y bool 'Logitech busmouse support' CONFIG_BUSMOUSE n -bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE n +bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE y if [ "$CONFIG_PSMOUSE" = "y" ]; then bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE y fi bool 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n bool 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n -bool 'Selection (cut and paste for virtual consoles)' CONFIG_SELECTION n +bool 'Selection (cut and paste for virtual consoles)' CONFIG_SELECTION y bool 'QIC-02 tape support' CONFIG_QIC02_TAPE n if [ "$CONFIG_QIC02_TAPE" = "y" ]; then @@ -189,7 +191,7 @@ fi fi -bool 'QIC-117 tape support' CONFIG_FTAPE n +bool 'QIC-117 tape support' CONFIG_FTAPE y if [ "$CONFIG_FTAPE" = "y" ]; then int ' number of ftape buffers' NR_FTAPE_BUFFERS 3 fi @@ -203,5 +205,5 @@ #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC n bool 'Kernel profiling support' CONFIG_PROFILE n if [ "$CONFIG_SCSI" = "y" ]; then -bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS y +bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS n fi diff -u --recursive --new-file linux-1.1.55/config.old linux/config.old --- linux-1.1.55/config.old Wed Dec 31 18:00:00 1969 +++ linux/config.old Thu Oct 20 17:09:06 1994 @@ -0,0 +1,209 @@ +# +# For a description of the syntax of this configuration file, +# see the Configure script. +# + +comment 'General setup' + +bool 'Kernel math emulation' CONFIG_MATH_EMULATION y +bool 'Normal harddisk support' CONFIG_BLK_DEV_HD y +bool 'XT harddisk support' CONFIG_BLK_DEV_XD n +bool 'Networking support' CONFIG_NET y +bool 'Filesystem quota support' CONFIG_QUOTA n +bool 'Limit memory to low 16MB' CONFIG_MAX_16M n +bool 'System V IPC' CONFIG_SYSVIPC y +bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y +bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 y + +if [ "$CONFIG_NET" = "y" ]; then +comment 'Networking options' +bool 'TCP/IP networking' CONFIG_INET y +if [ "$CONFIG_INET" "=" "y" ]; then +bool 'IP forwarding/gatewaying' CONFIG_IP_FORWARD n +comment '(it is safe to leave these untouched)' +bool 'PC/TCP compatibility mode' CONFIG_INET_PCTCP n +bool 'Reverse ARP' CONFIG_INET_RARP n +bool 'Assume subnets are local' CONFIG_INET_SNARL y +bool 'Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n +fi +bool 'The IPX protocol' CONFIG_IPX n +#bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n +fi + +comment 'SCSI support' + +bool 'SCSI support?' CONFIG_SCSI y + +if [ "$CONFIG_SCSI" = "n" ]; then + +comment 'Skipping SCSI configuration options...' + +else + +comment 'SCSI support type (disk, tape, CDrom)' + +bool 'Scsi disk support' CONFIG_BLK_DEV_SD y +bool 'Scsi tape support' CONFIG_CHR_DEV_ST y +bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR y +bool 'Scsi generic support' CONFIG_CHR_DEV_SG n + +comment 'SCSI low-level drivers' + +bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X y +bool 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 y +bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 y +bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC y +bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN y +bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 y +bool 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx y +#bool 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 n +bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 y +bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE y +bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 y +bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR y +bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST y +#bool 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n +fi + + +if [ "$CONFIG_NET" = "y" ]; then + +comment 'Network device support' + +bool 'Network device support?' CONFIG_NETDEVICES y +if [ "$CONFIG_NETDEVICES" = "n" ]; then + +comment 'Skipping network driver configuration options...' + +else +bool 'Dummy net driver support' CONFIG_DUMMY n +bool 'SLIP (serial line) support' CONFIG_SLIP y +if [ "$CONFIG_SLIP" = "y" ]; then + bool ' CSLIP compressed headers' SL_COMPRESSED y +# bool ' SLIP debugging on' SL_DUMP y +fi +bool 'PPP (point-to-point) support' CONFIG_PPP y +bool 'PLIP (parallel port) support' CONFIG_PLIP n +bool 'Load balancing support (experimental)' CONFIG_SLAVE_BALANCING n +bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA n +bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC y +if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then + bool 'WD80*3 support' CONFIG_WD80x3 y + bool 'SMC Ultra support' CONFIG_ULTRA y +fi +bool '3COM cards' CONFIG_NET_VENDOR_3COM y +if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then + bool '3c501 support' CONFIG_EL1 y + bool '3c503 support' CONFIG_EL2 y + if [ "$CONFIG_NET_ALPHA" = "y" ]; then + bool '3c505 support' CONFIG_ELPLUS n + bool '3c507 support' CONFIG_EL16 n + fi + bool '3c509/3c579 support' CONFIG_EL3 y +fi +bool 'Other ISA cards' CONFIG_NET_ISA y +if [ "$CONFIG_NET_ISA" = "y" ]; then + bool 'AT1500 and NE2100 (LANCE and PCnet-ISA) support' CONFIG_LANCE y + bool 'Cabletron E21xx support (not recommended)' CONFIG_E2100 y + bool 'DEPCA support' CONFIG_DEPCA y + if [ "$CONFIG_NET_ALPHA" = "y" ]; then + bool 'EtherExpress support' CONFIG_EEXPRESS n + bool 'AT1700 support' CONFIG_AT1700 n + bool 'NI5210 support' CONFIG_NI52 n + bool 'NI6510 support' CONFIG_NI65 n + fi + bool 'HP PCLAN support' CONFIG_HPLAN y + bool 'NE2000/NE1000 support' CONFIG_NE2000 y + bool 'SK_G16 support' CONFIG_SK_G16 y +fi +bool 'EISA and on board controllers' CONFIG_NET_EISA y + if [ "$CONFIG_NET_ALPHA" = "y" ]; then + bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n + fi + bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT y +bool 'Pocket and portable adaptors' CONFIG_NET_POCKET y +if [ "$CONFIG_NET_POCKET" = "y" ]; then + bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 y + bool 'D-Link DE620 pocket adaptor support' CONFIG_DE620 y + bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP y + bool 'Zenith Z-Note support' CONFIG_ZNET y +fi +fi +fi + +comment 'CD-ROM drivers' + +bool 'Sony CDU31A/CDU33A CDROM driver support' CONFIG_CDU31A n +bool 'Mitsumi CDROM driver support' CONFIG_MCD n +bool 'Matsushita/Panasonic CDROM driver support' CONFIG_SBPCD n +if [ "$CONFIG_SBPCD" = "y" ]; then + bool 'Matsushita/Panasonic second CDROM controller support' CONFIG_SBPCD2 n + if [ "$CONFIG_SBPCD2" = "y" ]; then + bool 'Matsushita/Panasonic third CDROM controller support' CONFIG_SBPCD3 n + if [ "$CONFIG_SBPCD3" = "y" ]; then + bool 'Matsushita/Panasonic fourth CDROM controller support' CONFIG_SBPCD4 n + fi + fi +fi + +comment 'Filesystems' + +bool 'Standard (minix) fs support' CONFIG_MINIX_FS y +bool 'Extended fs support' CONFIG_EXT_FS n +bool 'Second extended fs support' CONFIG_EXT2_FS y +bool 'xiafs filesystem support' CONFIG_XIA_FS y +bool 'msdos fs support' CONFIG_MSDOS_FS y +if [ "$CONFIG_MSDOS_FS" = "y" ]; then +bool 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS y +fi +bool '/proc filesystem support' CONFIG_PROC_FS y +if [ "$CONFIG_INET" = "y" ]; then +bool 'NFS filesystem support' CONFIG_NFS_FS y +fi +bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y +bool 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS y +bool 'System V and Coherent filesystem support' CONFIG_SYSV_FS n + +comment 'character devices' + +bool 'Parallel printer support' CONFIG_PRINTER y +bool 'Logitech busmouse support' CONFIG_BUSMOUSE n +bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE y +if [ "$CONFIG_PSMOUSE" = "y" ]; then +bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE y +fi +bool 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n +bool 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n +bool 'Selection (cut and paste for virtual consoles)' CONFIG_SELECTION y + +bool 'QIC-02 tape support' CONFIG_QIC02_TAPE n +if [ "$CONFIG_QIC02_TAPE" = "y" ]; then +bool 'Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF y +if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then + +comment '>>> Edit configuration parameters in ./include/linux/tpqic02.h!' + +else + +comment '>>> Setting runtime QIC-02 configuration is done with qic02conf' +comment '>>> Which is available from ftp://ftp.funet.fi/pub/OS/Linux/BETA/QIC-02/' + +fi +fi + +bool 'QIC-117 tape support' CONFIG_FTAPE y +if [ "$CONFIG_FTAPE" = "y" ]; then +int ' number of ftape buffers' NR_FTAPE_BUFFERS 3 +fi + +comment 'Sound' + +bool 'Sound card support' CONFIG_SOUND n + +comment 'Kernel hacking' + +#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC n +bool 'Kernel profiling support' CONFIG_PROFILE n +if [ "$CONFIG_SCSI" = "y" ]; then +bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS n +fi diff -u --recursive --new-file linux-1.1.55/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- linux-1.1.55/drivers/block/ll_rw_blk.c Sat Sep 17 21:50:28 1994 +++ linux/drivers/block/ll_rw_blk.c Thu Oct 20 17:01:16 1994 @@ -149,6 +149,23 @@ static void add_request(struct blk_dev_struct * dev, struct request * req) { struct request * tmp; + short disk_index; + + switch (MAJOR(req->dev)) { + case SCSI_DISK_MAJOR: + disk_index = (MINOR(req->dev) & 0x0070) >> 4; + if (disk_index < 4) + kstat.dk_drive[disk_index]++; + break; + case HD_MAJOR: + case XT_DISK_MAJOR: + disk_index = (MINOR(req->dev) & 0x00C0) >> 6; + if (disk_index < 4) + kstat.dk_drive[disk_index]++; + break; + default: + break; + } req->next = NULL; cli(); diff -u --recursive --new-file linux-1.1.55/fs/Makefile linux/fs/Makefile --- linux-1.1.55/fs/Makefile Thu Oct 20 15:14:26 1994 +++ linux/fs/Makefile Thu Oct 20 17:01:16 1994 @@ -56,9 +56,9 @@ .s.o: $(AS) -o $*.o $< -OBJS= open.o read_write.o inode.o devices.o file_table.o buffer.o super.o \ - block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \ - select.o fifo.o locks.o filesystems.o dcache.o $(BINFMTS) +OBJS= open.o read_write.o inode.o devices.o file_table.o fileio.o buffer.o \ + super.o block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \ + select.o fifo.o locks.o dcache.o dquot.o filesystems.o $(BINFMTS) all: fs.o filesystems.a modules diff -u --recursive --new-file linux-1.1.55/fs/binfmt_elf.c linux/fs/binfmt_elf.c --- linux-1.1.55/fs/binfmt_elf.c Thu Oct 20 15:14:27 1994 +++ linux/fs/binfmt_elf.c Thu Oct 20 17:01:16 1994 @@ -497,6 +497,8 @@ current->mm->end_code = 0; current->mm->start_mmap = ELF_START_MMAP; current->mm->mmap = NULL; + current->flags &= ~PF_FORKNOEXEC; /* accounting flags */ + current->io_usage = 0; elf_entry = (unsigned int) elf_ex.e_entry; /* Do this so that we can load the interpreter, if need be. We will diff -u --recursive --new-file linux-1.1.55/fs/buffer.c linux/fs/buffer.c --- linux-1.1.55/fs/buffer.c Thu Oct 13 21:31:07 1994 +++ linux/fs/buffer.c Thu Oct 20 17:01:16 1994 @@ -217,6 +217,9 @@ sync_supers(dev); sync_inodes(dev); sync_buffers(dev, 0); +#ifdef CONFIG_QUOTA + sync_dquots(dev, -1); +#endif } int fsync_dev(dev_t dev) @@ -224,6 +227,9 @@ sync_buffers(dev, 0); sync_supers(dev); sync_inodes(dev); +#ifdef CONFIG_QUOTA + sync_dquots(dev, -1); +#endif return sync_buffers(dev, 1); } diff -u --recursive --new-file linux-1.1.55/fs/dquot.c linux/fs/dquot.c --- linux-1.1.55/fs/dquot.c Wed Dec 31 18:00:00 1969 +++ linux/fs/dquot.c Thu Oct 20 17:01:17 1994 @@ -0,0 +1,1008 @@ +/* + * QUOTA An implementation of the diskquota system for the LINUX operating + * system. QUOTA is implemented using the BSD systemcall interface as + * the means of communication with the user level. Should work for all + * filesystems because of integration into the VFS layer of the + * operating system. This is based on the Melbourne quota system wich + * uses both user and group quota files. + * + * Main layer of quota management + * + * Version: $Id: dquot.c,v 3.11 1994/10/17 09:52:47 mvw Exp mvw $ + * + * Authors: Marco van Wieringen + * Edvard Tuinder + * Linus Torvalds + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + */ + +#include +#include +#include +#include + +#ifdef CONFIG_QUOTA +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static char quotamessage[MAX_QUOTA_MESSAGE]; +static char *quotatypes[] = INITQFNAMES; + +static int nr_dquots = 0, nr_free_dquots = 0; +static struct dquot *hash_table[NR_DQHASH]; +static struct dquot *first_dquot; + +static struct wait_queue *dquot_wait = (struct wait_queue *)NULL; + +extern void add_dquot_ref(dev_t dev, short type); +extern void reset_dquot_ptrs(dev_t dev, short type); +extern void close_fp(struct file *filp, int fd); + +#ifndef min +#define min(a,b) ((a) < (b)) ? (a) : (b) +#endif + +/* + * Functions for management of the hashlist. + */ +static inline int const hashfn(dev_t dev, unsigned int id, short type) +{ + return ((dev ^ id) * (MAXQUOTAS - type)) % NR_DQHASH; +} + +static inline struct dquot **const hash(dev_t dev, unsigned int id, short type) +{ + return hash_table + hashfn(dev, id, type); +} + +static void insert_dquot_free(struct dquot *dquot) +{ + dquot->dq_next = first_dquot; + dquot->dq_prev = first_dquot->dq_prev; + dquot->dq_next->dq_prev = dquot; + dquot->dq_prev->dq_next = dquot; + first_dquot = dquot; +} + +static void remove_dquot_free(struct dquot *dquot) +{ + if (first_dquot == dquot) + first_dquot = first_dquot->dq_next; + if (dquot->dq_next) + dquot->dq_next->dq_prev = dquot->dq_prev; + if (dquot->dq_prev) + dquot->dq_prev->dq_next = dquot->dq_next; + dquot->dq_next = dquot->dq_prev = NODQUOT; +} + +static void insert_dquot_hash(struct dquot *dquot) +{ + struct dquot **h; + + h = hash(dquot->dq_dev, dquot->dq_id, dquot->dq_type); + dquot->dq_hash_next = *h; + dquot->dq_hash_prev = NODQUOT; + if (dquot->dq_hash_next) + dquot->dq_hash_next->dq_hash_prev = dquot; + *h = dquot; +} + +static void remove_dquot_hash(struct dquot *dquot) +{ + struct dquot **h; + + h = hash(dquot->dq_dev, dquot->dq_id, dquot->dq_type); + if (*h == dquot) + *h = dquot->dq_hash_next; + if (dquot->dq_hash_next) + dquot->dq_hash_next->dq_hash_prev = dquot->dq_hash_prev; + if (dquot->dq_hash_prev) + dquot->dq_hash_prev->dq_hash_next = dquot->dq_hash_next; + dquot->dq_hash_prev = dquot->dq_hash_next = NODQUOT; +} + +static void put_last_free(struct dquot *dquot) +{ + remove_dquot_free(dquot); + dquot->dq_prev = first_dquot->dq_prev; + dquot->dq_prev->dq_next = dquot; + dquot->dq_next = first_dquot; + dquot->dq_next->dq_prev = dquot; +} + +static void grow_dquots(void) +{ + struct dquot *dquot; + int i; + + if (!(dquot = (struct dquot*) get_free_page(GFP_KERNEL))) + return; + i = PAGE_SIZE / sizeof(struct dquot); + nr_dquots += i; + nr_free_dquots += i; + if (!first_dquot) + dquot->dq_next = dquot->dq_prev = first_dquot = dquot++, i--; + for ( ; i ; i-- ) + insert_dquot_free(dquot++); +} + +/* + * Functions for locking and waiting on dquots. + */ +static void __wait_on_dquot(struct dquot *dquot) +{ + struct wait_queue wait = {current, NULL}; + + add_wait_queue(&dquot->dq_wait, &wait); +repeat: + current->state = TASK_UNINTERRUPTIBLE; + if (dquot->dq_flags & DQ_LOCKED) { + dquot->dq_flags |= DQ_WANT; + schedule(); + goto repeat; + } + remove_wait_queue(&dquot->dq_wait, &wait); + current->state = TASK_RUNNING; +} + +static inline void wait_on_dquot(struct dquot *dquot) +{ + if (dquot->dq_flags & DQ_LOCKED) + __wait_on_dquot(dquot); +} + +static inline void lock_dquot(struct dquot *dquot) +{ + wait_on_dquot(dquot); + dquot->dq_flags |= DQ_LOCKED; +} + +static inline void unlock_dquot(struct dquot *dquot) +{ + dquot->dq_flags &= ~DQ_LOCKED; + if (dquot->dq_flags & DQ_WANT) { + dquot->dq_flags &= ~DQ_WANT; + wake_up(&dquot->dq_wait); + } +} +/* + * Note that we don't want to disturb any wait-queues when we discard + * an dquot. + * + * FIXME: As soon as we have a nice solution for the inode problem we + * can also fix this one. I.e. the volatile part. + */ +static void clear_dquot(struct dquot * dquot) +{ + struct wait_queue *wait; + + wait_on_dquot(dquot); + remove_dquot_hash(dquot); + remove_dquot_free(dquot); + wait = ((volatile struct dquot *) dquot)->dq_wait; + if (dquot->dq_count) + nr_free_dquots++; + memset(dquot, 0, sizeof(*dquot)); + ((volatile struct dquot *) dquot)->dq_wait = wait; + insert_dquot_free(dquot); +} + +static void write_dquot(struct dquot *dquot) +{ + short type = dquot->dq_type; + struct file *filp = dquot->dq_mnt->mnt_quotas[type]; + unsigned short fs; + + if (!(dquot->dq_flags & DQ_MOD) || (filp == (struct file *)0)) + return; + lock_dquot(dquot); + down(&dquot->dq_mnt->mnt_sem); + if (filp->f_op->lseek) { + if (filp->f_op->lseek(filp->f_inode, filp, + dqoff(dquot->dq_id), 0) != dqoff(dquot->dq_id)) { + up(&dquot->dq_mnt->mnt_sem); + return; + } + } else + filp->f_pos = dqoff(dquot->dq_id); + fs = get_fs(); + set_fs(KERNEL_DS); + if (filp->f_op->write(filp->f_inode, filp, + (char *)&dquot->dq_dqb, sizeof(struct dqblk)) == sizeof(struct dqblk)) + dquot->dq_flags &= ~DQ_MOD; + up(&dquot->dq_mnt->mnt_sem); + set_fs(fs); + unlock_dquot(dquot); +} + +static void read_dquot(struct dquot *dquot) +{ + short type = dquot->dq_type; + struct file *filp = dquot->dq_mnt->mnt_quotas[type]; + unsigned short fs; + + if (filp == (struct file *)0) + return; + lock_dquot(dquot); + down(&dquot->dq_mnt->mnt_sem); + if (filp->f_op->lseek) { + if (filp->f_op->lseek(filp->f_inode, filp, + dqoff(dquot->dq_id),0) != dqoff(dquot->dq_id)) { + up(&dquot->dq_mnt->mnt_sem); + return; + } + } else + filp->f_pos = dqoff(dquot->dq_id); + fs = get_fs(); + set_fs(KERNEL_DS); + filp->f_op->read(filp->f_inode, filp, + (char *)&dquot->dq_dqb, sizeof(struct dqblk)); + up(&dquot->dq_mnt->mnt_sem); + set_fs(fs); + if (dquot->dq_bhardlimit == 0 && dquot->dq_bsoftlimit == 0 && + dquot->dq_ihardlimit == 0 && dquot->dq_isoftlimit == 0) + dquot->dq_flags |= DQ_FAKE; + unlock_dquot(dquot); +} + +int sync_dquots(dev_t dev, short type) +{ + struct dquot *dquot = first_dquot; + int i; + + for(i = 0; i < nr_dquots * 2; i++, dquot = dquot->dq_next) { + if (!dquot->dq_count || (dev && dquot->dq_dev != dev)) + continue; + if (type != -1 && dquot->dq_type != type) + continue; + wait_on_dquot(dquot); + if (dquot->dq_flags & DQ_MOD) + write_dquot(dquot); + } + return 0; + /* NOTREACHED */ +} + +/* + * Trash the cache for a certain type on a device. + */ +void invalidate_dquots(dev_t dev, short type) +{ + struct dquot *dquot, *next; + int i; + + next = first_dquot; + for(i = nr_dquots ; i > 0 ; i--) { + dquot = next; + next = dquot->dq_next; + if (dquot->dq_dev != dev || dquot->dq_type != type) + continue; + if (dquot->dq_flags & DQ_LOCKED) { + printk("VFS: dquot busy on removed device %d/%d\n", MAJOR(dev), MINOR(dev)); + continue; + } + if (dquot->dq_flags & DQ_MOD) + write_dquot(dquot); + clear_dquot(dquot); + } +} + +/* + * Check quota for inodes. Returns QUOTA_OK if can allocate and + * NO_QUOTA if it can't. + */ +static int check_idq(struct dquot *dquot, int id, short type, u_long wanted_inodes) +{ + if (wanted_inodes == 0 || dquot->dq_flags & DQ_FAKE) + return QUOTA_OK; + if (dquot->dq_ihardlimit && + (dquot->dq_curinodes + wanted_inodes) >= dquot->dq_ihardlimit) { + if (!(dquot->dq_flags & DQ_INODES)) { + sprintf(quotamessage, + "File LIMIT reached on %s for %s %d. !! NO MORE !!\n\r", + dquot->dq_mnt->mnt_devname, quotatypes[type], id); + tty_write_message(current->tty, quotamessage); + dquot->dq_flags |= DQ_INODES; + } + return NO_QUOTA; + } + if (dquot->dq_isoftlimit && + (dquot->dq_curinodes + wanted_inodes) >= dquot->dq_isoftlimit && + dquot->dq_itime && CURRENT_TIME >= dquot->dq_itime) { + sprintf(quotamessage, + "File QUOTA exceeded TOO long on %s for %s %d. !! NO MORE !!\n\r", + dquot->dq_mnt->mnt_devname, quotatypes[type], id); + tty_write_message(current->tty, quotamessage); + return NO_QUOTA; + } + if (dquot->dq_isoftlimit && + (dquot->dq_curinodes + wanted_inodes) >= dquot->dq_isoftlimit && + dquot->dq_itime == 0) { + sprintf(quotamessage, + "File QUOTA exceeded on %s for %s %d\n\r", + dquot->dq_mnt->mnt_devname, quotatypes[type], id); + tty_write_message(current->tty, quotamessage); + dquot->dq_itime = CURRENT_TIME + dquot->dq_mnt->mnt_iexp[type]; + } + return QUOTA_OK; + /* NOTREACHED */ +} + +/* + * Check quota for blocks. Returns QUOTA_OK if can allocate and + * NO_QUOTA if it can't. When we can't allocate wanted_blocks you get + * the number we can allocate in avail_blocks. + */ +static int check_bdq(struct dquot *dquot, int id, short type, + u_long wanted_blocks, u_long *avail_blocks) +{ + *avail_blocks = wanted_blocks; + if (wanted_blocks == 0 || dquot->dq_flags & DQ_FAKE) + return QUOTA_OK; + if (dquot->dq_bhardlimit && + (dquot->dq_curblocks + wanted_blocks) >= dquot->dq_bhardlimit) { + if ((dquot->dq_flags & DQ_BLKS) == 0) { + sprintf(quotamessage, + "Block LIMIT reached on %s for %s %d. !! NO MORE !!\n\r", + dquot->dq_mnt->mnt_devname, quotatypes[type], id); + tty_write_message(current->tty, quotamessage); + dquot->dq_flags |= DQ_BLKS; + } + if (dquot->dq_curblocks < dquot->dq_bhardlimit) { + *avail_blocks = dquot->dq_bhardlimit - dquot->dq_curblocks; + return QUOTA_OK; + } else + return NO_QUOTA; + } + if (dquot->dq_bsoftlimit && + (dquot->dq_curblocks + wanted_blocks) >= dquot->dq_bsoftlimit && + dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime) { + sprintf(quotamessage, + "Block QUOTA exceeded TOO long on %s for %s %d. !! NO MORE !!\n\r", + dquot->dq_mnt->mnt_devname, quotatypes[type], id); + tty_write_message(current->tty, quotamessage); + return NO_QUOTA; + } + if (dquot->dq_bsoftlimit && + (dquot->dq_curblocks + wanted_blocks) >= dquot->dq_bsoftlimit && + dquot->dq_btime == 0) { + sprintf(quotamessage, + "Block QUOTA exceeded on %s for %s %d\n\r", + dquot->dq_mnt->mnt_devname, quotatypes[type], id); + tty_write_message(current->tty, quotamessage); + dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_bexp[type]; + } + return QUOTA_OK; + /* NOTREACHED */ +} + +/* + * Add a number of inodes and blocks to a diskquota. + */ +static inline void incr_quota(struct dquot *dquot, u_long inodes, u_long blocks) +{ + lock_dquot(dquot); + dquot->dq_curinodes += inodes; + dquot->dq_curblocks += blocks; + dquot->dq_flags |= DQ_MOD; + unlock_dquot(dquot); +} + +/* + * Remove a number of inodes and blocks from a quota. + * Reset gracetimes if under softlimit. + */ +static inline void decr_quota(struct dquot *dquot, u_long inodes, u_long blocks) +{ + lock_dquot(dquot); + if (dquot->dq_curinodes >= inodes) + dquot->dq_curinodes -= inodes; + else + dquot->dq_curinodes = 0; + if (dquot->dq_curinodes < dquot->dq_isoftlimit) + dquot->dq_itime = (time_t) 0; + dquot->dq_flags &= ~DQ_INODES; + if (dquot->dq_curblocks >= blocks) + dquot->dq_curblocks -= blocks; + else + dquot->dq_curblocks = 0; + if (dquot->dq_curblocks < dquot->dq_bsoftlimit) + dquot->dq_btime = (time_t) 0; + dquot->dq_flags &= ~DQ_BLKS; + dquot->dq_flags |= DQ_MOD; + unlock_dquot(dquot); +} + +/* + * Initialize a dquot-struct with new quota info. This is used by the + * systemcall interface functions. + */ +static int set_dqblk(dev_t dev, int id, short type, int flags, struct dqblk *dqblk) +{ + struct dquot *dquot; + struct dqblk dq_dqblk; + int error; + + if (dqblk == (struct dqblk *)0) + return -EFAULT; + + if (flags & QUOTA_SYSCALL) { + if ((error = verify_area(VERIFY_READ, dqblk, sizeof(struct dqblk))) != 0) + return error; + memcpy_fromfs(&dq_dqblk, dqblk, sizeof(struct dqblk)); + } else { + memcpy(&dq_dqblk, dqblk, sizeof(struct dqblk)); + } + if ((dquot = dqget(dev, id, type)) != NODQUOT) { + lock_dquot(dquot); + if (id > 0 && ((flags & SET_QUOTA) || (flags & SET_QLIMIT))) { + dquot->dq_bhardlimit = dq_dqblk.dqb_bhardlimit; + dquot->dq_bsoftlimit = dq_dqblk.dqb_bsoftlimit; + dquot->dq_ihardlimit = dq_dqblk.dqb_ihardlimit; + dquot->dq_isoftlimit = dq_dqblk.dqb_isoftlimit; + } + if ((flags & SET_QUOTA) || (flags & SET_USE)) { + if (dquot->dq_isoftlimit && + dquot->dq_curinodes < dquot->dq_isoftlimit && + dq_dqblk.dqb_curinodes >= dquot->dq_isoftlimit) + dquot->dq_itime = CURRENT_TIME + dquot->dq_mnt->mnt_iexp[type]; + dquot->dq_curinodes = dq_dqblk.dqb_curinodes; + if (dquot->dq_curinodes < dquot->dq_isoftlimit) + dquot->dq_flags &= ~DQ_INODES; + if (dquot->dq_bsoftlimit && + dquot->dq_curblocks < dquot->dq_bsoftlimit && + dq_dqblk.dqb_curblocks >= dquot->dq_bsoftlimit) + dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_bexp[type]; + dquot->dq_curblocks = dq_dqblk.dqb_curblocks; + if (dquot->dq_curblocks < dquot->dq_bsoftlimit) + dquot->dq_flags &= ~DQ_BLKS; + } + if (id == 0) { + /* + * Change in expiretimes, change them in dq_mnt. + */ + dquot->dq_mnt->mnt_bexp[type] = dquot->dq_btime = dq_dqblk.dqb_btime; + dquot->dq_mnt->mnt_iexp[type] = dquot->dq_itime = dq_dqblk.dqb_itime; + } + if (dq_dqblk.dqb_bhardlimit == 0 && dq_dqblk.dqb_bsoftlimit == 0 && + dq_dqblk.dqb_ihardlimit == 0 && dq_dqblk.dqb_isoftlimit == 0) + dquot->dq_flags |= DQ_FAKE; /* No limits, only usage */ + dquot->dq_flags |= DQ_MOD; + unlock_dquot(dquot); + dqput(dquot); + } + return 0; +} + +static int get_quota(dev_t dev, int id, short type, struct dqblk * dqblk) +{ + struct vfsmount *vfsmnt; + struct dquot *dquot; + int error; + + if ((vfsmnt = lookup_vfsmnt(dev)) != (struct vfsmount *)0 && + vfsmnt->mnt_quotas[type] != (struct file *)0) { + if (dqblk == (struct dqblk *) 0) + return -EFAULT; + + if ((error = verify_area(VERIFY_WRITE, dqblk, sizeof(struct dqblk))) != 0) + return (error); + + if ((dquot = dqget(dev, id, type)) != NODQUOT) { + memcpy_tofs(dqblk, (char *)&dquot->dq_dqb, sizeof(struct dqblk)); + dqput(dquot); + return 0; + } + } + return -ESRCH; +} + +/* + * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) + */ +int quota_off(dev_t dev, short type) +{ + struct vfsmount *vfsmnt; + short cnt; + + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (type != -1 && cnt != type) + continue; + if ((vfsmnt = lookup_vfsmnt(dev)) == (struct vfsmount *)0 || + vfsmnt->mnt_quotas[cnt] == (struct file *)0) + continue; + vfsmnt->mnt_flags |= QF_CLOSING; + reset_dquot_ptrs(dev, cnt); + invalidate_dquots(dev, cnt); + close_fp(vfsmnt->mnt_quotas[cnt], 0); + vfsmnt->mnt_quotas[cnt] = (struct file *)0; + vfsmnt->mnt_iexp[cnt] = vfsmnt->mnt_bexp[cnt] = (time_t)0; + vfsmnt->mnt_flags &= ~QF_CLOSING; + } + return 0; +} + +static int quota_on(dev_t dev, short type, char *path) +{ + struct file *filp = (struct file *)0; + struct vfsmount *vfsmnt; + struct inode *inode; + struct dquot *dquot; + char *tmp; + int error; + + if ((vfsmnt = lookup_vfsmnt(dev)) == (struct vfsmount *)0) + return -ENODEV; + if (vfsmnt->mnt_quotas[type] != (struct file *)0) + return -EBUSY; + if ((error = getname(path, &tmp)) != 0) + return (error); + vfsmnt->mnt_flags |= QF_OPENING; + error = open_namei(tmp, O_RDWR, 0600, &inode, 0); + putname(tmp); + if (error) { + vfsmnt->mnt_flags &= ~QF_OPENING; + return (error); + } + if (!S_ISREG(inode->i_mode)) { + vfsmnt->mnt_flags &= ~QF_OPENING; + iput(inode); + return -EACCES; + } + if (!inode->i_op || !inode->i_op->default_file_ops) + goto end_quotaon; + if ((filp = get_empty_filp()) == (struct file *)0) + goto end_quotaon; + filp->f_mode = (O_RDWR + 1) & O_ACCMODE; + filp->f_flags = O_RDWR; + filp->f_inode = inode; + filp->f_pos = 0; + filp->f_reada = 0; + filp->f_op = inode->i_op->default_file_ops; + if (filp->f_op->open) + if (filp->f_op->open(filp->f_inode, filp)) + goto end_quotaon; + if (!filp->f_op->read || !filp->f_op->write) + goto end_quotaon; + vfsmnt->mnt_quotas[type] = filp; + vfs_open(filp); + vfsmnt->mnt_flags &= ~QF_OPENING; + dquot = dqget(dev, 0, type); + vfsmnt->mnt_iexp[type] = (dquot) ? dquot->dq_itime : MAX_IQ_TIME; + vfsmnt->mnt_bexp[type] = (dquot) ? dquot->dq_btime : MAX_DQ_TIME; + dqput(dquot); + add_dquot_ref(dev, type); + return 0; +end_quotaon: + vfsmnt->mnt_flags &= ~QF_OPENING; + if (filp != (struct file *)0) + filp->f_count--; + iput(inode); + return -EIO; +} + +/* + * Just like iput, decrement referencecount of dquot. + */ +void dqput(struct dquot *dquot) +{ + if (!dquot) + return; + /* + * If the dq_mnt pointer isn't initialized this entry needs no + * checking and doesn't need to be written. It just an empty + * dquot that is put back into the freelist. + */ + if (dquot->dq_mnt != (struct vfsmount *)0) { + wait_on_dquot(dquot); + if (!dquot->dq_count) { + printk("VFS: iput: trying to free free dquot\n"); + printk("VFS: device %d/%d, dquot of %s %d\n", + MAJOR(dquot->dq_dev), MINOR(dquot->dq_dev), + quotatypes[dquot->dq_type], dquot->dq_id); + return; + } +repeat: + if (dquot->dq_count > 1) { + dquot->dq_count--; + return; + } + wake_up(&dquot_wait); + if (dquot->dq_flags & DQ_MOD) { + write_dquot(dquot); /* we can sleep - so do again */ + wait_on_dquot(dquot); + goto repeat; + } + } + if (dquot->dq_count) { + dquot->dq_count--; + nr_free_dquots++; + } + return; +} + +static struct dquot *get_empty_dquot(void) +{ + struct dquot *dquot, *best; + int i; + + if (nr_dquots < NR_DQUOTS && nr_free_dquots < (nr_dquots >> 2)) + grow_dquots(); + +repeat: + dquot = first_dquot; + best = NODQUOT; + for (i = 0; i < nr_dquots; dquot = dquot->dq_next, i++) { + if (!dquot->dq_count) { + if (!best) + best = dquot; + if (!(dquot->dq_flags & DQ_MOD) && !(dquot->dq_flags & DQ_LOCKED)) { + best = dquot; + break; + } + } + } + if (!best || best->dq_flags & DQ_MOD || best->dq_flags & DQ_LOCKED) + if (nr_dquots < NR_DQUOTS) { + grow_dquots(); + goto repeat; + } + dquot = best; + if (!dquot) { + printk("VFS: No free dquots - contact mvw@mcs.ow.org\n"); + sleep_on(&dquot_wait); + goto repeat; + } + if (dquot->dq_flags & DQ_LOCKED) { + wait_on_dquot(dquot); + goto repeat; + } + if (dquot->dq_flags & DQ_MOD) { + write_dquot(dquot); + goto repeat; + } + if (dquot->dq_count) + goto repeat; + clear_dquot(dquot); + dquot->dq_count = 1; + nr_free_dquots--; + if (nr_free_dquots < 0) { + printk ("VFS: get_empty_dquot: bad free dquot count.\n"); + nr_free_dquots = 0; + } + return dquot; +} + +/* + * Just like iget, increment referencecount of a dquot and return + * pointer to it in the hashqueue. + */ +struct dquot *dqget(dev_t dev, unsigned int id, short type) +{ + struct dquot *dquot, *empty; + struct vfsmount *vfsmnt; + + if ((vfsmnt = lookup_vfsmnt(dev)) == (struct vfsmount *)0 || + (vfsmnt->mnt_flags & (QF_OPENING | QF_CLOSING)) || + (vfsmnt->mnt_quotas[type] == (struct file *)0)) + return (NODQUOT); + empty = get_empty_dquot(); +repeat: + dquot = *(hash(dev, id, type)); + while (dquot) { + if (dquot->dq_dev != dev || dquot->dq_id != id) { + dquot = dquot->dq_hash_next; + continue; + } + wait_on_dquot(dquot); + if (dquot->dq_dev != dev || dquot->dq_id != id) + goto repeat; + if (!dquot->dq_count) + nr_free_dquots--; + dquot->dq_count++; + if (empty) + dqput(empty); + return dquot; + } + if (!empty) + return (NODQUOT); + dquot = empty; + dquot->dq_id = id; + dquot->dq_type = type; + dquot->dq_dev = dev; + dquot->dq_mnt = vfsmnt; + put_last_free(dquot); + insert_dquot_hash(dquot); + read_dquot(dquot); + return dquot; +} + +/* + * Initialize pointer in a inode to the right dquots. + * Be smart and increment count only if already valid pointervalue. + */ +void getinoquota(struct inode *inode, short type) +{ + unsigned int id = 0; + short cnt; + + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (type != -1 && cnt != type) + continue; + if (inode->i_dquot[cnt] != NODQUOT) { + inode->i_dquot[cnt]->dq_count++; + continue; + } + switch (cnt) { + case USRQUOTA: + id = inode->i_uid; + break; + case GRPQUOTA: + id = inode->i_gid; + break; + } + inode->i_dquot[cnt] = dqget(inode->i_dev, id, cnt); + } +} + +void putinoquota(struct inode *inode) +{ + short cnt; + + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (inode->i_dquot[cnt] == NODQUOT) + continue; + dqput(inode->i_dquot[cnt]); + if (!inode->i_writecount) + inode->i_dquot[cnt] = NODQUOT; + } +} + +/* + * This are two simple algorithms that calculates the size of a file in blocks + * and from a number of blocks to a isize. + * It is not perfect but works most of the time. + */ +u_long isize_to_blocks(size_t isize, size_t blksize) +{ + u_long blocks; + u_long indirect; + + if (!blksize) + blksize = BLOCK_SIZE; + blocks = (isize / blksize) + ((isize % blksize) ? 1 : 0); + if (blocks > 10) { + indirect = ((blocks - 11) >> 8) + 1; /* single indirect blocks */ + if (blocks > (10 + 256)) { + indirect += ((blocks - 267) >> 16) + 1; /* double indirect blocks */ + if (blocks > (10 + 256 + (256 << 8))) + indirect++; /* triple indirect blocks */ + } + blocks += indirect; + } + return blocks; +} + +size_t blocks_to_isize(u_long blocks, size_t blksize) +{ + size_t isize; + u_long indirect; + + if (!blksize) + blksize = BLOCK_SIZE; + isize = blocks * blksize; + if (blocks > 10) { + indirect = ((blocks - 11) >> 8) + 1; /* single indirect blocks */ + if (blocks > (10 + 256)) { + indirect += ((blocks - 267) >> 16) + 1; /* double indirect blocks */ + if (blocks > (10 + 256 + (256 << 8))) + indirect++; /* triple indirect blocks */ + } + isize -= indirect * blksize; + } + return isize; +} + +/* + * Allocate the number of inodes and blocks from a diskquota. + */ +int quota_alloc(struct inode *inode, u_long wanted_inodes, u_long wanted_blocks, + u_long *avail_blocks) +{ + u_long availblocks, local_avail; + unsigned short cnt; + + availblocks = wanted_blocks; + if (wanted_inodes > 0 || wanted_blocks > 0) { + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (inode->i_dquot[cnt] == NODQUOT) + continue; + if (check_idq(inode->i_dquot[cnt], inode->i_dquot[cnt]->dq_id, + cnt, wanted_inodes) == NO_QUOTA || + check_bdq(inode->i_dquot[cnt], inode->i_dquot[cnt]->dq_id, + cnt, wanted_blocks, &local_avail) == NO_QUOTA) + return NO_QUOTA; + availblocks = min(availblocks, local_avail); + } + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (inode->i_dquot[cnt] == NODQUOT) + continue; + incr_quota(inode->i_dquot[cnt], wanted_inodes, availblocks); + } + } + if (avail_blocks != (u_long *)0) + *avail_blocks = availblocks; + return QUOTA_OK; + /* NOTREACHED */ +} + +/* + * Remove the number of inodes and blocks from a diskquota. + */ +void quota_remove(struct inode *inode, u_long inodes, u_long blocks) +{ + short cnt; + + if (inodes > 0 || blocks > 0) { + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (inode->i_dquot[cnt] == NODQUOT) + continue; + decr_quota(inode->i_dquot[cnt], inodes, blocks); + } + } +} + +/* + * Transfer the number of inode and blocks from one diskquota to an other. + */ +int quota_transfer(struct inode *inode, uid_t newuid, gid_t newgid, + u_long inodes, u_long blocks) +{ + struct dquot *transfer_to[MAXQUOTAS]; + u_long availblocks; + unsigned int id = 0; + short cnt, disc; + + if (inodes > 0 || blocks > 0) { + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + transfer_to[cnt] = NODQUOT; + switch(cnt) { + case USRQUOTA: + if (inode->i_uid == newuid) + continue; + id = newuid; + break; + case GRPQUOTA: + if (inode->i_gid == newgid) + continue; + id = newgid; + break; + } + if ((transfer_to[cnt] = dqget(inode->i_dev, id, cnt)) == NODQUOT) + continue; + + if (check_idq(transfer_to[cnt], id, cnt, inodes) == NO_QUOTA || + check_bdq(transfer_to[cnt], id, cnt, blocks, &availblocks) == NO_QUOTA || + availblocks != blocks) { + for (disc = 0; disc <= cnt; disc++) + dqput(transfer_to[disc]); + return NO_QUOTA; + } + } + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (transfer_to[cnt] == NODQUOT) + continue; + decr_quota(inode->i_dquot[cnt], inodes, blocks); + incr_quota(transfer_to[cnt], inodes, blocks); + transfer_to[cnt]->dq_count += inode->i_writecount; + inode->i_dquot[cnt]->dq_count -= inode->i_writecount; + dqput(inode->i_dquot[cnt]); + inode->i_dquot[cnt] = transfer_to[cnt]; + } + } + return QUOTA_OK; + /* NOTREACHED */ +} + +void quota_init(void) +{ + memset(hash_table, 0, sizeof(hash_table)); + first_dquot = NODQUOT; +} + +/* + * Ok this is the systemcall interface, this communicates with + * the userlevel programs. + */ +asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr) +{ + int cmds = 0, type = 0, flags = 0; + struct vfsmount *vfsmnt; + struct inode *ino; + dev_t dev; + + cmds = cmd >> SUBCMDSHIFT; + type = cmd & SUBCMDMASK; + + if ((u_int) type >= MAXQUOTAS) + return -EINVAL; + switch (cmds) { + case Q_SYNC: + break; + case Q_GETQUOTA: + if (((type == USRQUOTA && current->uid != id) || + (type == GRPQUOTA && current->gid != id)) && !suser()) + return -EPERM; + break; + default: + if (!suser()) + return -EPERM; + } + + if (special == (char *)0 && cmds == Q_SYNC) + dev = 0; + else { + if (namei(special, &ino)) + return -EINVAL; + dev = ino->i_rdev; + if (!S_ISBLK(ino->i_mode)) { + iput(ino); + return -ENOTBLK; + } + iput(ino); + } + + switch (cmds) { + case Q_QUOTAON: + return quota_on(dev, type, (char *) addr); + case Q_QUOTAOFF: + return quota_off(dev, type); + case Q_GETQUOTA: + return get_quota(dev, id, type, (struct dqblk *) addr); + case Q_SETQUOTA: + flags |= SET_QUOTA; + break; + case Q_SETUSE: + flags |= SET_USE; + break; + case Q_SETQLIM: + flags |= SET_QLIMIT; + break; + case Q_SYNC: + return sync_dquots(dev, type); + default: + return -EINVAL; + } + + flags |= QUOTA_SYSCALL; + if ((vfsmnt = lookup_vfsmnt(dev)) != (struct vfsmount *)0 && + vfsmnt->mnt_quotas[type] != (struct file *)0) + return set_dqblk(dev, id, type, flags, (struct dqblk *) addr); + return -ESRCH; + /* NOTREACHED */ +} + +#else + +asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr) +{ + return -ENOSYS; +} + +#endif /* CONFIG_QUOTA */ + diff -u --recursive --new-file linux-1.1.55/fs/exec.c linux/fs/exec.c --- linux-1.1.55/fs/exec.c Thu Oct 20 15:14:26 1994 +++ linux/fs/exec.c Thu Oct 20 17:01:17 1994 @@ -43,6 +43,7 @@ #include #include +#include #include #include @@ -137,6 +138,7 @@ return error; } } + vfs_open(f); inode->i_count++; return fd; } @@ -146,7 +148,7 @@ * macros to write out all the necessary info. */ #define DUMP_WRITE(addr,nr) \ -while (file.f_op->write(inode,&file,(char *)(addr),(nr)) != (nr)) goto close_coredump +while (vfs_write(inode,&file,(char *)(addr),(nr)) != (nr)) goto close_coredump #define DUMP_SEEK(offset) \ if (file.f_op->lseek) { \ @@ -154,6 +156,8 @@ goto close_coredump; \ } else file.f_pos = (offset) +extern int close_fp(struct file *filp, unsigned int fd); + /* * Routine writes a core dump image in the current directory. * Currently only a stub-function. @@ -207,9 +211,11 @@ if (file.f_op->open) if (file.f_op->open(inode,&file)) goto end_coredump; + vfs_open(&file); if (!file.f_op->write) goto close_coredump; has_dumped = 1; + current->flags |= PF_DUMPCORE; /* changed the size calculations - should hopefully work better. lbt */ dump.magic = CMAGIC; dump.start_code = 0; @@ -271,8 +277,9 @@ set_fs(KERNEL_DS); DUMP_WRITE(current,sizeof(*current)); close_coredump: - if (file.f_op->release) - file.f_op->release(inode,&file); + close_fp(&file, 0); + set_fs(fs); + return has_dumped; end_coredump: set_fs(fs); iput(inode); @@ -824,6 +831,8 @@ current->mm->mmap = NULL; current->suid = current->euid = current->fsuid = bprm->e_uid; current->sgid = current->egid = current->fsgid = bprm->e_gid; + current->flags &= ~PF_FORKNOEXEC; /* accounting flags */ + current->io_usage = 0; if (N_MAGIC(ex) == OMAGIC) { do_mmap(NULL, 0, ex.a_text+ex.a_data, PROT_READ|PROT_WRITE|PROT_EXEC, diff -u --recursive --new-file linux-1.1.55/fs/ext2/super.c linux/fs/ext2/super.c --- linux-1.1.55/fs/ext2/super.c Sat Sep 17 21:49:55 1994 +++ linux/fs/ext2/super.c Thu Oct 20 17:01:17 1994 @@ -260,11 +260,8 @@ return 0; } } - else { - printk ("EXT2-fs: Unrecognized mount option %s\n", this_char); - return 0; + else return 1; } - } return 1; } diff -u --recursive --new-file linux-1.1.55/fs/fcntl.c linux/fs/fcntl.c --- linux-1.1.55/fs/fcntl.c Sat Sep 17 21:49:56 1994 +++ linux/fs/fcntl.c Thu Oct 20 17:01:17 1994 @@ -12,6 +12,7 @@ #include #include #include +#include extern int fcntl_getlk(unsigned int, struct flock *); extern int fcntl_setlk(unsigned int, unsigned int, struct flock *); @@ -32,6 +33,7 @@ return -EMFILE; FD_CLR(arg, ¤t->files->close_on_exec); (current->files->fd[arg] = current->files->fd[fd])->f_count++; + vfs_open(current->files->fd[fd]); return arg; } diff -u --recursive --new-file linux-1.1.55/fs/file_table.c linux/fs/file_table.c --- linux-1.1.55/fs/file_table.c Tue Feb 8 04:52:14 1994 +++ linux/fs/file_table.c Thu Oct 20 17:01:17 1994 @@ -7,6 +7,7 @@ #include #include #include +#include struct file * first_file; int nr_files = 0; @@ -87,3 +88,34 @@ } return NULL; } + +#ifdef CONFIG_QUOTA +void add_dquot_ref(dev_t dev, short type) +{ + struct file *filp; + int i; + + /* Check files that are currently opened for writing. */ + for (filp = first_file, i = 0; i < nr_files; i++, filp = filp->f_next) { + if (!filp->f_count || !filp->f_inode || filp->f_inode->i_dev != dev) + continue; + if (filp->f_inode->i_writecount > 0) { + getinoquota(filp->f_inode, type); + if (filp->f_inode->i_dquot[type] != NODQUOT) + filp->f_inode->i_dquot[type]->dq_count += + (filp->f_inode->i_writecount - 1); + } + } +} + +void reset_dquot_ptrs(dev_t dev, short type) +{ + struct file *filp; + int i; + + for (filp = first_file, i = 0; i < nr_files; i++, filp = filp->f_next) + if (filp->f_count && filp->f_inode && + filp->f_inode->i_writecount && filp->f_inode->i_dev == dev) + filp->f_inode->i_dquot[type] = NODQUOT; +} +#endif diff -u --recursive --new-file linux-1.1.55/fs/fileio.c linux/fs/fileio.c --- linux-1.1.55/fs/fileio.c Wed Dec 31 18:00:00 1969 +++ linux/fs/fileio.c Thu Oct 20 17:01:17 1994 @@ -0,0 +1,379 @@ +/* + * + * Simple VFS definitions for fileio. + * + * Authors: Marco van Wieringen + * Edvard Tuinder + * + * Version: $Id: fileio.c,v 1.10 1994/10/17 15:59:26 mvw Exp mvw $ + * + */ + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_QUOTA +extern int lookup(struct inode *, const char *, int, struct inode **); + +int vfs_write(struct inode *inode, struct file *filp, char *addr, size_t bytes) +{ + size_t written; + u_long cur_blocks, wanted_blocks = 0, avail_blocks = 0; + + if (S_ISREG(inode->i_mode)) { + cur_blocks = isize_to_blocks(inode->i_size, inode->i_blksize); + if ((filp->f_pos + bytes) > inode->i_size) { + wanted_blocks = isize_to_blocks(filp->f_pos + bytes, + inode->i_blksize) - cur_blocks; + if (wanted_blocks && quota_alloc(inode, 0, wanted_blocks, + &avail_blocks) == NO_QUOTA) + return -EDQUOT; + if (wanted_blocks && (avail_blocks < wanted_blocks)) + bytes = blocks_to_isize((cur_blocks + avail_blocks), + inode->i_blksize) - filp->f_pos; + } + if ((written = filp->f_op->write(inode, filp, addr, bytes)) != bytes) { + quota_remove(inode, 0, avail_blocks - + (isize_to_blocks(inode->i_size, inode->i_blksize) - + isize_to_blocks((inode->i_size - written), inode->i_blksize))); + } + current->io_usage += written; + if (wanted_blocks && (avail_blocks < wanted_blocks)) + return -EDQUOT; + + return written; + } else { + current->io_usage += bytes; + return filp->f_op->write(inode, filp, (char *)addr, bytes); + } +} + +int vfs_create(struct inode *dir, const char *basename, + int namelen, int mode, struct inode **res_ino) +{ + int error; + struct inode new_inode; + + memset(&new_inode, 0, sizeof(struct inode)); + new_inode.i_dev = dir->i_dev; + new_inode.i_uid = current->fsuid; + new_inode.i_gid = current->fsgid; + getinoquota(&new_inode, -1); + + if (quota_alloc(&new_inode, 1, 0, (u_long *)0) == NO_QUOTA) { + putinoquota(&new_inode); + return -EDQUOT; + } + error = dir->i_op->create(dir, basename, namelen, mode, res_ino); + if (error) + quota_remove(&new_inode, 1, 0); + putinoquota(&new_inode); + + return error; +} + +int vfs_truncate(struct inode *ino, size_t lenght) +{ + int error; + size_t old_isize; + + old_isize = ino->i_size; + ino->i_size = lenght; + if (ino->i_op && ino->i_op->truncate) + ino->i_op->truncate(ino); + ino->i_ctime = ino->i_mtime = CURRENT_TIME; + ino->i_dirt = 1; + if ((error = notify_change(NOTIFY_SIZE, ino))) + return error; + getinoquota(ino, -1); + quota_remove(ino, 0, isize_to_blocks(old_isize, ino->i_blksize)); + putinoquota(ino); + + return error; +} + +int vfs_mknod(struct inode *dir, const char *basename, + int namelen, int mode, dev_t dev) +{ + int error; + struct inode new_inode; + + memset(&new_inode, 0, sizeof(struct inode)); + new_inode.i_dev = dir->i_dev; + new_inode.i_uid = current->fsuid; + new_inode.i_gid = current->fsgid; + getinoquota(&new_inode, -1); + + if (quota_alloc(&new_inode, 1, 0, (u_long *)0) == NO_QUOTA) { + putinoquota(&new_inode); + iput(dir); + return -EDQUOT; + } + dir->i_count++; + error = dir->i_op->mknod(dir, basename, namelen, mode, dev); + if (error) + quota_remove(&new_inode, 1, 0); + putinoquota(&new_inode); + iput(dir); + + return error; +} + +int vfs_mkdir(struct inode *dir, const char *basename, int namelen, int mode) +{ + int error; + struct inode new_inode; + + memset(&new_inode, 0, sizeof(struct inode)); + new_inode.i_dev = dir->i_dev; + new_inode.i_uid = current->fsuid; + new_inode.i_gid = current->fsgid; + getinoquota(&new_inode, -1); + + if (quota_alloc(&new_inode, 1, 1, (u_long *)0) == NO_QUOTA) { + putinoquota(&new_inode); + iput(dir); + return -EDQUOT; + } + dir->i_count++; + error = dir->i_op->mkdir(dir, basename, namelen, mode); + if (error) + quota_remove(&new_inode, 1, 1); + putinoquota(&new_inode); + iput(dir); + + return error; +} + +int vfs_rmdir(struct inode *dir, const char *basename, int namelen) +{ + int error; + struct inode *old_inode; + + /* + * Need inode entry of directory for quota operations + */ + dir->i_count++; + if ((error = lookup(dir, basename, namelen, &old_inode))) { + iput(dir); + return error; + } + getinoquota(old_inode, -1); + if (!(error = dir->i_op->rmdir(dir, basename, namelen))) + quota_remove(old_inode, 1, 1); + putinoquota(old_inode); + iput(old_inode); + + return error; +} + +int vfs_unlink(struct inode *dir, const char *basename, int namelen) +{ + int error; + struct inode *old_inode; + + /* + * Need inode info of to remove file for quota operations. + */ + dir->i_count++; + if ((error = lookup(dir, basename, namelen, &old_inode))) { + iput(dir); + return error; + } + getinoquota(old_inode, -1); + error = dir->i_op->unlink(dir, basename, namelen); + /* + * Remove blocks and inode. Only if link-count is 0 ! + */ + if (!error && old_inode->i_nlink == 0) + quota_remove(old_inode, 1, + isize_to_blocks(old_inode->i_size, old_inode->i_blksize)); + putinoquota(old_inode); + iput(old_inode); + + return error; +} + +int vfs_symlink(struct inode *dir, const char *basename, + int namelen, const char *oldname) +{ + int error; + struct inode new_inode; + + memset(&new_inode, 0, sizeof(struct inode)); + new_inode.i_dev = dir->i_dev; + new_inode.i_uid = current->fsuid; + new_inode.i_gid = current->fsgid; + getinoquota(&new_inode, -1); + + if (quota_alloc(&new_inode, 1, 1, (u_long *)0) == NO_QUOTA) { + putinoquota(&new_inode); + iput(dir); + return -EDQUOT; + } + dir->i_count++; + if (!(error = dir->i_op->symlink(dir, basename, namelen, oldname))) + quota_remove(&new_inode, 1, 1); + putinoquota(&new_inode); + iput(dir); + + return error; +} + +int vfs_chown(struct inode *ino, uid_t uid, gid_t gid) +{ + int error; + uid_t olduid, oldgid; + int notify_flag = 0; + + olduid = ino->i_uid; + oldgid = ino->i_gid; + getinoquota(ino, -1); + if (quota_transfer(ino, uid, gid, 1, + isize_to_blocks(ino->i_size, + ino->i_blksize)) == NO_QUOTA) { + putinoquota(ino); + return -EDQUOT; + } + /* + * If the owner has been changed, remove the setuid bit + */ + if (ino->i_uid != uid && ino->i_mode & S_ISUID) { + ino->i_mode &= ~S_ISUID; + notify_flag = NOTIFY_MODE; + } + /* + * If the group has been changed, remove the setgid bit + */ + if (ino->i_gid != gid && ino->i_mode & S_ISGID) { + ino->i_mode &= ~S_ISGID; + notify_flag = NOTIFY_MODE; + } + ino->i_uid = uid; + ino->i_gid = gid; + notify_flag |= NOTIFY_UIDGID; + ino->i_ctime = CURRENT_TIME; + ino->i_dirt = 1; + if ((error = notify_change(notify_flag, ino))) + quota_transfer(ino, olduid, oldgid, 1, + isize_to_blocks(ino->i_size, ino->i_blksize)); + putinoquota(ino); + return error; +} + +int vfs_rename(struct inode *old_dir, const char *old_base, int old_len, + struct inode *new_dir, const char *new_base, int new_len) +{ + int error; + struct inode *old_inode, *new_inode; + + /* + * Check if target file already exists, drop quota of file if + * it already exists and is overwritten. Extra check needed for + * renames of file to the same file. + */ + old_dir->i_count++; + if ((error = lookup(old_dir, old_base, old_len, &old_inode))) { + iput(old_dir); + iput(new_dir); + return error; + } + new_dir->i_count++; + if (!lookup(new_dir, new_base, new_len, &new_inode)) { + if (old_dir != new_dir && old_inode != new_inode) { + iput(old_inode); + error = old_dir->i_op->rename(old_dir, old_base, old_len, + new_dir, new_base, new_len); + if (!error) { + getinoquota(new_inode, -1); + quota_remove(new_inode, 1, + isize_to_blocks(new_inode->i_size, new_inode->i_blksize)); + putinoquota(new_inode); + iput(new_inode); + } + return error; + } + iput(new_inode); + } + iput(old_inode); + return old_dir->i_op->rename(old_dir, old_base, old_len, + new_dir, new_base, new_len); +} + +void vfs_open(struct file *filp) +{ + if (filp->f_inode && S_ISREG(filp->f_inode->i_mode) && (filp->f_mode & 2)) { + filp->f_inode->i_writecount++; + getinoquota(filp->f_inode, -1); + } +} + +void vfs_close(struct file *filp) +{ + if (filp->f_inode && S_ISREG(filp->f_inode->i_mode) && (filp->f_mode & 2)) { + filp->f_inode->i_writecount--; + putinoquota(filp->f_inode); + } +} + +#else /* CONFIG_QUOTA */ + +int vfs_truncate(struct inode *ino, size_t lenght) +{ + int error; + + ino->i_size = lenght; + if (ino->i_op && ino->i_op->truncate) + ino->i_op->truncate(ino); + if ((error = notify_change(NOTIFY_SIZE, ino))) { + return error; + } + ino->i_dirt = 1; + + return error; +} + +int vfs_chown(struct inode *ino, uid_t uid, gid_t gid) +{ + int notify_flag = 0; + + /* + * If the owner has been changed, remove the setuid bit + */ + if (ino->i_uid != uid && ino->i_mode & S_ISUID) { + ino->i_mode &= ~S_ISUID; + notify_flag = NOTIFY_MODE; + } + /* + * If the group has been changed, remove the setgid bit + */ + if (ino->i_gid != gid && ino->i_mode & S_ISGID) { + ino->i_mode &= ~S_ISGID; + notify_flag = NOTIFY_MODE; + } + ino->i_uid = uid; + ino->i_gid = gid; + notify_flag |= NOTIFY_UIDGID; + ino->i_ctime = CURRENT_TIME; + ino->i_dirt = 1; + return(notify_change(notify_flag, ino)); +} + +void vfs_open(struct file *filp) +{ + if (filp->f_inode && S_ISREG(filp->f_inode->i_mode) && (filp->f_mode & 2)) + filp->f_inode->i_writecount++; +} + +void vfs_close(struct file *filp) +{ + if (filp->f_inode && S_ISREG(filp->f_inode->i_mode) && (filp->f_mode & 2)) + filp->f_inode->i_writecount--; +} + +#endif /* CONFIG_QUOTA */ + diff -u --recursive --new-file linux-1.1.55/fs/inode.c linux/fs/inode.c --- linux-1.1.55/fs/inode.c Sat Sep 17 21:50:27 1994 +++ linux/fs/inode.c Thu Oct 20 17:01:17 1994 @@ -427,6 +427,7 @@ struct inode_hash_entry * h; struct inode * inode; struct inode * empty = NULL; + short cnt; if (!sb) panic("VFS: iget with sb==NULL"); @@ -455,8 +456,11 @@ goto return_it; found_it: - if (!inode->i_count) + if (!inode->i_count) { nr_free_inodes--; + for (cnt = 0; cnt < MAXQUOTAS; cnt++) + inode->i_dquot[cnt] = NODQUOT; + } inode->i_count++; wait_on_inode(inode); if (inode->i_dev != sb->s_dev || inode->i_ino != nr) { diff -u --recursive --new-file linux-1.1.55/fs/isofs/inode.c linux/fs/isofs/inode.c --- linux-1.1.55/fs/isofs/inode.c Sat Sep 17 21:48:44 1994 +++ linux/fs/isofs/inode.c Thu Oct 20 17:01:17 1994 @@ -124,7 +124,7 @@ break; } } - else return 0; + else return 1; } return 1; } diff -u --recursive --new-file linux-1.1.55/fs/msdos/inode.c linux/fs/msdos/inode.c --- linux-1.1.55/fs/msdos/inode.c Sat Sep 17 21:41:19 1994 +++ linux/fs/msdos/inode.c Thu Oct 20 17:01:17 1994 @@ -133,7 +133,7 @@ if (value) return 0; *quiet = 1; } - else return 0; + else return 1; } return 1; } diff -u --recursive --new-file linux-1.1.55/fs/namei.c linux/fs/namei.c --- linux-1.1.55/fs/namei.c Sat Sep 17 21:49:58 1994 +++ linux/fs/namei.c Thu Oct 20 17:01:17 1994 @@ -16,6 +16,7 @@ #include #include #include +#include #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) @@ -345,7 +346,7 @@ error = -EROFS; else { dir->i_count++; /* create eats the dir */ - error = dir->i_op->create(dir,basename,namelen,mode,res_inode); + error = vfs_create(dir,basename,namelen,mode,res_inode); up(&dir->i_sem); iput(dir); return error; @@ -396,6 +397,7 @@ } } } + /* * An append-only file must be opened in append mode for writing */ @@ -403,16 +405,8 @@ iput(inode); return -EPERM; } - if (flag & O_TRUNC) { - inode->i_size = 0; - if (inode->i_op && inode->i_op->truncate) - inode->i_op->truncate(inode); - if ((error = notify_change(NOTIFY_SIZE, inode))) { - iput(inode); - return error; - } - inode->i_dirt = 1; - } + if (flag & O_TRUNC) + vfs_truncate(inode, 0); *res_inode = inode; return 0; } @@ -445,7 +439,7 @@ } dir->i_count++; down(&dir->i_sem); - error = dir->i_op->mknod(dir,basename,namelen,mode,dev); + error = vfs_mknod(dir,basename,namelen,mode,dev); up(&dir->i_sem); iput(dir); return error; @@ -502,7 +496,7 @@ } dir->i_count++; down(&dir->i_sem); - error = dir->i_op->mkdir(dir,basename,namelen,mode); + error = vfs_mkdir(dir,basename,namelen,mode); up(&dir->i_sem); iput(dir); return error; @@ -553,7 +547,7 @@ iput(dir); return -EPERM; } - return dir->i_op->rmdir(dir,basename,namelen); + return vfs_rmdir(dir,basename,namelen); } asmlinkage int sys_rmdir(const char * pathname) @@ -601,7 +595,7 @@ iput(dir); return -EPERM; } - return dir->i_op->unlink(dir,basename,namelen); + return vfs_unlink(dir,basename,namelen); } asmlinkage int sys_unlink(const char * pathname) @@ -644,7 +638,7 @@ } dir->i_count++; down(&dir->i_sem); - error = dir->i_op->symlink(dir,basename,namelen,oldname); + error = vfs_symlink(dir,basename,namelen,oldname); up(&dir->i_sem); iput(dir); return error; @@ -799,7 +793,7 @@ } new_dir->i_count++; down(&new_dir->i_sem); - error = old_dir->i_op->rename(old_dir, old_base, old_len, + error = vfs_rename(old_dir, old_base, old_len, new_dir, new_base, new_len); up(&new_dir->i_sem); iput(new_dir); diff -u --recursive --new-file linux-1.1.55/fs/open.c linux/fs/open.c --- linux-1.1.55/fs/open.c Sat Sep 17 21:49:58 1994 +++ linux/fs/open.c Thu Oct 20 17:01:17 1994 @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -85,12 +86,7 @@ iput(inode); return -EPERM; } - inode->i_size = length; - if (inode->i_op && inode->i_op->truncate) - inode->i_op->truncate(inode); - inode->i_ctime = inode->i_mtime = CURRENT_TIME; - inode->i_dirt = 1; - error = notify_change(NOTIFY_SIZE, inode); + error = vfs_truncate(inode, length); iput(inode); return error; } @@ -108,12 +104,7 @@ return -EACCES; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; - inode->i_size = length; - if (inode->i_op && inode->i_op->truncate) - inode->i_op->truncate(inode); - inode->i_ctime = inode->i_mtime = CURRENT_TIME; - inode->i_dirt = 1; - return notify_change(NOTIFY_SIZE, inode); + return vfs_truncate(inode, length); } /* If times==NULL, set access and modification to current time, @@ -319,25 +310,7 @@ if ((current->fsuid == inode->i_uid && user == inode->i_uid && (in_group_p(group) || group == inode->i_gid)) || fsuser()) { - inode->i_uid = user; - inode->i_gid = group; - /* - * If the owner has been changed, remove the setuid bit - */ - if (old_user != inode->i_uid && inode->i_mode & S_ISUID) { - inode->i_mode &= ~S_ISUID; - notify_flag = NOTIFY_MODE; - } - /* - * If the group has been changed, remove the setgid bit - */ - if (old_group != inode->i_gid && inode->i_mode & S_ISGID) { - inode->i_mode &= ~S_ISGID; - notify_flag = NOTIFY_MODE; - } - inode->i_ctime = CURRENT_TIME; - inode->i_dirt = 1; - return notify_change(notify_flag | NOTIFY_UIDGID, inode); + return vfs_chown(inode, user, group); } return -EPERM; } @@ -366,25 +339,7 @@ if ((current->fsuid == inode->i_uid && user == inode->i_uid && (in_group_p(group) || group == inode->i_gid)) || fsuser()) { - inode->i_uid = user; - inode->i_gid = group; - /* - * If the owner has been changed, remove the setuid bit - */ - if (old_user != inode->i_uid && inode->i_mode & S_ISUID) { - inode->i_mode &= ~S_ISUID; - notify_flag = NOTIFY_MODE; - } - /* - * If the group has been changed, remove the setgid bit - */ - if (old_group != inode->i_gid && inode->i_mode & S_ISGID) { - inode->i_mode &= ~S_ISGID; - notify_flag = NOTIFY_MODE; - } - inode->i_ctime = CURRENT_TIME; - inode->i_dirt = 1; - error = notify_change(notify_flag | NOTIFY_UIDGID, inode); + error = vfs_chown(inode, user, group); iput(inode); return error; } @@ -450,6 +405,7 @@ return error; } } + vfs_open(f); f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); return (fd); } @@ -483,6 +439,7 @@ inode = filp->f_inode; if (inode) fcntl_remove_locks(current, filp, fd); + vfs_close(filp); if (filp->f_count > 1) { filp->f_count--; return 0; diff -u --recursive --new-file linux-1.1.55/fs/read_write.c linux/fs/read_write.c --- linux-1.1.55/fs/read_write.c Thu Oct 20 15:14:28 1994 +++ linux/fs/read_write.c Thu Oct 20 17:01:17 1994 @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -130,6 +131,7 @@ error = verify_area(VERIFY_WRITE,buf,count); if (error) return error; + current->io_usage += count; return file->f_op->read(inode,file,buf,count); } diff -u --recursive --new-file linux-1.1.55/fs/super.c linux/fs/super.c --- linux-1.1.55/fs/super.c Thu Oct 13 21:31:08 1994 +++ linux/fs/super.c Thu Oct 20 17:01:18 1994 @@ -2,16 +2,20 @@ * linux/fs/super.c * * Copyright (C) 1991, 1992 Linus Torvalds + * + * super.c contains code to handle: - mount structures + * - super-block tables. + * - mount systemcall + * - umount systemcall */ -/* - * super.c contains code to handle the super-block tables. - */ #include #include #include #include +#include +#include #include #include #include @@ -21,23 +25,112 @@ #include #include #include - + extern struct file_operations * get_blkfops(unsigned int); -extern struct file_operations * get_chrfops(unsigned int); extern void wait_for_keypress(void); extern void fcntl_init_locks(void); extern int root_mountflags; -struct super_block super_blocks[NR_SUPER]; - static int do_remount_sb(struct super_block *sb, int flags, char * data); -/* this is initialized in init/main.c */ +/* + * This is initialized in init/main.c + */ dev_t ROOT_DEV = 0; -static struct file_system_type * file_systems = NULL; +struct super_block super_blocks[NR_SUPER]; +static struct file_system_type *file_systems = (struct file_system_type *) NULL; +static struct vfsmount *vfsmntlist = (struct vfsmount *) NULL, + *vfsmnttail = (struct vfsmount *) NULL, + *mru_vfsmnt = (struct vfsmount *) NULL; + +/* + * This part handles the management of the list of mounted filesystems. + * Superblock retrieval is also done with this list. + */ +struct vfsmount *lookup_vfsmnt(dev_t dev) +{ + register struct vfsmount *lptr; + + if (vfsmntlist == (struct vfsmount *) 0) + return ((struct vfsmount *) 0); + + if (mru_vfsmnt != (struct vfsmount *) 0 && mru_vfsmnt->mnt_dev == dev) + return (mru_vfsmnt); + + for (lptr = vfsmntlist; lptr != (struct vfsmount *)0; lptr = lptr->mnt_next) + if (lptr->mnt_dev == dev) + return (lptr); + + return ((struct vfsmount *) 0); + /* NOTREACHED */ +} + +static struct vfsmount *add_vfsmnt(dev_t dev, const char *dev_name, + const char *dir_name) +{ + register struct vfsmount *lptr; + char *tmp; + + if ((lptr = (struct vfsmount *) + kmalloc(sizeof(struct vfsmount), GFP_KERNEL)) == (struct vfsmount *) 0) + panic("VFS: Unable to allocate memory for vfsmount devicelist"); + + memset(lptr, 0, sizeof(struct vfsmount)); + lptr->mnt_dev = dev; + if (dev_name) { + if (!getname(dev_name, &tmp)) { + if ((lptr->mnt_devname = + (char *) kmalloc(strlen(tmp), GFP_KERNEL)) != (char *)0) + strcpy(lptr->mnt_devname, tmp); + putname(tmp); + } + } + if (dir_name) { + if (!getname(dir_name, &tmp)) { + if ((lptr->mnt_dirname = + (char *) kmalloc(strlen(tmp), GFP_KERNEL)) != (char *)0) + strcpy(lptr->mnt_dirname, tmp); + putname(tmp); + } + } + + if (vfsmntlist == (struct vfsmount *)0) + vfsmntlist = vfsmnttail = lptr; + else { + vfsmnttail->mnt_next = lptr; + vfsmnttail = lptr; + } + return (lptr); +} + +static void remove_vfsmnt(dev_t dev) +{ + register struct vfsmount *lptr, *tofree; + + if (vfsmntlist == (struct vfsmount *) 0) + return; + lptr = vfsmntlist; + if (lptr->mnt_dev == dev) { + tofree = lptr; + vfsmntlist = lptr->mnt_next; + } else { + while (lptr->mnt_next != (struct vfsmount *) 0) { + if (lptr->mnt_next->mnt_dev == dev) + break; + lptr = lptr->mnt_next; + } + tofree = lptr->mnt_next; + if (vfsmnttail->mnt_dev == dev) + vfsmnttail = lptr; + lptr->mnt_next = lptr->mnt_next->mnt_next; + } + kfree(tofree->mnt_devname); + kfree(tofree->mnt_dirname); + kfree_s(tofree, sizeof(struct vfsmount)); +} int register_filesystem(struct file_system_type * fs) { @@ -319,17 +412,30 @@ MAJOR(dev), MINOR(dev)); } +extern void acct_auto_close(dev_t dev); + static int do_umount(dev_t dev) { struct super_block * sb; int retval; if (dev==ROOT_DEV) { - /* Special case for "unmounting" root. We just try to remount - it readonly, and sync() the device. */ + /* + * Special case for "unmounting" root. We just try to remount + * it readonly, and sync() the device. + */ if (!(sb=get_super(dev))) return -ENOENT; if (!(sb->s_flags & MS_RDONLY)) { +#ifdef CONFIG_QUOTA + /* + * Make sure all quotas are turned off on this device we need to mount + * it readonly so no more writes by the quotasystem. + * If later on the remount fails to bad there are no quotas running + * anymore. Turn them on again by hand. + */ + (void) quota_off(dev, -1); +#endif fsync_dev(dev); retval = do_remount_sb(sb, MS_RDONLY, 0); if (retval) @@ -342,6 +448,18 @@ if (!sb->s_covered->i_mount) printk("VFS: umount(%d/%d): mounted inode has i_mount=NULL\n", MAJOR(dev), MINOR(dev)); +#ifdef CONFIG_QUOTA + /* + * Before checking if the filesystem is still busy make sure the kernel + * doesn't hold any quotafiles open on that device. If the umount fails + * to bad there are no quotas running anymore. Turn them on again by hand. + */ + (void) quota_off(dev, -1); +#endif + /* + * The same as for quota is also true for the accounting file. + */ + acct_auto_close(dev); if (!fs_may_umount(dev, sb->s_mounted)) return -EBUSY; sb->s_covered->i_mount = NULL; @@ -352,6 +470,7 @@ if (sb->s_op && sb->s_op->write_super && sb->s_dirt) sb->s_op->write_super(sb); put_super(dev); + remove_vfsmnt(dev); return 0; } @@ -427,13 +546,15 @@ * We also have to flush all inode-data for this device, as the new mount * might need new info. */ -static int do_mount(dev_t dev, const char * dir, char * type, int flags, void * data) +static int do_mount(dev_t dev, const char * dev_name, const char * dir_name, + char * type, int flags, void * data) { struct inode * dir_i; struct super_block * sb; + struct vfsmount *vfsmnt; int error; - error = namei(dir,&dir_i); + error = namei(dir_name,&dir_i); if (error) return error; if (dir_i->i_count != 1 || dir_i->i_mount) { @@ -453,6 +574,9 @@ iput(dir_i); return -EBUSY; } + vfsmnt = add_vfsmnt(dev, dev_name, dir_name); + vfsmnt->mnt_sb = sb; + vfsmnt->mnt_sem.count = 1; sb->s_covered = dir_i; dir_i->i_mount = sb->s_mounted; return 0; /* we don't iput(dir_i) - see umount */ @@ -623,7 +747,7 @@ return retval; } } - retval = do_mount(dev,dir_name,t,flags,(void *) page); + retval = do_mount(dev,dev_name,dir_name,t,flags,(void *) page); free_page(page); if (retval && fops && fops->release) fops->release(inode, NULL); @@ -635,10 +759,11 @@ { struct file_system_type * fs_type; struct super_block * sb; + struct vfsmount *vfsmnt; struct inode * inode, d_inode; struct file filp; int retval; - + memset(super_blocks, 0, sizeof(super_blocks)); fcntl_init_locks(); if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { @@ -664,9 +789,9 @@ for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) { if(retval) break; - if (!fs_type->requires_dev) - continue; - sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1); + if (!fs_type->requires_dev) + continue; + sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1); if (sb) { inode = sb->s_mounted; inode->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */ @@ -677,6 +802,9 @@ printk ("VFS: Mounted root (%s filesystem)%s.\n", fs_type->name, (sb->s_flags & MS_RDONLY) ? " readonly" : ""); + vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/"); + vfsmnt->mnt_sb = sb; + vfsmnt->mnt_sem.count = 1; return; } } diff -u --recursive --new-file linux-1.1.55/ibcs/binfmt_coff.c linux/ibcs/binfmt_coff.c --- linux-1.1.55/ibcs/binfmt_coff.c Sat Sep 17 21:48:00 1994 +++ linux/ibcs/binfmt_coff.c Thu Oct 20 17:01:18 1994 @@ -455,6 +455,8 @@ /* * Do the end processing once the stack has been constructed */ + current->flags &= ~PF_FORKNOEXEC; /* accounting flags */ + current->io_usage = 0; current->mm->start_code = text_vaddr & PAGE_MASK; current->mm->end_code = text_vaddr + text_size; current->mm->end_data = data_vaddr + data_size; diff -u --recursive --new-file linux-1.1.55/include/linux/acct.h linux/include/linux/acct.h --- linux-1.1.55/include/linux/acct.h Wed Dec 31 18:00:00 1969 +++ linux/include/linux/acct.h Thu Oct 20 17:01:18 1994 @@ -0,0 +1,28 @@ +#ifndef __LINUX_ACCT_H +#define __LINUX_ACCT_H + +#define ACCT_COMM 16 + +struct acct +{ + char ac_comm[ACCT_COMM]; /* Accounting command name */ + time_t ac_utime; /* Accounting user time */ + time_t ac_stime; /* Accounting system time */ + time_t ac_etime; /* Accounting elapsed time */ + time_t ac_btime; /* Beginning time */ + uid_t ac_uid; /* Accounting user ID */ + gid_t ac_gid; /* Accounting group ID */ + dev_t ac_tty; /* controlling tty */ + char ac_flag; /* Accounting flag */ + unsigned long ac_mem; /* Pages of memory used */ + unsigned long ac_io; /* Number of bytes read/written */ +}; + +#define AFORK 0001 /* has executed fork, but no exec */ +#define ASU 0002 /* used super-user privileges */ +#define ACORE 0004 /* dumped core */ +#define AXSIG 0010 /* killed by a signal */ + +#define AHZ 100 + +#endif diff -u --recursive --new-file linux-1.1.55/include/linux/autoconf.h linux/include/linux/autoconf.h --- linux-1.1.55/include/linux/autoconf.h Wed Dec 31 18:00:00 1969 +++ linux/include/linux/autoconf.h Thu Oct 20 17:09:32 1994 @@ -0,0 +1,147 @@ +/* + * Automatically generated C config: don't edit + */ + +/* + * General setup + */ +#define CONFIG_MATH_EMULATION 1 +#define CONFIG_BLK_DEV_HD 1 +#undef CONFIG_BLK_DEV_XD +#define CONFIG_NET 1 +#undef CONFIG_QUOTA +#undef CONFIG_MAX_16M +#define CONFIG_SYSVIPC 1 +#define CONFIG_BINFMT_ELF 1 +#define CONFIG_M486 1 + +/* + * Networking options + */ +#define CONFIG_INET 1 +#undef CONFIG_IP_FORWARD + +/* + * (it is safe to leave these untouched) + */ +#undef CONFIG_INET_PCTCP +#undef CONFIG_INET_RARP +#define CONFIG_INET_SNARL 1 +#undef CONFIG_TCP_NAGLE_OFF +#undef CONFIG_IPX + +/* + * SCSI support + */ +#define CONFIG_SCSI 1 + +/* + * SCSI support type (disk, tape, CDrom) + */ +#define CONFIG_BLK_DEV_SD 1 +#define CONFIG_CHR_DEV_ST 1 +#define CONFIG_BLK_DEV_SR 1 +#undef CONFIG_CHR_DEV_SG + +/* + * SCSI low-level drivers + */ +#define CONFIG_SCSI_AHA152X 1 +#define CONFIG_SCSI_AHA1542 1 +#define CONFIG_SCSI_AHA1740 1 +#define CONFIG_SCSI_BUSLOGIC 1 +#define CONFIG_SCSI_FUTURE_DOMAIN 1 +#define CONFIG_SCSI_GENERIC_NCR5380 1 +#define CONFIG_SCSI_NCR53C7xx 1 +#define CONFIG_SCSI_PAS16 1 +#define CONFIG_SCSI_SEAGATE 1 +#define CONFIG_SCSI_T128 1 +#define CONFIG_SCSI_ULTRASTOR 1 +#define CONFIG_SCSI_7000FASST 1 + +/* + * Network device support + */ +#define CONFIG_NETDEVICES 1 +#undef CONFIG_DUMMY +#define CONFIG_SLIP 1 +#define SL_COMPRESSED 1 +#define CONFIG_PPP 1 +#undef CONFIG_PLIP +#undef CONFIG_SLAVE_BALANCING +#define CONFIG_NET_ALPHA 1 +#define CONFIG_NET_VENDOR_SMC 1 +#define CONFIG_WD80x3 1 +#define CONFIG_ULTRA 1 +#define CONFIG_NET_VENDOR_3COM 1 +#define CONFIG_EL1 1 +#define CONFIG_EL2 1 +#define CONFIG_ELPLUS 1 +#define CONFIG_EL16 1 +#define CONFIG_EL3 1 +#define CONFIG_NET_ISA 1 +#define CONFIG_LANCE 1 +#define CONFIG_E2100 1 +#define CONFIG_DEPCA 1 +#define CONFIG_EEXPRESS 1 +#define CONFIG_AT1700 1 +#define CONFIG_NI52 1 +#define CONFIG_NI65 1 +#define CONFIG_HPLAN 1 +#define CONFIG_NE2000 1 +#define CONFIG_SK_G16 1 +#define CONFIG_NET_EISA 1 +#define CONFIG_AC3200 1 +#define CONFIG_APRICOT 1 +#define CONFIG_NET_POCKET 1 +#define CONFIG_DE600 1 +#define CONFIG_DE620 1 +#define CONFIG_ATP 1 +#define CONFIG_ZNET 1 + +/* + * CD-ROM drivers + */ +#undef CONFIG_CDU31A +#undef CONFIG_MCD +#undef CONFIG_SBPCD + +/* + * Filesystems + */ +#define CONFIG_MINIX_FS 1 +#undef CONFIG_EXT_FS +#define CONFIG_EXT2_FS 1 +#define CONFIG_XIA_FS 1 +#define CONFIG_MSDOS_FS 1 +#define CONFIG_UMSDOS_FS 1 +#define CONFIG_PROC_FS 1 +#define CONFIG_NFS_FS 1 +#define CONFIG_ISO9660_FS 1 +#define CONFIG_HPFS_FS 1 +#undef CONFIG_SYSV_FS + +/* + * character devices + */ +#define CONFIG_PRINTER 1 +#undef CONFIG_BUSMOUSE +#define CONFIG_PSMOUSE 1 +#define CONFIG_82C710_MOUSE 1 +#undef CONFIG_MS_BUSMOUSE +#undef CONFIG_ATIXL_BUSMOUSE +#define CONFIG_SELECTION 1 +#undef CONFIG_QIC02_TAPE +#define CONFIG_FTAPE 1 +#define NR_FTAPE_BUFFERS (3) + +/* + * Sound + */ +#undef CONFIG_SOUND + +/* + * Kernel hacking + */ +#undef CONFIG_PROFILE +#undef CONFIG_SCSI_CONSTANTS diff -u --recursive --new-file linux-1.1.55/include/linux/fileio.h linux/include/linux/fileio.h --- linux-1.1.55/include/linux/fileio.h Wed Dec 31 18:00:00 1969 +++ linux/include/linux/fileio.h Thu Oct 20 17:01:18 1994 @@ -0,0 +1,70 @@ +/* + * + * Simple VFS definitions for fileio. + * + * Authors: Marco van Wieringen + * Edvard Tuinder + * + * Version: $Id: fileio.h,v 1.5 1994/05/30 18:39:42 mvw Exp mvw $ + * + */ +#ifndef _LINUX_FILEIO_H +#define _LINUX_FILEIO_H + +#include +#include + +#ifdef CONFIG_QUOTA + +int vfs_write(struct inode *ino, struct file *file, char *addr, size_t bytes); +int vfs_create(struct inode *dir, const char *basename, + int namelen, int mode, struct inode **res_ino); +int vfs_truncate(struct inode *ino, size_t lenght); +int vfs_mknod(struct inode *dir, const char *basename, + int namelen, int mode, dev_t dev); +int vfs_mkdir(struct inode *dir, const char *basename, int namelen, int mode); +int vfs_rmdir(struct inode *dir, const char *basename, int namelen); +int vfs_unlink(struct inode *dir, const char *basename, int namelen); +int vfs_symlink(struct inode *dir, const char *basename, + int namelen, const char *oldname); +int vfs_chown(struct inode *ino, uid_t uid, gid_t gid); +int vfs_rename(struct inode *old_dir, const char *old_base, int old_len, + struct inode *new_dir, const char *mew_base, int new_len); +void vfs_open(struct file *filp); +void vfs_close(struct file *filp); + +#else /* CONFIG_QUOTA */ + +#define vfs_write(ino, file, addr, bytes) \ +(file)->f_op->write((ino),(file),(addr),(bytes)) + +#define vfs_create(dir, basename, namelen, mode, res_ino) \ +(dir)->i_op->create((dir),(basename),(namelen),(mode),(res_ino)) + +int vfs_truncate(struct inode *ino, size_t lenght); + +#define vfs_mknod(dir, basename, namelen, mode, dev) \ +(dir)->i_op->mknod((dir),(basename),(namelen),(mode),(dev)) + +#define vfs_mkdir(dir, basename, namelen, mode) \ +(dir)->i_op->mkdir((dir),(basename),(namelen),(mode)) + +#define vfs_rmdir(dir, basename, namelen) \ +(dir)->i_op->rmdir((dir),(basename),(namelen)) + +#define vfs_unlink(dir, basename, namelen) \ +(dir)->i_op->unlink((dir),(basename),(namelen)) + +#define vfs_symlink(dir, basename, namelen, oldname) \ +(dir)->i_op->symlink((dir),(basename),(namelen),(oldname)) + +int vfs_chown(struct inode *ino, uid_t uid, gid_t gid); + +#define vfs_rename(old_dir, old_base, old_len, new_dir, new_base, new_len) \ +(old_dir)->i_op->rename((old_dir),(old_base),(old_len),(new_dir),(new_base),(new_len)) + +void vfs_open(struct file *filp); +void vfs_close(struct file *filp); + +#endif /* CONFIG_QUOTA */ +#endif /* _LINUX_FILEIO_H */ diff -u --recursive --new-file linux-1.1.55/include/linux/fs.h linux/include/linux/fs.h --- linux-1.1.55/include/linux/fs.h Sat Sep 17 21:50:00 1994 +++ linux/include/linux/fs.h Thu Oct 20 17:01:18 1994 @@ -171,6 +171,7 @@ #include #include #include +#include #ifdef __KERNEL__ @@ -200,7 +201,9 @@ struct inode * i_bound_to, * i_bound_by; struct inode * i_mount; struct socket * i_socket; + struct dquot * i_dquot[MAXQUOTAS]; unsigned short i_count; + unsigned short i_writecount; unsigned short i_flags; unsigned char i_lock; unsigned char i_dirt; diff -u --recursive --new-file linux-1.1.55/include/linux/kernel.h linux/include/linux/kernel.h --- linux-1.1.55/include/linux/kernel.h Sat Sep 17 21:49:17 1994 +++ linux/include/linux/kernel.h Thu Oct 20 17:01:18 1994 @@ -54,19 +54,6 @@ asmlinkage int printk(const char * fmt, ...) __attribute__ ((format (printf, 1, 2))); -/* - * This is defined as a macro, but at some point this might become a - * real subroutine that sets a flag if it returns true (to do - * BSD-style accounting where the process is flagged if it uses root - * privs). The implication of this is that you should do normal - * permissions checks first, and check suser() last. - * - * "suser()" checks against the effective user id, while "fsuser()" - * is used for file permission checking and checks against the fsuid.. - */ -#define suser() (current->euid == 0) -#define fsuser() (current->fsuid == 0) - extern int splx (int new_ipl); #endif /* __KERNEL__ */ diff -u --recursive --new-file linux-1.1.55/include/linux/mount.h linux/include/linux/mount.h --- linux-1.1.55/include/linux/mount.h Wed Dec 31 18:00:00 1969 +++ linux/include/linux/mount.h Thu Oct 20 17:01:18 1994 @@ -0,0 +1,34 @@ +/* + * + * Definitions for mount interface. This describes the in the kernel build + * linkedlist with mounted filesystems. + * + * Authors: Marco van Wieringen + * Edvard Tuinder + * + * Version: $Id: mount.h,v 1.3 1994/07/20 22:01:00 mvw Exp mvw $ + * + */ +#ifndef _LINUX_MOUNT_H +#define _LINUX_MOUNT_H + +#define QF_OPENING 0x01 /* Quotafile is in progress of being opened */ +#define QF_CLOSING 0x02 /* Quotafile is in progress of being closed */ + +struct vfsmount +{ + dev_t mnt_dev; /* Device this applies to */ + char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ + char *mnt_dirname; /* Name of directory mounted on */ + unsigned int mnt_flags; /* Flags of this device see above */ + struct semaphore mnt_sem; /* lock device while I/O in progress */ + struct super_block *mnt_sb; /* pointer to superblock */ + struct file *mnt_quotas[MAXQUOTAS]; /* fp's to quotafiles */ + time_t mnt_iexp[MAXQUOTAS]; /* expiretime for inodes */ + time_t mnt_bexp[MAXQUOTAS]; /* expiretime for blocks */ + struct vfsmount *mnt_next; /* pointer to next in linkedlist */ +}; + +struct vfsmount *lookup_vfsmnt(dev_t dev); + +#endif /* _LINUX_MOUNT_H */ diff -u --recursive --new-file linux-1.1.55/include/linux/quota.h linux/include/linux/quota.h --- linux-1.1.55/include/linux/quota.h Wed Dec 31 18:00:00 1969 +++ linux/include/linux/quota.h Thu Oct 20 17:01:18 1994 @@ -0,0 +1,208 @@ +/* + * Copyright (c) 1982, 1986 Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Robert Elz at The University of Melbourne. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Version: $Id: quota.h,v 1.5 1994/01/06 20:45:20 mvw Exp mvw $ + */ + +#ifndef _LINUX_QUOTA_ +#define _LINUX_QUOTA_ + +#include + +/* + * Convert diskblocks to blocks and the other way around. + * currently only to fool the BSD source. :-) + */ +#define dbtob(num) (num << 10) +#define btodb(num) (num >> 10) + +/* + * Definitions for disk quotas imposed on the average user + * (big brother finally hits Linux). + * + * The following constants define the amount of time given a user + * before the soft limits are treated as hard limits (usually resulting + * in an allocation failure). The timer is started when the user crosses + * their soft limit, it is reset when they go below their soft limit. + */ +#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */ +#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */ + +#define MAXQUOTAS 2 +#define USRQUOTA 0 /* element used for user quotas */ +#define GRPQUOTA 1 /* element used for group quotas */ + +/* + * Definitions for the default names of the quotas files. + */ +#define INITQFNAMES { \ + "user", /* USRQUOTA */ \ + "group", /* GRPQUOTA */ \ + "undefined", \ +}; + +#define QUOTAFILENAME "quota" +#define QUOTAGROUP "staff" + +#define NR_DQHASH 43 /* Just an arbitrary number any suggestions ? */ +#define NR_DQUOTS 256 /* Number of quotas active at one time */ + +/* + * Command definitions for the 'quotactl' system call. + * The commands are broken into a main command defined below + * and a subcommand that is used to convey the type of + * quota that is being manipulated (see above). + */ +#define SUBCMDMASK 0x00ff +#define SUBCMDSHIFT 8 +#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK)) + +#define Q_QUOTAON 0x0100 /* enable quotas */ +#define Q_QUOTAOFF 0x0200 /* disable quotas */ +#define Q_GETQUOTA 0x0300 /* get limits and usage */ +#define Q_SETQUOTA 0x0400 /* set limits and usage */ +#define Q_SETUSE 0x0500 /* set usage */ +#define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */ +#define Q_SETQLIM 0x0700 /* set limits */ + +/* + * The following structure defines the format of the disk quota file + * (as it appears on disk) - the file is an array of these structures + * indexed by user or group number. + */ +struct dqblk + { + u_long dqb_bhardlimit; /* absolute limit on disk blks alloc */ + u_long dqb_bsoftlimit; /* preferred limit on disk blks */ + u_long dqb_curblocks; /* current block count */ + u_long dqb_ihardlimit; /* maximum # allocated inodes */ + u_long dqb_isoftlimit; /* preferred inode limit */ + u_long dqb_curinodes; /* current # allocated inodes */ + time_t dqb_btime; /* time limit for excessive disk use */ + time_t dqb_itime; /* time limit for excessive files */ + }; + +/* + * Shorthand notation. + */ +#define dq_bhardlimit dq_dqb.dqb_bhardlimit +#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit +#define dq_curblocks dq_dqb.dqb_curblocks +#define dq_ihardlimit dq_dqb.dqb_ihardlimit +#define dq_isoftlimit dq_dqb.dqb_isoftlimit +#define dq_curinodes dq_dqb.dqb_curinodes +#define dq_btime dq_dqb.dqb_btime +#define dq_itime dq_dqb.dqb_itime + +#define dqoff(UID) ((off_t)((UID) * sizeof (struct dqblk))) + +#ifdef __KERNEL__ + +/* + * Maximum lenght of a message generated in the quota system, + * that needs to be kicked onto the tty. + */ +#define MAX_QUOTA_MESSAGE 75 + +#define DQ_LOCKED 0x01 /* locked for update */ +#define DQ_WANT 0x02 /* wanted for update */ +#define DQ_MOD 0x04 /* dquot modified since read */ +#define DQ_BLKS 0x10 /* uid/gid has been warned about blk limit */ +#define DQ_INODES 0x20 /* uid/gid has been warned about inode limit */ +#define DQ_FAKE 0x40 /* no limits only usage */ + +struct dquot +{ + unsigned int dq_id; /* id this applies to (uid, gid) */ + short dq_type; /* type of quota */ + dev_t dq_dev; /* Device this applies to */ + short dq_flags; /* see DQ_* */ + short dq_count; /* reference count */ + struct vfsmount *dq_mnt; /* vfsmountpoint this applies to */ + struct dqblk dq_dqb; /* diskquota usage */ + struct wait_queue *dq_wait; /* pointer to waitqueue */ + struct dquot *dq_prev; /* pointer to prev dquot */ + struct dquot *dq_next; /* pointer to next dquot */ + struct dquot *dq_hash_prev; /* pointer to prev dquot */ + struct dquot *dq_hash_next; /* pointer to next dquot */ +}; + +#define NODQUOT (struct dquot *)NULL + +/* + * Flags used for set_dqblk. + */ +#define QUOTA_SYSCALL 0x01 +#define SET_QUOTA 0x02 +#define SET_USE 0x04 +#define SET_QLIMIT 0x08 + +/* + * Return values when requesting quota. + */ +#define NO_QUOTA 0 /* no more quota available */ +#define QUOTA_OK 1 /* can allocate the space */ + +/* + * declaration of quota_function calls in kernel. + */ +struct dquot *dqget (dev_t dev, unsigned int id, short type); +void dqput (struct dquot *dquot); + +int quota_off (dev_t dev, short type); +int sync_dquots (dev_t dev, short type); + +u_long isize_to_blocks (size_t isize, size_t blksize); +size_t blocks_to_isize (u_long blocks, size_t blksize); + +void quota_remove (struct inode *inode, u_long inodes, u_long blocks); +int quota_alloc (struct inode *inode, u_long wantedinodes, + u_long wantedblocks, u_long * availblocks); +int quota_transfer (struct inode *inode, uid_t newuid, + gid_t newgid, u_long inodes, u_long blocks); + +void getinoquota (struct inode *inode, short type); +void putinoquota (struct inode *inode); + +#else + +#include + +__BEGIN_DECLS +int quotactl __P ((int, const char *, int, caddr_t)); +__END_DECLS + +#endif /* __KERNEL__ */ +#endif /* _QUOTA_ */ diff -u --recursive --new-file linux-1.1.55/include/linux/sched.h linux/include/linux/sched.h --- linux-1.1.55/include/linux/sched.h Sat Sep 17 21:50:01 1994 +++ linux/include/linux/sched.h Thu Oct 20 17:01:18 1994 @@ -280,6 +280,7 @@ long utime, stime, cutime, cstime, start_time; struct rlimit rlim[RLIM_NLIMITS]; unsigned short used_math; + unsigned long io_usage; /* number of bytes read/written */ char comm[16]; /* virtual 86 mode stuff */ struct vm86_struct * vm86_info; @@ -310,6 +311,10 @@ /* Not implemented yet, only for 486*/ #define PF_PTRACED 0x00000010 /* set if ptrace (0) has been called. */ #define PF_TRACESYS 0x00000020 /* tracing system calls */ +#define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ +#define PF_SUPERPREV 0x00000100 /* used super-user privileges */ +#define PF_DUMPCORE 0x00000200 /* dumped core */ +#define PF_SIGNALED 0x00000400 /* killed by a signal */ /* * cloning flags: @@ -340,6 +345,7 @@ {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ { 0, LONG_MAX}, {LONG_MAX, LONG_MAX}}, \ /* math */ 0, \ +/* io_usage */ 0, \ /* comm */ "swapper", \ /* vm86_info */ NULL, 0, 0, 0, 0, \ /* fs info */ 0,NULL, \ @@ -449,6 +455,29 @@ #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base ) #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 ) + +/* + * This has now become a routine instead of a macro, it sets a flag if + * it returns true (to do BSD-style accounting where the process is flagged + * if it uses root privs). The implication of this is that you should do + * normal permissions checks first, and check suser() last. + * + * "suser()" checks against the effective user id, while "fsuser()" + * is used for file permission checking and checks against the fsuid.. + */ +extern inline int suser(void) +{ + if (current->euid == 0) + current->flags |= PF_SUPERPREV; + return (current->euid == 0); +} + +extern inline int fsuser(void) +{ + if (current->fsuid == 0) + current->flags |= PF_SUPERPREV; + return (current->fsuid == 0); +} /* * The wait-queues are circular lists, and you have to be *very* sure diff -u --recursive --new-file linux-1.1.55/include/linux/sys.h linux/include/linux/sys.h --- linux-1.1.55/include/linux/sys.h Sat Sep 17 21:40:01 1994 +++ linux/include/linux/sys.h Thu Oct 20 17:01:18 1994 @@ -32,6 +32,5 @@ * These are system calls that haven't been implemented yet * but have an entry in the table for future expansion.. */ -#define _sys_quotactl _sys_ni_syscall #endif diff -u --recursive --new-file linux-1.1.55/include/linux/tty.h linux/include/linux/tty.h --- linux-1.1.55/include/linux/tty.h Thu Oct 20 15:14:28 1994 +++ linux/include/linux/tty.h Thu Oct 20 17:01:18 1994 @@ -292,6 +292,7 @@ extern int tty_unregister_driver(struct tty_driver *driver); extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, int buflen); +extern void tty_write_message(struct tty_struct *tty, char *msg); extern int is_orphaned_pgrp(int pgrp); extern int is_ignored(int sig); diff -u --recursive --new-file linux-1.1.55/init/main.c linux/init/main.c --- linux-1.1.55/init/main.c Sat Sep 17 21:50:25 1994 +++ linux/init/main.c Thu Oct 20 17:01:18 1994 @@ -103,6 +103,9 @@ #ifdef CONFIG_SYSVIPC extern void ipc_init(void); #endif +#ifdef CONFIG_QUOTA +extern void quota_init(void); +#endif #ifdef CONFIG_SCSI extern unsigned long scsi_dev_init(unsigned long, unsigned long); #endif @@ -457,6 +460,9 @@ sock_init(); #ifdef CONFIG_SYSVIPC ipc_init(); +#endif +#ifdef CONFIG_QUOTA + quota_init(); #endif sti(); diff -u --recursive --new-file linux-1.1.55/kernel/exit.c linux/kernel/exit.c --- linux-1.1.55/kernel/exit.c Sat Sep 17 21:48:05 1994 +++ linux/kernel/exit.c Thu Oct 20 17:01:18 1994 @@ -19,6 +19,7 @@ #include extern void shm_exit (void); extern void sem_exit (void); +extern void acct_process (void); int getrusage(struct task_struct *, int, struct rusage *); @@ -411,6 +412,7 @@ intr_count = 0; } fake_volatile: + acct_process(); if (current->semun) sem_exit(); if (current->shm) diff -u --recursive --new-file linux-1.1.55/kernel/fork.c linux/kernel/fork.c --- linux-1.1.55/kernel/fork.c Sat Sep 17 21:46:36 1994 +++ linux/kernel/fork.c Thu Oct 20 17:01:18 1994 @@ -2,9 +2,7 @@ * linux/kernel/fork.c * * Copyright (C) 1991, 1992 Linus Torvalds - */ - -/* + * * 'fork.c' contains the help-routines for the 'fork' system call * (see also system_call.s). * Fork is rather simple, once you get the hang of it, but the memory @@ -21,6 +19,7 @@ #include #include #include +#include #include #include @@ -84,6 +83,7 @@ new_file->f_count = 0; new_file = NULL; } + vfs_open(new_file); } } return new_file; @@ -124,8 +124,10 @@ p->files->fd[i] = copy_fd(f); } else { for (i=0; ifiles->fd[i]) != NULL) + if ((f = p->files->fd[i]) != NULL) { f->f_count++; + vfs_open(f); + } } } @@ -188,7 +190,9 @@ p->did_exec = 0; p->kernel_stack_page = 0; p->state = TASK_UNINTERRUPTIBLE; - p->flags &= ~(PF_PTRACED|PF_TRACESYS); + p->flags &= ~(PF_PTRACED|PF_TRACESYS|PF_SUPERPREV); + p->flags |= PF_FORKNOEXEC; + p->io_usage = 0; /* Child doesn't inherit parent's I/O usage */ p->pid = last_pid; p->p_pptr = p->p_opptr = current; p->p_cptr = NULL; diff -u --recursive --new-file linux-1.1.55/kernel/printk.c linux/kernel/printk.c --- linux-1.1.55/kernel/printk.c Sat Sep 17 21:47:42 1994 +++ linux/kernel/printk.c Thu Oct 20 17:01:18 1994 @@ -19,6 +19,8 @@ #include #include #include +#include +#include #define LOG_BUF_LEN 4096 @@ -226,4 +228,17 @@ msg_level = -1; j = 0; } +} + +/* + * Write a message to a certain tty, not just the console. This is used for + * messages that need to be redirected to a specific tty. + * We don't put it into the syslog queue right now maybe in the future if + * really needed. + */ +void tty_write_message(struct tty_struct *tty, char *msg) +{ + if (tty && tty->driver.write) + tty->driver.write(tty, 0, msg, strlen(msg)); + return; } diff -u --recursive --new-file linux-1.1.55/kernel/sys.c linux/kernel/sys.c --- linux-1.1.55/kernel/sys.c Thu Oct 13 21:31:09 1994 +++ linux/kernel/sys.c Thu Oct 20 17:01:18 1994 @@ -17,6 +17,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -251,9 +255,128 @@ return 0; } -asmlinkage int sys_acct(void) +static char acct_active = 0; +static struct file *acct_file; +#define KSTK_ESP(stack) (((unsigned long *) stack)[1022]) + +int acct_process(void) +{ + struct acct ac; + unsigned short fs; + unsigned long vsize, esp; + + if (acct_active) { + memset(&ac, 0, sizeof(struct acct)); + strncpy(ac.ac_comm, current->comm, ACCT_COMM); + ac.ac_comm[ACCT_COMM] = '\0'; + ac.ac_utime = current->utime; + ac.ac_stime = current->stime; + ac.ac_btime = CT_TO_SECS(current->start_time) + (xtime.tv_sec - (jiffies / HZ)); + ac.ac_etime = CURRENT_TIME - ac.ac_btime; + ac.ac_uid = current->uid; + ac.ac_gid = current->gid; + ac.ac_tty = (current->tty) ? MKDEV(4, current->tty->device) : MKDEV(4, -1); + ac.ac_flag = 0; + if (current->flags & PF_FORKNOEXEC) + ac.ac_flag |= AFORK; + if (current->flags & PF_SUPERPREV) + ac.ac_flag |= ASU; + if (current->flags & PF_DUMPCORE) + ac.ac_flag |= ACORE; + if (current->flags & PF_SIGNALED) + ac.ac_flag |= AXSIG; + ac.ac_io = current->io_usage; + + /* Figure out the vsize of the current process and divide by the + * page size to calculate AC_MEM. This is the approved method + * from the proc filesystem. + */ + vsize = current->kernel_stack_page; + if (vsize) { + esp = KSTK_ESP(vsize); + vsize = current->mm->brk - current->mm->start_code + (PAGE_SIZE - 1); + if (esp) + vsize += TASK_SIZE - esp; + } + /* now vsize contains the number of bytes used -- we want to + * find out the number of pages, so divide it by the page size + * and round up. + */ + ac.ac_mem = (vsize / PAGE_SIZE) + ((vsize % PAGE_SIZE) != 0); + + /* Kernel segment override */ + fs = get_fs(); + set_fs(KERNEL_DS); + + acct_file->f_op->write(acct_file->f_inode, acct_file, + (char *)&ac, sizeof(struct acct)); + + set_fs(fs); + } + return 0; +} + +extern void close_fp(struct file *, int); + +asmlinkage int sys_acct(const char *name) { - return -ENOSYS; + struct inode *inode = (struct inode *)0; + char *tmp; + int error; + + if (!suser()) + return -EPERM; + + if (name == (char *)0) { + if (acct_active) { + acct_process(); + acct_active = 0; + close_fp(acct_file, 0); + } + return 0; + } else { + if (!acct_active) { + if ((error = getname(name, &tmp)) != 0) + return (error); + error = open_namei(tmp, O_RDWR, 0600, &inode, 0); + putname(tmp); + if (error) + return (error); + if (!S_ISREG(inode->i_mode)) { + iput(inode); + return -EACCES; + } + if (!inode->i_op || !inode->i_op->default_file_ops || + !inode->i_op->default_file_ops->write) { + iput(inode); + return -EIO; + } + if ((acct_file = get_empty_filp()) == (struct file *)0) + return -EUSERS; + acct_file->f_mode = (O_WRONLY + 1) & O_ACCMODE; + acct_file->f_flags = O_WRONLY; + acct_file->f_inode = inode; + acct_file->f_pos = inode->i_size; + acct_file->f_reada = 0; + acct_file->f_op = inode->i_op->default_file_ops; + if (acct_file->f_op->open) + if (acct_file->f_op->open(acct_file->f_inode, acct_file)) { + iput(inode); + return -EIO; + } + + vfs_open(acct_file); + acct_active = 1; + return 0; + } else + return -EBUSY; + } +} + +void acct_auto_close(dev_t dev) +{ + if (acct_active && acct_file && acct_file->f_inode->i_dev == dev) + sys_acct((char *)0); } asmlinkage int sys_phys(void)