E: rfflaxa@immd4.informatik.uni-erlangen.de
D: The Linux Support Team Erlangen
+N: Lawrence Foard
+E: entropy@world.std.com
+D: Floppy track reading, fs code
+S: Suite #108
+S: 217 Park Ave.
+S: Worcester Ma 01609
+S: USA
+
N: Nigel Gamble
E: nigel%gamble.uucp@gate.net
D: Interrupt-driven printer driver
VERSION = 1
PATCHLEVEL = 1
-SUBLEVEL = 10
+SUBLEVEL = 11
all: Version zImage
* This block is from a device that we're about to stomp on.
* So make sure nobody thinks this block is usable.
*/
- bh->b_dirt=0;
- bh->b_uptodate=0;
+ bh->b_dirt = 0;
+ bh->b_uptodate = 0;
+ bh->b_req = 0;
if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
p = (struct partition *) (0x1BE + bh->b_data);
/*
blk_size[dev->major] = dev->sizes;
}
-void device_setup(void * BIOS)
+void device_setup(void)
{
struct gendisk *p;
int nr=0;
mpnt->vm_offset = off;
mpnt->vm_ops = NULL;
insert_vm_struct(current, mpnt);
- merge_segments(current->mmap, NULL, NULL);
+ merge_segments(current->mm->mmap, NULL, NULL);
return 0;
}
mpnt->vm_offset = off;
mpnt->vm_ops = NULL;
insert_vm_struct(current, mpnt);
- merge_segments(current->mmap, ignoff_mergep, inode);
+ merge_segments(current->mm->mmap, ignoff_mergep, inode);
return 0;
}
send_sig(SIGKILL, *p, 1);
else {
for (i=0; i < NR_OPEN; i++) {
- filp = (*p)->filp[i];
+ filp = (*p)->files->fd[i];
if (filp && (filp->f_op == &tty_fops) &&
(MINOR(filp->f_rdev) == line)) {
send_sig(SIGKILL, *p, 1);
struct mailbox * mb;
struct ccb *ccb;
- unchar cmd[5] = {CMD_MBINIT, AHA1542_MAILBOXES};
+ unchar cmd[5] = {CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};
mb = HOSTDATA(shpnt)->mb;
ccb = HOSTDATA(shpnt)->ccb;
irq_ok = 1;
break;
+#ifndef EXCLUDE_MIDI
+
case IMODE_MIDI:
sb_midi_interrupt (unit);
break;
+#endif
+
default:
printk ("SoundBlaster: Unexpected interrupt\n");
}
status = fd;
}
else
- fp = current->filp[fd];
+ fp = current->files->fd[fd];
}
else
fd = -1; /* Invalidate the open file descriptor */
/*
* Define the initial locations for the various items in the new process
*/
- current->mmap = NULL;
- current->rss = 0;
+ current->mm->mmap = NULL;
+ current->mm->rss = 0;
/*
* Construct the parameter and environment string table entries.
*/
/*
* Do the end processing once the stack has been constructed
*/
- current->start_code = text_vaddr & PAGE_MASK;
- current->end_code = text_vaddr + text_size;
- current->end_data = data_vaddr + data_size;
- current->start_brk =
- current->brk = bss_vaddr + bss_size;
- current->suid =
- current->euid = bprm->e_uid;
- current->sgid =
- current->egid = bprm->e_gid;
- current->executable = bprm->inode; /* Store inode for file */
+ current->mm->start_code = text_vaddr & PAGE_MASK;
+ current->mm->end_code = text_vaddr + text_size;
+ current->mm->end_data = data_vaddr + data_size;
+ current->mm->start_brk =
+ current->mm->brk = bss_vaddr + bss_size;
+ current->suid =
+ current->euid = bprm->e_uid;
+ current->sgid =
+ current->egid = bprm->e_gid;
+ current->executable = bprm->inode; /* Store inode for file */
++bprm->inode->i_count; /* Count the open inode */
- regs->eip = start_addr; /* Current EIP register */
- regs->esp =
- current->start_stack = bprm->p;
+ regs->eip = start_addr; /* Current EIP register */
+ regs->esp =
+ current->mm->start_stack = bprm->p;
}
/*
* Map the text pages
memset (bprm, '\0', sizeof (struct linux_binprm));
- file = current->filp[fd];
+ file = current->files->fd[fd];
bprm->inode = file->f_inode; /* The only item _really_ needed */
bprm->filename = ""; /* Make it a legal string */
/*
mpnt->vm_offset = 0;
mpnt->vm_ops = NULL;
insert_vm_struct(current, mpnt);
- current->stk_vma = mpnt;
+ current->mm->stk_vma = mpnt;
}
sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
if(exec) sp -= DLINFO_ITEMS*2;
};
put_fs_long((unsigned long)argc,--sp);
- current->arg_start = (unsigned long) p;
+ current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
put_fs_long((unsigned long) p,argv++);
while (get_fs_byte(p++)) /* nothing */ ;
}
put_fs_long(0,argv);
- current->arg_end = current->env_start = (unsigned long) p;
+ current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) {
put_fs_long((unsigned long) p,envp++);
while (get_fs_byte(p++)) /* nothing */ ;
}
put_fs_long(0,envp);
- current->env_end = (unsigned long) p;
+ current->mm->env_end = (unsigned long) p;
return sp;
}
elf_exec_fileno = open_inode(interpreter_inode, O_RDONLY);
if (elf_exec_fileno < 0) return 0xffffffff;
- file = current->filp[elf_exec_fileno];
+ file = current->files->fd[elf_exec_fileno];
eppnt = elf_phdata;
for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
int retval;
unsigned int elf_entry;
- current->brk = interp_ex->a_bss +
- (current->end_data = interp_ex->a_data +
- (current->end_code = interp_ex->a_text));
+ current->mm->brk = interp_ex->a_bss +
+ (current->mm->end_data = interp_ex->a_data +
+ (current->mm->end_code = interp_ex->a_text));
elf_entry = interp_ex->a_entry;
return elf_exec_fileno;
}
- file = current->filp[elf_exec_fileno];
+ file = current->files->fd[elf_exec_fileno];
elf_stack = 0xffffffff;
elf_interpreter = NULL;
/* OK, This is the point of no return */
flush_old_exec(bprm);
- current->end_data = 0;
- current->end_code = 0;
- current->start_mmap = ELF_START_MMAP;
- current->mmap = NULL;
+ current->mm->end_data = 0;
+ current->mm->end_code = 0;
+ current->mm->start_mmap = ELF_START_MMAP;
+ current->mm->mmap = NULL;
elf_entry = (unsigned int) elf_ex.e_entry;
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
- current->rss = 0;
+ current->mm->rss = 0;
bprm->p += change_ldt(0, bprm->page);
- current->start_stack = bprm->p;
+ current->mm->start_stack = bprm->p;
/* Now we do a little grungy work by mmaping the ELF image into
the correct location in memory. At this point, we assume that
load_addr,
(interpreter_type == INTERPRETER_AOUT ? 0 : 1));
if(interpreter_type == INTERPRETER_AOUT)
- current->arg_start += strlen(passed_fileno) + 1;
- current->start_brk = current->brk = elf_brk;
- current->end_code = end_code;
- current->start_code = start_code;
- current->end_data = end_data;
- current->start_stack = bprm->p;
+ current->mm->arg_start += strlen(passed_fileno) + 1;
+ current->mm->start_brk = current->mm->brk = elf_brk;
+ current->mm->end_code = end_code;
+ current->mm->start_code = start_code;
+ current->mm->end_data = end_data;
+ current->mm->start_stack = bprm->p;
current->suid = current->euid = bprm->e_uid;
current->sgid = current->egid = bprm->e_gid;
/* Calling sys_brk effectively mmaps the pages that we need for the bss and break
sections */
- current->brk = (elf_bss + 0xfff) & 0xfffff000;
+ current->mm->brk = (elf_bss + 0xfff) & 0xfffff000;
sys_brk((elf_brk + 0xfff) & 0xfffff000);
padzero(elf_bss);
int i,j, k;
len = 0;
- file = current->filp[fd];
+ file = current->files->fd[fd];
inode = file->f_inode;
elf_bss = 0;
struct file * file;
struct inode * inode;
- if (fd>=NR_OPEN || !(file=current->filp[fd]) || !(inode=file->f_inode))
+ if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode))
return -EBADF;
if (!file->f_op || !file->f_op->fsync)
return -EINVAL;
while (nrbuf-- > 0)
brelse(bh[nrbuf]);
free_page(address);
- ++current->min_flt;
+ ++current->mm->min_flt;
return page;
no_go:
while (nrbuf-- > 0)
read_buffers(arr,block);
while (block-- > 0)
brelse(arr[block]);
- ++current->maj_flt;
+ ++current->mm->maj_flt;
return address;
not_aligned:
while ((tmp = bh) != NULL) {
if (where)
return where;
}
- ++current->maj_flt;
+ ++current->mm->maj_flt;
for (i=0, j=0; j<PAGE_SIZE ; i++, j+= size) {
bh[i] = NULL;
if (b[i])
if (!f)
return -EMFILE;
fd = 0;
- fpp = current->filp;
+ fpp = current->files->fd;
for (;;) {
if (!*fpp)
break;
dump.magic = CMAGIC;
dump.start_code = 0;
dump.start_stack = regs->esp & ~(PAGE_SIZE - 1);
- dump.u_tsize = ((unsigned long) current->end_code) >> 12;
- dump.u_dsize = ((unsigned long) (current->brk + (PAGE_SIZE-1))) >> 12;
+ dump.u_tsize = ((unsigned long) current->mm->end_code) >> 12;
+ dump.u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> 12;
dump.u_dsize -= dump.u_tsize;
dump.u_ssize = 0;
for(i=0; i<8; i++) dump.u_debugreg[i] = current->debugreg[i];
fd = sys_open(library, 0, 0);
if (fd < 0)
return fd;
- file = current->filp[fd];
+ file = current->files->fd[fd];
retval = -ENOEXEC;
if (file && file->f_inode && file->f_op && file->f_op->read) {
fmt = formats;
mpnt->vm_offset = 0;
mpnt->vm_ops = NULL;
insert_vm_struct(current, mpnt);
- current->stk_vma = mpnt;
+ current->mm->stk_vma = mpnt;
}
sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
sp -= envc+1;
put_fs_long((unsigned long)argv,--sp);
}
put_fs_long((unsigned long)argc,--sp);
- current->arg_start = (unsigned long) p;
+ current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
put_fs_long((unsigned long) p,argv++);
while (get_fs_byte(p++)) /* nothing */ ;
}
put_fs_long(0,argv);
- current->arg_end = current->env_start = (unsigned long) p;
+ current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) {
put_fs_long((unsigned long) p,envp++);
while (get_fs_byte(p++)) /* nothing */ ;
}
put_fs_long(0,envp);
- current->env_end = (unsigned long) p;
+ current->mm->env_end = (unsigned long) p;
return sp;
}
code_limit = TASK_SIZE;
data_limit = TASK_SIZE;
code_base = data_base = 0;
- current->start_code = code_base;
+ current->mm->start_code = code_base;
data_base += data_limit;
for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) {
data_base -= PAGE_SIZE;
if (page[i]) {
- current->rss++;
+ current->mm->rss++;
put_dirty_page(current,page[i],data_base);
}
}
}
/* Release all of the old mmap stuff. */
- mpnt = current->mmap;
- current->mmap = NULL;
- current->stk_vma = NULL;
+ mpnt = current->mm->mmap;
+ current->mm->mmap = NULL;
+ current->mm->stk_vma = NULL;
while (mpnt) {
mpnt1 = mpnt->vm_next;
if (mpnt->vm_ops && mpnt->vm_ops->close)
current->sigaction[i].sa_handler = NULL;
}
for (i=0 ; i<NR_OPEN ; i++)
- if (FD_ISSET(i,¤t->close_on_exec))
+ if (FD_ISSET(i,¤t->files->close_on_exec))
sys_close(i);
- FD_ZERO(¤t->close_on_exec);
+ FD_ZERO(¤t->files->close_on_exec);
clear_page_tables(current);
if (last_task_used_math == current)
last_task_used_math = NULL;
/* OK, This is the point of no return */
flush_old_exec(bprm);
- current->end_code = N_TXTADDR(ex) + ex.a_text;
- current->end_data = ex.a_data + current->end_code;
- current->start_brk = current->end_data;
- current->brk = current->start_brk + ex.a_bss;
- current->start_code += N_TXTADDR(ex);
- current->rss = 0;
- current->suid = current->euid = bprm->e_uid;
- current->mmap = NULL;
+ current->mm->brk = ex.a_bss +
+ (current->mm->start_brk =
+ (current->mm->end_data = ex.a_data +
+ (current->mm->end_code = ex.a_text +
+ (current->mm->start_code = N_TXTADDR(ex)))));
+ current->mm->rss = 0;
+ current->mm->mmap = NULL;
current->executable = NULL; /* for OMAGIC files */
+ current->suid = current->euid = bprm->e_uid;
current->sgid = current->egid = bprm->e_gid;
if (N_MAGIC(ex) == OMAGIC) {
do_mmap(NULL, 0, ex.a_text+ex.a_data,
if (fd < 0)
return fd;
- file = current->filp[fd];
+ file = current->files->fd[fd];
if (!file->f_op || !file->f_op->mmap) {
sys_close(fd);
do_mmap(NULL, 0, ex.a_text+ex.a_data,
bprm->inode->i_count++;
}
beyond_if:
- set_brk(current->start_brk, current->brk);
+ set_brk(current->mm->start_brk, current->mm->brk);
p += change_ldt(ex.a_text,bprm->page);
p -= MAX_ARG_PAGES*PAGE_SIZE;
p = (unsigned long) create_tables((char *)p,bprm->argc,bprm->envc,0);
- current->start_stack = p;
+ current->mm->start_stack = p;
regs->eip = ex.a_entry; /* eip, magic happens :-) */
regs->esp = p; /* stack pointer */
if (current->flags & PF_PTRACED)
unsigned int start_addr;
int error;
- file = current->filp[fd];
+ file = current->files->fd[fd];
inode = file->f_inode;
set_fs(KERNEL_DS);
inode->i_nlink = 2;
mark_buffer_dirty(dir_block, 1);
brelse(dir_block);
- inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
+ inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
if (dir->i_mode & S_ISGID)
inode->i_mode |= S_ISGID;
inode->i_dirt = 1;
*res_inode = NULL;
if (!dir) {
- dir = current->root;
+ dir = current->fs->root;
dir->i_count++;
}
if (!inode) {
inode->i_nlink = 2;
mark_buffer_dirty(dir_block, 1);
brelse (dir_block);
- inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->umask);
+ inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->fs->umask);
if (dir->i_mode & S_ISGID)
inode->i_mode |= S_ISGID;
inode->i_dirt = 1;
*res_inode = NULL;
if (!dir) {
- dir = current->root;
+ dir = current->fs->root;
dir->i_count++;
}
if (!inode) {
static int dupfd(unsigned int fd, unsigned int arg)
{
- if (fd >= NR_OPEN || !current->filp[fd])
+ if (fd >= NR_OPEN || !current->files->fd[fd])
return -EBADF;
if (arg >= NR_OPEN)
return -EINVAL;
while (arg < NR_OPEN)
- if (current->filp[arg])
+ if (current->files->fd[arg])
arg++;
else
break;
if (arg >= NR_OPEN)
return -EMFILE;
- FD_CLR(arg, ¤t->close_on_exec);
- (current->filp[arg] = current->filp[fd])->f_count++;
+ FD_CLR(arg, ¤t->files->close_on_exec);
+ (current->files->fd[arg] = current->files->fd[fd])->f_count++;
return arg;
}
asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
{
- if (oldfd >= NR_OPEN || !current->filp[oldfd])
+ if (oldfd >= NR_OPEN || !current->files->fd[oldfd])
return -EBADF;
if (newfd == oldfd)
return newfd;
{
struct file * filp;
- if (fd >= NR_OPEN || !(filp = current->filp[fd]))
+ if (fd >= NR_OPEN || !(filp = current->files->fd[fd]))
return -EBADF;
switch (cmd) {
case F_DUPFD:
return dupfd(fd,arg);
case F_GETFD:
- return FD_ISSET(fd, ¤t->close_on_exec);
+ return FD_ISSET(fd, ¤t->files->close_on_exec);
case F_SETFD:
if (arg&1)
- FD_SET(fd, ¤t->close_on_exec);
+ FD_SET(fd, ¤t->files->close_on_exec);
else
- FD_CLR(fd, ¤t->close_on_exec);
+ FD_CLR(fd, ¤t->files->close_on_exec);
return 0;
case F_GETFL:
return filp->f_flags;
*uid = current->uid;
*gid = current->gid;
- *umask = current->umask;
+ *umask = current->fs->umask;
*lowercase = 1;
*conv = CONV_BINARY;
struct file * filp;
int on;
- if (fd >= NR_OPEN || !(filp = current->filp[fd]))
+ if (fd >= NR_OPEN || !(filp = current->files->fd[fd]))
return -EBADF;
switch (cmd) {
case FIOCLEX:
- FD_SET(fd, ¤t->close_on_exec);
+ FD_SET(fd, ¤t->files->close_on_exec);
return 0;
case FIONCLEX:
- FD_CLR(fd, ¤t->close_on_exec);
+ FD_CLR(fd, ¤t->files->close_on_exec);
return 0;
case FIONBIO:
char * pnt;
if (!dir) {
- dir = current->root;
+ dir = current->fs->root;
dir->i_count++;
}
if (!inode) {
struct file *filp;
struct file_lock *fl,file_lock;
- if (fd >= NR_OPEN || !(filp = current->filp[fd]))
+ if (fd >= NR_OPEN || !(filp = current->files->fd[fd]))
return -EBADF;
error = verify_area(VERIFY_WRITE,l, sizeof(*l));
if (error)
* Get arguments and validate them ...
*/
- if (fd >= NR_OPEN || !(filp = current->filp[fd]))
+ if (fd >= NR_OPEN || !(filp = current->files->fd[fd]))
return -EBADF;
error = verify_area(VERIFY_WRITE, l, sizeof(*l));
if (error)
inode->i_nlink = 2;
mark_buffer_dirty(dir_block, 1);
brelse(dir_block);
- inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
+ inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
if (dir->i_mode & S_ISGID)
inode->i_mode |= S_ISGID;
inode->i_dirt = 1;
*res_inode = NULL;
if (!dir) {
- dir = current->root;
+ dir = current->fs->root;
dir->i_count++;
}
if (!inode) {
#include <linux/msdos_fs.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/string.h>
#include <linux/stat.h>
*conversion = 'b';
*uid = current->uid;
*gid = current->gid;
- *umask = current->umask;
+ *umask = current->fs->umask;
*debug = *fat = *quiet = 0;
if (!options) return 1;
for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
/* check permissions before traversing mount-points */
perm = permission(dir,MAY_EXEC);
if (len==2 && name[0] == '.' && name[1] == '.') {
- if (dir == current->root) {
+ if (dir == current->fs->root) {
*result = dir;
return 0;
} else if ((sb = dir->i_sb) && (dir == sb->s_mounted)) {
*res_inode = NULL;
if (!base) {
- base = current->pwd;
+ base = current->fs->pwd;
base->i_count++;
}
if ((c = *pathname) == '/') {
iput(base);
- base = current->root;
+ base = current->fs->root;
pathname++;
base->i_count++;
}
struct inode * dir, *inode;
struct task_struct ** p;
- mode &= S_IALLUGO & ~current->umask;
+ mode &= S_IALLUGO & ~current->fs->umask;
mode |= S_IFREG;
error = dir_namei(pathname,&namelen,&basename,base,&dir);
if (error)
iput(inode);
return -ETXTBSY;
}
- for(mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next) {
+ for(mpnt = (*p)->mm->mmap; mpnt; mpnt = mpnt->vm_next) {
if (mpnt->vm_page_prot & PAGE_RW)
continue;
if (inode == mpnt->vm_inode) {
int namelen, error;
struct inode * dir;
- mode &= ~current->umask;
+ mode &= ~current->fs->umask;
error = dir_namei(filename,&namelen,&basename, NULL, &dir);
if (error)
return error;
printk("nfs warning: mount version %s than kernel\n",
data->version < NFS_MOUNT_VERSION ? "older" : "newer");
}
- if (fd >= NR_OPEN || !(filp = current->filp[fd])) {
+ if (fd >= NR_OPEN || !(filp = current->files->fd[fd])) {
printk("nfs_read_super: invalid file descriptor\n");
sb->s_dev = 0;
return NULL;
mpnt->vm_offset = off;
mpnt->vm_ops = &nfs_file_mmap;
insert_vm_struct(current, mpnt);
- merge_segments(current->mmap, NULL, NULL);
+ merge_segments(current->mm->mmap, NULL, NULL);
return 0;
}
page = get_free_page(GFP_KERNEL);
if (share_page(area, area->vm_task, inode, address, error_code, page)) {
- ++area->vm_task->min_flt;
+ ++area->vm_task->mm->min_flt;
return;
}
- ++area->vm_task->maj_flt;
+ ++area->vm_task->mm->maj_flt;
if (!page) {
oom(current);
put_page(area->vm_task, BAD_PAGE, address, PAGE_PRIVATE);
*res_inode = NULL;
if (!dir) {
- dir = current->root;
+ dir = current->fs->root;
dir->i_count++;
}
if (!inode) {
error = verify_area(VERIFY_WRITE, buf, sizeof(struct statfs));
if (error)
return error;
- if (fd >= NR_OPEN || !(file = current->filp[fd]))
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
return -EBADF;
if (!(inode = file->f_inode))
return -ENOENT;
struct inode * inode;
struct file * file;
- if (fd >= NR_OPEN || !(file = current->filp[fd]))
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
return -EBADF;
if (!(inode = file->f_inode))
return -ENOENT;
iput(inode);
return -EACCES;
}
- iput(current->pwd);
- current->pwd = inode;
+ iput(current->fs->pwd);
+ current->fs->pwd = inode;
return (0);
}
struct inode * inode;
struct file * file;
- if (fd >= NR_OPEN || !(file = current->filp[fd]))
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
return -EBADF;
if (!(inode = file->f_inode))
return -ENOENT;
return -ENOTDIR;
if (!permission(inode,MAY_EXEC))
return -EACCES;
- iput(current->pwd);
- current->pwd = inode;
+ iput(current->fs->pwd);
+ current->fs->pwd = inode;
inode->i_count++;
return (0);
}
iput(inode);
return -EPERM;
}
- iput(current->root);
- current->root = inode;
+ iput(current->fs->root);
+ current->fs->root = inode;
return (0);
}
struct inode * inode;
struct file * file;
- if (fd >= NR_OPEN || !(file = current->filp[fd]))
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
return -EBADF;
if (!(inode = file->f_inode))
return -ENOENT;
struct inode * inode;
struct file * file;
- if (fd >= NR_OPEN || !(file = current->filp[fd]))
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
return -EBADF;
if (!(inode = file->f_inode))
return -ENOENT;
int flag,error,fd;
for(fd=0 ; fd<NR_OPEN ; fd++)
- if (!current->filp[fd])
+ if (!current->files->fd[fd])
break;
if (fd>=NR_OPEN)
return -EMFILE;
- FD_CLR(fd,¤t->close_on_exec);
+ FD_CLR(fd,¤t->files->close_on_exec);
f = get_empty_filp();
if (!f)
return -ENFILE;
- current->filp[fd] = f;
+ current->files->fd[fd] = f;
f->f_flags = flag = flags;
f->f_mode = (flag+1) & O_ACCMODE;
if (f->f_mode)
flag |= 2;
error = open_namei(filename,flag,mode,&inode,NULL);
if (error) {
- current->filp[fd]=NULL;
+ current->files->fd[fd]=NULL;
f->f_count--;
return error;
}
if (error) {
iput(inode);
f->f_count--;
- current->filp[fd]=NULL;
+ current->files->fd[fd]=NULL;
return error;
}
}
if (fd >= NR_OPEN)
return -EBADF;
- FD_CLR(fd, ¤t->close_on_exec);
- if (!(filp = current->filp[fd]))
+ FD_CLR(fd, ¤t->files->close_on_exec);
+ if (!(filp = current->files->fd[fd]))
return -EBADF;
- current->filp[fd] = NULL;
+ current->files->fd[fd] = NULL;
return (close_fp (filp, fd));
}
return -ENFILE;
j=0;
for(i=0;j<2 && i<NR_OPEN;i++)
- if (!current->filp[i]) {
- current->filp[ fd[j]=i ] = f[j];
+ if (!current->files->fd[i]) {
+ current->files->fd[ fd[j]=i ] = f[j];
j++;
}
if (j==1)
- current->filp[fd[0]]=NULL;
+ current->files->fd[fd[0]]=NULL;
if (j<2) {
f[0]->f_count--;
f[1]->f_count--;
return -EMFILE;
}
if (!(inode=get_pipe_inode())) {
- current->filp[fd[0]] = NULL;
- current->filp[fd[1]] = NULL;
+ current->files->fd[fd[0]] = NULL;
+ current->files->fd[fd[1]] = NULL;
f[0]->f_count--;
f[1]->f_count--;
return -ENFILE;
if (!p || !*p)
return 0;
- return get_array(p, (*p)->env_start, (*p)->env_end, buffer);
+ return get_array(p, (*p)->mm->env_start, (*p)->mm->env_end, buffer);
}
static int get_arg(int pid, char * buffer)
if (!p || !*p)
return 0;
- return get_array(p, (*p)->arg_start, (*p)->arg_end, buffer);
+ return get_array(p, (*p)->mm->arg_start, (*p)->mm->arg_end, buffer);
}
static unsigned long get_wchan(struct task_struct *p)
if (vsize) {
eip = KSTK_EIP(vsize);
esp = KSTK_ESP(vsize);
- vsize = (*p)->brk - (*p)->start_code + PAGE_SIZE-1;
+ vsize = (*p)->mm->brk - (*p)->mm->start_code + PAGE_SIZE-1;
if (esp)
vsize += TASK_SIZE - esp;
}
else
tty_pgrp = -1;
return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
-%lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %u %u %lu %lu %lu %lu %lu %lu \
+%lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %u %lu %lu %lu %lu %lu %lu \
%lu %lu %lu %lu\n",
pid,
(*p)->comm,
(*p)->tty,
tty_pgrp,
(*p)->flags,
- (*p)->min_flt,
- (*p)->cmin_flt,
- (*p)->maj_flt,
- (*p)->cmaj_flt,
+ (*p)->mm->min_flt,
+ (*p)->mm->cmin_flt,
+ (*p)->mm->maj_flt,
+ (*p)->mm->cmaj_flt,
(*p)->utime,
(*p)->stime,
(*p)->cutime,
(*p)->it_real_value,
(*p)->start_time,
vsize,
- (*p)->rss, /* you might want to shift this left 3 */
+ (*p)->mm->rss, /* you might want to shift this left 3 */
(*p)->rlim[RLIMIT_RSS].rlim_cur,
- (*p)->start_code,
- (*p)->end_code,
- (*p)->start_stack,
+ (*p)->mm->start_code,
+ (*p)->mm->end_code,
+ (*p)->mm->start_stack,
esp,
eip,
(*p)->signal,
if (!p || !*p)
return 0;
- tpag = (*p)->end_code / PAGE_SIZE;
+ tpag = (*p)->mm->end_code / PAGE_SIZE;
if ((*p)->state != TASK_ZOMBIE) {
pagedir = (unsigned long *) (*p)->tss.cr3;
for (i = 0; i < 0x300; ++i) {
if (!p || !*p)
return 0;
- for(map = (*p)->mmap; map != NULL; map = map->vm_next) {
+ for(map = (*p)->mm->mmap; map != NULL; map = map->vm_next) {
char str[7], *cp = str;
int prot = map->vm_page_prot;
int perms, flags;
extern int get_module_list(char *);
extern int get_device_list(char *);
+extern int get_filesystem_list(char *);
static int array_read(struct inode * inode, struct file * file,char * buf, int count)
{
case 18:
length = get_device_list(page);
break;
+ case 19:
+ length = get_filesystem_list(page);
+ break;
default:
free_page((unsigned long) page);
return -EBADF;
if (!pid || i >= NR_TASKS)
return -ENOENT;
if (!ino) {
- if (fd >= NR_OPEN || !p->filp[fd] || !p->filp[fd]->f_inode)
+ if (fd >= NR_OPEN || !p->files->fd[fd] || !p->files->fd[fd]->f_inode)
return -ENOENT;
ino = (pid << 16) + 0x100 + fd;
} else {
int j = 0;
struct vm_area_struct * mpnt;
- for (mpnt = p->mmap; mpnt; mpnt = mpnt->vm_next)
+ for (mpnt = p->mm->mmap; mpnt; mpnt = mpnt->vm_next)
if (mpnt->vm_inode)
j++;
if (fd >= j)
if (!ino) {
if (fd >= NR_OPEN)
break;
- if (!p->filp[fd] || !p->filp[fd]->f_inode)
+ if (!p->files->fd[fd] || !p->files->fd[fd]->f_inode)
continue;
} else {
int j = 0;
struct vm_area_struct * mpnt;
- for (mpnt = p->mmap ; mpnt ; mpnt = mpnt->vm_next)
+ for (mpnt = p->mm->mmap ; mpnt ; mpnt = mpnt->vm_next)
if (mpnt->vm_inode)
j++;
if (fd >= j)
switch (ino >> 8) {
case 1:
ino &= 0xff;
- if (ino >= NR_OPEN || !p->filp[ino])
+ if (ino >= NR_OPEN || !p->files->fd[ino])
return;
inode->i_op = &proc_link_inode_operations;
inode->i_size = 64;
{
int j = 0;
struct vm_area_struct * mpnt;
- for (mpnt = p->mmap ; mpnt ; mpnt = mpnt->vm_next)
+ for (mpnt = p->mm->mmap ; mpnt ; mpnt = mpnt->vm_next)
if(mpnt->vm_inode)
j++;
if (ino >= j)
inode = NULL;
switch (ino) {
case 4:
- inode = p->pwd;
+ inode = p->fs->pwd;
break;
case 5:
- inode = p->root;
+ inode = p->fs->root;
break;
case 6:
inode = p->executable;
switch (ino >> 8) {
case 1:
ino &= 0xff;
- if (ino < NR_OPEN && p->filp[ino])
- inode = p->filp[ino]->f_inode;
+ if (ino < NR_OPEN && p->files->fd[ino])
+ inode = p->files->fd[ino]->f_inode;
break;
case 2:
ino &= 0xff;
{ int j = ino;
struct vm_area_struct * mpnt;
- for(mpnt = p->mmap; mpnt && j >= 0;
+ for(mpnt = p->mm->mmap; mpnt && j >= 0;
mpnt = mpnt->vm_next){
if(mpnt->vm_inode) {
if(j == 0) {
{16,7,"modules" },
{17,4,"stat" },
{18,7,"devices" },
+ {19,11,"filesystems" },
};
#define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0])))
struct file * file;
struct inode * inode;
- if (fd >= NR_OPEN || !(file = current->filp[fd]) ||
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]) ||
!(inode = file->f_inode))
return -EBADF;
error = -ENOTDIR;
struct file * file;
int tmp = -1;
- if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode))
+ if (fd >= NR_OPEN || !(file=current->files->fd[fd]) || !(file->f_inode))
return -EBADF;
if (origin > 2)
return -EINVAL;
struct file * file;
struct inode * inode;
- if (fd>=NR_OPEN || !(file=current->filp[fd]) || !(inode=file->f_inode))
+ if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode))
return -EBADF;
if (!(file->f_mode & 1))
return -EBADF;
struct file * file;
struct inode * inode;
- if (fd>=NR_OPEN || !(file=current->filp[fd]) || !(inode=file->f_inode))
+ if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode))
return -EBADF;
if (!(file->f_mode & 2))
return -EBADF;
goto end_check;
if (!(set & 1))
continue;
- if (!current->filp[i])
+ if (!current->files->fd[i])
return -EBADF;
- if (!current->filp[i]->f_inode)
+ if (!current->files->fd[i]->f_inode)
return -EBADF;
max = i;
}
repeat:
current->state = TASK_INTERRUPTIBLE;
for (i = 0 ; i < n ; i++) {
- if (FD_ISSET(i,in) && check(SEL_IN,wait,current->filp[i])) {
+ if (FD_ISSET(i,in) && check(SEL_IN,wait,current->files->fd[i])) {
FD_SET(i, res_in);
count++;
wait = NULL;
}
- if (FD_ISSET(i,out) && check(SEL_OUT,wait,current->filp[i])) {
+ if (FD_ISSET(i,out) && check(SEL_OUT,wait,current->files->fd[i])) {
FD_SET(i, res_out);
count++;
wait = NULL;
}
- if (FD_ISSET(i,ex) && check(SEL_EX,wait,current->filp[i])) {
+ if (FD_ISSET(i,ex) && check(SEL_EX,wait,current->files->fd[i])) {
FD_SET(i, res_ex);
count++;
wait = NULL;
*/
#include <linux/errno.h>
+#include <linux/string.h>
#include <linux/stat.h>
#include <linux/fs.h>
#include <linux/sched.h>
static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
{
- struct new_stat tmp = {0, };
+ struct new_stat tmp;
unsigned int blocks, indirect;
+ memset(&tmp, 0, sizeof(tmp));
tmp.st_dev = inode->i_dev;
tmp.st_ino = inode->i_ino;
tmp.st_mode = inode->i_mode;
error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
if (error)
return error;
- if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode))
+ if (fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))
return -EBADF;
cp_old_stat(inode,statbuf);
return 0;
error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
if (error)
return error;
- if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode))
+ if (fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))
return -EBADF;
cp_new_stat(inode,statbuf);
return 0;
/*
* super.c contains code to handle the super-block tables.
*/
+#include <stdarg.h>
+
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
return -EINVAL;
}
+static int fs_index(const char * __name)
+{
+ struct file_system_type * tmp;
+ char * name;
+ int err, index;
+
+ err = getname(__name, &name);
+ if (err)
+ return err;
+ index = 0;
+ for (tmp = file_systems ; tmp ; tmp = tmp->next) {
+ if (strcmp(tmp->name, name) == 0) {
+ putname(name);
+ return index;
+ }
+ index++;
+ }
+ putname(name);
+ return -EINVAL;
+}
+
+static int fs_name(unsigned int index, char * buf)
+{
+ struct file_system_type * tmp;
+ int err, len;
+
+ tmp = file_systems;
+ while (tmp && index > 0) {
+ tmp = tmp->next;
+ index--;
+ }
+ if (!tmp)
+ return -EINVAL;
+ len = strlen(tmp->name) + 1;
+ err = verify_area(VERIFY_WRITE, buf, len);
+ if (err)
+ return err;
+ memcpy_tofs(buf, tmp->name, len);
+ return 0;
+}
+
+static int fs_maxindex(void)
+{
+ struct file_system_type * tmp;
+ int index;
+
+ index = 0;
+ for (tmp = file_systems ; tmp ; tmp = tmp->next)
+ index++;
+ return index;
+}
+
+/*
+ * Whee.. Weird sysv syscall.
+ */
+asmlinkage int sys_sysfs(int option, ...)
+{
+ va_list args;
+ int retval = -EINVAL;
+ unsigned int index;
+
+ va_start(args, option);
+ switch (option) {
+ case 1:
+ retval = fs_index(va_arg(args, const char *));
+ break;
+
+ case 2:
+ index = va_arg(args, unsigned int);
+ retval = fs_name(index, va_arg(args, char *));
+ break;
+
+ case 3:
+ retval = fs_maxindex();
+ break;
+ }
+ va_end(args);
+ return retval;
+}
+
+int get_filesystem_list(char * buf)
+{
+ int len = 0;
+ struct file_system_type * tmp;
+
+ tmp = file_systems;
+ while (tmp && len < PAGE_SIZE - 80) {
+ len += sprintf(buf+len, "%s\t%s\n",
+ tmp->requires_dev ? "" : "nodev",
+ tmp->name);
+ tmp = tmp->next;
+ }
+ return len;
+}
+
struct file_system_type *get_fs_type(char *name)
{
struct file_system_type * fs = file_systems;
if (!data)
return 0;
- for (vma = current->mmap ; ; ) {
+ for (vma = current->mm->mmap ; ; ) {
if (!vma ||
(unsigned long) data < vma->vm_start) {
return -EFAULT;
inode->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */
sb->s_covered = inode;
sb->s_flags = root_mountflags;
- current->pwd = inode;
- current->root = inode;
+ current->fs->pwd = inode;
+ current->fs->root = inode;
printk ("VFS: Mounted root (%s filesystem)%s.\n",
fs_type->name,
(sb->s_flags & MS_RDONLY) ? " readonly" : "");
inode->i_nlink = 2;
mark_buffer_dirty(dir_block, 1);
brelse(dir_block);
- inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
+ inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
if (dir->i_mode & S_ISGID)
inode->i_mode |= S_ISGID;
inode->i_dirt = 1;
*res_inode = NULL;
if (!dir) {
- dir = current->root;
+ dir = current->fs->root;
dir->i_count++;
}
if (!inode) {
inode->i_nlink = 2;
mark_buffer_dirty(dir_block, 1);
brelse(dir_block);
- inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->umask);
+ inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->fs->umask);
if (dir->i_mode & S_ISGID)
inode->i_mode |= S_ISGID;
inode->i_dirt = 1;
*res_inode = NULL;
if (!dir) {
- dir = current->root;
+ dir = current->fs->root;
dir->i_count++;
}
if (!inode) {
union i387_union i387;
};
+#define INIT_TSS { \
+ 0,0, \
+ sizeof(init_kernel_stack) + (long) &init_kernel_stack, \
+ KERNEL_DS, 0, \
+ 0,0,0,0,0,0, \
+ (long) &swapper_pg_dir, \
+ 0,0,0,0,0,0,0,0,0,0, \
+ USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0, \
+ _LDT(0),0, \
+ 0, 0x8000, \
+ {~0, }, /* ioperm */ \
+ _TSS(0), 0, 0,0, \
+ { { 0, }, } /* 387 state */ \
+}
+
+struct files_struct {
+ int count;
+ fd_set close_on_exec;
+ struct file * fd[NR_OPEN];
+};
+
+#define INIT_FILES { \
+ 0, \
+ { { 0, } }, \
+ { NULL, } \
+}
+
+struct fs_struct {
+ int count;
+ unsigned short umask;
+ struct inode * root, * pwd;
+};
+
+#define INIT_FS { \
+ 0, \
+ 0022, \
+ NULL, NULL \
+}
+
+struct mm_struct {
+ int count;
+ unsigned long start_code, end_code, end_data;
+ unsigned long start_brk, brk, start_stack, start_mmap;
+ unsigned long arg_start, arg_end, env_start, env_end;
+ unsigned long rss;
+ unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
+ int swappable:1;
+#ifdef NEW_SWAP
+ unsigned long old_maj_flt; /* old value of maj_flt */
+ unsigned long dec_flt; /* page fault count of the last time */
+ unsigned long swap_cnt; /* number of pages to swap on next pass */
+ short swap_table; /* current page table */
+ short swap_page; /* current page */
+#endif NEW_SWAP
+ struct vm_area_struct * mmap;
+ struct vm_area_struct * stk_vma;
+};
+
+#define INIT_MM { \
+ 0, \
+ 0, 0, 0, \
+ 0, 0, 0, 0, \
+ 0, 0, 0, 0, \
+ 0, \
+/* ?_flt */ 0, 0, 0, 0, \
+ 0, \
+/* swap */ 0, 0, 0, 0, 0, \
+ NULL, NULL }
+
struct task_struct {
/* these are hardcoded - don't touch */
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
int exit_code, exit_signal;
int elf_executable:1;
int dumpable:1;
- int swappable:1;
int did_exec:1;
- unsigned long start_code,end_code,end_data,start_brk,brk,start_stack,start_mmap;
- unsigned long arg_start, arg_end, env_start, env_end;
int pid,pgrp,session,leader;
int groups[NGROUPS];
/*
* older sibling, respectively. (p->father can be replaced with
* p->p_pptr->pid)
*/
- struct task_struct *p_opptr,*p_pptr, *p_cptr, *p_ysptr, *p_osptr;
+ struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
struct wait_queue *wait_chldexit; /* for wait4() */
- /*
- * For ease of programming... Normal sleeps don't need to
- * keep track of a wait-queue: every task has an entry of its own
- */
unsigned short uid,euid,suid;
unsigned short gid,egid,sgid;
unsigned long timeout;
unsigned long it_real_value, it_prof_value, it_virt_value;
unsigned long it_real_incr, it_prof_incr, it_virt_incr;
- long utime,stime,cutime,cstime,start_time;
- unsigned long min_flt, maj_flt;
- unsigned long cmin_flt, cmaj_flt;
+ long utime, stime, cutime, cstime, start_time;
struct rlimit rlim[RLIM_NLIMITS];
unsigned short used_math;
- unsigned short rss; /* number of resident pages */
char comm[16];
/* virtual 86 mode stuff */
struct vm86_struct * vm86_info;
/* file system info */
int link_count;
int tty; /* -1 if no tty, so it must be signed */
- unsigned short umask;
- struct inode * pwd;
- struct inode * root;
struct inode * executable;
- struct vm_area_struct * mmap;
struct shm_desc *shm;
struct sem_undo *semun;
- struct file * filp[NR_OPEN];
- fd_set close_on_exec;
/* ldt for this task - used by Wine. If NULL, default_ldt is used */
struct desc_struct *ldt;
/* tss for this task */
struct tss_struct tss;
-#ifdef NEW_SWAP
- unsigned long old_maj_flt; /* old value of maj_flt */
- unsigned long dec_flt; /* page fault count of the last time */
- unsigned long swap_cnt; /* number of pages to swap on next pass */
- short swap_table; /* current page table */
- short swap_page; /* current page */
-#endif NEW_SWAP
- struct vm_area_struct *stk_vma;
+/* filesystem information */
+ struct fs_struct fs[1];
+/* open file information */
+ struct files_struct files[1];
+/* memory management info */
+ struct mm_struct mm[1];
};
/*
/* schedlink */ &init_task,&init_task, \
/* signals */ {{ 0, },}, \
/* stack */ 0,(unsigned long) &init_kernel_stack, \
-/* ec,brk... */ 0,0,0,0,0,0,0,0,0,0,0,0,0, \
-/* argv.. */ 0,0,0,0, \
+/* ec,brk... */ 0,0,0,0,0, \
/* pid etc.. */ 0,0,0,0, \
/* suppl grps*/ {NOGROUP,}, \
/* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \
/* uid etc */ 0,0,0,0,0,0, \
/* timeout */ 0,0,0,0,0,0,0,0,0,0,0,0, \
-/* min_flt */ 0,0,0,0, \
/* rlimits */ { {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \
{LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \
{ 0, LONG_MAX}, {LONG_MAX, LONG_MAX}}, \
/* math */ 0, \
-/* rss */ 2, \
/* comm */ "swapper", \
/* vm86_info */ NULL, 0, 0, 0, 0, \
-/* fs info */ 0,-1,0022,NULL,NULL,NULL,NULL, \
+/* fs info */ 0,-1,NULL, \
/* ipc */ NULL, NULL, \
-/* filp */ {NULL,}, \
-/* cloe */ {{ 0, }}, \
/* ldt */ NULL, \
-/*tss*/ {0,0, \
- sizeof(init_kernel_stack) + (long) &init_kernel_stack, KERNEL_DS, 0, \
- 0,0,0,0,0,0, \
- (long) &swapper_pg_dir, \
- 0,0,0,0,0,0,0,0,0,0, \
- USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0, \
- _LDT(0),0, \
- 0, 0x8000, \
-/* ioperm */ {~0, }, \
- _TSS(0), 0, 0,0, \
-/* 387 state */ { { 0, }, } \
- } \
+/* tss */ INIT_TSS, \
+/* fs */ { INIT_FS }, \
+/* files */ { INIT_FILES }, \
+/* mm */ { INIT_MM } \
}
extern struct task_struct init_task;
#define __NR_getpgid 132
#define __NR_fchdir 133
#define __NR_bdflush 134
+#define __NR_sysfs 135
extern int errno;
#ifdef __KERNEL__
void handle_vm86_fault(struct vm86_regs *, long);
+void handle_vm86_debug(struct vm86_regs *, long);
#endif
if (!remap)
return -EINVAL;
if (*page_table & PAGE_PRESENT) {
- --current->rss;
+ --current->mm->rss;
free_page (*page_table & PAGE_MASK);
}
else
else
return -EINVAL;
}
- if ((addr > current->start_stack - 16384 - PAGE_SIZE*shp->shm_npages))
+ if ((addr > current->mm->start_stack - 16384 - PAGE_SIZE*shp->shm_npages))
return -EINVAL;
if (shmflg & SHM_REMAP)
for (shmd = current->shm; shmd; shmd = shmd->task_next) {
shmd->task = current;
shp->shm_nattch++; /* prevent destruction */
- if (addr < current->end_data) {
+ if (addr < current->mm->end_data) {
iput (current->executable);
current->executable = NULL;
/* current->end_data = current->end_code = 0; */
shm_rss++;
shp->shm_pages[idx] = page | (PAGE_SHARED | PAGE_DIRTY);
} else
- --current->maj_flt; /* was incremented in do_no_page */
+ --current->mm->maj_flt; /* was incremented in do_no_page */
done:
- current->min_flt++;
+ current->mm->min_flt++;
page = shp->shm_pages[idx];
if (code & SHM_READ_ONLY) /* write-protect */
page &= ~2;
tmp = shmd->shm_sgn | idx << SHM_IDX_SHIFT;
*pte = tmp;
mem_map[MAP_NR(page)]--;
- shmd->task->rss--;
+ shmd->task->mm->rss--;
invalid++;
}
}
}
-NORET_TYPE void do_exit(long code)
+static void exit_mm(void)
{
- struct task_struct *p;
- int i;
-
- if (intr_count) {
- printk("Aiee, killing interrupt handler\n");
- intr_count = 0;
- }
-fake_volatile:
- if (current->semun)
- sem_exit();
- if (current->shm)
- shm_exit();
- /* Release all of the old mmap stuff. */
-
- {
- struct vm_area_struct * mpnt, *mpnt1;
- mpnt = current->mmap;
- current->mmap = NULL;
- while (mpnt) {
- mpnt1 = mpnt->vm_next;
- if (mpnt->vm_ops && mpnt->vm_ops->close)
- mpnt->vm_ops->close(mpnt);
- kfree(mpnt);
- mpnt = mpnt1;
- }
+ struct vm_area_struct * mpnt;
+
+ mpnt = current->mm->mmap;
+ current->mm->mmap = NULL;
+ while (mpnt) {
+ struct vm_area_struct * next = mpnt->vm_next;
+ if (mpnt->vm_ops && mpnt->vm_ops->close)
+ mpnt->vm_ops->close(mpnt);
+ kfree(mpnt);
+ mpnt = next;
}
/* forget local segments */
}
free_page_tables(current);
+}
+
+static void exit_files(void)
+{
+ int i;
+
for (i=0 ; i<NR_OPEN ; i++)
- if (current->filp[i])
+ if (current->files->fd[i])
sys_close(i);
- forget_original_parent(current);
- iput(current->pwd);
- current->pwd = NULL;
- iput(current->root);
- current->root = NULL;
+}
+
+static void exit_fs(void)
+{
+ iput(current->fs->pwd);
+ current->fs->pwd = NULL;
+ iput(current->fs->root);
+ current->fs->root = NULL;
iput(current->executable);
current->executable = NULL;
+}
+
+NORET_TYPE void do_exit(long code)
+{
+ struct task_struct *p;
+
+ if (intr_count) {
+ printk("Aiee, killing interrupt handler\n");
+ intr_count = 0;
+ }
+fake_volatile:
+ if (current->semun)
+ sem_exit();
+ if (current->shm)
+ shm_exit();
+ exit_mm();
+ exit_files();
+ exit_fs();
+ forget_original_parent(current);
/*
* Check to see if any process groups have become orphaned
* as a result of our exiting, and if they have any stopped
last_task_used_math = NULL;
current->state = TASK_ZOMBIE;
current->exit_code = code;
- current->rss = 0;
+ current->mm->rss = 0;
#ifdef DEBUG_PROC_TREE
audit_ptree();
#endif
case TASK_ZOMBIE:
current->cutime += p->utime + p->cutime;
current->cstime += p->stime + p->cstime;
- current->cmin_flt += p->min_flt + p->cmin_flt;
- current->cmaj_flt += p->maj_flt + p->cmaj_flt;
+ current->mm->cmin_flt += p->mm->min_flt + p->mm->cmin_flt;
+ current->mm->cmaj_flt += p->mm->maj_flt + p->mm->cmaj_flt;
if (ru != NULL)
getrusage(p, RUSAGE_BOTH, ru);
flag = p->pid;
return new_file;
}
-int dup_mmap(struct task_struct * tsk)
+static int dup_mmap(struct task_struct * tsk)
{
struct vm_area_struct * mpnt, **p, *tmp;
- tsk->mmap = NULL;
- tsk->stk_vma = NULL;
- p = &tsk->mmap;
- for (mpnt = current->mmap ; mpnt ; mpnt = mpnt->vm_next) {
+ tsk->mm->mmap = NULL;
+ tsk->mm->stk_vma = NULL;
+ p = &tsk->mm->mmap;
+ for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) {
tmp = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
if (!tmp)
return -ENOMEM;
tmp->vm_inode->i_count++;
*p = tmp;
p = &tmp->vm_next;
- if (current->stk_vma == mpnt)
- tsk->stk_vma = tmp;
+ if (current->mm->stk_vma == mpnt)
+ tsk->mm->stk_vma = tmp;
}
return 0;
}
+/*
+ * SHAREFD not yet implemented..
+ */
+static void copy_files(unsigned long clone_flags, struct task_struct * p)
+{
+ int i;
+ struct file * f;
+
+ if (clone_flags & COPYFD) {
+ for (i=0; i<NR_OPEN;i++)
+ if ((f = p->files->fd[i]) != NULL)
+ p->files->fd[i] = copy_fd(f);
+ } else {
+ for (i=0; i<NR_OPEN;i++)
+ if ((f = p->files->fd[i]) != NULL)
+ f->f_count++;
+ }
+}
+
+/*
+ * CLONEVM not yet correctly implemented: needs to clone the mmap
+ * instead of duplicating it..
+ */
+static int copy_mm(unsigned long clone_flags, struct task_struct * p)
+{
+ if (clone_flags & COPYVM) {
+ p->mm->swappable = 1;
+ p->mm->min_flt = p->mm->maj_flt = 0;
+ p->mm->cmin_flt = p->mm->cmaj_flt = 0;
+ if (copy_page_tables(p))
+ return 1;
+ dup_mmap(p);
+ } else {
+ if (clone_page_tables(p))
+ return 1;
+ dup_mmap(p); /* wrong.. */
+ }
+ return 0;
+}
+
+static void copy_fs(unsigned long clone_flags, struct task_struct * p)
+{
+ if (current->fs->pwd)
+ current->fs->pwd->i_count++;
+ if (current->fs->root)
+ current->fs->root->i_count++;
+ if (current->executable)
+ current->executable->i_count++;
+}
+
#define IS_CLONE (regs.orig_eax == __NR_clone)
-#define copy_vm(p) ((clone_flags & COPYVM)?copy_page_tables(p):clone_page_tables(p))
/*
* Ok, this is the main fork-routine. It copies the system process
struct pt_regs * childregs;
struct task_struct *p;
int i,nr;
- struct file *f;
unsigned long clone_flags = COPYVM | SIGCHLD;
if(!(p = (struct task_struct*)__get_free_page(GFP_KERNEL)))
p->state = TASK_UNINTERRUPTIBLE;
p->flags &= ~(PF_PTRACED|PF_TRACESYS);
p->pid = last_pid;
- p->swappable = 1;
p->p_pptr = p->p_opptr = current;
p->p_cptr = NULL;
SET_LINKS(p);
p->leader = 0; /* process leadership doesn't inherit */
p->utime = p->stime = 0;
p->cutime = p->cstime = 0;
- p->min_flt = p->maj_flt = 0;
- p->cmin_flt = p->cmaj_flt = 0;
p->start_time = jiffies;
/*
* set up new TSS and kernel stack
if (last_task_used_math == current)
__asm__("clts ; fnsave %0 ; frstor %0":"=m" (p->tss.i387));
p->semun = NULL; p->shm = NULL;
- if (copy_vm(p) || shm_fork(current, p))
+ if (copy_mm(clone_flags, p) || shm_fork(current, p))
goto bad_fork_cleanup;
- if (clone_flags & COPYFD) {
- for (i=0; i<NR_OPEN;i++)
- if ((f = p->filp[i]) != NULL)
- p->filp[i] = copy_fd(f);
- } else {
- for (i=0; i<NR_OPEN;i++)
- if ((f = p->filp[i]) != NULL)
- f->f_count++;
- }
- if (current->pwd)
- current->pwd->i_count++;
- if (current->root)
- current->root->i_count++;
- if (current->executable)
- current->executable->i_count++;
- dup_mmap(p);
+ copy_files(clone_flags, p);
+ copy_fs(clone_flags, p);
set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss));
if (p->ldt)
set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,p->ldt, 512);
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/malloc.h>
+#include <linux/binfmts.h>
+#include <linux/ptrace.h>
+#include <linux/sys.h>
+#include <linux/utsname.h>
+
+extern void *sys_call_table;
#define X(name) { (void *) &name, "_" #name }
extern void (*do_floppy)(void);
#endif
+#ifdef CONFIG_BINFMT_IBCS
+extern int do_execve(char * filename, char ** argv, char ** envp,
+ struct pt_regs * regs);
+extern void flush_old_exec(struct linux_binprm * bprm);
+extern int open_inode(struct inode * inode, int mode);
+extern int read_exec(struct inode *inode, unsigned long offset,
+ char * addr, unsigned long count);
+
+extern void check_pending(int signum);
+extern int do_signal(unsigned long oldmask, struct pt_regs * regs);
+extern int (*ibcs_invmapsig)(int);
+
+extern void (* iABI_hook)(struct pt_regs * regs);
+#endif
+
struct {
void *addr;
const char *name;
} symbol_table[] = {
- /* process memory management */
+ /* system info variables */
+ X(EISA_bus),
X(wp_works_ok),
+
+ /* process memory management */
X(__verify_write),
X(do_mmap),
X(do_munmap),
X(register_blkdev),
X(unregister_blkdev),
+ /* filesystem registration */
+ X(register_filesystem),
+ X(unregister_filesystem),
+
/* interrupt handling */
X(request_irq),
X(free_irq),
X(printk),
X(sprintf),
X(vsprintf),
+ X(system_utsname),
+ X(sys_call_table),
#ifdef CONFIG_FTAPE
/* The next labels are needed for ftape driver. */
X(ftape_big_buffer),
X(do_floppy),
#endif
+
+#ifdef CONFIG_BINFMT_IBCS
+/*
+ * The following are needed if iBCS support is modular rather than
+ * compiled in.
+ */
+ /* Emulator hooks. */
+ X(iABI_hook),
+ X(ibcs_invmapsig),
+
+ /* Signal interfaces */
+ X(do_signal),
+ X(check_pending),
+ X(send_sig),
+
+ /* Program loader interfaces */
+ X(change_ldt),
+ X(copy_strings),
+ X(create_tables),
+ X(do_execve),
+ X(flush_old_exec),
+ X(formats),
+ X(insert_vm_struct),
+ X(open_inode),
+ X(read_exec),
+ X(zeromap_page_range),
+
+ /* Miscellaneous access points */
+ X(si_meminfo),
+#endif
};
int symbol_table_size = sizeof (symbol_table) / sizeof (symbol_table[0]);
/*
- * This is done BSD-style, with no consideration of the saved gid, except
- * that if you set the effective gid, it sets the saved gid too. This
- * makes it possible for a setgid program to completely drop its privileges,
- * which is often a useful assertion to make when you are doing a security
- * audit over a program.
+ * Unprivileged users may change the real gid to the effective gid
+ * or vice versa. (BSD-style)
+ *
+ * If you set the real gid at all, or set the effective gid to a value not
+ * equal to the real gid, then the saved gid is set to the new effective gid.
+ *
+ * This makes it possible for a setgid program to completely drop its
+ * privileges, which is often a useful assertion to make when you are doing
+ * a security audit over a program.
*
* The general idea is that a program which uses just setregid() will be
* 100% compatible with BSD. A program which uses just setgid() will be
if (egid != (gid_t) -1) {
if ((old_rgid == egid) ||
(current->egid == egid) ||
- suser()) {
+ suser())
current->egid = egid;
- current->sgid = egid;
- } else {
+ else {
current->gid = old_rgid;
return(-EPERM);
}
}
+ if (rgid != (gid_t) -1 ||
+ egid != (gid_t) -1 && egid != old_rgid)
+ current->sgid = current->egid;
return 0;
}
}
/*
- * Unprivileged users may change the real user id to the effective uid
+ * Unprivileged users may change the real uid to the effective uid
* or vice versa. (BSD-style)
*
- * When you set the effective uid, it sets the saved uid too. This
- * makes it possible for a setuid program to completely drop its privileges,
- * which is often a useful assertion to make when you are doing a security
- * audit over a program.
+ * If you set the real uid at all, or set the effective uid to a value not
+ * equal to the real uid, then the saved uid is set to the new effective uid.
+ *
+ * This makes it possible for a setuid program to completely drop its
+ * privileges, which is often a useful assertion to make when you are doing
+ * a security audit over a program.
*
* The general idea is that a program which uses just setreuid() will be
* 100% compatible with BSD. A program which uses just setuid() will be
asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
{
int old_ruid = current->uid;
-
+
if (ruid != (uid_t) -1) {
if ((current->euid==ruid) ||
- (old_ruid == ruid) ||
+ (old_ruid == ruid) ||
suser())
current->uid = ruid;
else
if (euid != (uid_t) -1) {
if ((old_ruid == euid) ||
(current->euid == euid) ||
- suser()) {
+ suser())
current->euid = euid;
- current->suid = euid;
- } else {
+ else {
current->uid = old_ruid;
return(-EPERM);
}
}
+ if (ruid != (uid_t) -1 ||
+ euid != (uid_t) -1 && euid != old_ruid)
+ current->suid = current->euid;
return 0;
}
unsigned long rlim;
unsigned long newbrk, oldbrk;
- if (brk < current->end_code)
- return current->brk;
+ if (brk < current->mm->end_code)
+ return current->mm->brk;
newbrk = PAGE_ALIGN(brk);
- oldbrk = PAGE_ALIGN(current->brk);
+ oldbrk = PAGE_ALIGN(current->mm->brk);
if (oldbrk == newbrk)
- return current->brk = brk;
+ return current->mm->brk = brk;
/*
* Always allow shrinking brk
*/
- if (brk <= current->brk) {
- current->brk = brk;
+ if (brk <= current->mm->brk) {
+ current->mm->brk = brk;
do_munmap(newbrk, oldbrk-newbrk);
return brk;
}
rlim = current->rlim[RLIMIT_DATA].rlim_cur;
if (rlim >= RLIM_INFINITY)
rlim = ~0;
- if (brk - current->end_code > rlim || brk >= current->start_stack - 16384)
- return current->brk;
+ if (brk - current->mm->end_code > rlim ||
+ brk >= current->mm->start_stack - 16384)
+ return current->mm->brk;
/*
* stupid algorithm to decide if we have enough memory: while
* simple, it hopefully works in most obvious cases.. Easy to
freepages -= (high_memory - 0x100000) >> 16;
freepages -= (newbrk-oldbrk) >> 12;
if (freepages < 0)
- return current->brk;
+ return current->mm->brk;
#if 0
- freepages += current->rss;
+ freepages += current->mm->rss;
freepages -= oldbrk >> 12;
if (freepages < 0)
- return current->brk;
+ return current->mm->brk;
#endif
/*
* Ok, we have probably got enough memory - let it rip.
*/
- current->brk = brk;
+ current->mm->brk = brk;
do_mmap(NULL, oldbrk, newbrk-oldbrk,
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0);
r.ru_utime.tv_usec = CT_TO_USECS(p->utime);
r.ru_stime.tv_sec = CT_TO_SECS(p->stime);
r.ru_stime.tv_usec = CT_TO_USECS(p->stime);
- r.ru_minflt = p->min_flt;
- r.ru_majflt = p->maj_flt;
+ r.ru_minflt = p->mm->min_flt;
+ r.ru_majflt = p->mm->maj_flt;
break;
case RUSAGE_CHILDREN:
r.ru_utime.tv_sec = CT_TO_SECS(p->cutime);
r.ru_utime.tv_usec = CT_TO_USECS(p->cutime);
r.ru_stime.tv_sec = CT_TO_SECS(p->cstime);
r.ru_stime.tv_usec = CT_TO_USECS(p->cstime);
- r.ru_minflt = p->cmin_flt;
- r.ru_majflt = p->cmaj_flt;
+ r.ru_minflt = p->mm->cmin_flt;
+ r.ru_majflt = p->mm->cmaj_flt;
break;
default:
r.ru_utime.tv_sec = CT_TO_SECS(p->utime + p->cutime);
r.ru_utime.tv_usec = CT_TO_USECS(p->utime + p->cutime);
r.ru_stime.tv_sec = CT_TO_SECS(p->stime + p->cstime);
r.ru_stime.tv_usec = CT_TO_USECS(p->stime + p->cstime);
- r.ru_minflt = p->min_flt + p->cmin_flt;
- r.ru_majflt = p->maj_flt + p->cmaj_flt;
+ r.ru_minflt = p->mm->min_flt + p->mm->cmin_flt;
+ r.ru_majflt = p->mm->maj_flt + p->mm->cmaj_flt;
break;
}
lp = (unsigned long *) &r;
asmlinkage int sys_umask(int mask)
{
- int old = current->umask;
+ int old = current->fs->umask;
- current->umask = mask & S_IRWXUGO;
+ current->fs->umask = mask & S_IRWXUGO;
return (old);
}
.long _sys_getpgid
.long _sys_fchdir
.long _sys_bdflush
+ .long _sys_sysfs /* 135 */
- .space (NR_syscalls-130)*4
+ .space (NR_syscalls-135)*4
asmlinkage void do_debug(struct pt_regs * regs, long error_code)
{
+ if (regs->eflags & VM_MASK) {
+ handle_vm86_debug((struct vm86_regs *) regs, error_code);
+ return;
+ }
if (current->flags & PF_PTRACED)
current->blocked &= ~(1 << (SIGTRAP-1));
send_sig(SIGTRAP, current, 1);
current->tss.trap_no = 1;
current->tss.error_code = error_code;
- if((regs->cs & 3) == 0) {
- /* If this is a kernel mode trap, then reset db7 and allow us to continue */
- __asm__("movl $0,%%edx\n\t" \
- "movl %%edx,%%db7\n\t" \
- : /* no output */ \
- : /* no input */ :"dx");
-
- return;
- };
+ if ((regs->cs & 3) == 0) {
+ /* If this is a kernel mode trap, then reset db7 and allow us to continue */
+ __asm__("movl %0,%%db7"
+ : /* no output */
+ : "r" (0));
+ return;
+ }
die_if_kernel("debug",regs,error_code);
}
#include <asm/io.h>
/*
- * 16-bit register defines..
+ * Known problems:
+ *
+ * Interrupt handling is not guaranteed:
+ * - a real x86 will disable all interrupts for one instruction
+ * after a "mov ss,xx" to make stack handling atomic even without
+ * the 'lss' instruction. We can't guarantee this in v86 mode,
+ * as the next instruction might result in a page fault or similar.
+ * - a real x86 will have interrupts disabled for one instruction
+ * past the 'sti' that enables them. We don't bother with all the
+ * details yet..
+ *
+ * Hopefully these problems do not actually matter for anything.
*/
+
+/*
+ * 8- and 16-bit register defines..
+ */
+#define AL(regs) (((unsigned char *) ((regs)->eax))[0])
+#define AH(regs) (((unsigned char *) ((regs)->eax))[1])
#define IP(regs) (*(unsigned short *)&((regs)->eip))
#define SP(regs) (*(unsigned short *)&((regs)->esp))
if (seg == BIOSSEG || regs->cs == BIOSSEG ||
is_revectored(i, ¤t->vm86_info->int_revectored))
return_to_32bit(regs, VM86_INTx + (i << 8));
- if (i==0x21 && is_revectored((regs->eax >> 4) & 0xff,¤t->vm86_info->int21_revectored)) {
+ if (i==0x21 && is_revectored(AH(regs),¤t->vm86_info->int21_revectored)) {
return_to_32bit(regs, VM86_INTx + (i << 8));
}
pushw(ssp, sp, get_vflags(regs));
return;
}
+void handle_vm86_debug(struct vm86_regs * regs, long error_code)
+{
+ do_int(regs, 3, (unsigned char *) (regs->ss << 4), SP(regs));
+}
void handle_vm86_fault(struct vm86_regs * regs, long error_code)
{
return;
/* sti */
+ /*
+ * Damn. This is incorrect: the 'sti' instruction should actually
+ * enable interrupts after the /next/ instruction. Not good.
+ *
+ * Probably needs some horsing around with the TF flag. Aiee..
+ */
case 0xfb:
IP(regs)++;
set_IF(regs);
*page_table = 0;
if (1 & page) {
if (!(mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED))
- if (current->rss > 0)
- --current->rss;
+ if (current->mm->rss > 0)
+ --current->mm->rss;
free_page(PAGE_MASK & page);
} else
swap_free(page);
*page_table = 0;
if (page & PAGE_PRESENT) {
if (!(mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED))
- if (current->rss > 0)
- --current->rss;
+ if (current->mm->rss > 0)
+ --current->mm->rss;
free_page(PAGE_MASK & page);
} else
swap_free(page);
*page_table = 0;
if (PAGE_PRESENT & page) {
if (!(mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED))
- if (current->rss > 0)
- --current->rss;
+ if (current->mm->rss > 0)
+ --current->mm->rss;
free_page(PAGE_MASK & page);
} else
swap_free(page);
else {
*page_table++ = (to | mask);
if (!(mem_map[MAP_NR(to)] & MAP_PAGE_RESERVED)) {
- ++current->rss;
+ ++current->mm->rss;
mem_map[MAP_NR(to)]++;
}
}
goto bad_wp_page;
if (old_page & PAGE_RW)
goto end_wp_page;
- tsk->min_flt++;
+ tsk->mm->min_flt++;
prot = (old_page & ~PAGE_MASK) | PAGE_RW;
old_page &= PAGE_MASK;
if (mem_map[MAP_NR(old_page)] != 1) {
if (new_page) {
if (mem_map[MAP_NR(old_page)] & MAP_PAGE_RESERVED)
- ++tsk->rss;
+ ++tsk->mm->rss;
copy_page(old_page,new_page);
*(unsigned long *) pte = new_page | prot;
free_page(old_page);
we can share pages with */
if(area){
struct vm_area_struct * mpnt;
- for (mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next) {
+ for (mpnt = (*p)->mm->mmap; mpnt; mpnt = mpnt->vm_next) {
if (mpnt->vm_ops == area->vm_ops &&
mpnt->vm_inode->i_ino == area->vm_inode->i_ino&&
mpnt->vm_inode->i_dev == area->vm_inode->i_dev){
tmp = *(unsigned long *) page;
if (tmp & PAGE_PRESENT)
return;
- ++tsk->rss;
+ ++tsk->mm->rss;
if (tmp) {
- ++tsk->maj_flt;
+ ++tsk->mm->maj_flt;
swap_in((unsigned long *) page);
return;
}
address &= 0xfffff000;
tmp = 0;
- for (mpnt = tsk->mmap; mpnt != NULL; mpnt = mpnt->vm_next) {
+ for (mpnt = tsk->mm->mmap; mpnt != NULL; mpnt = mpnt->vm_next) {
if (address < mpnt->vm_start)
break;
if (address >= mpnt->vm_end) {
continue;
}
if (!mpnt->vm_ops || !mpnt->vm_ops->nopage) {
- ++tsk->min_flt;
+ ++tsk->mm->min_flt;
get_empty_page(tsk,address);
return;
}
}
if (tsk != current)
goto ok_no_page;
- if (address >= tsk->end_data && address < tsk->brk)
+ if (address >= tsk->mm->end_data && address < tsk->mm->brk)
goto ok_no_page;
- if (mpnt && mpnt == tsk->stk_vma &&
+ if (mpnt && mpnt == tsk->mm->stk_vma &&
address - tmp > mpnt->vm_start - address &&
tsk->rlim[RLIMIT_STACK].rlim_cur > mpnt->vm_end - address) {
mpnt->vm_start = address;
if (error_code & 4) /* user level access? */
return;
ok_no_page:
- ++tsk->min_flt;
+ ++tsk->mm->min_flt;
get_empty_page(tsk,address);
}
page = get_free_page(GFP_KERNEL);
if (share_page(area, area->vm_task, inode, address, error_code, page)) {
- ++area->vm_task->min_flt;
+ ++area->vm_task->mm->min_flt;
return;
}
- ++area->vm_task->maj_flt;
+ ++area->vm_task->mm->maj_flt;
if (!page) {
oom(current);
put_page(area->vm_task, BAD_PAGE, address, PAGE_PRIVATE);
/* Maybe this works.. Ugly it is. */
addr = SHM_RANGE_START;
while (addr+len < SHM_RANGE_END) {
- for (vmm = current->mmap ; vmm ; vmm = vmm->vm_next) {
+ for (vmm = current->mm->mmap ; vmm ; vmm = vmm->vm_next) {
if (addr >= vmm->vm_end)
continue;
if (addr + len <= vmm->vm_start)
flags = get_fs_long(buffer+3);
if (!(flags & MAP_ANONYMOUS)) {
unsigned long fd = get_fs_long(buffer+4);
- if (fd >= NR_OPEN || !(file = current->filp[fd]))
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
return -EBADF;
}
return do_mmap(file, get_fs_long(buffer), get_fs_long(buffer+1),
* every area affected in some way (by any overlap) is put
* on the list. If nothing is put on, nothing is affected.
*/
- npp = ¤t->mmap;
+ npp = ¤t->mm->mmap;
free = NULL;
for (mpnt = *npp; mpnt != NULL; mpnt = *npp) {
unsigned long end = addr+len;
mpnt->vm_offset = off;
mpnt->vm_ops = &file_mmap;
insert_vm_struct(current, mpnt);
- merge_segments(current->mmap, NULL, NULL);
+ merge_segments(current->mm->mmap, NULL, NULL);
return 0;
}
{
struct vm_area_struct **nxtpp, *mpnt;
- nxtpp = &t->mmap;
+ nxtpp = &t->mm->mmap;
- for(mpnt = t->mmap; mpnt != NULL; mpnt = mpnt->vm_next)
+ for(mpnt = t->mm->mmap; mpnt != NULL; mpnt = mpnt->vm_next)
{
if (mpnt->vm_start > vmp->vm_start)
break;
mpnt->vm_offset = 0;
mpnt->vm_ops = NULL;
insert_vm_struct(current, mpnt);
- merge_segments(current->mmap, ignoff_mergep, NULL);
+ merge_segments(current->mm->mmap, ignoff_mergep, NULL);
return 0;
}
}
p = task[swap_task];
- if(p && p->swappable && p->rss)
+ if(p && p->mm->swappable && p->mm->rss)
break;
swap_task++;
/*
* Determine the number of pages to swap from this process.
*/
- if(! p -> swap_cnt) {
- p->dec_flt = (p->dec_flt * 3) / 4 + p->maj_flt - p->old_maj_flt;
- p->old_maj_flt = p->maj_flt;
-
- if(p->dec_flt >= SWAP_RATIO / SWAP_MIN) {
- p->dec_flt = SWAP_RATIO / SWAP_MIN;
- p->swap_cnt = SWAP_MIN;
- } else if(p->dec_flt <= SWAP_RATIO / SWAP_MAX)
- p->swap_cnt = SWAP_MAX;
+ if(! p->mm->swap_cnt) {
+ p->mm->dec_flt = (p->mm->dec_flt * 3) / 4 + p->mm->maj_flt - p->mm->old_maj_flt;
+ p->mm->old_maj_flt = p->mm->maj_flt;
+
+ if(p->mm->dec_flt >= SWAP_RATIO / SWAP_MIN) {
+ p->mm->dec_flt = SWAP_RATIO / SWAP_MIN;
+ p->mm->swap_cnt = SWAP_MIN;
+ } else if(p->mm->dec_flt <= SWAP_RATIO / SWAP_MAX)
+ p->mm->swap_cnt = SWAP_MAX;
else
- p->swap_cnt = SWAP_RATIO / p->dec_flt;
+ p->mm->swap_cnt = SWAP_RATIO / p->mm->dec_flt;
}
/*
* Go through process' page directory.
*/
- for(table = p->swap_table; table < 1024; table++) {
+ for(table = p->mm->swap_table; table < 1024; table++) {
pg_table = ((unsigned long *) p->tss.cr3)[table];
if(pg_table >= high_memory)
continue;
/*
* Go through this page table.
*/
- for(page = p->swap_page; page < 1024; page++) {
+ for(page = p->mm->swap_page; page < 1024; page++) {
switch(try_to_swap_out(page + (unsigned long *) pg_table)) {
case 0:
break;
case 1:
- p->rss--;
+ p->mm->rss--;
/* continue with the following page the next time */
- p->swap_table = table;
- p->swap_page = page + 1;
- if((--p->swap_cnt) == 0)
+ p->mm->swap_table = table;
+ p->mm->swap_page = page + 1;
+ if((--p->mm->swap_cnt) == 0)
swap_task++;
return 1;
default:
- p->rss--;
+ p->mm->rss--;
break;
}
}
- p->swap_page = 0;
+ p->mm->swap_page = 0;
}
/*
* Finish work with this process, if we reached the end of the page
* directory. Mark restart from the beginning the next time.
*/
- p->swap_table = 0;
+ p->mm->swap_table = 0;
}
return 0;
}
goto check_task;
}
p = task[swap_task];
- if (!p || !p->swappable) {
+ if (!p || !p->mm->swappable) {
swap_task++;
goto check_task;
}
}
switch (try_to_swap_out(swap_page + (unsigned long *) pg_table)) {
case 0: break;
- case 1: p->rss--; return 1;
- default: p->rss--;
+ case 1: p->mm->rss--; return 1;
+ default: p->mm->rss--;
}
swap_page++;
goto check_table;
read_swap_page(page, (char *) tmp);
if (*ppage == page) {
*ppage = tmp | (PAGE_DIRTY | PAGE_PRIVATE);
- ++p->rss;
+ ++p->mm->rss;
swap_free(page);
tmp = 0;
}
file = get_empty_filp();
if (!file) return(-1);
for (fd = 0; fd < NR_OPEN; ++fd)
- if (!current->filp[fd]) break;
+ if (!current->files->fd[fd]) break;
if (fd == NR_OPEN) {
file->f_count = 0;
return(-1);
}
- FD_CLR(fd, ¤t->close_on_exec);
- current->filp[fd] = file;
+ FD_CLR(fd, ¤t->files->close_on_exec);
+ current->files->fd[fd] = file;
file->f_op = &socket_file_ops;
file->f_mode = 3;
file->f_flags = 0;
{
struct file *file;
- if (fd < 0 || fd >= NR_OPEN || !(file = current->filp[fd])) return(NULL);
+ if (fd < 0 || fd >= NR_OPEN || !(file = current->files->fd[fd])) return(NULL);
if (pfile) *pfile = file;
return(socki_lookup(file->f_inode));
}
int i;
DPRINTF((net_debug, "NET: sock_bind: fd = %d\n", fd));
- if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
+ if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
return(-EBADF);
if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
if ((i = sock->ops->bind(sock, umyaddr, addrlen)) < 0) {
struct socket *sock;
DPRINTF((net_debug, "NET: sock_listen: fd = %d\n", fd));
- if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
+ if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
return(-EBADF);
if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
if (sock->state != SS_UNCONNECTED) {
int i;
DPRINTF((net_debug, "NET: sock_accept: fd = %d\n", fd));
- if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
+ if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
return(-EBADF);
if (!(sock = sockfd_lookup(fd, &file))) return(-ENOTSOCK);
int i;
DPRINTF((net_debug, "NET: sock_connect: fd = %d\n", fd));
- if (fd < 0 || fd >= NR_OPEN || (file=current->filp[fd]) == NULL)
+ if (fd < 0 || fd >= NR_OPEN || (file=current->files->fd[fd]) == NULL)
return(-EBADF);
if (!(sock = sockfd_lookup(fd, &file))) return(-ENOTSOCK);
struct socket *sock;
DPRINTF((net_debug, "NET: sock_getsockname: fd = %d\n", fd));
- if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
+ if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
return(-EBADF);
if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
return(sock->ops->getname(sock, usockaddr, usockaddr_len, 0));
struct socket *sock;
DPRINTF((net_debug, "NET: sock_getpeername: fd = %d\n", fd));
- if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
+ if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
return(-EBADF);
if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
return(sock->ops->getname(sock, usockaddr, usockaddr_len, 1));
"NET: sock_send(fd = %d, buff = %X, len = %d, flags = %X)\n",
fd, buff, len, flags));
- if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
+ if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
return(-EBADF);
if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
"NET: sock_sendto(fd = %d, buff = %X, len = %d, flags = %X,"
" addr=%X, alen = %d\n", fd, buff, len, flags, addr, addr_len));
- if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
+ if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
return(-EBADF);
if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
"NET: sock_recv(fd = %d, buff = %X, len = %d, flags = %X)\n",
fd, buff, len, flags));
- if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
+ if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
return(-EBADF);
if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
"NET: sock_recvfrom(fd = %d, buff = %X, len = %d, flags = %X,"
" addr=%X, alen=%X\n", fd, buff, len, flags, addr, addr_len));
- if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
+ if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
return(-EBADF);
if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
DPRINTF((net_debug, " optval = %X, optlen = %d)\n",
optval, optlen));
- if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
+ if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
return(-EBADF);
if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
DPRINTF((net_debug, " optval = %X, optlen = %X)\n",
optval, optlen));
- if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
+ if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
return(-EBADF);
if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
DPRINTF((net_debug, "NET: sock_shutdown(fd = %d, how = %d)\n", fd, how));
- if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
+ if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
return(-EBADF);
if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);