Commit 17e3d4ce authored by Linus Torvalds's avatar Linus Torvalds

Linux 2.1.89-4

It should fix the problem another way that I'm happier with (fixing that
problem also revealed a few other misuses of close_fp() due to historical
reasons - the uses really needed to be "fput()"s instead).
2.1.89-4 also uses "struct file" for mmap's, which means that the problem
that somebody was complaining about with mmap (that the mapping would
exist even after the last "release()" on that file, and thus the file
would still be active) are gone. As of -4 the kernel will guarantee that
it will call the file->f_op->release() onle after there really aren't any
uses of that file pointer any more..

                Linus
parent b0532cc2
...@@ -68,11 +68,14 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg) ...@@ -68,11 +68,14 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg)
goto out; goto out;
if (!(a.flags & MAP_ANONYMOUS)) { if (!(a.flags & MAP_ANONYMOUS)) {
error = -EBADF; error = -EBADF;
if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd])) file = fget(a.fd);
if (!file)
goto out; goto out;
} }
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset); error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
if (file)
fput(file);
out: out:
unlock_kernel(); unlock_kernel();
return error; return error;
......
...@@ -112,7 +112,7 @@ static unsigned int joystick_poll(struct file *file, poll_table *wait) ...@@ -112,7 +112,7 @@ static unsigned int joystick_poll(struct file *file, poll_table *wait)
{ {
int minor = DEVICE_NR(file->f_dentry->d_inode->i_rdev); int minor = DEVICE_NR(file->f_dentry->d_inode->i_rdev);
poll_wait(&joystick[minor].wait, wait); poll_wait(file, &joystick[minor].wait, wait);
if (joystick[minor].ready) if (joystick[minor].ready)
return POLLIN | POLLRDNORM; return POLLIN | POLLRDNORM;
return 0; return 0;
......
...@@ -2101,8 +2101,8 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma, ...@@ -2101,8 +2101,8 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
{ {
if((vma->vm_flags & (VM_WRITE|VM_SHARED)) == (VM_WRITE|VM_SHARED)) { if((vma->vm_flags & (VM_WRITE|VM_SHARED)) == (VM_WRITE|VM_SHARED)) {
struct vm_area_struct *vmaring; struct vm_area_struct *vmaring;
struct dentry *dentry; struct file *file;
struct inode *inode = NULL; struct inode *inode;
unsigned long flags, offset, vaddr, start; unsigned long flags, offset, vaddr, start;
int alias_found = 0; int alias_found = 0;
pgd_t *pgdp; pgd_t *pgdp;
...@@ -2111,11 +2111,10 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma, ...@@ -2111,11 +2111,10 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
save_and_cli(flags); save_and_cli(flags);
dentry = vma->vm_dentry; file = vma->vm_file;
if(dentry) if (!file)
inode = dentry->d_inode;
if (!inode)
goto done; goto done;
inode = file->f_dentry->d_inode;
offset = (address & PAGE_MASK) - vma->vm_start; offset = (address & PAGE_MASK) - vma->vm_start;
vmaring = inode->i_mmap; vmaring = inode->i_mmap;
do { do {
......
...@@ -220,7 +220,8 @@ static int fb_mmap(struct file *file, struct vm_area_struct * vma) ...@@ -220,7 +220,8 @@ static int fb_mmap(struct file *file, struct vm_area_struct * vma)
if (remap_page_range(vma->vm_start, vma->vm_offset, if (remap_page_range(vma->vm_start, vma->vm_offset,
vma->vm_end - vma->vm_start, vma->vm_page_prot)) vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN; return -EAGAIN;
vma->vm_dentry = dget(file->f_dentry); vma->vm_file = file;
file->f_count++;
return 0; return 0;
} }
......
...@@ -561,6 +561,7 @@ unsigned int hfmodem_poll(struct file *file, poll_table *wait) ...@@ -561,6 +561,7 @@ unsigned int hfmodem_poll(struct file *file, poll_table *wait)
unsigned long flags; unsigned long flags;
int i, cnt1, cnt2; int i, cnt1, cnt2;
poll_wait(file, &dev->wait, wait);
save_flags(flags); save_flags(flags);
cli(); cli();
for (i = cnt1 = cnt2 = 0; i < HFMODEM_NUMTXSLOTS; i++) { for (i = cnt1 = cnt2 = 0; i < HFMODEM_NUMTXSLOTS; i++) {
...@@ -576,7 +577,6 @@ unsigned int hfmodem_poll(struct file *file, poll_table *wait) ...@@ -576,7 +577,6 @@ unsigned int hfmodem_poll(struct file *file, poll_table *wait)
cnt2++; cnt2++;
} }
restore_flags(flags); restore_flags(flags);
poll_wait(&dev->wait, wait);
if (cnt1 || !cnt2) if (cnt1 || !cnt2)
return POLLIN | POLLRDNORM; return POLLIN | POLLRDNORM;
return 0; return 0;
......
...@@ -142,7 +142,8 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) ...@@ -142,7 +142,8 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start, if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
vma->vm_page_prot)) vma->vm_page_prot))
return -EAGAIN; return -EAGAIN;
vma->vm_dentry = dget(file->f_dentry); vma->vm_file = file;
file->f_count++;
return 0; return 0;
} }
......
...@@ -207,7 +207,7 @@ capi_poll(struct file *file, poll_table * wait) ...@@ -207,7 +207,7 @@ capi_poll(struct file *file, poll_table * wait)
return POLLERR; return POLLERR;
cdev = &capidevs[minor]; cdev = &capidevs[minor];
poll_wait(&(cdev->recv_wait), wait); poll_wait(file, &(cdev->recv_wait), wait);
mask = POLLOUT | POLLWRNORM; mask = POLLOUT | POLLWRNORM;
if (!skb_queue_empty(&cdev->recv_queue)) if (!skb_queue_empty(&cdev->recv_queue))
mask |= POLLIN | POLLRDNORM; mask |= POLLIN | POLLRDNORM;
......
...@@ -846,7 +846,7 @@ static ssize_t aux_read(struct file * file, char * buffer, ...@@ -846,7 +846,7 @@ static ssize_t aux_read(struct file * file, char * buffer,
static unsigned int aux_poll(struct file *file, poll_table * wait) static unsigned int aux_poll(struct file *file, poll_table * wait)
{ {
poll_wait(&queue->proc_list, wait); poll_wait(file, &queue->proc_list, wait);
if (aux_ready) if (aux_ready)
return POLLIN | POLLRDNORM; return POLLIN | POLLRDNORM;
return 0; return 0;
......
...@@ -1317,7 +1317,7 @@ static int kbd_fasync (struct file *filp, int on) ...@@ -1317,7 +1317,7 @@ static int kbd_fasync (struct file *filp, int on)
static unsigned int kbd_poll (struct file *f, poll_table *wait) static unsigned int kbd_poll (struct file *f, poll_table *wait)
{ {
poll_wait(&kbd_wait, wait); poll_wait(f, &kbd_wait, wait);
if (kbd_head != kbd_tail) if (kbd_head != kbd_tail)
return POLLIN | POLLRDNORM; return POLLIN | POLLRDNORM;
return 0; return 0;
......
...@@ -420,7 +420,7 @@ sun_mouse_read(struct file *file, char *buffer, ...@@ -420,7 +420,7 @@ sun_mouse_read(struct file *file, char *buffer,
static unsigned int sun_mouse_poll(struct file *file, poll_table *wait) static unsigned int sun_mouse_poll(struct file *file, poll_table *wait)
{ {
poll_wait(&sunmouse.proc_list, wait); poll_wait(file, &sunmouse.proc_list, wait);
if(sunmouse.ready) if(sunmouse.ready)
return POLLIN | POLLRDNORM; return POLLIN | POLLRDNORM;
return 0; return 0;
......
...@@ -365,7 +365,7 @@ shmiq_qcntl_poll (struct file *filp, poll_table *wait) ...@@ -365,7 +365,7 @@ shmiq_qcntl_poll (struct file *filp, poll_table *wait)
if (!shmiqs [minor].mapped) if (!shmiqs [minor].mapped)
return 0; return 0;
poll_wait (&shmiqs [minor].proc_list, wait); poll_wait (filp, &shmiqs [minor].proc_list, wait);
s = shmiqs [minor].shmiq_vaddr; s = shmiqs [minor].shmiq_vaddr;
if (s->head != s->tail) if (s->head != s->tail)
return POLLIN | POLLRDNORM; return POLLIN | POLLRDNORM;
......
...@@ -211,7 +211,7 @@ static int maui_init(int irq) ...@@ -211,7 +211,7 @@ static int maui_init(int irq)
outb((0x80), HOST_CTRL_PORT); /* Leave reset */ outb((0x80), HOST_CTRL_PORT); /* Leave reset */
outb((0xD0), HOST_CTRL_PORT); /* Cause interrupt */ outb((0xD0), HOST_CTRL_PORT); /* Cause interrupt */
#ifndef __SMP__ #ifdef __SMP__
for (i = 0; i < 1000000 && !irq_ok; i++); for (i = 0; i < 1000000 && !irq_ok; i++);
if (!irq_ok) if (!irq_ok)
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/unistd.h> #include <linux/unistd.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
static int errno;
static int do_mod_firmware_load(const char *fn, char **fp) static int do_mod_firmware_load(const char *fn, char **fp)
{ {
int fd; int fd;
......
...@@ -732,7 +732,8 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -732,7 +732,8 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
vma->vm_page_prot)) vma->vm_page_prot))
return -EAGAIN; return -EAGAIN;
vma->vm_dentry = dget(file->f_dentry); vma->vm_file = file;
file->f_count++;
dmap->mapping_flags |= DMA_MAP_MAPPED; dmap->mapping_flags |= DMA_MAP_MAPPED;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/file.h>
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/malloc.h> #include <linux/malloc.h>
...@@ -217,76 +218,60 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -217,76 +218,60 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
unsigned long *interp_load_addr) unsigned long *interp_load_addr)
{ {
struct file * file; struct file * file;
struct elf_phdr *elf_phdata = NULL; struct elf_phdr *elf_phdata;
struct elf_phdr *eppnt; struct elf_phdr *eppnt;
unsigned long load_addr; unsigned long load_addr = 0;
int load_addr_set = 0; int load_addr_set = 0;
unsigned long last_bss = 0, elf_bss = 0;
unsigned long error = ~0UL;
int elf_exec_fileno; int elf_exec_fileno;
int retval; int retval, i, size;
unsigned long last_bss, elf_bss;
unsigned long error;
int i;
elf_bss = 0;
last_bss = 0;
error = load_addr = 0;
/* First of all, some simple consistency checks */ /* First of all, some simple consistency checks */
if ((interp_elf_ex->e_type != ET_EXEC && if (interp_elf_ex->e_type != ET_EXEC &&
interp_elf_ex->e_type != ET_DYN) || interp_elf_ex->e_type != ET_DYN)
!elf_check_arch(interp_elf_ex->e_machine) || goto out;
(!interpreter_dentry->d_inode->i_op || if (!elf_check_arch(interp_elf_ex->e_machine))
!interpreter_dentry->d_inode->i_op->default_file_ops->mmap)){ goto out;
return ~0UL; if (!interpreter_dentry->d_inode->i_op ||
} !interpreter_dentry->d_inode->i_op->default_file_ops->mmap)
goto out;
/* Now read in all of the header information */
if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > ELF_EXEC_PAGESIZE) {
return ~0UL;
}
elf_phdata = (struct elf_phdr *)
kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum,
GFP_KERNEL);
if (!elf_phdata) {
return ~0UL;
}
/* /*
* If the size of this structure has changed, then punt, since * If the size of this structure has changed, then punt, since
* we will be doing the wrong thing. * we will be doing the wrong thing.
*/ */
if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr))
{ goto out;
kfree(elf_phdata);
return ~0UL;
}
retval = read_exec(interpreter_dentry, interp_elf_ex->e_phoff, /* Now read in all of the header information */
(char *) elf_phdata,
sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, 1);
if (retval < 0) { size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum;
kfree (elf_phdata); if (size > ELF_EXEC_PAGESIZE)
return retval; goto out;
} elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
if (!elf_phdata)
goto out;
elf_exec_fileno = open_dentry(interpreter_dentry, O_RDONLY); retval = read_exec(interpreter_dentry, interp_elf_ex->e_phoff,
if (elf_exec_fileno < 0) { (char *) elf_phdata, size, 1);
kfree(elf_phdata); error = retval;
return ~0UL; if (retval < 0)
} goto out_free;
file = current->files->fd[elf_exec_fileno]; error = ~0UL;
elf_exec_fileno = open_dentry(interpreter_dentry, O_RDONLY);
if (elf_exec_fileno < 0)
goto out_free;
file = fget(elf_exec_fileno);
eppnt = elf_phdata; eppnt = elf_phdata;
for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
if (eppnt->p_type == PT_LOAD) { if (eppnt->p_type == PT_LOAD) {
int elf_type = MAP_PRIVATE | MAP_DENYWRITE; int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
int elf_prot = 0; int elf_prot = 0;
unsigned long vaddr = 0; unsigned long vaddr = 0;
unsigned long k; unsigned long k, map_addr;
if (eppnt->p_flags & PF_R) elf_prot = PROT_READ; if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
...@@ -301,22 +286,17 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -301,22 +286,17 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
#endif #endif
} }
error = do_mmap(file, map_addr = do_mmap(file,
load_addr + ELF_PAGESTART(vaddr), load_addr + ELF_PAGESTART(vaddr),
eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr),
elf_prot, elf_prot,
elf_type, elf_type,
eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr)); eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
if (map_addr > -1024UL) /* Real error */
if (error > -1024UL) { goto out_close;
/* Real error */
sys_close(elf_exec_fileno);
kfree(elf_phdata);
return ~0UL;
}
if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
load_addr = error; load_addr = map_addr;
load_addr_set = 1; load_addr_set = 1;
} }
...@@ -325,20 +305,21 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -325,20 +305,21 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
* track of the largest address we see for this. * track of the largest address we see for this.
*/ */
k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
if (k > elf_bss) elf_bss = k; if (k > elf_bss)
elf_bss = k;
/* /*
* Do the same thing for the memory mapping - between * Do the same thing for the memory mapping - between
* elf_bss and last_bss is the bss section. * elf_bss and last_bss is the bss section.
*/ */
k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
if (k > last_bss) last_bss = k; if (k > last_bss)
last_bss = k;
}
} }
/* Now use mmap to map the library into memory. */ /* Now use mmap to map the library into memory. */
sys_close(elf_exec_fileno);
/* /*
* Now fill out the bss section. First pad the last page up * Now fill out the bss section. First pad the last page up
* to the page boundary, and then perform a mmap to make sure * to the page boundary, and then perform a mmap to make sure
...@@ -350,52 +331,60 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -350,52 +331,60 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
/* Map the last of the bss segment */ /* Map the last of the bss segment */
if (last_bss > elf_bss) if (last_bss > elf_bss)
do_mmap(NULL, elf_bss, last_bss-elf_bss, do_mmap(NULL, elf_bss, last_bss - elf_bss,
PROT_READ|PROT_WRITE|PROT_EXEC, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0); MAP_FIXED|MAP_PRIVATE, 0);
kfree(elf_phdata);
*interp_load_addr = load_addr; *interp_load_addr = load_addr;
return ((unsigned long) interp_elf_ex->e_entry) + load_addr; error = ((unsigned long) interp_elf_ex->e_entry) + load_addr;
out_close:
fput(file);
sys_close(elf_exec_fileno);
out_free:
kfree(elf_phdata);
out:
return error;
} }
static unsigned long load_aout_interp(struct exec * interp_ex, static unsigned long load_aout_interp(struct exec * interp_ex,
struct dentry * interpreter_dentry) struct dentry * interpreter_dentry)
{ {
unsigned long text_data, offset, elf_entry = ~0UL;
char * addr;
int retval; int retval;
unsigned long elf_entry;
current->mm->brk = interp_ex->a_bss + current->mm->end_code = interp_ex->a_text;
(current->mm->end_data = interp_ex->a_data + text_data = interp_ex->a_text + interp_ex->a_data;
(current->mm->end_code = interp_ex->a_text)); current->mm->end_data = text_data;
elf_entry = interp_ex->a_entry; current->mm->brk = interp_ex->a_bss + text_data;
switch (N_MAGIC(*interp_ex)) {
case OMAGIC:
offset = 32;
addr = (char *) 0;
break;
case ZMAGIC:
case QMAGIC:
offset = N_TXTOFF(*interp_ex);
addr = (char *) N_TXTADDR(*interp_ex);
break;
default:
goto out;
}
if (N_MAGIC(*interp_ex) == OMAGIC) { do_mmap(NULL, 0, text_data,
do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0);
PROT_READ|PROT_WRITE|PROT_EXEC, retval = read_exec(interpreter_dentry, offset, addr, text_data, 0);
MAP_FIXED|MAP_PRIVATE, 0); if (retval < 0)
retval = read_exec(interpreter_dentry, 32, (char *) 0, goto out;
interp_ex->a_text+interp_ex->a_data, 0);
} else if (N_MAGIC(*interp_ex) == ZMAGIC || N_MAGIC(*interp_ex) == QMAGIC) {
do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data,
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0);
retval = read_exec(interpreter_dentry,
N_TXTOFF(*interp_ex) ,
(char *) N_TXTADDR(*interp_ex),
interp_ex->a_text+interp_ex->a_data, 0);
} else
retval = -1;
if (retval >= 0) do_mmap(NULL, ELF_PAGESTART(text_data + ELF_EXEC_PAGESIZE - 1),
do_mmap(NULL, ELF_PAGESTART(interp_ex->a_text + interp_ex->a_data + ELF_EXEC_PAGESIZE - 1),
interp_ex->a_bss, interp_ex->a_bss,
PROT_READ|PROT_WRITE|PROT_EXEC, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0);
MAP_FIXED|MAP_PRIVATE, 0); elf_entry = interp_ex->a_entry;
if (retval < 0) {
return ~0UL; out:
}
return elf_entry; return elf_entry;
} }
...@@ -412,118 +401,103 @@ static unsigned long load_aout_interp(struct exec * interp_ex, ...@@ -412,118 +401,103 @@ static unsigned long load_aout_interp(struct exec * interp_ex,
static inline int static inline int
do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{ {
struct elfhdr elf_ex;
struct elfhdr interp_elf_ex;
struct file * file; struct file * file;
struct exec interp_ex;
struct dentry *interpreter_dentry = NULL; /* to shut gcc up */ struct dentry *interpreter_dentry = NULL; /* to shut gcc up */
unsigned long load_addr, load_bias; unsigned long load_addr = 0, load_bias;
int load_addr_set = 0; int load_addr_set = 0;
char * elf_interpreter = NULL;
unsigned int interpreter_type = INTERPRETER_NONE; unsigned int interpreter_type = INTERPRETER_NONE;
unsigned char ibcs2_interpreter; unsigned char ibcs2_interpreter = 0;
int i;
mm_segment_t old_fs; mm_segment_t old_fs;
unsigned long error; unsigned long error;
struct elf_phdr * elf_ppnt, *elf_phdata; struct elf_phdr * elf_ppnt, *elf_phdata;
int elf_exec_fileno;
unsigned long elf_bss, k, elf_brk; unsigned long elf_bss, k, elf_brk;
int retval; int elf_exec_fileno;
char * elf_interpreter; int retval, size, i;
unsigned long elf_entry, interp_load_addr = 0; unsigned long elf_entry, interp_load_addr = 0;
int status;
unsigned long start_code, end_code, end_data; unsigned long start_code, end_code, end_data;
struct elfhdr elf_ex;
struct elfhdr interp_elf_ex;
struct exec interp_ex;
char passed_fileno[6]; char passed_fileno[6];
ibcs2_interpreter = 0; /* Get the exec-header */
status = 0; elf_ex = *((struct elfhdr *) bprm->buf);
load_addr = 0;
elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
if (elf_ex.e_ident[0] != 0x7f ||
strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
return -ENOEXEC;
}
retval = -ENOEXEC;
/* First of all, some simple consistency checks */ /* First of all, some simple consistency checks */
if ((elf_ex.e_type != ET_EXEC && if (elf_ex.e_ident[0] != 0x7f ||
elf_ex.e_type != ET_DYN) || strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0)
(! elf_check_arch(elf_ex.e_machine)) || goto out;
(!bprm->dentry->d_inode->i_op || !bprm->dentry->d_inode->i_op->default_file_ops ||
!bprm->dentry->d_inode->i_op->default_file_ops->mmap)){ if (elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN)
return -ENOEXEC; goto out;
} if (!elf_check_arch(elf_ex.e_machine))
goto out;
if (!bprm->dentry->d_inode->i_op ||
!bprm->dentry->d_inode->i_op->default_file_ops ||
!bprm->dentry->d_inode->i_op->default_file_ops->mmap)
goto out;
/* Now read in all of the header information */ /* Now read in all of the header information */
elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize * retval = -ENOMEM;
elf_ex.e_phnum, GFP_KERNEL); size = elf_ex.e_phentsize * elf_ex.e_phnum;
if (elf_phdata == NULL) { elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
return -ENOMEM; if (!elf_phdata)
} goto out;
retval = read_exec(bprm->dentry, elf_ex.e_phoff, (char *) elf_phdata, retval = read_exec(bprm->dentry, elf_ex.e_phoff,
elf_ex.e_phentsize * elf_ex.e_phnum, 1); (char *) elf_phdata, size, 1);
if (retval < 0) { if (retval < 0)
kfree (elf_phdata); goto out_free_ph;
return retval;
}
elf_ppnt = elf_phdata; retval = open_dentry(bprm->dentry, O_RDONLY);
if (retval < 0)
goto out_free_ph;
elf_exec_fileno = retval;
file = fget(elf_exec_fileno);
elf_ppnt = elf_phdata;
elf_bss = 0; elf_bss = 0;
elf_brk = 0; elf_brk = 0;
elf_exec_fileno = open_dentry(bprm->dentry, O_RDONLY);
if (elf_exec_fileno < 0) {
kfree (elf_phdata);
return elf_exec_fileno;
}
file = current->files->fd[elf_exec_fileno];
elf_interpreter = NULL;
start_code = ~0UL; start_code = ~0UL;
end_code = 0; end_code = 0;
end_data = 0; end_data = 0;
for(i=0;i < elf_ex.e_phnum; i++){ for (i = 0; i < elf_ex.e_phnum; i++) {
if (elf_ppnt->p_type == PT_INTERP) { if (elf_ppnt->p_type == PT_INTERP) {
if ( elf_interpreter != NULL ) retval = -EINVAL;
{ if (elf_interpreter)
kfree (elf_phdata); goto out_free_interp;
kfree(elf_interpreter);
sys_close(elf_exec_fileno);
return -EINVAL;
}
/* This is the program interpreter used for /* This is the program interpreter used for
* shared libraries - for now assume that this * shared libraries - for now assume that this
* is an a.out format binary * is an a.out format binary
*/ */
retval = -ENOMEM;
elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz, elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,
GFP_KERNEL); GFP_KERNEL);
if (elf_interpreter == NULL) { if (!elf_interpreter)
kfree (elf_phdata); goto out_free_file;
sys_close(elf_exec_fileno);
return -ENOMEM;
}
retval = read_exec(bprm->dentry,elf_ppnt->p_offset, retval = read_exec(bprm->dentry, elf_ppnt->p_offset,
elf_interpreter, elf_interpreter,
elf_ppnt->p_filesz, 1); elf_ppnt->p_filesz, 1);
if (retval < 0)
goto out_free_interp;
/* If the program interpreter is one of these two, /* If the program interpreter is one of these two,
then assume an iBCS2 image. Otherwise assume * then assume an iBCS2 image. Otherwise assume
a native linux image. */ * a native linux image.
*/
if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 || if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0)
ibcs2_interpreter = 1; ibcs2_interpreter = 1;
#if 0 #if 0
printk("Using ELF interpreter %s\n", elf_interpreter); printk("Using ELF interpreter %s\n", elf_interpreter);
#endif #endif
if (retval >= 0) {
old_fs = get_fs(); /* This could probably be optimized */ old_fs = get_fs(); /* This could probably be optimized */
set_fs(get_ds()); set_fs(get_ds());
#ifdef __sparc__ #ifdef __sparc__
...@@ -531,36 +505,32 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -531,36 +505,32 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
unsigned long old_pers = current->personality; unsigned long old_pers = current->personality;
current->personality = PER_SVR4; current->personality = PER_SVR4;
interpreter_dentry = open_namei(elf_interpreter, 0, 0); interpreter_dentry = open_namei(elf_interpreter,
0, 0);
current->personality = old_pers; current->personality = old_pers;
} else } else
#endif #endif
interpreter_dentry = open_namei(elf_interpreter, 0, 0); interpreter_dentry = open_namei(elf_interpreter,
0, 0);
set_fs(old_fs); set_fs(old_fs);
if (IS_ERR(interpreter_dentry))
retval = PTR_ERR(interpreter_dentry); retval = PTR_ERR(interpreter_dentry);
} if (IS_ERR(interpreter_dentry))
goto out_free_interp;
if (retval >= 0)
retval = read_exec(interpreter_dentry,0,bprm->buf,128, 1);
if (retval >= 0) { retval = read_exec(interpreter_dentry, 0, bprm->buf,
interp_ex = *((struct exec *) bprm->buf); /* exec-header */ 128, 1);
interp_elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ if (retval < 0)
goto out_free_dentry;
} /* Get the exec headers */
if (retval < 0) { interp_ex = *((struct exec *) bprm->buf);
kfree (elf_phdata); interp_elf_ex = *((struct elfhdr *) bprm->buf);
kfree(elf_interpreter);
sys_close(elf_exec_fileno);
return retval;
}
} }
elf_ppnt++; elf_ppnt++;
} }
/* Some simple consistency checks for the interpreter */ /* Some simple consistency checks for the interpreter */
if (elf_interpreter){ if (elf_interpreter) {
interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT; interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
/* Now figure out which format our binary is */ /* Now figure out which format our binary is */
...@@ -570,15 +540,18 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -570,15 +540,18 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
interpreter_type = INTERPRETER_ELF; interpreter_type = INTERPRETER_ELF;
if (interp_elf_ex.e_ident[0] != 0x7f || if (interp_elf_ex.e_ident[0] != 0x7f ||
strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) strncmp(&interp_elf_ex.e_ident[1], "ELF", 3) != 0)
interpreter_type &= ~INTERPRETER_ELF; interpreter_type &= ~INTERPRETER_ELF;
retval = -ELIBBAD;
if (!interpreter_type) if (!interpreter_type)
{ goto out_free_dentry;
kfree(elf_interpreter);
kfree(elf_phdata); /* Make sure only one type was selected */
sys_close(elf_exec_fileno); if ((interpreter_type & INTERPRETER_ELF) &&
return -ELIBBAD; interpreter_type != INTERPRETER_ELF) {
printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n");
interpreter_type = INTERPRETER_ELF;
} }
} }
...@@ -597,20 +570,15 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -597,20 +570,15 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
bprm->argc++; bprm->argc++;
} }
} }
if (!bprm->p) { retval = -E2BIG;
if (elf_interpreter) { if (!bprm->p)
kfree(elf_interpreter); goto out_free_dentry;
}
kfree (elf_phdata);
sys_close(elf_exec_fileno);
return -E2BIG;
}
} }
/* Flush all traces of the currently running executable */ /* Flush all traces of the currently running executable */
retval = flush_old_exec(bprm); retval = flush_old_exec(bprm);
if (retval) if (retval)
return retval; goto out_free_dentry;
/* OK, This is the point of no return */ /* OK, This is the point of no return */
current->mm->end_data = 0; current->mm->end_data = 0;
...@@ -677,15 +645,19 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -677,15 +645,19 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
k = elf_ppnt->p_vaddr; k = elf_ppnt->p_vaddr;
if (k < start_code) start_code = k; if (k < start_code) start_code = k;
k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz; k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
if (k > elf_bss) elf_bss = k; if (k > elf_bss)
elf_bss = k;
if ((elf_ppnt->p_flags & PF_X) && end_code < k) if ((elf_ppnt->p_flags & PF_X) && end_code < k)
end_code = k; end_code = k;
if (end_data < k) end_data = k; if (end_data < k)
end_data = k;
k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz; k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
if (k > elf_brk) elf_brk = k; if (k > elf_brk)
elf_brk = k;
} }
} }
set_fs(old_fs); set_fs(old_fs);
fput(file); /* all done with the file */
elf_entry += load_bias; elf_entry += load_bias;
elf_bss += load_bias; elf_bss += load_bias;
...@@ -695,10 +667,10 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -695,10 +667,10 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
end_data += load_bias; end_data += load_bias;
if (elf_interpreter) { if (elf_interpreter) {
if (interpreter_type & 1) if (interpreter_type == INTERPRETER_AOUT)
elf_entry = load_aout_interp(&interp_ex, elf_entry = load_aout_interp(&interp_ex,
interpreter_dentry); interpreter_dentry);
else if (interpreter_type & 2) else
elf_entry = load_elf_interp(&interp_elf_ex, elf_entry = load_elf_interp(&interp_elf_ex,
interpreter_dentry, interpreter_dentry,
&interp_load_addr); &interp_load_addr);
...@@ -707,7 +679,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -707,7 +679,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
kfree(elf_interpreter); kfree(elf_interpreter);
if (elf_entry == ~0UL) { if (elf_entry == ~0UL) {
printk("Unable to load interpreter\n"); printk(KERN_ERR "Unable to load interpreter\n");
kfree(elf_phdata); kfree(elf_phdata);
send_sig(SIGSEGV, current, 0); send_sig(SIGSEGV, current, 0);
return 0; return 0;
...@@ -744,6 +716,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -744,6 +716,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
load_addr, load_addr,
interp_load_addr, interp_load_addr,
(interpreter_type == INTERPRETER_AOUT ? 0 : 1)); (interpreter_type == INTERPRETER_AOUT ? 0 : 1));
/* N.B. passed_fileno might not be initialized? */
if (interpreter_type == INTERPRETER_AOUT) if (interpreter_type == INTERPRETER_AOUT)
current->mm->arg_start += strlen(passed_fileno) + 1; current->mm->arg_start += strlen(passed_fileno) + 1;
current->mm->start_brk = current->mm->brk = elf_brk; current->mm->start_brk = current->mm->brk = elf_brk;
...@@ -752,8 +725,9 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -752,8 +725,9 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->mm->end_data = end_data; current->mm->end_data = end_data;
current->mm->start_stack = bprm->p; current->mm->start_stack = bprm->p;
/* Calling set_brk effectively mmaps the pages that we need for the bss and break /* Calling set_brk effectively mmaps the pages that we need
sections */ * for the bss and break sections
*/
set_brk(elf_bss, elf_brk); set_brk(elf_bss, elf_brk);
padzero(elf_bss); padzero(elf_bss);
...@@ -773,6 +747,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -773,6 +747,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
and some applications "depend" upon this behavior. and some applications "depend" upon this behavior.
Since we do not have the power to recompile these, we Since we do not have the power to recompile these, we
emulate the SVr4 behavior. Sigh. */ emulate the SVr4 behavior. Sigh. */
/* N.B. Shouldn't the size here be PAGE_SIZE?? */
error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE, 0); MAP_FIXED | MAP_PRIVATE, 0);
} }
...@@ -787,11 +762,25 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -787,11 +762,25 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
ELF_PLAT_INIT(regs); ELF_PLAT_INIT(regs);
#endif #endif
start_thread(regs, elf_entry, bprm->p); start_thread(regs, elf_entry, bprm->p);
if (current->flags & PF_PTRACED) if (current->flags & PF_PTRACED)
send_sig(SIGTRAP, current, 0); send_sig(SIGTRAP, current, 0);
return 0; retval = 0;
out:
return retval;
/* error cleanup */
out_free_dentry:
dput(interpreter_dentry);
out_free_interp:
if (elf_interpreter)
kfree(elf_interpreter);
out_free_file:
fput(file);
sys_close(elf_exec_fileno);
out_free_ph:
kfree(elf_phdata);
goto out;
} }
static int static int
...@@ -809,75 +798,72 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -809,75 +798,72 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
a.out library that is given an ELF header. */ a.out library that is given an ELF header. */
static inline int static inline int
do_load_elf_library(int fd){ do_load_elf_library(int fd)
{
struct file * file; struct file * file;
struct elfhdr elf_ex;
struct elf_phdr *elf_phdata = NULL;
struct dentry * dentry; struct dentry * dentry;
struct inode * inode; struct inode * inode;
unsigned long len; struct elf_phdr *elf_phdata;
int elf_bss; unsigned long elf_bss = 0, bss, len, k;
int retval; int retval, error, i, j;
unsigned long bss; struct elfhdr elf_ex;
int error;
int i,j, k;
len = 0; error = -EACCES;
file = current->files->fd[fd]; file = fget(fd);
if (!file || !file->f_op)
goto out;
dentry = file->f_dentry; dentry = file->f_dentry;
inode = dentry->d_inode; inode = dentry->d_inode;
elf_bss = 0;
if (!file || !file->f_op)
return -EACCES;
/* seek to the beginning of the file */ /* seek to the beginning of the file */
error = -ENOEXEC;
if (file->f_op->llseek) { if (file->f_op->llseek) {
if ((error = file->f_op->llseek(file, 0, 0)) != 0) retval = file->f_op->llseek(file, 0, 0);
return -ENOEXEC; if (retval != 0)
goto out_putf;
} else } else
file->f_pos = 0; file->f_pos = 0;
/* N.B. save current DS?? */
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
error = file->f_op->read(file, (char *) &elf_ex, retval = file->f_op->read(file, (char *) &elf_ex,
sizeof(elf_ex), &file->f_pos); sizeof(elf_ex), &file->f_pos);
set_fs(USER_DS); set_fs(USER_DS);
if (error != sizeof(elf_ex)) if (retval != sizeof(elf_ex))
return -ENOEXEC; goto out_putf;
if (elf_ex.e_ident[0] != 0x7f || if (elf_ex.e_ident[0] != 0x7f ||
strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0)
return -ENOEXEC; goto out_putf;
/* First of all, some simple consistency checks */ /* First of all, some simple consistency checks */
if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
!elf_check_arch(elf_ex.e_machine) || !elf_check_arch(elf_ex.e_machine) ||
(!inode->i_op || !inode->i_op->default_file_ops->mmap)) (!inode->i_op || !inode->i_op->default_file_ops->mmap))
return -ENOEXEC; goto out_putf;
/* Now read in all of the header information */ /* Now read in all of the header information */
if (sizeof(struct elf_phdr) * elf_ex.e_phnum > ELF_EXEC_PAGESIZE) j = sizeof(struct elf_phdr) * elf_ex.e_phnum;
return -ENOEXEC; if (j > ELF_EXEC_PAGESIZE)
goto out_putf;
elf_phdata = (struct elf_phdr *) error = -ENOMEM;
kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL); elf_phdata = (struct elf_phdr *) kmalloc(j, GFP_KERNEL);
if (elf_phdata == NULL) if (!elf_phdata)
return -ENOMEM; goto out_putf;
/* N.B. check for error return?? */
retval = read_exec(dentry, elf_ex.e_phoff, (char *) elf_phdata, retval = read_exec(dentry, elf_ex.e_phoff, (char *) elf_phdata,
sizeof(struct elf_phdr) * elf_ex.e_phnum, 1); sizeof(struct elf_phdr) * elf_ex.e_phnum, 1);
j = 0; error = -ENOEXEC;
for(i=0; i<elf_ex.e_phnum; i++) for (j = 0, i = 0; i<elf_ex.e_phnum; i++)
if ((elf_phdata + i)->p_type == PT_LOAD) j++; if ((elf_phdata + i)->p_type == PT_LOAD) j++;
if (j != 1)
goto out_free_ph;
if (j != 1) { while (elf_phdata->p_type != PT_LOAD) elf_phdata++;
kfree(elf_phdata);
return -ENOEXEC;
}
while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
/* Now use mmap to map the library into memory. */ /* Now use mmap to map the library into memory. */
error = do_mmap(file, error = do_mmap(file,
...@@ -888,25 +874,29 @@ do_load_elf_library(int fd){ ...@@ -888,25 +874,29 @@ do_load_elf_library(int fd){
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
(elf_phdata->p_offset - (elf_phdata->p_offset -
ELF_PAGEOFFSET(elf_phdata->p_vaddr))); ELF_PAGEOFFSET(elf_phdata->p_vaddr)));
if (error != ELF_PAGESTART(elf_phdata->p_vaddr))
goto out_free_ph;
k = elf_phdata->p_vaddr + elf_phdata->p_filesz; k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
if (k > elf_bss) elf_bss = k; if (k > elf_bss)
elf_bss = k;
if (error != ELF_PAGESTART(elf_phdata->p_vaddr)) {
kfree(elf_phdata);
return error;
}
padzero(elf_bss); padzero(elf_bss);
len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr+ ELF_EXEC_PAGESIZE - 1); len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr +
ELF_EXEC_PAGESIZE - 1);
bss = elf_phdata->p_memsz + elf_phdata->p_vaddr; bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
if (bss > len) if (bss > len)
do_mmap(NULL, len, bss-len, do_mmap(NULL, len, bss - len,
PROT_READ|PROT_WRITE|PROT_EXEC, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0); MAP_FIXED|MAP_PRIVATE, 0);
error = 0;
out_free_ph:
kfree(elf_phdata); kfree(elf_phdata);
return 0; out_putf:
fput(file);
out:
return error;
} }
static int load_elf_library(int fd) static int load_elf_library(int fd)
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/sysrq.h> #include <linux/sysrq.h>
#include <linux/file.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -332,31 +333,29 @@ asmlinkage int sys_fsync(unsigned int fd) ...@@ -332,31 +333,29 @@ asmlinkage int sys_fsync(unsigned int fd)
lock_kernel(); lock_kernel();
err = -EBADF; err = -EBADF;
file = fget(fd);
if (fd >= NR_OPEN)
goto out;
file = current->files->fd[fd];
if (!file) if (!file)
goto out; goto out;
dentry = file->f_dentry; dentry = file->f_dentry;
if (!dentry) if (!dentry)
goto out; goto out_putf;
inode = dentry->d_inode; inode = dentry->d_inode;
if (!inode) if (!inode)
goto out; goto out_putf;
err = -EINVAL; err = -EINVAL;
if (!file->f_op || !file->f_op->fsync) if (!file->f_op || !file->f_op->fsync)
goto out; goto out_putf;
/* We need to protect against concurrent writers.. */ /* We need to protect against concurrent writers.. */
down(&inode->i_sem); down(&inode->i_sem);
err = file->f_op->fsync(file, file->f_dentry); err = file->f_op->fsync(file, dentry);
up(&inode->i_sem); up(&inode->i_sem);
out_putf:
fput(file);
out: out:
unlock_kernel(); unlock_kernel();
return err; return err;
...@@ -371,29 +370,27 @@ asmlinkage int sys_fdatasync(unsigned int fd) ...@@ -371,29 +370,27 @@ asmlinkage int sys_fdatasync(unsigned int fd)
lock_kernel(); lock_kernel();
err = -EBADF; err = -EBADF;
file = fget(fd);
if (fd >= NR_OPEN)
goto out;
file = current->files->fd[fd];
if (!file) if (!file)
goto out; goto out;
dentry = file->f_dentry; dentry = file->f_dentry;
if (!dentry) if (!dentry)
goto out; goto out_putf;
inode = dentry->d_inode; inode = dentry->d_inode;
if (!inode) if (!inode)
goto out; goto out_putf;
err = -EINVAL; err = -EINVAL;
if (!file->f_op || !file->f_op->fsync) if (!file->f_op || !file->f_op->fsync)
goto out; goto out_putf;
/* this needs further work, at the moment it is identical to fsync() */ /* this needs further work, at the moment it is identical to fsync() */
err = file->f_op->fsync(file, file->f_dentry); err = file->f_op->fsync(file, dentry);
out_putf:
fput(file);
out: out:
unlock_kernel(); unlock_kernel();
return err; return err;
...@@ -1530,8 +1527,9 @@ void mark_buffer_uptodate(struct buffer_head * bh, int on) ...@@ -1530,8 +1527,9 @@ void mark_buffer_uptodate(struct buffer_head * bh, int on)
* mark_buffer_uptodate() functions propagate buffer state into the * mark_buffer_uptodate() functions propagate buffer state into the
* page struct once IO has completed. * page struct once IO has completed.
*/ */
int generic_readpage(struct dentry * dentry, struct page * page) int generic_readpage(struct file * file, struct page * page)
{ {
struct dentry *dentry = file->f_dentry;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
unsigned long block; unsigned long block;
int *p, nr[PAGE_SIZE/512]; int *p, nr[PAGE_SIZE/512];
......
...@@ -330,7 +330,7 @@ unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm) ...@@ -330,7 +330,7 @@ unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm)
mpnt->vm_flags = VM_STACK_FLAGS; mpnt->vm_flags = VM_STACK_FLAGS;
mpnt->vm_ops = NULL; mpnt->vm_ops = NULL;
mpnt->vm_offset = 0; mpnt->vm_offset = 0;
mpnt->vm_dentry = NULL; mpnt->vm_file = NULL;
mpnt->vm_pte = 0; mpnt->vm_pte = 0;
insert_vm_struct(current->mm, mpnt); insert_vm_struct(current->mm, mpnt);
current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
......
...@@ -32,7 +32,7 @@ static unsigned long fat_file_mmap_nopage( ...@@ -32,7 +32,7 @@ static unsigned long fat_file_mmap_nopage(
unsigned long address, unsigned long address,
int error_code) int error_code)
{ {
struct inode * inode = area->vm_dentry->d_inode; struct inode * inode = area->vm_file->f_dentry->d_inode;
unsigned long page; unsigned long page;
unsigned int clear; unsigned int clear;
int pos; int pos;
...@@ -112,7 +112,8 @@ int fat_mmap(struct file * file, struct vm_area_struct * vma) ...@@ -112,7 +112,8 @@ int fat_mmap(struct file * file, struct vm_area_struct * vma)
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
vma->vm_dentry = dget(file->f_dentry); vma->vm_file = file;
file->f_count++;
vma->vm_ops = &fat_file_mmap; vma->vm_ops = &fat_file_mmap;
return 0; return 0;
} }
......
...@@ -63,7 +63,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, ...@@ -63,7 +63,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Set up the missing parts of the file_lock structure */ /* Set up the missing parts of the file_lock structure */
lock->fl.fl_file = &file->f_file; lock->fl.fl_file = &file->f_file;
lock->fl.fl_owner = host; lock->fl.fl_owner = (fl_owner_t) host;
} }
return 0; return 0;
......
...@@ -128,7 +128,7 @@ nlm_decode_lock(u32 *p, struct nlm_lock *lock) ...@@ -128,7 +128,7 @@ nlm_decode_lock(u32 *p, struct nlm_lock *lock)
return NULL; return NULL;
memset(fl, 0, sizeof(*fl)); memset(fl, 0, sizeof(*fl));
fl->fl_owner = current; fl->fl_owner = current->files;
fl->fl_pid = ntohl(*p++); fl->fl_pid = ntohl(*p++);
fl->fl_flags = FL_POSIX; fl->fl_flags = FL_POSIX;
fl->fl_type = F_RDLCK; /* as good as anything else */ fl->fl_type = F_RDLCK; /* as good as anything else */
......
...@@ -471,10 +471,9 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l) ...@@ -471,10 +471,9 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
* This function is called when the file is being removed * This function is called when the file is being removed
* from the task's fd array. * from the task's fd array.
*/ */
void locks_remove_posix(struct task_struct *task, struct file *filp) void locks_remove_posix(struct file *filp, fl_owner_t owner)
{ {
struct inode * inode = filp->f_dentry->d_inode; struct inode * inode = filp->f_dentry->d_inode;
void * owner = task->files;
struct file_lock file_lock, *fl; struct file_lock file_lock, *fl;
struct file_lock **before; struct file_lock **before;
...@@ -575,7 +574,7 @@ int locks_verify_area(int read_write, struct inode *inode, struct file *filp, ...@@ -575,7 +574,7 @@ int locks_verify_area(int read_write, struct inode *inode, struct file *filp,
int locks_mandatory_locked(struct inode *inode) int locks_mandatory_locked(struct inode *inode)
{ {
void * owner = current->files; fl_owner_t owner = current->files;
struct file_lock *fl; struct file_lock *fl;
/* Search the lock list for this inode for any POSIX locks. /* Search the lock list for this inode for any POSIX locks.
......
...@@ -33,7 +33,8 @@ static inline int min(int a, int b) ...@@ -33,7 +33,8 @@ static inline int min(int a, int b)
static unsigned long ncp_file_mmap_nopage(struct vm_area_struct *area, static unsigned long ncp_file_mmap_nopage(struct vm_area_struct *area,
unsigned long address, int no_share) unsigned long address, int no_share)
{ {
struct dentry *dentry = area->vm_dentry; struct file *file = area->vm_file;
struct dentry *dentry = file->f_dentry;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
unsigned long page; unsigned long page;
unsigned int clear; unsigned int clear;
...@@ -136,7 +137,8 @@ int ncp_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -136,7 +137,8 @@ int ncp_mmap(struct file *file, struct vm_area_struct *vma)
inode->i_atime = CURRENT_TIME; inode->i_atime = CURRENT_TIME;
} }
vma->vm_dentry = dget(file->f_dentry); vma->vm_file = file;
file->f_count++;
vma->vm_ops = &ncp_file_mmap; vma->vm_ops = &ncp_file_mmap;
return 0; return 0;
} }
...@@ -221,8 +221,9 @@ nfs_readpage_async(struct dentry *dentry, struct inode *inode, ...@@ -221,8 +221,9 @@ nfs_readpage_async(struct dentry *dentry, struct inode *inode,
* - The server is congested. * - The server is congested.
*/ */
int int
nfs_readpage(struct dentry *dentry, struct page *page) nfs_readpage(struct file *file, struct page *page)
{ {
struct dentry *dentry = file->f_dentry;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
int error = -1; int error = -1;
......
...@@ -493,8 +493,9 @@ wait_on_write_request(struct nfs_wreq *req) ...@@ -493,8 +493,9 @@ wait_on_write_request(struct nfs_wreq *req)
* (for now), and we currently do this synchronously only. * (for now), and we currently do this synchronously only.
*/ */
int int
nfs_writepage(struct dentry *dentry, struct page *page) nfs_writepage(struct file * file, struct page *page)
{ {
struct dentry *dentry = file->f_dentry;
return nfs_writepage_sync(dentry, dentry->d_inode, page, 0, PAGE_SIZE); return nfs_writepage_sync(dentry, dentry->d_inode, page, 0, PAGE_SIZE);
} }
...@@ -505,9 +506,10 @@ nfs_writepage(struct dentry *dentry, struct page *page) ...@@ -505,9 +506,10 @@ nfs_writepage(struct dentry *dentry, struct page *page)
* things with a page scheduled for an RPC call (e.g. invalidate it). * things with a page scheduled for an RPC call (e.g. invalidate it).
*/ */
int int
nfs_updatepage(struct dentry *dentry, struct page *page, const char *buffer, nfs_updatepage(struct file *file, struct page *page, const char *buffer,
unsigned long offset, unsigned int count, int sync) unsigned long offset, unsigned int count, int sync)
{ {
struct dentry *dentry = file->f_dentry;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
u8 *page_addr = (u8 *) page_address(page); u8 *page_addr = (u8 *) page_address(page);
struct nfs_wreq *req; struct nfs_wreq *req;
......
...@@ -770,7 +770,11 @@ int __fput(struct file *filp) ...@@ -770,7 +770,11 @@ int __fput(struct file *filp)
return error; return error;
} }
int close_fp(struct file *filp) /*
* "id" is the POSIX thread ID. We use the
* files pointer for this..
*/
int close_fp(struct file *filp, fl_owner_t id)
{ {
struct dentry *dentry = filp->f_dentry; struct dentry *dentry = filp->f_dentry;
...@@ -779,7 +783,7 @@ int close_fp(struct file *filp) ...@@ -779,7 +783,7 @@ int close_fp(struct file *filp)
return 0; return 0;
} }
if (dentry->d_inode) if (dentry->d_inode)
locks_remove_posix(current, filp); locks_remove_posix(filp, id);
return fput(filp); return fput(filp);
} }
...@@ -801,7 +805,7 @@ asmlinkage int sys_close(unsigned int fd) ...@@ -801,7 +805,7 @@ asmlinkage int sys_close(unsigned int fd)
put_unused_fd(fd); put_unused_fd(fd);
FD_CLR(fd, &files->close_on_exec); FD_CLR(fd, &files->close_on_exec);
files->fd[fd] = NULL; files->fd[fd] = NULL;
error = close_fp(filp); error = close_fp(filp, files);
} }
unlock_kernel(); unlock_kernel();
return error; return error;
......
...@@ -651,7 +651,7 @@ static inline char * task_mem(struct task_struct *p, char *buffer) ...@@ -651,7 +651,7 @@ static inline char * task_mem(struct task_struct *p, char *buffer)
for (vma = mm->mmap; vma; vma = vma->vm_next) { for (vma = mm->mmap; vma; vma = vma->vm_next) {
unsigned long len = (vma->vm_end - vma->vm_start) >> 10; unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
if (!vma->vm_dentry) { if (!vma->vm_file) {
data += len; data += len;
if (vma->vm_flags & VM_GROWSDOWN) if (vma->vm_flags & VM_GROWSDOWN)
stack += len; stack += len;
...@@ -1049,10 +1049,10 @@ static ssize_t read_maps (int pid, struct file * file, char * buf, ...@@ -1049,10 +1049,10 @@ static ssize_t read_maps (int pid, struct file * file, char * buf,
dev = 0; dev = 0;
ino = 0; ino = 0;
if (map->vm_dentry != NULL) { if (map->vm_file != NULL) {
dev = map->vm_dentry->d_inode->i_dev; dev = map->vm_file->f_dentry->d_inode->i_dev;
ino = map->vm_dentry->d_inode->i_ino; ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_dentry, buffer, PAGE_SIZE); line = d_path(map->vm_file->f_dentry, buffer, PAGE_SIZE);
buffer[PAGE_SIZE-1] = '\n'; buffer[PAGE_SIZE-1] = '\n';
line -= maxlen; line -= maxlen;
if(line < buffer) if(line < buffer)
...@@ -1065,7 +1065,7 @@ static ssize_t read_maps (int pid, struct file * file, char * buf, ...@@ -1065,7 +1065,7 @@ static ssize_t read_maps (int pid, struct file * file, char * buf,
map->vm_start, map->vm_end, str, map->vm_offset, map->vm_start, map->vm_end, str, map->vm_offset,
kdevname(dev), ino); kdevname(dev), ino);
if(map->vm_dentry) { if(map->vm_file) {
for(i = len; i < maxlen; i++) for(i = len; i < maxlen; i++)
line[i] = ' '; line[i] = ' ';
len = buffer + PAGE_SIZE - line; len = buffer + PAGE_SIZE - line;
......
...@@ -105,8 +105,8 @@ static struct dentry * proc_follow_link(struct dentry *dentry, ...@@ -105,8 +105,8 @@ static struct dentry * proc_follow_link(struct dentry *dentry,
break; break;
vma = p->mm->mmap; vma = p->mm->mmap;
while (vma) { while (vma) {
if (vma->vm_flags & VM_EXECUTABLE) if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
return dget(vma->vm_dentry); return dget(vma->vm_file->f_dentry);
vma = vma->vm_next; vma = vma->vm_next;
} }
......
...@@ -418,13 +418,20 @@ extern int init_private_file(struct file *, struct dentry *, int); ...@@ -418,13 +418,20 @@ extern int init_private_file(struct file *, struct dentry *, int);
#define FL_ACCESS 8 /* for processes suspended by mandatory locking */ #define FL_ACCESS 8 /* for processes suspended by mandatory locking */
#define FL_LOCKD 16 /* lock held by rpc.lockd */ #define FL_LOCKD 16 /* lock held by rpc.lockd */
/*
* The POSIX file lock owner is determined by
* the "struct files_struct" in the thread group
* (or NULL for no owner - BSD locks).
*/
typedef struct files_struct *fl_owner_t;
struct file_lock { struct file_lock {
struct file_lock *fl_next; /* singly linked list for this inode */ struct file_lock *fl_next; /* singly linked list for this inode */
struct file_lock *fl_nextlink; /* doubly linked list of all locks */ struct file_lock *fl_nextlink; /* doubly linked list of all locks */
struct file_lock *fl_prevlink; /* used to simplify lock removal */ struct file_lock *fl_prevlink; /* used to simplify lock removal */
struct file_lock *fl_nextblock; /* circular list of blocked processes */ struct file_lock *fl_nextblock; /* circular list of blocked processes */
struct file_lock *fl_prevblock; struct file_lock *fl_prevblock;
void *fl_owner; /* usu. the process' task_struct */ fl_owner_t fl_owner;
unsigned int fl_pid; unsigned int fl_pid;
struct wait_queue *fl_wait; struct wait_queue *fl_wait;
struct file *fl_file; struct file *fl_file;
...@@ -448,7 +455,7 @@ extern int fcntl_getlk(unsigned int fd, struct flock *l); ...@@ -448,7 +455,7 @@ extern int fcntl_getlk(unsigned int fd, struct flock *l);
extern int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l); extern int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l);
/* fs/locks.c */ /* fs/locks.c */
extern void locks_remove_posix(struct task_struct *, struct file *); extern void locks_remove_posix(struct file *, fl_owner_t id);
extern void locks_remove_flock(struct file *); extern void locks_remove_flock(struct file *);
extern struct file_lock *posix_test_lock(struct file *, struct file_lock *); extern struct file_lock *posix_test_lock(struct file *, struct file_lock *);
extern int posix_lock_file(struct file *, struct file_lock *, unsigned int); extern int posix_lock_file(struct file *, struct file_lock *, unsigned int);
...@@ -594,13 +601,13 @@ struct inode_operations { ...@@ -594,13 +601,13 @@ struct inode_operations {
struct inode *, struct dentry *); struct inode *, struct dentry *);
int (*readlink) (struct dentry *, char *,int); int (*readlink) (struct dentry *, char *,int);
struct dentry * (*follow_link) (struct dentry *, struct dentry *); struct dentry * (*follow_link) (struct dentry *, struct dentry *);
int (*readpage) (struct dentry *, struct page *); int (*readpage) (struct file *, struct page *);
int (*writepage) (struct dentry *, struct page *); int (*writepage) (struct file *, struct page *);
int (*bmap) (struct inode *,int); int (*bmap) (struct inode *,int);
void (*truncate) (struct inode *); void (*truncate) (struct inode *);
int (*permission) (struct inode *, int); int (*permission) (struct inode *, int);
int (*smap) (struct inode *,int); int (*smap) (struct inode *,int);
int (*updatepage) (struct dentry *, struct page *, const char *, int (*updatepage) (struct file *, struct page *, const char *,
unsigned long, unsigned int, int); unsigned long, unsigned int, int);
int (*revalidate) (struct dentry *); int (*revalidate) (struct dentry *);
}; };
...@@ -646,7 +653,7 @@ extern int do_truncate(struct dentry *, unsigned long); ...@@ -646,7 +653,7 @@ extern int do_truncate(struct dentry *, unsigned long);
extern int get_unused_fd(void); extern int get_unused_fd(void);
extern void put_unused_fd(unsigned int); extern void put_unused_fd(unsigned int);
extern int __fput(struct file *); extern int __fput(struct file *);
extern int close_fp(struct file *); extern int close_fp(struct file *, fl_owner_t id);
extern char * getname(const char * filename); extern char * getname(const char * filename);
extern void putname(char * name); extern void putname(char * name);
...@@ -796,7 +803,7 @@ extern struct buffer_head * breada(kdev_t dev,int block, int size, ...@@ -796,7 +803,7 @@ extern struct buffer_head * breada(kdev_t dev,int block, int size,
extern int brw_page(int, struct page *, kdev_t, int [], int, int); extern int brw_page(int, struct page *, kdev_t, int [], int, int);
extern int generic_readpage(struct dentry *, struct page *); extern int generic_readpage(struct file *, struct page *);
extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern int generic_file_mmap(struct file *, struct vm_area_struct *);
extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *); extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
extern ssize_t generic_file_write(struct file *, const char*, size_t, loff_t*); extern ssize_t generic_file_write(struct file *, const char*, size_t, loff_t*);
......
...@@ -48,7 +48,7 @@ struct vm_area_struct { ...@@ -48,7 +48,7 @@ struct vm_area_struct {
struct vm_operations_struct * vm_ops; struct vm_operations_struct * vm_ops;
unsigned long vm_offset; unsigned long vm_offset;
struct dentry * vm_dentry; struct file * vm_file;
unsigned long vm_pte; /* shared mem */ unsigned long vm_pte; /* shared mem */
}; };
......
...@@ -210,20 +210,20 @@ extern int nfs_lock(struct file *, int, struct file_lock *); ...@@ -210,20 +210,20 @@ extern int nfs_lock(struct file *, int, struct file_lock *);
/* /*
* linux/fs/nfs/write.c * linux/fs/nfs/write.c
*/ */
extern int nfs_writepage(struct dentry *, struct page *); extern int nfs_writepage(struct file *, struct page *);
extern int nfs_find_dentry_request(struct inode *, struct dentry *); extern int nfs_find_dentry_request(struct inode *, struct dentry *);
extern int nfs_check_failed_request(struct inode *); extern int nfs_check_failed_request(struct inode *);
extern int nfs_check_error(struct inode *); extern int nfs_check_error(struct inode *);
extern int nfs_flush_dirty_pages(struct inode *, pid_t, off_t, off_t); extern int nfs_flush_dirty_pages(struct inode *, pid_t, off_t, off_t);
extern int nfs_truncate_dirty_pages(struct inode *, unsigned long); extern int nfs_truncate_dirty_pages(struct inode *, unsigned long);
extern void nfs_invalidate_pages(struct inode *); extern void nfs_invalidate_pages(struct inode *);
extern int nfs_updatepage(struct dentry *, struct page *, const char *, extern int nfs_updatepage(struct file *, struct page *, const char *,
unsigned long, unsigned int, int); unsigned long, unsigned int, int);
/* /*
* linux/fs/nfs/read.c * linux/fs/nfs/read.c
*/ */
extern int nfs_readpage(struct dentry *, struct page *); extern int nfs_readpage(struct file *, struct page *);
/* /*
* linux/fs/mount_clnt.c * linux/fs/mount_clnt.c
......
...@@ -561,7 +561,7 @@ asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr) ...@@ -561,7 +561,7 @@ asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
shmd->vm_flags = VM_SHM | VM_MAYSHARE | VM_SHARED shmd->vm_flags = VM_SHM | VM_MAYSHARE | VM_SHARED
| VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC
| ((shmflg & SHM_RDONLY) ? 0 : VM_MAYWRITE | VM_WRITE); | ((shmflg & SHM_RDONLY) ? 0 : VM_MAYWRITE | VM_WRITE);
shmd->vm_dentry = NULL; shmd->vm_file = NULL;
shmd->vm_offset = 0; shmd->vm_offset = 0;
shmd->vm_ops = &shm_vm_ops; shmd->vm_ops = &shm_vm_ops;
......
...@@ -164,7 +164,7 @@ static inline void close_files(struct files_struct * files) ...@@ -164,7 +164,7 @@ static inline void close_files(struct files_struct * files)
struct file * file = files->fd[i]; struct file * file = files->fd[i];
if (file) { if (file) {
files->fd[i] = NULL; files->fd[i] = NULL;
close_fp(file); close_fp(file, files);
} }
} }
i++; i++;
......
...@@ -211,7 +211,7 @@ static inline int dup_mmap(struct mm_struct * mm) ...@@ -211,7 +211,7 @@ static inline int dup_mmap(struct mm_struct * mm)
flush_cache_mm(current->mm); flush_cache_mm(current->mm);
pprev = &mm->mmap; pprev = &mm->mmap;
for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) { for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) {
struct dentry *dentry; struct file *file;
retval = -ENOMEM; retval = -ENOMEM;
tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
...@@ -222,11 +222,11 @@ static inline int dup_mmap(struct mm_struct * mm) ...@@ -222,11 +222,11 @@ static inline int dup_mmap(struct mm_struct * mm)
tmp->vm_mm = mm; tmp->vm_mm = mm;
mm->map_count++; mm->map_count++;
tmp->vm_next = NULL; tmp->vm_next = NULL;
dentry = tmp->vm_dentry; file = tmp->vm_file;
if (dentry) { if (file) {
dget(dentry); file->f_count++;
if (tmp->vm_flags & VM_DENYWRITE) if (tmp->vm_flags & VM_DENYWRITE)
dentry->d_inode->i_writecount--; file->f_dentry->d_inode->i_writecount--;
/* insert tmp into the share list, just after mpnt */ /* insert tmp into the share list, just after mpnt */
if((tmp->vm_next_share = mpnt->vm_next_share) != NULL) if((tmp->vm_next_share = mpnt->vm_next_share) != NULL)
......
...@@ -197,6 +197,7 @@ EXPORT_SYMBOL(posix_lock_file); ...@@ -197,6 +197,7 @@ EXPORT_SYMBOL(posix_lock_file);
EXPORT_SYMBOL(posix_test_lock); EXPORT_SYMBOL(posix_test_lock);
EXPORT_SYMBOL(posix_block_lock); EXPORT_SYMBOL(posix_block_lock);
EXPORT_SYMBOL(posix_unblock_lock); EXPORT_SYMBOL(posix_unblock_lock);
EXPORT_SYMBOL(locks_remove_flock);
EXPORT_SYMBOL(dput); EXPORT_SYMBOL(dput);
EXPORT_SYMBOL(get_cached_page); EXPORT_SYMBOL(get_cached_page);
EXPORT_SYMBOL(put_cached_page); EXPORT_SYMBOL(put_cached_page);
...@@ -206,10 +207,6 @@ EXPORT_SYMBOL(shrink_dcache_parent); ...@@ -206,10 +207,6 @@ EXPORT_SYMBOL(shrink_dcache_parent);
EXPORT_SYMBOL(find_inode_number); EXPORT_SYMBOL(find_inode_number);
EXPORT_SYMBOL(is_subdir); EXPORT_SYMBOL(is_subdir);
#ifdef CONFIG_AUTOFS_FS_MODULE
EXPORT_SYMBOL(locks_remove_flock);
#endif
#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE) #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
EXPORT_SYMBOL(do_nfsservctl); EXPORT_SYMBOL(do_nfsservctl);
#endif #endif
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/sysrq.h> #include <linux/sysrq.h>
#include <linux/interrupt.h>
asmlinkage void sys_sync(void); /* it's really int */ asmlinkage void sys_sync(void); /* it's really int */
extern void unblank_console(void); extern void unblank_console(void);
...@@ -42,6 +43,8 @@ NORET_TYPE void panic(const char * fmt, ...) ...@@ -42,6 +43,8 @@ NORET_TYPE void panic(const char * fmt, ...)
printk(KERN_EMERG "Kernel panic: %s\n",buf); printk(KERN_EMERG "Kernel panic: %s\n",buf);
if (current == task[0]) if (current == task[0])
printk(KERN_EMERG "In swapper task - not syncing\n"); printk(KERN_EMERG "In swapper task - not syncing\n");
else if (in_interrupt())
printk(KERN_EMERG "In interrupt handler - not syncing\n");
else else
sys_sync(); sys_sync();
......
...@@ -758,6 +758,7 @@ sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo) ...@@ -758,6 +758,7 @@ sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo)
Nor can they impersonate a kill(), which adds source info. */ Nor can they impersonate a kill(), which adds source info. */
if (info.si_code >= 0) if (info.si_code >= 0)
return -EPERM; return -EPERM;
info.si_signo = sig;
/* POSIX.1b doesn't mention process groups. */ /* POSIX.1b doesn't mention process groups. */
return kill_proc_info(sig, &info, pid); return kill_proc_info(sig, &info, pid);
...@@ -860,7 +861,7 @@ sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset) ...@@ -860,7 +861,7 @@ sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset)
sigdelsetmask(&current->blocked, new_set); sigdelsetmask(&current->blocked, new_set);
break; break;
case SIG_SETMASK: case SIG_SETMASK:
siginitset(&current->blocked, new_set); current->blocked.sig[0] = new_set;
break; break;
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/file.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
...@@ -266,10 +267,10 @@ static inline void add_to_page_cache(struct page * page, ...@@ -266,10 +267,10 @@ static inline void add_to_page_cache(struct page * page,
* that we could use for the cache (if it is 0 we can try to create one, * that we could use for the cache (if it is 0 we can try to create one,
* this is all overlapped with the IO on the previous page finishing anyway) * this is all overlapped with the IO on the previous page finishing anyway)
*/ */
static unsigned long try_to_read_ahead(struct dentry * dentry, static unsigned long try_to_read_ahead(struct file * file,
unsigned long offset, unsigned long page_cache) unsigned long offset, unsigned long page_cache)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = file->f_dentry->d_inode;
struct page * page; struct page * page;
struct page ** hash; struct page ** hash;
...@@ -290,7 +291,7 @@ static unsigned long try_to_read_ahead(struct dentry * dentry, ...@@ -290,7 +291,7 @@ static unsigned long try_to_read_ahead(struct dentry * dentry,
*/ */
page = mem_map + MAP_NR(page_cache); page = mem_map + MAP_NR(page_cache);
add_to_page_cache(page, inode, offset, hash); add_to_page_cache(page, inode, offset, hash);
inode->i_op->readpage(dentry, page); inode->i_op->readpage(file, page);
page_cache = 0; page_cache = 0;
} }
release_page(page); release_page(page);
...@@ -519,7 +520,7 @@ static inline unsigned long generic_file_readahead(int reada_ok, ...@@ -519,7 +520,7 @@ static inline unsigned long generic_file_readahead(int reada_ok,
ahead = 0; ahead = 0;
while (ahead < max_ahead) { while (ahead < max_ahead) {
ahead += PAGE_SIZE; ahead += PAGE_SIZE;
page_cache = try_to_read_ahead(filp->f_dentry, raend + ahead, page_cache = try_to_read_ahead(filp, raend + ahead,
page_cache); page_cache);
} }
/* /*
...@@ -726,7 +727,7 @@ ssize_t generic_file_read(struct file * filp, char * buf, ...@@ -726,7 +727,7 @@ ssize_t generic_file_read(struct file * filp, char * buf,
if (reada_ok && filp->f_ramax > MIN_READAHEAD) if (reada_ok && filp->f_ramax > MIN_READAHEAD)
filp->f_ramax = MIN_READAHEAD; filp->f_ramax = MIN_READAHEAD;
error = inode->i_op->readpage(dentry, page); error = inode->i_op->readpage(filp, page);
if (!error) if (!error)
goto found_page; goto found_page;
release_page(page); release_page(page);
...@@ -738,7 +739,7 @@ ssize_t generic_file_read(struct file * filp, char * buf, ...@@ -738,7 +739,7 @@ ssize_t generic_file_read(struct file * filp, char * buf,
* Try to re-read it _once_. We do this synchronously, * Try to re-read it _once_. We do this synchronously,
* because this happens only if there were errors. * because this happens only if there were errors.
*/ */
error = inode->i_op->readpage(dentry, page); error = inode->i_op->readpage(filp, page);
if (!error) { if (!error) {
wait_on_page(page); wait_on_page(page);
if (PageUptodate(page) && !PageError(page)) if (PageUptodate(page) && !PageError(page))
...@@ -773,7 +774,8 @@ ssize_t generic_file_read(struct file * filp, char * buf, ...@@ -773,7 +774,8 @@ ssize_t generic_file_read(struct file * filp, char * buf,
*/ */
static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share) static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share)
{ {
struct dentry * dentry = area->vm_dentry; struct file * file = area->vm_file;
struct dentry * dentry = file->f_dentry;
struct inode * inode = dentry->d_inode; struct inode * inode = dentry->d_inode;
unsigned long offset; unsigned long offset;
struct page * page, **hash; struct page * page, **hash;
...@@ -857,14 +859,14 @@ static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long ...@@ -857,14 +859,14 @@ static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long
new_page = 0; new_page = 0;
add_to_page_cache(page, inode, offset, hash); add_to_page_cache(page, inode, offset, hash);
if (inode->i_op->readpage(dentry, page) != 0) if (inode->i_op->readpage(file, page) != 0)
goto failure; goto failure;
/* /*
* Do a very limited read-ahead if appropriate * Do a very limited read-ahead if appropriate
*/ */
if (PageLocked(page)) if (PageLocked(page))
new_page = try_to_read_ahead(dentry, offset + PAGE_SIZE, 0); new_page = try_to_read_ahead(file, offset + PAGE_SIZE, 0);
goto found_page; goto found_page;
page_locked_wait: page_locked_wait:
...@@ -879,7 +881,7 @@ static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long ...@@ -879,7 +881,7 @@ static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long
* because there really aren't any performance issues here * because there really aren't any performance issues here
* and we need to check for errors. * and we need to check for errors.
*/ */
if (inode->i_op->readpage(dentry, page) != 0) if (inode->i_op->readpage(file, page) != 0)
goto failure; goto failure;
wait_on_page(page); wait_on_page(page);
if (PageError(page)) if (PageError(page))
...@@ -935,7 +937,7 @@ static int filemap_write_page(struct vm_area_struct * vma, ...@@ -935,7 +937,7 @@ static int filemap_write_page(struct vm_area_struct * vma,
unsigned long page) unsigned long page)
{ {
int result; int result;
struct file file; struct file * file;
struct dentry * dentry; struct dentry * dentry;
struct inode * inode; struct inode * inode;
struct buffer_head * bh; struct buffer_head * bh;
...@@ -955,27 +957,21 @@ static int filemap_write_page(struct vm_area_struct * vma, ...@@ -955,27 +957,21 @@ static int filemap_write_page(struct vm_area_struct * vma,
return 0; return 0;
} }
dentry = vma->vm_dentry; file = vma->vm_file;
dentry = file->f_dentry;
inode = dentry->d_inode; inode = dentry->d_inode;
file.f_op = inode->i_op->default_file_ops; if (!file->f_op->write)
if (!file.f_op->write)
return -EIO; return -EIO;
file.f_mode = 3;
file.f_flags = 0;
file.f_count = 1;
file.f_dentry = dentry;
file.f_pos = offset;
file.f_reada = 0;
/* /*
* If a task terminates while we're swapping the page, the vma and * If a task terminates while we're swapping the page, the vma and
* and dentry could be released ... increment the count to be safe. * and file could be released ... increment the count to be safe.
*/ */
dget(dentry); file->f_count++;
down(&inode->i_sem); down(&inode->i_sem);
result = do_write_page(inode, &file, (const char *) page, offset); result = do_write_page(inode, file, (const char *) page, offset);
up(&inode->i_sem); up(&inode->i_sem);
dput(dentry); fput(file);
return result; return result;
} }
...@@ -1210,7 +1206,8 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma) ...@@ -1210,7 +1206,8 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
if (!inode->i_op || !inode->i_op->readpage) if (!inode->i_op || !inode->i_op->readpage)
return -ENOEXEC; return -ENOEXEC;
UPDATE_ATIME(inode); UPDATE_ATIME(inode);
vma->vm_dentry = dget(file->f_dentry); vma->vm_file = file;
file->f_count++;
vma->vm_ops = ops; vma->vm_ops = ops;
return 0; return 0;
} }
...@@ -1223,15 +1220,16 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma) ...@@ -1223,15 +1220,16 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
static int msync_interval(struct vm_area_struct * vma, static int msync_interval(struct vm_area_struct * vma,
unsigned long start, unsigned long end, int flags) unsigned long start, unsigned long end, int flags)
{ {
if (vma->vm_dentry && vma->vm_ops && vma->vm_ops->sync) { if (vma->vm_file && vma->vm_ops && vma->vm_ops->sync) {
int error; int error;
error = vma->vm_ops->sync(vma, start, end-start, flags); error = vma->vm_ops->sync(vma, start, end-start, flags);
if (!error && (flags & MS_SYNC)) { if (!error && (flags & MS_SYNC)) {
struct dentry * dentry = vma->vm_dentry; struct file * file = vma->vm_file;
if (dentry) { if (file) {
struct dentry * dentry = file->f_dentry;
struct inode * inode = dentry->d_inode; struct inode * inode = dentry->d_inode;
down(&inode->i_sem); down(&inode->i_sem);
error = file_fsync(NULL,dentry); error = file_fsync(file, dentry);
up(&inode->i_sem); up(&inode->i_sem);
} }
} }
...@@ -1382,7 +1380,7 @@ generic_file_write(struct file *file, const char *buf, ...@@ -1382,7 +1380,7 @@ generic_file_write(struct file *file, const char *buf,
status = -EIO; status = -EIO;
if (didread >= 2) if (didread >= 2)
goto done_with_page; goto done_with_page;
status = inode->i_op->readpage(dentry, page); status = inode->i_op->readpage(file, page);
if (status < 0) if (status < 0)
goto done_with_page; goto done_with_page;
didread++; didread++;
...@@ -1402,7 +1400,7 @@ generic_file_write(struct file *file, const char *buf, ...@@ -1402,7 +1400,7 @@ generic_file_write(struct file *file, const char *buf,
do_update_page: do_update_page:
/* Alright, the page is there. Now update it. */ /* Alright, the page is there. Now update it. */
status = inode->i_op->updatepage(dentry, page, buf, status = inode->i_op->updatepage(file, page, buf,
offset, bytes, sync); offset, bytes, sync);
done_with_page: done_with_page:
__free_page(page); __free_page(page);
......
...@@ -38,7 +38,8 @@ static inline int mlock_fixup_start(struct vm_area_struct * vma, ...@@ -38,7 +38,8 @@ static inline int mlock_fixup_start(struct vm_area_struct * vma,
n->vm_end = end; n->vm_end = end;
vma->vm_offset += vma->vm_start - n->vm_start; vma->vm_offset += vma->vm_start - n->vm_start;
n->vm_flags = newflags; n->vm_flags = newflags;
n->vm_dentry = dget(vma->vm_dentry); if (n->vm_file)
n->vm_file->f_count++;
if (n->vm_ops && n->vm_ops->open) if (n->vm_ops && n->vm_ops->open)
n->vm_ops->open(n); n->vm_ops->open(n);
insert_vm_struct(current->mm, n); insert_vm_struct(current->mm, n);
...@@ -58,7 +59,8 @@ static inline int mlock_fixup_end(struct vm_area_struct * vma, ...@@ -58,7 +59,8 @@ static inline int mlock_fixup_end(struct vm_area_struct * vma,
n->vm_start = start; n->vm_start = start;
n->vm_offset += n->vm_start - vma->vm_start; n->vm_offset += n->vm_start - vma->vm_start;
n->vm_flags = newflags; n->vm_flags = newflags;
n->vm_dentry = dget(vma->vm_dentry); if (n->vm_file)
n->vm_file->f_count++;
if (n->vm_ops && n->vm_ops->open) if (n->vm_ops && n->vm_ops->open)
n->vm_ops->open(n); n->vm_ops->open(n);
insert_vm_struct(current->mm, n); insert_vm_struct(current->mm, n);
...@@ -87,8 +89,8 @@ static inline int mlock_fixup_middle(struct vm_area_struct * vma, ...@@ -87,8 +89,8 @@ static inline int mlock_fixup_middle(struct vm_area_struct * vma,
vma->vm_offset += vma->vm_start - left->vm_start; vma->vm_offset += vma->vm_start - left->vm_start;
right->vm_offset += right->vm_start - left->vm_start; right->vm_offset += right->vm_start - left->vm_start;
vma->vm_flags = newflags; vma->vm_flags = newflags;
if (vma->vm_dentry) if (vma->vm_file)
vma->vm_dentry->d_count += 2; vma->vm_file->f_count += 2;
if (vma->vm_ops && vma->vm_ops->open) { if (vma->vm_ops && vma->vm_ops->open) {
vma->vm_ops->open(left); vma->vm_ops->open(left);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/file.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -74,11 +75,11 @@ static inline int vm_enough_memory(long pages) ...@@ -74,11 +75,11 @@ static inline int vm_enough_memory(long pages)
/* Remove one vm structure from the inode's i_mmap ring. */ /* Remove one vm structure from the inode's i_mmap ring. */
static inline void remove_shared_vm_struct(struct vm_area_struct *vma) static inline void remove_shared_vm_struct(struct vm_area_struct *vma)
{ {
struct dentry * dentry = vma->vm_dentry; struct file * file = vma->vm_file;
if (dentry) { if (file) {
if (vma->vm_flags & VM_DENYWRITE) if (vma->vm_flags & VM_DENYWRITE)
dentry->d_inode->i_writecount++; file->f_dentry->d_inode->i_writecount++;
if(vma->vm_next_share) if(vma->vm_next_share)
vma->vm_next_share->vm_pprev_share = vma->vm_pprev_share; vma->vm_next_share->vm_pprev_share = vma->vm_pprev_share;
*vma->vm_pprev_share = vma->vm_next_share; *vma->vm_pprev_share = vma->vm_next_share;
...@@ -261,7 +262,7 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len, ...@@ -261,7 +262,7 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f]; vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
vma->vm_ops = NULL; vma->vm_ops = NULL;
vma->vm_offset = off; vma->vm_offset = off;
vma->vm_dentry = NULL; vma->vm_file = NULL;
vma->vm_pte = 0; vma->vm_pte = 0;
/* Clear old maps */ /* Clear old maps */
...@@ -394,8 +395,8 @@ static int unmap_fixup(struct vm_area_struct *area, unsigned long addr, ...@@ -394,8 +395,8 @@ static int unmap_fixup(struct vm_area_struct *area, unsigned long addr,
if (addr == area->vm_start && end == area->vm_end) { if (addr == area->vm_start && end == area->vm_end) {
if (area->vm_ops && area->vm_ops->close) if (area->vm_ops && area->vm_ops->close)
area->vm_ops->close(area); area->vm_ops->close(area);
if (area->vm_dentry) if (area->vm_file)
dput(area->vm_dentry); fput(area->vm_file);
return 0; return 0;
} }
...@@ -418,7 +419,9 @@ static int unmap_fixup(struct vm_area_struct *area, unsigned long addr, ...@@ -418,7 +419,9 @@ static int unmap_fixup(struct vm_area_struct *area, unsigned long addr,
mpnt->vm_flags = area->vm_flags; mpnt->vm_flags = area->vm_flags;
mpnt->vm_ops = area->vm_ops; mpnt->vm_ops = area->vm_ops;
mpnt->vm_offset = area->vm_offset + (end - area->vm_start); mpnt->vm_offset = area->vm_offset + (end - area->vm_start);
mpnt->vm_dentry = dget(area->vm_dentry); mpnt->vm_file = area->vm_file;
if (mpnt->vm_file)
mpnt->vm_file->f_count++;
if (mpnt->vm_ops && mpnt->vm_ops->open) if (mpnt->vm_ops && mpnt->vm_ops->open)
mpnt->vm_ops->open(mpnt); mpnt->vm_ops->open(mpnt);
area->vm_end = addr; /* Truncate area */ area->vm_end = addr; /* Truncate area */
...@@ -577,8 +580,8 @@ void exit_mmap(struct mm_struct * mm) ...@@ -577,8 +580,8 @@ void exit_mmap(struct mm_struct * mm)
mm->map_count--; mm->map_count--;
remove_shared_vm_struct(mpnt); remove_shared_vm_struct(mpnt);
zap_page_range(mm, start, size); zap_page_range(mm, start, size);
if (mpnt->vm_dentry) if (mpnt->vm_file)
dput(mpnt->vm_dentry); fput(mpnt->vm_file);
kmem_cache_free(vm_area_cachep, mpnt); kmem_cache_free(vm_area_cachep, mpnt);
mpnt = next; mpnt = next;
} }
...@@ -594,7 +597,7 @@ void exit_mmap(struct mm_struct * mm) ...@@ -594,7 +597,7 @@ void exit_mmap(struct mm_struct * mm)
void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp) void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp)
{ {
struct vm_area_struct **pprev = &mm->mmap; struct vm_area_struct **pprev = &mm->mmap;
struct dentry * dentry; struct file * file;
mm->map_count++; mm->map_count++;
...@@ -608,9 +611,9 @@ void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp) ...@@ -608,9 +611,9 @@ void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp)
*pprev = vmp; *pprev = vmp;
vmp->vm_pprev = pprev; vmp->vm_pprev = pprev;
dentry = vmp->vm_dentry; file = vmp->vm_file;
if (dentry) { if (file) {
struct inode * inode = dentry->d_inode; struct inode * inode = file->f_dentry->d_inode;
if (vmp->vm_flags & VM_DENYWRITE) if (vmp->vm_flags & VM_DENYWRITE)
inode->i_writecount--; inode->i_writecount--;
...@@ -657,8 +660,8 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l ...@@ -657,8 +660,8 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l
for ( ; mpnt && prev->vm_start < end_addr ; prev = mpnt, mpnt = next) { for ( ; mpnt && prev->vm_start < end_addr ; prev = mpnt, mpnt = next) {
next = mpnt->vm_next; next = mpnt->vm_next;
/* To share, we must have the same dentry, operations.. */ /* To share, we must have the same file, operations.. */
if ((mpnt->vm_dentry != prev->vm_dentry)|| if ((mpnt->vm_file != prev->vm_file)||
(mpnt->vm_pte != prev->vm_pte) || (mpnt->vm_pte != prev->vm_pte) ||
(mpnt->vm_ops != prev->vm_ops) || (mpnt->vm_ops != prev->vm_ops) ||
(mpnt->vm_flags != prev->vm_flags) || (mpnt->vm_flags != prev->vm_flags) ||
...@@ -666,10 +669,10 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l ...@@ -666,10 +669,10 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l
continue; continue;
/* /*
* If we have a dentry or it's a shared memory area * If we have a file or it's a shared memory area
* the offsets must be contiguous.. * the offsets must be contiguous..
*/ */
if ((mpnt->vm_dentry != NULL) || (mpnt->vm_flags & VM_SHM)) { if ((mpnt->vm_file != NULL) || (mpnt->vm_flags & VM_SHM)) {
unsigned long off = prev->vm_offset+prev->vm_end-prev->vm_start; unsigned long off = prev->vm_offset+prev->vm_end-prev->vm_start;
if (off != mpnt->vm_offset) if (off != mpnt->vm_offset)
continue; continue;
...@@ -691,8 +694,8 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l ...@@ -691,8 +694,8 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l
} }
mm->map_count--; mm->map_count--;
remove_shared_vm_struct(mpnt); remove_shared_vm_struct(mpnt);
if (mpnt->vm_dentry) if (mpnt->vm_file)
dput(mpnt->vm_dentry); fput(mpnt->vm_file);
kmem_cache_free(vm_area_cachep, mpnt); kmem_cache_free(vm_area_cachep, mpnt);
mpnt = prev; mpnt = prev;
} }
......
...@@ -110,7 +110,8 @@ static inline int mprotect_fixup_start(struct vm_area_struct * vma, ...@@ -110,7 +110,8 @@ static inline int mprotect_fixup_start(struct vm_area_struct * vma,
vma->vm_offset += vma->vm_start - n->vm_start; vma->vm_offset += vma->vm_start - n->vm_start;
n->vm_flags = newflags; n->vm_flags = newflags;
n->vm_page_prot = prot; n->vm_page_prot = prot;
n->vm_dentry = dget(n->vm_dentry); if (n->vm_file)
n->vm_file->f_count++;
if (n->vm_ops && n->vm_ops->open) if (n->vm_ops && n->vm_ops->open)
n->vm_ops->open(n); n->vm_ops->open(n);
insert_vm_struct(current->mm, n); insert_vm_struct(current->mm, n);
...@@ -132,7 +133,8 @@ static inline int mprotect_fixup_end(struct vm_area_struct * vma, ...@@ -132,7 +133,8 @@ static inline int mprotect_fixup_end(struct vm_area_struct * vma,
n->vm_offset += n->vm_start - vma->vm_start; n->vm_offset += n->vm_start - vma->vm_start;
n->vm_flags = newflags; n->vm_flags = newflags;
n->vm_page_prot = prot; n->vm_page_prot = prot;
n->vm_dentry = dget(n->vm_dentry); if (n->vm_file)
n->vm_file->f_count++;
if (n->vm_ops && n->vm_ops->open) if (n->vm_ops && n->vm_ops->open)
n->vm_ops->open(n); n->vm_ops->open(n);
insert_vm_struct(current->mm, n); insert_vm_struct(current->mm, n);
...@@ -163,8 +165,8 @@ static inline int mprotect_fixup_middle(struct vm_area_struct * vma, ...@@ -163,8 +165,8 @@ static inline int mprotect_fixup_middle(struct vm_area_struct * vma,
right->vm_offset += right->vm_start - left->vm_start; right->vm_offset += right->vm_start - left->vm_start;
vma->vm_flags = newflags; vma->vm_flags = newflags;
vma->vm_page_prot = prot; vma->vm_page_prot = prot;
if (vma->vm_dentry) if (vma->vm_file)
vma->vm_dentry->d_count += 2; vma->vm_file->f_count += 2;
if (vma->vm_ops && vma->vm_ops->open) { if (vma->vm_ops && vma->vm_ops->open) {
vma->vm_ops->open(left); vma->vm_ops->open(left);
vma->vm_ops->open(right); vma->vm_ops->open(right);
......
...@@ -140,7 +140,9 @@ static inline unsigned long move_vma(struct vm_area_struct * vma, ...@@ -140,7 +140,9 @@ static inline unsigned long move_vma(struct vm_area_struct * vma,
new_vma->vm_start = new_addr; new_vma->vm_start = new_addr;
new_vma->vm_end = new_addr+new_len; new_vma->vm_end = new_addr+new_len;
new_vma->vm_offset = vma->vm_offset + (addr - vma->vm_start); new_vma->vm_offset = vma->vm_offset + (addr - vma->vm_start);
new_vma->vm_dentry = dget(vma->vm_dentry); new_vma->vm_file = vma->vm_file;
if (new_vma->vm_file)
new_vma->vm_file->f_count++;
if (new_vma->vm_ops && new_vma->vm_ops->open) if (new_vma->vm_ops && new_vma->vm_ops->open)
new_vma->vm_ops->open(new_vma); new_vma->vm_ops->open(new_vma);
insert_vm_struct(current->mm, new_vma); insert_vm_struct(current->mm, new_vma);
......
...@@ -111,7 +111,7 @@ void __scm_destroy(struct scm_cookie *scm) ...@@ -111,7 +111,7 @@ void __scm_destroy(struct scm_cookie *scm)
if (fpl) { if (fpl) {
scm->fp = NULL; scm->fp = NULL;
for (i=fpl->count-1; i>=0; i--) for (i=fpl->count-1; i>=0; i--)
close_fp(fpl->fp[i]); fput(fpl->fp[i]);
kfree(fpl); kfree(fpl);
} }
} }
......
...@@ -42,7 +42,7 @@ static unsigned int netlink_poll(struct file *file, poll_table * wait) ...@@ -42,7 +42,7 @@ static unsigned int netlink_poll(struct file *file, poll_table * wait)
if (sock->ops->poll==NULL) if (sock->ops->poll==NULL)
return 0; return 0;
return sock->ops->poll(sock, wait); return sock->ops->poll(file, sock, wait);
} }
/* /*
......
...@@ -48,11 +48,11 @@ ...@@ -48,11 +48,11 @@
#include <linux/udp.h> #include <linux/udp.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/sunrpc/clnt.h> #include <linux/sunrpc/clnt.h>
#include <linux/file.h>
#include <net/sock.h> #include <net/sock.h>
#if LINUX_VERSION_CODE >= 0x020100
#include <asm/uaccess.h> #include <asm/uaccess.h>
#endif
#define SOCK_HAS_USER_DATA #define SOCK_HAS_USER_DATA
...@@ -319,7 +319,7 @@ xprt_close(struct rpc_xprt *xprt) ...@@ -319,7 +319,7 @@ xprt_close(struct rpc_xprt *xprt)
sk->write_space = xprt->old_write_space; sk->write_space = xprt->old_write_space;
if (xprt->file) if (xprt->file)
close_fp(xprt->file); fput(xprt->file);
else else
sock_release(xprt->sock); sock_release(xprt->sock);
} }
......
...@@ -44,11 +44,13 @@ ...@@ -44,11 +44,13 @@
#include <linux/malloc.h> #include <linux/malloc.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/file.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <net/af_unix.h> #include <net/af_unix.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <net/scm.h> #include <net/scm.h>
/* Internal data structures and random procedures: */ /* Internal data structures and random procedures: */
...@@ -275,7 +277,7 @@ void unix_gc(void) ...@@ -275,7 +277,7 @@ void unix_gc(void)
*/ */
if(s->socket && s->socket->file && s->socket->file->f_count) if(s->socket && s->socket->file && s->socket->file->f_count)
close_fp(s->socket->file); fput(s->socket->file);
} }
else else
s->protinfo.af_unix.marksweep&=~MARKED; /* unmark everything for next collection */ s->protinfo.af_unix.marksweep&=~MARKED; /* unmark everything for next collection */
......
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