Commit a5f0a0e2 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.27pre4

parent 01e8163c
This diff is collapsed.
This diff is collapsed.
......@@ -2,78 +2,78 @@
# ISDN device configuration
#
if [ "$CONFIG_INET" != "n" ]; then
bool 'Support synchronous PPP' CONFIG_ISDN_PPP
if [ "$CONFIG_ISDN_PPP" != "n" ]; then
bool 'Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
bool 'Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
fi
bool ' Support synchronous PPP' CONFIG_ISDN_PPP
if [ "$CONFIG_ISDN_PPP" != "n" ]; then
bool ' Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
bool ' Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
fi
fi
bool 'Support audio via ISDN' CONFIG_ISDN_AUDIO
bool ' Support audio via ISDN' CONFIG_ISDN_AUDIO
if [ "$CONFIG_ISDN_AUDIO" != "n" ]; then
bool 'Support AT-Fax Class 2 commands' CONFIG_ISDN_TTY_FAX
bool ' Support AT-Fax Class 2 commands' CONFIG_ISDN_TTY_FAX
fi
bool 'Support isdn diversion services' CONFIG_ISDN_DIVERSION
if [ "$CONFIG_X25" != "n" ]; then
bool 'X.25 PLP on top of ISDN (EXPERIMENTAL)' CONFIG_ISDN_X25
bool ' Support isdn diversion services' CONFIG_ISDN_DIVERSION
if [ "$CONFIG_X25" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' X.25 PLP on top of ISDN (EXPERIMENTAL)' CONFIG_ISDN_X25
fi
dep_tristate 'ICN 2B and 4B support' CONFIG_ISDN_DRV_ICN $CONFIG_ISDN
dep_tristate 'isdnloop support' CONFIG_ISDN_DRV_LOOP $CONFIG_ISDN
dep_tristate 'PCBIT-D support' CONFIG_ISDN_DRV_PCBIT $CONFIG_ISDN
dep_tristate 'HiSax SiemensChipSet driver support' CONFIG_ISDN_DRV_HISAX $CONFIG_ISDN
dep_tristate ' ICN 2B and 4B support' CONFIG_ISDN_DRV_ICN $CONFIG_ISDN
dep_tristate ' isdnloop support' CONFIG_ISDN_DRV_LOOP $CONFIG_ISDN
dep_tristate ' PCBIT-D support' CONFIG_ISDN_DRV_PCBIT $CONFIG_ISDN
dep_tristate ' HiSax SiemensChipSet driver support' CONFIG_ISDN_DRV_HISAX $CONFIG_ISDN
if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then
bool 'HiSax Support for EURO/DSS1' CONFIG_HISAX_EURO
if [ "$CONFIG_HISAX_EURO" != "n" ]; then
bool 'Support for german chargeinfo' CONFIG_DE_AOC
bool 'Disable sending complete' CONFIG_HISAX_NO_SENDCOMPLETE
bool 'Disable sending low layer compatibility' CONFIG_HISAX_NO_LLC
fi
bool 'HiSax Support for german 1TR6' CONFIG_HISAX_1TR6
bool 'HiSax Support for Teles 16.0/8.0' CONFIG_HISAX_16_0
bool 'HiSax Support for Teles 16.3 or PNP or PCMCIA' CONFIG_HISAX_16_3
bool 'HiSax Support for Teles PCI' CONFIG_HISAX_TELESPCI
bool 'HiSax Support for Teles S0Box' CONFIG_HISAX_S0BOX
bool 'HiSax Support for AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1
bool 'HiSax Support for AVM PnP/PCI (Fritz!PnP/PCI)' CONFIG_HISAX_FRITZPCI
bool 'HiSax Support for AVM A1 PCMCIA (Fritz)' CONFIG_HISAX_AVM_A1_PCMCIA
bool 'HiSax Support for Elsa cards' CONFIG_HISAX_ELSA
bool 'HiSax Support for ITK ix1-micro Revision 2' CONFIG_HISAX_IX1MICROR2
bool 'HiSax Support for Eicon.Diehl Diva cards' CONFIG_HISAX_DIEHLDIVA
bool 'HiSax Support for ASUSCOM cards' CONFIG_HISAX_ASUSCOM
bool 'HiSax Support for TELEINT cards' CONFIG_HISAX_TELEINT
bool 'HiSax Support for HFC-S based cards' CONFIG_HISAX_HFCS
bool 'HiSax Support for Sedlbauer cards' CONFIG_HISAX_SEDLBAUER
bool 'HiSax Support for USR Sportster internal TA' CONFIG_HISAX_SPORTSTER
bool 'HiSax Support for MIC card' CONFIG_HISAX_MIC
bool 'HiSax Support for NETjet card' CONFIG_HISAX_NETJET
bool 'HiSax Support for Niccy PnP/PCI card' CONFIG_HISAX_NICCY
bool 'HiSax Support for Siemens I-Surf card' CONFIG_HISAX_ISURF
bool 'HiSax Support for HST Saphir card' CONFIG_HISAX_HSTSAPHIR
bool 'HiSax Support for Telekom A4T card' CONFIG_HISAX_BKM_A4T
bool 'HiSax Support for Scitel Quadro card' CONFIG_HISAX_SCT_QUADRO
bool 'HiSax Support for Gazel cards' CONFIG_HISAX_GAZEL
bool 'HiSax Support for HFC PCI-Bus cards' CONFIG_HISAX_HFC_PCI
if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
bool 'HiSax Support for Winbond W6692 based cards (EXPERIMENTAL)' CONFIG_HISAX_W6692
# bool 'HiSax Support for TESTEMULATOR (EXPERIMENTAL)' CONFIG_HISAX_TESTEMU
if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
bool 'HiSax Support for Am7930' CONFIG_HISAX_AMD7930
fi
fi
bool ' HiSax Support for EURO/DSS1' CONFIG_HISAX_EURO
if [ "$CONFIG_HISAX_EURO" != "n" ]; then
bool ' Support for german chargeinfo' CONFIG_DE_AOC
bool ' Disable sending complete' CONFIG_HISAX_NO_SENDCOMPLETE
bool ' Disable sending low layer compatibility' CONFIG_HISAX_NO_LLC
fi
bool ' HiSax Support for german 1TR6' CONFIG_HISAX_1TR6
bool ' HiSax Support for Teles 16.0/8.0' CONFIG_HISAX_16_0
bool ' HiSax Support for Teles 16.3 or PNP or PCMCIA' CONFIG_HISAX_16_3
bool ' HiSax Support for Teles PCI' CONFIG_HISAX_TELESPCI
bool ' HiSax Support for Teles S0Box' CONFIG_HISAX_S0BOX
bool ' HiSax Support for AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1
bool ' HiSax Support for AVM PnP/PCI (Fritz!PnP/PCI)' CONFIG_HISAX_FRITZPCI
bool ' HiSax Support for AVM A1 PCMCIA (Fritz)' CONFIG_HISAX_AVM_A1_PCMCIA
bool ' HiSax Support for Elsa cards' CONFIG_HISAX_ELSA
bool ' HiSax Support for ITK ix1-micro Revision 2' CONFIG_HISAX_IX1MICROR2
bool ' HiSax Support for Eicon.Diehl Diva cards' CONFIG_HISAX_DIEHLDIVA
bool ' HiSax Support for ASUSCOM cards' CONFIG_HISAX_ASUSCOM
bool ' HiSax Support for TELEINT cards' CONFIG_HISAX_TELEINT
bool ' HiSax Support for HFC-S based cards' CONFIG_HISAX_HFCS
bool ' HiSax Support for Sedlbauer cards' CONFIG_HISAX_SEDLBAUER
bool ' HiSax Support for USR Sportster internal TA' CONFIG_HISAX_SPORTSTER
bool ' HiSax Support for MIC card' CONFIG_HISAX_MIC
bool ' HiSax Support for NETjet card' CONFIG_HISAX_NETJET
bool ' HiSax Support for Niccy PnP/PCI card' CONFIG_HISAX_NICCY
bool ' HiSax Support for Siemens I-Surf card' CONFIG_HISAX_ISURF
bool ' HiSax Support for HST Saphir card' CONFIG_HISAX_HSTSAPHIR
bool ' HiSax Support for Telekom A4T card' CONFIG_HISAX_BKM_A4T
bool ' HiSax Support for Scitel Quadro card' CONFIG_HISAX_SCT_QUADRO
bool ' HiSax Support for Gazel cards' CONFIG_HISAX_GAZEL
bool ' HiSax Support for HFC PCI-Bus cards' CONFIG_HISAX_HFC_PCI
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' HiSax Support for Winbond W6692 based cards (EXPERIMENTAL)' CONFIG_HISAX_W6692
# bool ' HiSax Support for TESTEMULATOR (EXPERIMENTAL)' CONFIG_HISAX_TESTEMU
if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
bool ' HiSax Support for Am7930' CONFIG_HISAX_AMD7930
fi
fi
fi
if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
dep_tristate 'Spellcaster support (EXPERIMENTAL)' CONFIG_ISDN_DRV_SC $CONFIG_ISDN
dep_tristate 'IBM Active 2000 support (EXPERIMENTAL)' CONFIG_ISDN_DRV_ACT2000 $CONFIG_ISDN
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate ' Spellcaster support (EXPERIMENTAL)' CONFIG_ISDN_DRV_SC $CONFIG_ISDN
dep_tristate ' IBM Active 2000 support (EXPERIMENTAL)' CONFIG_ISDN_DRV_ACT2000 $CONFIG_ISDN
fi
dep_tristate 'Eicon.Diehl active card support' CONFIG_ISDN_DRV_EICON $CONFIG_ISDN
dep_tristate ' Eicon.Diehl active card support' CONFIG_ISDN_DRV_EICON $CONFIG_ISDN
if [ "$CONFIG_ISDN_DRV_EICON" != "n" ]; then
bool 'Eicon S,SX,SCOM,Quadro,S2M support' CONFIG_ISDN_DRV_EICON_ISA
bool ' Eicon S, SX, SCOM, Quadro, S2M support' CONFIG_ISDN_DRV_EICON_ISA
fi
dep_tristate 'AVM CAPI2.0 support' CONFIG_ISDN_DRV_AVMB1 $CONFIG_ISDN
dep_tristate ' AVM CAPI2.0 support' CONFIG_ISDN_DRV_AVMB1 $CONFIG_ISDN
if [ "$CONFIG_ISDN_DRV_AVMB1" != "n" ]; then
bool 'AVM B1 ISA support' CONFIG_ISDN_DRV_AVMB1_B1ISA
bool 'AVM B1 PCI support' CONFIG_ISDN_DRV_AVMB1_B1PCI
bool 'AVM T1/T1-B ISA support' CONFIG_ISDN_DRV_AVMB1_T1ISA
bool 'AVM B1/M1/M2 PCMCIA support' CONFIG_ISDN_DRV_AVMB1_B1PCMCIA
bool 'AVM T1/T1-B PCI support' CONFIG_ISDN_DRV_AVMB1_T1PCI
bool 'Verbose reason code reporting (kernel size +=7K)' CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
bool ' AVM B1 ISA support' CONFIG_ISDN_DRV_AVMB1_B1ISA
bool ' AVM B1 PCI support' CONFIG_ISDN_DRV_AVMB1_B1PCI
bool ' AVM T1/T1-B ISA support' CONFIG_ISDN_DRV_AVMB1_T1ISA
bool ' AVM B1/M1/M2 PCMCIA support' CONFIG_ISDN_DRV_AVMB1_B1PCMCIA
bool ' AVM T1/T1-B PCI support' CONFIG_ISDN_DRV_AVMB1_T1PCI
bool ' Verbose reason code reporting (kernel size +=7K)' CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
fi
......@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/poll.h>
......
......@@ -263,7 +263,7 @@ static struct super_block * bfs_read_super(struct super_block * s,
struct buffer_head * bh;
struct bfs_super_block * bfs_sb;
struct inode * inode;
int i, imap_len;
int i, imap_len, bmap_len;
MOD_INC_USE_COUNT;
lock_super(s);
......@@ -295,9 +295,11 @@ static struct super_block * bfs_read_super(struct super_block * s,
s->su_lasti = (bfs_sb->s_start - BFS_BSIZE)/sizeof(struct bfs_inode)
+ BFS_ROOT_INO - 1;
s->su_bmap = kmalloc(sizeof(struct bfs_bmap) * s->su_lasti, GFP_KERNEL);
bmap_len = sizeof(struct bfs_bmap) * s->su_lasti;
s->su_bmap = kmalloc(bmap_len, GFP_KERNEL);
if (!s->su_bmap)
goto out;
memset(s->su_bmap, 0, bmap_len);
imap_len = s->su_lasti/8 + 1;
s->su_imap = kmalloc(imap_len, GFP_KERNEL);
if (!s->su_imap) {
......
......@@ -62,6 +62,8 @@ static long long ext2_file_lseek(
case 1:
offset += file->f_pos;
}
if (offset<0)
return -EINVAL;
if (((unsigned long long) offset >> 32) != 0) {
if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
return -EINVAL;
......
......@@ -9,7 +9,7 @@
O_TARGET := proc.o
O_OBJS := inode.o root.o base.o generic.o array.o \
kmsg.o proc_tty.o sysvipc.o proc_misc.o kcore.o
kmsg.o proc_tty.o proc_misc.o kcore.o
ifdef CONFIG_OMIRR
O_OBJS := $(O_OBJS) omirr.o
endif
......
Inode allocations in the proc-fs (hex-numbers):
Current inode allocations in the proc-fs (hex-numbers):
00000000 reserved
00000001-00000fff static entries
00000001-00000fff static entries (goners)
001 root-ino
002 load-avg
003 uptime
...
080 net/*
...
100 scsi/*
...
xxx mca/*
...
yyy bus/*
...
fff end
00001000-00001fff dynamic entries
00002000-00002fff openprom entries
0001xxxx-7fffxxxx pid-dir entries for pid 1-7fff
0000 unused
0001 unused
0002 pid
0003 pid/status
...
0008 pid/fd
...
00xx-00ff unused
01xx pid/fd/* for fd 0-ff
...
01ff end
0200-ffff unused
80000000-ffffffff unused
New allocation:
00000000-0000ffff unchanged
0001xxxx-7fffxxxx pid-dir entries for pid 1-7fff
0000-00ff unchanged
0100-7fff unused
8000-ffff pid/fd/* for fd 0-7fff
80000000-ffffffff unchanged
Goals:
a) the only static inumber that will stay is root's.
b) scsi should go dynamic.
c) once we'll split the thing into several virtual filesystems we
will get rid of magical ranges (and this file, BTW).
......@@ -143,7 +143,7 @@ static char *storenote(struct memelfnote *men, char *bufp)
* store an ELF coredump header in the supplied buffer
* - assume the memory image is the size specified
*/
static void elf_kcore_store_hdr(char *bufp, size_t size, off_t dataoff)
static void elf_kcore_store_hdr(char *bufp)
{
struct elf_prstatus prstatus; /* NT_PRSTATUS */
struct elf_prpsinfo psinfo; /* NT_PRPSINFO */
......@@ -154,65 +154,86 @@ static void elf_kcore_store_hdr(char *bufp, size_t size, off_t dataoff)
/* acquire an ELF header block from the buffer */
elf = (struct elfhdr *) bufp;
bufp += sizeof(*elf);
offset += sizeof(*elf);
bufp += sizeof(struct elfhdr);
offset += sizeof(struct elfhdr);
/* set up header */
memcpy(elf->e_ident,ELFMAG,SELFMAG);
elf->e_ident[EI_CLASS] = ELF_CLASS;
elf->e_ident[EI_DATA] = ELF_DATA;
elf->e_ident[EI_VERSION]= EV_CURRENT;
memset(elf->e_ident+EI_PAD,0,EI_NIDENT-EI_PAD);
memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
elf->e_type = ET_CORE;
elf->e_machine = ELF_ARCH;
elf->e_version = EV_CURRENT;
elf->e_entry = 0;
elf->e_phoff = sizeof(*elf);
elf->e_phoff = sizeof(struct elfhdr);
elf->e_shoff = 0;
elf->e_flags = 0;
elf->e_ehsize = sizeof(*elf);
elf->e_ehsize = sizeof(struct elfhdr);
elf->e_phentsize= sizeof(struct elf_phdr);
elf->e_phnum = 2; /* no. of segments */
elf->e_phnum = 1; /* no. of segments = 1 + Nmodules */
elf->e_shentsize= 0;
elf->e_shnum = 0;
elf->e_shstrndx = 0;
/* acquire an ELF program header blocks from the buffer for notes */
nhdr = (struct elf_phdr *) bufp;
bufp += sizeof(*nhdr);
offset += sizeof(*nhdr);
bufp += sizeof(struct elf_phdr);
offset += sizeof(struct elf_phdr);
/* store program headers for notes dump */
nhdr->p_type = PT_NOTE;
nhdr->p_offset = 0;
nhdr->p_vaddr = 0;
nhdr->p_paddr = 0;
nhdr->p_filesz = 0;
nhdr->p_memsz = 0;
nhdr->p_flags = 0;
nhdr->p_align = 0;
/* acquire an ELF program header blocks from the buffer for data */
dhdr = (struct elf_phdr *) bufp;
bufp += sizeof(*dhdr);
offset += sizeof(*dhdr);
bufp += sizeof(struct elf_phdr);
offset += sizeof(struct elf_phdr);
/* store program headers for data dump */
dhdr->p_type = PT_LOAD;
dhdr->p_flags = PF_R|PF_W|PF_X;
dhdr->p_offset = dataoff;
dhdr->p_offset = PAGE_SIZE;
dhdr->p_vaddr = PAGE_OFFSET;
dhdr->p_paddr = __pa(PAGE_OFFSET);
dhdr->p_filesz = size;
dhdr->p_memsz = size;
dhdr->p_filesz = ((unsigned long)high_memory - PAGE_OFFSET + PAGE_SIZE);
dhdr->p_memsz = ((unsigned long)high_memory - PAGE_OFFSET + PAGE_SIZE);
dhdr->p_align = PAGE_SIZE;
#ifdef CONFIG_MODULES
{
struct module *m;
for (m=module_list; m; m=m->next) {
dhdr = (struct elf_phdr *) bufp;
bufp += sizeof(struct elf_phdr);
offset += sizeof(struct elf_phdr);
dhdr->p_type = PT_LOAD;
dhdr->p_flags = PF_R|PF_W|PF_X;
dhdr->p_offset = (unsigned long)m - PAGE_OFFSET + PAGE_SIZE;
dhdr->p_vaddr = (unsigned long)m;
dhdr->p_paddr = __pa(m);
dhdr->p_filesz = m->size;
dhdr->p_memsz = m->size;
dhdr->p_align = 0;
elf->e_phnum++;
}
}
#endif
/*
* Set up the notes in similar form to SVR4 core dumps made
* with info from their /proc.
*/
nhdr->p_offset = offset;
nhdr->p_filesz = 0;
/* set up the process status */
notes[0].name = "CORE";
......@@ -289,7 +310,7 @@ ssize_t read_kcore(struct file *file, char *buffer, size_t buflen,
/* create a header */
memset(page,0,PAGE_SIZE);
elf_kcore_store_hdr(page,size-PAGE_SIZE,PAGE_SIZE);
elf_kcore_store_hdr(page);
/* copy data to the users buffer */
copy_to_user(buffer,page,tsz);
......
......@@ -93,8 +93,7 @@ struct proc_dir_entry proc_root = {
&proc_root, NULL
};
struct proc_dir_entry *proc_net, *proc_bus, *proc_sysvipc,
*proc_root_fs, *proc_root_driver;
struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver;
#ifdef CONFIG_MCA
struct proc_dir_entry *proc_mca;
......@@ -226,6 +225,73 @@ static int make_inode_number(void)
return PROC_DYNAMIC_FIRST + i;
}
int proc_readlink(struct dentry * dentry, char * buffer, int buflen)
{
struct inode *inode = dentry->d_inode;
struct proc_dir_entry * de;
char *page;
int len = 0;
de = (struct proc_dir_entry *) inode->u.generic_ip;
if (!de)
return -ENOENT;
if (!(page = (char*) __get_free_page(GFP_KERNEL)))
return -ENOMEM;
if (de->readlink_proc)
len = de->readlink_proc(de, page);
if (len > buflen)
len = buflen;
copy_to_user(buffer, page, len);
free_page((unsigned long) page);
return len;
}
struct dentry * proc_follow_link(struct dentry * dentry, struct dentry *base, unsigned int follow)
{
struct inode *inode = dentry->d_inode;
struct proc_dir_entry * de;
char *page;
struct dentry *d;
int len = 0;
de = (struct proc_dir_entry *) inode->u.generic_ip;
if (!(page = (char*) __get_free_page(GFP_KERNEL)))
return NULL;
if (de->readlink_proc)
len = de->readlink_proc(de, page);
d = lookup_dentry(page, base, follow);
free_page((unsigned long) page);
return d;
}
static struct inode_operations proc_link_inode_operations = {
NULL, /* no file-ops */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
proc_readlink, /* readlink */
proc_follow_link, /* follow_link */
NULL, /* get_block */
NULL, /* readpage */
NULL, /* writepage */
NULL, /* flushpage */
NULL, /* truncate */
NULL, /* permission */
NULL, /* smap */
NULL /* revalidate */
};
int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
{
int i;
......@@ -338,50 +404,6 @@ static struct dentry * proc_self_follow_link(struct dentry *dentry,
return lookup_dentry(tmp, base, follow);
}
int proc_readlink(struct dentry * dentry, char * buffer, int buflen)
{
struct inode *inode = dentry->d_inode;
struct proc_dir_entry * de;
char *page;
int len = 0;
de = (struct proc_dir_entry *) inode->u.generic_ip;
if (!de)
return -ENOENT;
if (!(page = (char*) __get_free_page(GFP_KERNEL)))
return -ENOMEM;
if (de->readlink_proc)
len = de->readlink_proc(de, page);
if (len > buflen)
len = buflen;
copy_to_user(buffer, page, len);
free_page((unsigned long) page);
return len;
}
struct dentry * proc_follow_link(struct dentry * dentry, struct dentry *base, unsigned int follow)
{
struct inode *inode = dentry->d_inode;
struct proc_dir_entry * de;
char *page;
struct dentry *d;
int len = 0;
de = (struct proc_dir_entry *) inode->u.generic_ip;
if (!(page = (char*) __get_free_page(GFP_KERNEL)))
return NULL;
if (de->readlink_proc)
len = de->readlink_proc(de, page);
d = lookup_dentry(page, base, follow);
free_page((unsigned long) page);
return d;
}
static struct inode_operations proc_self_inode_operations = {
NULL, /* no file-ops */
NULL, /* create */
......@@ -405,29 +427,6 @@ static struct inode_operations proc_self_inode_operations = {
NULL /* revalidate */
};
static struct inode_operations proc_link_inode_operations = {
NULL, /* no file-ops */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
proc_readlink, /* readlink */
proc_follow_link, /* follow_link */
NULL, /* get_block */
NULL, /* readpage */
NULL, /* writepage */
NULL, /* flushpage */
NULL, /* truncate */
NULL, /* permission */
NULL, /* smap */
NULL /* revalidate */
};
static struct proc_dir_entry proc_root_self = {
0, 4, "self",
S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, 1, 0, 0,
......@@ -450,7 +449,7 @@ void __init proc_root_init(void)
proc_register(&proc_root, &proc_root_self);
proc_net = create_proc_entry("net", S_IFDIR, 0);
#ifdef CONFIG_SYSVIPC
proc_sysvipc = create_proc_entry("sysvipc", S_IFDIR, 0);
create_proc_entry("sysvipc", S_IFDIR, 0);
#endif
#ifdef CONFIG_SYSCTL
proc_sys_root = create_proc_entry("sys", S_IFDIR, 0);
......
/*
* linux/fs/proc/sysvipc.c
*
* Copyright (c) 1999 Dragos Acostachioaie
*
* This code is derived from linux/fs/proc/generic.c,
* which is Copyright (C) 1991, 1992 Linus Torvalds.
*
* /proc/sysvipc directory handling functions
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/mm.h>
#include <asm/uaccess.h>
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
/* 4K page size but our output routines use some slack for overruns */
#define PROC_BLOCK_SIZE (3*1024)
static ssize_t
proc_sysvipc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
{
struct inode * inode = file->f_dentry->d_inode;
char *page;
ssize_t retval=0;
int eof=0;
ssize_t n, count;
char *start;
struct proc_dir_entry * dp;
dp = (struct proc_dir_entry *) inode->u.generic_ip;
if (!(page = (char*) __get_free_page(GFP_KERNEL)))
return -ENOMEM;
while ((nbytes > 0) && !eof)
{
count = MIN(PROC_BLOCK_SIZE, nbytes);
start = NULL;
if (dp->get_info) {
/*
* Handle backwards compatibility with the old net
* routines.
*
* XXX What gives with the file->f_flags & O_ACCMODE
* test? Seems stupid to me....
*/
n = dp->get_info(page, &start, *ppos, count,
(file->f_flags & O_ACCMODE) == O_RDWR);
if (n < count)
eof = 1;
} else if (dp->read_proc) {
n = dp->read_proc(page, &start, *ppos,
count, &eof, dp->data);
} else
break;
if (!start) {
/*
* For proc files that are less than 4k
*/
start = page + *ppos;
n -= *ppos;
if (n <= 0)
break;
if (n > count)
n = count;
}
if (n == 0)
break; /* End of file */
if (n < 0) {
if (retval == 0)
retval = n;
break;
}
/* This is a hack to allow mangling of file pos independent
* of actual bytes read. Simply place the data at page,
* return the bytes, and set `start' to the desired offset
* as an unsigned int. - Paul.Russell@rustcorp.com.au
*/
n -= copy_to_user(buf, start < page ? page : start, n);
if (n == 0) {
if (retval == 0)
retval = -EFAULT;
break;
}
*ppos += start < page ? (long)start : n; /* Move down the file */
nbytes -= n;
buf += n;
retval += n;
}
free_page((unsigned long) page);
return retval;
}
static struct file_operations proc_sysvipc_operations = {
NULL, /* lseek */
proc_sysvipc_read, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* poll */
NULL, /* ioctl */
NULL, /* mmap */
NULL, /* no special open code */
NULL, /* no special release code */
NULL /* can't fsync */
};
/*
* proc directories can do almost nothing..
*/
struct inode_operations proc_sysvipc_inode_operations = {
&proc_sysvipc_operations, /* default net file-ops */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* get_block */
NULL, /* readpage */
NULL, /* writepage */
NULL, /* flushpage */
NULL, /* truncate */
NULL, /* permission */
NULL, /* smap */
NULL /* revalidate */
};
......@@ -34,6 +34,21 @@
* exposed a problem in readdir
* 2.1.107 code-freeze spellchecker run
* Aug 1998 2.1.118+ VFS changes
* Sep 1998 2.1.122 another VFS change (follow_link)
* Apr 1999 2.2.7 no more EBADF checking in
* lookup/readdir, use ERR_PTR
* Jun 1999 2.3.6 d_alloc_root use changed
* 2.3.9 clean up usage of ENOENT/negative
* dentries in lookup
* clean up page flags setting
* (error, uptodate, locking) in
* in readpage
* use init_special_inode for
* fifos/sockets (and streamline) in
* read_inode, fix _ops table order
* Aug 1999 2.3.16 __initfunc() => __init change
* Oct 1999 2.3.24 page->owner hack obsoleted
* Nov 1999 2.3.27 2.3.25+ page->offset => index change
*/
/* todo:
......@@ -404,7 +419,8 @@ romfs_readpage(struct file * file, struct page * page)
get_page(page);
buf = page_address(page);
offset = page->offset;
/* 32 bit warning -- but not for us :) */
offset = page->index << PAGE_CACHE_SHIFT;
if (offset < inode->i_size) {
avail = inode->i_size-offset;
readlen = min(avail, PAGE_SIZE);
......
......@@ -42,6 +42,8 @@ struct ipc_perm
#define IPC_UNUSED ((void *) -1)
#define IPC_NOID ((void *) -2) /* being allocated/destroyed */
#define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */
#endif /* __KERNEL__ */
#endif /* _LINUX_IPC_H */
......
......@@ -45,9 +45,9 @@ struct msginfo {
unsigned short msgseg;
};
#define MSGMNI 128 /* <= 32768 */ /* max # of msg queue identifiers */
#define MSGMAX 4056 /* <= 4056 (?)*/ /* max size of message (bytes) */
#define MSGMNB 16384 /* <= MAX_INT */ /* default max size of a message queue */
#define MSGMNI 128 /* <= IPCMNI */ /* max # of msg queue identifiers */
#define MSGMAX 8192 /* <= INT_MAX */ /* max size of message (bytes) */
#define MSGMNB 16384 /* <= INT_MAX */ /* default max size of a message queue */
/* unused */
#define MSGPOOL (MSGMNI*MSGMNB/1024) /* size in kilobytes of message pool */
......
......@@ -90,15 +90,6 @@ enum scsi_directory_inos {
PROC_SCSI_LAST = (PROC_SCSI_FILE + 16) /* won't ever see more than */
}; /* 16 HBAs in one machine */
enum mca_directory_inos {
PROC_MCA_MACHINE = (PROC_SCSI_LAST+1),
PROC_MCA_REGISTERS,
PROC_MCA_VIDEO,
PROC_MCA_SCSI,
PROC_MCA_SLOT, /* the 8 adapter slots */
PROC_MCA_LAST = (PROC_MCA_SLOT + 8)
};
/* Finally, the dynamically allocatable proc entries are reserved: */
#define PROC_DYNAMIC_FIRST 4096
......@@ -173,11 +164,8 @@ extern struct proc_dir_entry *proc_net;
extern struct proc_dir_entry *proc_scsi;
extern struct proc_dir_entry proc_sys;
extern struct proc_dir_entry proc_openprom;
extern struct proc_dir_entry proc_pid;
extern struct proc_dir_entry proc_pid_fd;
extern struct proc_dir_entry *proc_mca;
extern struct proc_dir_entry *proc_bus;
extern struct proc_dir_entry *proc_sysvipc;
extern struct proc_dir_entry *proc_root_driver;
extern struct proc_dir_entry proc_root_kcore;
......@@ -272,8 +260,6 @@ extern inline int proc_driver_register(const char *module_name)
return (p == NULL) ? -1 : 0;
}
extern struct super_block *proc_super_blocks;
extern struct dentry_operations proc_dentry_operations;
extern struct super_block *proc_read_super(struct super_block *,void *,int);
......@@ -315,21 +301,16 @@ extern int proc_openprom_unregdev(struct openpromfs_dev *);
extern struct inode_operations proc_dir_inode_operations;
extern struct inode_operations proc_file_inode_operations;
extern struct inode_operations proc_netdir_inode_operations;
extern struct inode_operations proc_openprom_inode_operations;
extern struct inode_operations proc_mem_inode_operations;
extern struct inode_operations proc_sys_inode_operations;
extern struct inode_operations proc_kcore_inode_operations;
extern struct inode_operations proc_profile_inode_operations;
extern struct inode_operations proc_kmsg_inode_operations;
extern struct inode_operations proc_link_inode_operations;
extern struct inode_operations proc_fd_inode_operations;
#if CONFIG_AP1000
extern struct inode_operations proc_ringbuf_inode_operations;
#endif
extern struct inode_operations proc_omirr_inode_operations;
extern struct inode_operations proc_ppc_htab_inode_operations;
extern struct inode_operations proc_sysvipc_inode_operations;
/*
* proc_tty.c
......@@ -374,16 +355,6 @@ extern inline void proc_net_remove(const char *name)
remove_proc_entry(name,proc_net);
}
extern inline int proc_net_register(struct proc_dir_entry * x)
{
return proc_register(proc_net, x);
}
extern inline int proc_net_unregister(int x)
{
return proc_unregister(proc_net, x);
}
#else
extern inline int proc_register(struct proc_dir_entry *a, struct proc_dir_entry *b) { return 0; }
......@@ -391,8 +362,6 @@ extern inline int proc_unregister(struct proc_dir_entry *a, int b) { return 0; }
extern inline struct proc_dir_entry *proc_net_create(const char *name, mode_t mode,
get_info_t *get_info) {return NULL;}
extern inline void proc_net_remove(const char *name) {}
extern inline int proc_net_register(struct proc_dir_entry * x) { return 0; }
extern inline int proc_net_unregister(int x) { return 0; }
extern inline int proc_scsi_register(struct proc_dir_entry *b, struct proc_dir_entry *c) { return 0; }
extern inline int proc_scsi_unregister(struct proc_dir_entry *a, int x) { return 0; }
......
......@@ -60,10 +60,10 @@ struct seminfo {
int semaem;
};
#define SEMMNI 128 /* <= 32767 max # of semaphore identifiers */
#define SEMMSL 250 /* <= 512 max num of semaphores per id */
#define SEMMNS (SEMMNI*SEMMSL) /* <= MAX_INT max # of semaphores in system */
#define SEMOPM 32 /* <= 160 max num of ops per semop call */
#define SEMMNI 128 /* <= IPCMNI max # of semaphore identifiers */
#define SEMMSL 250 /* <= 8 000 max num of semaphores per id */
#define SEMMNS (SEMMNI*SEMMSL) /* <= INT_MAX max # of semaphores in system */
#define SEMOPM 32 /* <= 1 000 max num of ops per semop call */
#define SEMVMX 32767 /* <= 32767 semaphore maximum value */
/* unused */
......
......@@ -102,9 +102,11 @@ enum
KERN_MSGMNB=36, /* int: Maximum message queue size */
KERN_MSGPOOL=37, /* int: Maximum system message pool size */
KERN_SYSRQ=38, /* int: Sysreq enable */
KERN_MAX_THREADS=39, /* int: Maximum nr of threads in the system */
KERN_MAX_THREADS=39, /* int: Maximum nr of threads in the system */
KERN_RANDOM=40, /* Random driver */
KERN_SHMALL=41 /* int: Maximum size of shared memory */
KERN_SHMALL=41, /* int: Maximum size of shared memory */
KERN_MSGMNI=42, /* int: msg queue identifiers */
KERN_SEM=43 /* int: sysv semaphore limits */
};
......
This diff is collapsed.
This diff is collapsed.
......@@ -6,6 +6,8 @@
* get BSD style process accounting right.
* Occurs in several places in the IPC code.
* Chris Evans, <chris@ferret.lmh.ox.ac.uk>
* Nov 1999 - ipc helper functions, unified SMP locking
* Manfred Spraul <manfreds@colorfullife.com>
*/
#include <linux/config.h>
......@@ -13,12 +15,13 @@
#include <linux/shm.h>
#include <linux/init.h>
#include <linux/msg.h>
#include "util.h"
#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/malloc.h>
#if defined(CONFIG_SYSVIPC)
extern void sem_init (void), msg_init (void), shm_init (void);
#include "util.h"
void __init ipc_init (void)
{
......@@ -28,6 +31,157 @@ void __init ipc_init (void)
return;
}
void __init ipc_init_ids(struct ipc_ids* ids, int size)
{
int i;
sema_init(&ids->sem,1);
ids->size = size;
if(size == 0)
return;
if(size > IPCMNI)
size = IPCMNI;
ids->in_use = 0;
ids->max_id = -1;
ids->seq = 0;
{
int seq_limit = INT_MAX/SEQ_MULTIPLIER;
if(seq_limit > USHRT_MAX)
ids->seq_max = USHRT_MAX;
else
ids->seq_max = seq_limit;
}
ids->entries = ipc_alloc(sizeof(struct ipc_id)*size);
if(ids->entries == NULL) {
printk(KERN_ERR "ipc_init_ids() failed, ipc service disabled.\n");
ids->size = 0;
}
ids->ary = SPIN_LOCK_UNLOCKED;
for(i=0;i<size;i++) {
ids->entries[i].p = NULL;
}
}
int ipc_findkey(struct ipc_ids* ids, key_t key)
{
int id;
struct ipc_perm* p;
for (id = 0; id <= ids->max_id; id++) {
p = ids->entries[id].p;
if(p==NULL)
continue;
if (key == p->key)
return id;
}
return -1;
}
static int grow_ary(struct ipc_ids* ids, int newsize)
{
struct ipc_id* new;
struct ipc_id* old;
int i;
if(newsize > IPCMNI)
newsize = IPCMNI;
if(newsize <= ids->size)
return newsize;
new = ipc_alloc(sizeof(struct ipc_id)*newsize);
if(new == NULL)
return ids->size;
memcpy(new, ids->entries, sizeof(struct ipc_id)*ids->size);
for(i=ids->size;i<newsize;i++) {
new[i].p = NULL;
}
spin_lock(&ids->ary);
old = ids->entries;
ids->entries = new;
i = ids->size;
ids->size = newsize;
spin_unlock(&ids->ary);
ipc_free(old, sizeof(struct ipc_id)*i);
return ids->size;
}
int ipc_addid(struct ipc_ids* ids, struct ipc_perm* new, int size)
{
int id;
size = grow_ary(ids,size);
for (id = 0; id < size; id++) {
if(ids->entries[id].p == NULL)
goto found;
}
return -1;
found:
ids->in_use++;
if (id > ids->max_id)
ids->max_id = id;
new->cuid = new->uid = current->euid;
new->gid = new->cgid = current->egid;
new->seq = ids->seq++;
if(ids->seq > ids->seq_max)
ids->seq = 0;
ipc_lock(ids,id);
ids->entries[id].p = new;
return id;
}
struct ipc_perm* ipc_rmid(struct ipc_ids* ids, int id)
{
struct ipc_perm* p;
int lid = id % SEQ_MULTIPLIER;
if(lid > ids->size)
BUG();
p = ids->entries[lid].p;
ids->entries[lid].p = NULL;
if(p==NULL)
BUG();
ids->in_use--;
if (lid == ids->max_id) {
do {
lid--;
if(lid == -1)
break;
} while (ids->entries[lid].p == NULL);
ids->max_id = lid;
}
return p;
}
void* ipc_alloc(int size)
{
void* out;
if(size > PAGE_SIZE) {
lock_kernel();
out = vmalloc(size);
unlock_kernel();
} else {
out = kmalloc(size, GFP_KERNEL);
}
return out;
}
void ipc_free(void* ptr, int size)
{
if(size > PAGE_SIZE) {
lock_kernel();
vfree(ptr);
unlock_kernel();
} else {
kfree(ptr);
}
}
/*
* Check user, group, other permissions for access
* to ipc resources. return 0 if allowed
......
/*
* linux/ipc/util.h
* Copyright (C) 1999 Christoph Rohland
*
* ipc helper functions (c) 1999 Manfred Spraul <manfreds@colorfullife.com>
*/
/*
* IPCMNI is the absolute maximum for ipc identifier. This is used to
* detect stale identifiers
#define USHRT_MAX 0xffff
#define SEQ_MULTIPLIER (IPCMNI)
void sem_init (void);
void msg_init (void);
void shm_init (void);
struct ipc_ids {
int size;
int in_use;
int max_id;
unsigned short seq;
unsigned short seq_max;
struct semaphore sem;
spinlock_t ary;
struct ipc_id* entries;
};
struct ipc_id {
struct ipc_perm* p;
};
void __init ipc_init_ids(struct ipc_ids* ids, int size);
/* must be called with ids->sem acquired.*/
int ipc_findkey(struct ipc_ids* ids, key_t key);
int ipc_addid(struct ipc_ids* ids, struct ipc_perm* new, int size);
/* must be called with both locks acquired. */
struct ipc_perm* ipc_rmid(struct ipc_ids* ids, int id);
int ipcperms (struct ipc_perm *ipcp, short flg);
/* for rare, potentially huge allocations.
* both function can sleep
*/
#define IPCMNI (1<<15)
void* ipc_alloc(int size);
void ipc_free(void* ptr, int size);
extern inline struct ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
{
struct ipc_perm* out;
int lid = id % SEQ_MULTIPLIER;
if(lid > ids->size)
return NULL;
spin_lock(&ids->ary);
out = ids->entries[lid].p;
if(out==NULL)
spin_unlock(&ids->ary);
return out;
}
extern inline void ipc_unlock(struct ipc_ids* ids, int id)
{
spin_unlock(&ids->ary);
}
extern inline int ipc_buildid(struct ipc_ids* ids, int id, int seq)
{
return SEQ_MULTIPLIER*seq + id;
}
extern inline int ipc_checkid(struct ipc_ids* ids, struct ipc_perm* ipcp, int uid)
{
if(uid/SEQ_MULTIPLIER != ipcp->seq)
return 1;
return 0;
}
extern int ipcperms (struct ipc_perm *ipcp, short shmflg);
......@@ -60,7 +60,7 @@ unsigned long get_kcore_size(void)
struct module * m;
if (module_list == &kernel_module)
return ((size_t)high_memory - PAGE_OFFSET + PAGE_SIZE);
return ((unsigned long)high_memory - PAGE_OFFSET + PAGE_SIZE);
/* shouldn't we have a rw spinlock for module_list? */
lock_kernel();
......@@ -992,7 +992,7 @@ get_module_symbol(char *modname, char *symname)
/* no MODULES so high_memory is good enough for /proc/kcore (TA) */
unsigned long get_kcore_size(void)
{
return ((size_t)high_memory - PAGE_OFFSET + PAGE_SIZE);
return ((unsigned long)high_memory - PAGE_OFFSET + PAGE_SIZE);
}
......
......@@ -20,7 +20,7 @@ struct resource iomem_resource = { "PCI mem", 0x00000000, 0xFFFFFFFF, IORESOURCE
static rwlock_t resource_lock = RW_LOCK_UNLOCKED;
/*
* This generates reports for /proc/ioports and /proc/memory
* This generates reports for /proc/ioports and /proc/iomem
*/
static char * do_resource_list(struct resource *entry, const char *fmt, int offset, char *buf, char *end)
{
......
......@@ -50,6 +50,10 @@ extern int sg_big_buff;
#endif
#ifdef CONFIG_SYSVIPC
extern size_t shm_prm[];
extern int msg_ctlmax;
extern int msg_ctlmnb;
extern int msg_ctlmni;
extern int sem_ctls[];
#endif
#ifdef __sparc__
......@@ -215,6 +219,14 @@ static ctl_table kern_table[] = {
#ifdef CONFIG_SYSVIPC
{KERN_SHMMAX, "shmmax", &shm_prm, 3*sizeof (size_t),
0644, NULL, &proc_doulongvec_minmax},
{KERN_MSGMAX, "msgmax", &msg_ctlmax, sizeof (int),
0644, NULL, &proc_dointvec},
{KERN_MSGMNI, "msgmni", &msg_ctlmni, sizeof (int),
0644, NULL, &proc_dointvec},
{KERN_MSGMNB, "msgmnb", &msg_ctlmnb, sizeof (int),
0644, NULL, &proc_dointvec},
{KERN_SEM, "sem", &sem_ctls, 4*sizeof (int),
0644, NULL, &proc_dointvec},
#endif
#ifdef CONFIG_MAGIC_SYSRQ
{KERN_SYSRQ, "sysrq", &sysrq_enabled, sizeof (int),
......
......@@ -1999,6 +1999,7 @@ int unregister_netdevice(struct net_device *dev)
*
*/
extern void net_device_init(void);
extern void ip_auto_config(void);
int __init net_dev_init(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment