From 17e3d4ce302b69773344867ac9ca31059344775c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:14:49 -0500 Subject: [PATCH] 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 --- arch/i386/kernel/sys_i386.c | 7 +- arch/m68k/atari/joystick.c | 2 +- arch/sparc/mm/srmmu.c | 11 +- drivers/char/fbmem.c | 3 +- drivers/char/hfmodem/modem.c | 2 +- drivers/char/mem.c | 3 +- drivers/isdn/avmb1/capi.c | 2 +- drivers/sbus/char/pcikbd.c | 2 +- drivers/sbus/char/sunkbd.c | 2 +- drivers/sbus/char/sunmouse.c | 2 +- drivers/sgi/char/shmiq.c | 2 +- drivers/sound/maui.c | 2 +- drivers/sound/sound_firmware.c | 1 + drivers/sound/soundcard.c | 3 +- fs/binfmt_elf.c | 546 ++++++++++++++++----------------- fs/buffer.c | 36 +-- fs/exec.c | 2 +- fs/fat/mmap.c | 5 +- fs/lockd/svcproc.c | 2 +- fs/lockd/xdr.c | 2 +- fs/locks.c | 5 +- fs/ncpfs/mmap.c | 6 +- fs/nfs/read.c | 3 +- fs/nfs/write.c | 6 +- fs/open.c | 10 +- fs/proc/array.c | 12 +- fs/proc/link.c | 4 +- include/linux/fs.h | 21 +- include/linux/mm.h | 2 +- include/linux/nfs_fs.h | 6 +- ipc/shm.c | 2 +- kernel/exit.c | 2 +- kernel/fork.c | 10 +- kernel/ksyms.c | 5 +- kernel/panic.c | 3 + kernel/signal.c | 3 +- mm/filemap.c | 60 ++-- mm/mlock.c | 10 +- mm/mmap.c | 41 +-- mm/mprotect.c | 10 +- mm/mremap.c | 4 +- net/core/scm.c | 2 +- net/netlink/netlink_dev.c | 2 +- net/sunrpc/xprt.c | 6 +- net/unix/garbage.c | 8 +- 45 files changed, 450 insertions(+), 430 deletions(-) diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c index 80ef4be47866..b89b5f89ba6d 100644 --- a/arch/i386/kernel/sys_i386.c +++ b/arch/i386/kernel/sys_i386.c @@ -65,14 +65,17 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg) lock_kernel(); if (copy_from_user(&a, arg, sizeof(a))) - goto out; + goto out; if (!(a.flags & MAP_ANONYMOUS)) { error = -EBADF; - if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd])) + file = fget(a.fd); + if (!file) goto out; } a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset); + if (file) + fput(file); out: unlock_kernel(); return error; diff --git a/arch/m68k/atari/joystick.c b/arch/m68k/atari/joystick.c index 9a1b79be3f34..82eb85288b1f 100644 --- a/arch/m68k/atari/joystick.c +++ b/arch/m68k/atari/joystick.c @@ -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); - poll_wait(&joystick[minor].wait, wait); + poll_wait(file, &joystick[minor].wait, wait); if (joystick[minor].ready) return POLLIN | POLLRDNORM; return 0; diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 5193b28cddb3..b16e3cc1e1b1 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -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)) { struct vm_area_struct *vmaring; - struct dentry *dentry; - struct inode *inode = NULL; + struct file *file; + struct inode *inode; unsigned long flags, offset, vaddr, start; int alias_found = 0; pgd_t *pgdp; @@ -2111,11 +2111,10 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma, save_and_cli(flags); - dentry = vma->vm_dentry; - if(dentry) - inode = dentry->d_inode; - if (!inode) + file = vma->vm_file; + if (!file) goto done; + inode = file->f_dentry->d_inode; offset = (address & PAGE_MASK) - vma->vm_start; vmaring = inode->i_mmap; do { diff --git a/drivers/char/fbmem.c b/drivers/char/fbmem.c index d475413b3cfb..fd2b28ec9773 100644 --- a/drivers/char/fbmem.c +++ b/drivers/char/fbmem.c @@ -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, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; - vma->vm_dentry = dget(file->f_dentry); + vma->vm_file = file; + file->f_count++; return 0; } diff --git a/drivers/char/hfmodem/modem.c b/drivers/char/hfmodem/modem.c index 4b21edd09ea1..02dcad5cc066 100644 --- a/drivers/char/hfmodem/modem.c +++ b/drivers/char/hfmodem/modem.c @@ -561,6 +561,7 @@ unsigned int hfmodem_poll(struct file *file, poll_table *wait) unsigned long flags; int i, cnt1, cnt2; + poll_wait(file, &dev->wait, wait); save_flags(flags); cli(); for (i = cnt1 = cnt2 = 0; i < HFMODEM_NUMTXSLOTS; i++) { @@ -576,7 +577,6 @@ unsigned int hfmodem_poll(struct file *file, poll_table *wait) cnt2++; } restore_flags(flags); - poll_wait(&dev->wait, wait); if (cnt1 || !cnt2) return POLLIN | POLLRDNORM; return 0; diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 5aacad357128..a5c10988e57a 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -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, vma->vm_page_prot)) return -EAGAIN; - vma->vm_dentry = dget(file->f_dentry); + vma->vm_file = file; + file->f_count++; return 0; } diff --git a/drivers/isdn/avmb1/capi.c b/drivers/isdn/avmb1/capi.c index 544ca0e20907..14a5e7d0f052 100644 --- a/drivers/isdn/avmb1/capi.c +++ b/drivers/isdn/avmb1/capi.c @@ -207,7 +207,7 @@ capi_poll(struct file *file, poll_table * wait) return POLLERR; cdev = &capidevs[minor]; - poll_wait(&(cdev->recv_wait), wait); + poll_wait(file, &(cdev->recv_wait), wait); mask = POLLOUT | POLLWRNORM; if (!skb_queue_empty(&cdev->recv_queue)) mask |= POLLIN | POLLRDNORM; diff --git a/drivers/sbus/char/pcikbd.c b/drivers/sbus/char/pcikbd.c index 88333a961524..31485aac8fd0 100644 --- a/drivers/sbus/char/pcikbd.c +++ b/drivers/sbus/char/pcikbd.c @@ -846,7 +846,7 @@ repeat: 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) return POLLIN | POLLRDNORM; return 0; diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c index c72c9b03428e..d55fb5ba5b89 100644 --- a/drivers/sbus/char/sunkbd.c +++ b/drivers/sbus/char/sunkbd.c @@ -1317,7 +1317,7 @@ static int kbd_fasync (struct file *filp, int on) 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) return POLLIN | POLLRDNORM; return 0; diff --git a/drivers/sbus/char/sunmouse.c b/drivers/sbus/char/sunmouse.c index d1c6cd5a892f..0de65c330208 100644 --- a/drivers/sbus/char/sunmouse.c +++ b/drivers/sbus/char/sunmouse.c @@ -420,7 +420,7 @@ sun_mouse_read(struct file *file, char *buffer, 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) return POLLIN | POLLRDNORM; return 0; diff --git a/drivers/sgi/char/shmiq.c b/drivers/sgi/char/shmiq.c index 27365ae5782a..2108d7600645 100644 --- a/drivers/sgi/char/shmiq.c +++ b/drivers/sgi/char/shmiq.c @@ -365,7 +365,7 @@ shmiq_qcntl_poll (struct file *filp, poll_table *wait) if (!shmiqs [minor].mapped) return 0; - poll_wait (&shmiqs [minor].proc_list, wait); + poll_wait (filp, &shmiqs [minor].proc_list, wait); s = shmiqs [minor].shmiq_vaddr; if (s->head != s->tail) return POLLIN | POLLRDNORM; diff --git a/drivers/sound/maui.c b/drivers/sound/maui.c index 32f9d71d825b..5cd620dbff2b 100644 --- a/drivers/sound/maui.c +++ b/drivers/sound/maui.c @@ -211,7 +211,7 @@ static int maui_init(int irq) outb((0x80), HOST_CTRL_PORT); /* Leave reset */ outb((0xD0), HOST_CTRL_PORT); /* Cause interrupt */ -#ifndef __SMP__ +#ifdef __SMP__ for (i = 0; i < 1000000 && !irq_ok; i++); if (!irq_ok) diff --git a/drivers/sound/sound_firmware.c b/drivers/sound/sound_firmware.c index 26d2e171dc9e..cc566e497c99 100644 --- a/drivers/sound/sound_firmware.c +++ b/drivers/sound/sound_firmware.c @@ -5,6 +5,7 @@ #include #include +static int errno; static int do_mod_firmware_load(const char *fn, char **fp) { int fd; diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c index 7f354b78ee53..e23e5486e2a8 100644 --- a/drivers/sound/soundcard.c +++ b/drivers/sound/soundcard.c @@ -732,7 +732,8 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_page_prot)) return -EAGAIN; - vma->vm_dentry = dget(file->f_dentry); + vma->vm_file = file; + file->f_count++; dmap->mapping_flags |= DMA_MAP_MAPPED; diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index ce9d3fbfc00c..aeac9e886f96 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -217,76 +218,60 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, unsigned long *interp_load_addr) { struct file * file; - struct elf_phdr *elf_phdata = NULL; + struct elf_phdr *elf_phdata; struct elf_phdr *eppnt; - unsigned long load_addr; + unsigned long load_addr = 0; int load_addr_set = 0; + unsigned long last_bss = 0, elf_bss = 0; + unsigned long error = ~0UL; int elf_exec_fileno; - int retval; - unsigned long last_bss, elf_bss; - unsigned long error; - int i; - - elf_bss = 0; - last_bss = 0; - error = load_addr = 0; + int retval, i, size; /* First of all, some simple consistency checks */ - if ((interp_elf_ex->e_type != ET_EXEC && - interp_elf_ex->e_type != ET_DYN) || - !elf_check_arch(interp_elf_ex->e_machine) || - (!interpreter_dentry->d_inode->i_op || - !interpreter_dentry->d_inode->i_op->default_file_ops->mmap)){ - return ~0UL; - } - - /* 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 (interp_elf_ex->e_type != ET_EXEC && + interp_elf_ex->e_type != ET_DYN) + goto out; + if (!elf_check_arch(interp_elf_ex->e_machine)) + goto out; + if (!interpreter_dentry->d_inode->i_op || + !interpreter_dentry->d_inode->i_op->default_file_ops->mmap) + goto out; /* * If the size of this structure has changed, then punt, since * we will be doing the wrong thing. */ if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) - { - kfree(elf_phdata); - return ~0UL; - } + goto out; - retval = read_exec(interpreter_dentry, interp_elf_ex->e_phoff, - (char *) elf_phdata, - sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, 1); + /* Now read in all of the header information */ - if (retval < 0) { - kfree (elf_phdata); - return retval; - } + size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum; + if (size > ELF_EXEC_PAGESIZE) + 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); - if (elf_exec_fileno < 0) { - kfree(elf_phdata); - return ~0UL; - } + retval = read_exec(interpreter_dentry, interp_elf_ex->e_phoff, + (char *) elf_phdata, size, 1); + error = retval; + 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; - for(i=0; ie_phnum; i++, eppnt++) + for (i=0; ie_phnum; i++, eppnt++) { if (eppnt->p_type == PT_LOAD) { int elf_type = MAP_PRIVATE | MAP_DENYWRITE; int elf_prot = 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_W) elf_prot |= PROT_WRITE; @@ -301,44 +286,40 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, #endif } - error = do_mmap(file, + map_addr = do_mmap(file, load_addr + ELF_PAGESTART(vaddr), eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), elf_prot, elf_type, eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr)); - - if (error > -1024UL) { - /* Real error */ - sys_close(elf_exec_fileno); - kfree(elf_phdata); - return ~0UL; - } + if (map_addr > -1024UL) /* Real error */ + goto out_close; if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { - load_addr = error; - load_addr_set = 1; + load_addr = map_addr; + load_addr_set = 1; } /* - * Find the end of the file mapping for this phdr, and keep + * Find the end of the file mapping for this phdr, and keep * track of the largest address we see for this. */ 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 * elf_bss and last_bss is the bss section. */ 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. */ - sys_close(elf_exec_fileno); - /* * Now fill out the bss section. First pad the last page up * to the page boundary, and then perform a mmap to make sure @@ -350,53 +331,61 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, /* Map the last of the bss segment */ if (last_bss > elf_bss) - do_mmap(NULL, elf_bss, last_bss-elf_bss, - PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_FIXED|MAP_PRIVATE, 0); - kfree(elf_phdata); + do_mmap(NULL, elf_bss, last_bss - elf_bss, + PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_FIXED|MAP_PRIVATE, 0); *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, struct dentry * interpreter_dentry) { - int retval; - unsigned long elf_entry; - - 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; - - - if (N_MAGIC(*interp_ex) == OMAGIC) { - 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, 32, (char *) 0, - 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(interp_ex->a_text + interp_ex->a_data + ELF_EXEC_PAGESIZE - 1), - interp_ex->a_bss, - PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_FIXED|MAP_PRIVATE, 0); - if (retval < 0) { - return ~0UL; - } - return elf_entry; + unsigned long text_data, offset, elf_entry = ~0UL; + char * addr; + int retval; + + current->mm->end_code = interp_ex->a_text; + text_data = interp_ex->a_text + interp_ex->a_data; + current->mm->end_data = text_data; + 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; + } + + do_mmap(NULL, 0, text_data, + PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0); + retval = read_exec(interpreter_dentry, offset, addr, text_data, 0); + if (retval < 0) + goto out; + + do_mmap(NULL, ELF_PAGESTART(text_data + ELF_EXEC_PAGESIZE - 1), + interp_ex->a_bss, + PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0); + elf_entry = interp_ex->a_entry; + +out: + return elf_entry; } /* @@ -412,174 +401,158 @@ static unsigned long load_aout_interp(struct exec * interp_ex, static inline int 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 exec interp_ex; 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; + char * elf_interpreter = NULL; unsigned int interpreter_type = INTERPRETER_NONE; - unsigned char ibcs2_interpreter; - int i; + unsigned char ibcs2_interpreter = 0; mm_segment_t old_fs; unsigned long error; struct elf_phdr * elf_ppnt, *elf_phdata; - int elf_exec_fileno; unsigned long elf_bss, k, elf_brk; - int retval; - char * elf_interpreter; + int elf_exec_fileno; + int retval, size, i; unsigned long elf_entry, interp_load_addr = 0; - int status; 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]; - ibcs2_interpreter = 0; - status = 0; - 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; - } - + /* Get the exec-header */ + elf_ex = *((struct elfhdr *) bprm->buf); + retval = -ENOEXEC; /* First of all, some simple consistency checks */ - if ((elf_ex.e_type != ET_EXEC && - elf_ex.e_type != ET_DYN) || - (! elf_check_arch(elf_ex.e_machine)) || - (!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)){ - return -ENOEXEC; - } + if (elf_ex.e_ident[0] != 0x7f || + strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0) + goto out; + + if (elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) + 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 */ - elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize * - elf_ex.e_phnum, GFP_KERNEL); - if (elf_phdata == NULL) { - return -ENOMEM; - } + retval = -ENOMEM; + size = elf_ex.e_phentsize * elf_ex.e_phnum; + elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL); + if (!elf_phdata) + goto out; - retval = read_exec(bprm->dentry, elf_ex.e_phoff, (char *) elf_phdata, - elf_ex.e_phentsize * elf_ex.e_phnum, 1); - if (retval < 0) { - kfree (elf_phdata); - return retval; - } + retval = read_exec(bprm->dentry, elf_ex.e_phoff, + (char *) elf_phdata, size, 1); + if (retval < 0) + goto out_free_ph; - 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_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; end_code = 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_interpreter != NULL ) - { - kfree (elf_phdata); - kfree(elf_interpreter); - sys_close(elf_exec_fileno); - return -EINVAL; - } + retval = -EINVAL; + if (elf_interpreter) + goto out_free_interp; /* This is the program interpreter used for * shared libraries - for now assume that this * is an a.out format binary */ + retval = -ENOMEM; elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz, GFP_KERNEL); - if (elf_interpreter == NULL) { - kfree (elf_phdata); - sys_close(elf_exec_fileno); - return -ENOMEM; - } + if (!elf_interpreter) + goto out_free_file; - retval = read_exec(bprm->dentry,elf_ppnt->p_offset, + retval = read_exec(bprm->dentry, elf_ppnt->p_offset, elf_interpreter, elf_ppnt->p_filesz, 1); + if (retval < 0) + goto out_free_interp; /* If the program interpreter is one of these two, - then assume an iBCS2 image. Otherwise assume - a native linux image. */ + * then assume an iBCS2 image. Otherwise assume + * a native linux image. + */ if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 || strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) - ibcs2_interpreter = 1; + ibcs2_interpreter = 1; #if 0 printk("Using ELF interpreter %s\n", elf_interpreter); #endif - if (retval >= 0) { - old_fs = get_fs(); /* This could probably be optimized */ - set_fs(get_ds()); + old_fs = get_fs(); /* This could probably be optimized */ + set_fs(get_ds()); #ifdef __sparc__ - if (ibcs2_interpreter) { - unsigned long old_pers = current->personality; + if (ibcs2_interpreter) { + unsigned long old_pers = current->personality; - current->personality = PER_SVR4; - interpreter_dentry = open_namei(elf_interpreter, 0, 0); - current->personality = old_pers; - } else + current->personality = PER_SVR4; + interpreter_dentry = open_namei(elf_interpreter, + 0, 0); + current->personality = old_pers; + } else #endif - interpreter_dentry = open_namei(elf_interpreter, 0, 0); - set_fs(old_fs); - if (IS_ERR(interpreter_dentry)) - retval = PTR_ERR(interpreter_dentry); - } - - if (retval >= 0) - retval = read_exec(interpreter_dentry,0,bprm->buf,128, 1); - - if (retval >= 0) { - interp_ex = *((struct exec *) bprm->buf); /* exec-header */ - interp_elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ - - } - if (retval < 0) { - kfree (elf_phdata); - kfree(elf_interpreter); - sys_close(elf_exec_fileno); - return retval; - } + interpreter_dentry = open_namei(elf_interpreter, + 0, 0); + set_fs(old_fs); + retval = PTR_ERR(interpreter_dentry); + if (IS_ERR(interpreter_dentry)) + goto out_free_interp; + + retval = read_exec(interpreter_dentry, 0, bprm->buf, + 128, 1); + if (retval < 0) + goto out_free_dentry; + + /* Get the exec headers */ + interp_ex = *((struct exec *) bprm->buf); + interp_elf_ex = *((struct elfhdr *) bprm->buf); } elf_ppnt++; } /* Some simple consistency checks for the interpreter */ - if (elf_interpreter){ + if (elf_interpreter) { interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT; /* Now figure out which format our binary is */ if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) && (N_MAGIC(interp_ex) != QMAGIC)) - interpreter_type = INTERPRETER_ELF; + interpreter_type = INTERPRETER_ELF; if (interp_elf_ex.e_ident[0] != 0x7f || - strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) - interpreter_type &= ~INTERPRETER_ELF; + strncmp(&interp_elf_ex.e_ident[1], "ELF", 3) != 0) + interpreter_type &= ~INTERPRETER_ELF; + retval = -ELIBBAD; if (!interpreter_type) - { - kfree(elf_interpreter); - kfree(elf_phdata); - sys_close(elf_exec_fileno); - return -ELIBBAD; - } + goto out_free_dentry; + + /* Make sure only one type was selected */ + if ((interpreter_type & INTERPRETER_ELF) && + interpreter_type != INTERPRETER_ELF) { + printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n"); + interpreter_type = INTERPRETER_ELF; + } } /* OK, we are done with that, now set up the arg stuff, @@ -597,20 +570,15 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) bprm->argc++; } } - if (!bprm->p) { - if (elf_interpreter) { - kfree(elf_interpreter); - } - kfree (elf_phdata); - sys_close(elf_exec_fileno); - return -E2BIG; - } + retval = -E2BIG; + if (!bprm->p) + goto out_free_dentry; } /* Flush all traces of the currently running executable */ retval = flush_old_exec(bprm); if (retval) - return retval; + goto out_free_dentry; /* OK, This is the point of no return */ current->mm->end_data = 0; @@ -677,15 +645,19 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) k = elf_ppnt->p_vaddr; if (k < start_code) start_code = k; 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) 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; - if (k > elf_brk) elf_brk = k; + if (k > elf_brk) + elf_brk = k; } } set_fs(old_fs); + fput(file); /* all done with the file */ elf_entry += load_bias; elf_bss += load_bias; @@ -695,10 +667,10 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) end_data += load_bias; if (elf_interpreter) { - if (interpreter_type & 1) + if (interpreter_type == INTERPRETER_AOUT) elf_entry = load_aout_interp(&interp_ex, interpreter_dentry); - else if (interpreter_type & 2) + else elf_entry = load_elf_interp(&interp_elf_ex, interpreter_dentry, &interp_load_addr); @@ -707,7 +679,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) kfree(elf_interpreter); if (elf_entry == ~0UL) { - printk("Unable to load interpreter\n"); + printk(KERN_ERR "Unable to load interpreter\n"); kfree(elf_phdata); send_sig(SIGSEGV, current, 0); return 0; @@ -744,16 +716,18 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) load_addr, interp_load_addr, (interpreter_type == INTERPRETER_AOUT ? 0 : 1)); + /* N.B. passed_fileno might not be initialized? */ 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->end_code = end_code; current->mm->start_code = start_code; current->mm->end_data = end_data; current->mm->start_stack = bprm->p; - /* Calling set_brk effectively mmaps the pages that we need for the bss and break - sections */ + /* Calling set_brk effectively mmaps the pages that we need + * for the bss and break sections + */ set_brk(elf_bss, elf_brk); padzero(elf_bss); @@ -773,6 +747,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) and some applications "depend" upon this behavior. Since we do not have the power to recompile these, we 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, MAP_FIXED | MAP_PRIVATE, 0); } @@ -787,11 +762,25 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ELF_PLAT_INIT(regs); #endif - start_thread(regs, elf_entry, bprm->p); if (current->flags & PF_PTRACED) 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 @@ -809,75 +798,72 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) a.out library that is given an ELF header. */ static inline int -do_load_elf_library(int fd){ +do_load_elf_library(int fd) +{ struct file * file; - struct elfhdr elf_ex; - struct elf_phdr *elf_phdata = NULL; struct dentry * dentry; struct inode * inode; - unsigned long len; - int elf_bss; - int retval; - unsigned long bss; - int error; - int i,j, k; + struct elf_phdr *elf_phdata; + unsigned long elf_bss = 0, bss, len, k; + int retval, error, i, j; + struct elfhdr elf_ex; - len = 0; - file = current->files->fd[fd]; + error = -EACCES; + file = fget(fd); + if (!file || !file->f_op) + goto out; dentry = file->f_dentry; inode = dentry->d_inode; - elf_bss = 0; - - if (!file || !file->f_op) - return -EACCES; /* seek to the beginning of the file */ + error = -ENOEXEC; if (file->f_op->llseek) { - if ((error = file->f_op->llseek(file, 0, 0)) != 0) - return -ENOEXEC; + retval = file->f_op->llseek(file, 0, 0); + if (retval != 0) + goto out_putf; } else file->f_pos = 0; + /* N.B. save current 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); set_fs(USER_DS); - if (error != sizeof(elf_ex)) - return -ENOEXEC; + if (retval != sizeof(elf_ex)) + goto out_putf; if (elf_ex.e_ident[0] != 0x7f || - strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) - return -ENOEXEC; + strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0) + goto out_putf; /* First of all, some simple consistency checks */ if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || !elf_check_arch(elf_ex.e_machine) || (!inode->i_op || !inode->i_op->default_file_ops->mmap)) - return -ENOEXEC; + goto out_putf; /* Now read in all of the header information */ - if (sizeof(struct elf_phdr) * elf_ex.e_phnum > ELF_EXEC_PAGESIZE) - return -ENOEXEC; + j = sizeof(struct elf_phdr) * elf_ex.e_phnum; + if (j > ELF_EXEC_PAGESIZE) + goto out_putf; - elf_phdata = (struct elf_phdr *) - kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL); - if (elf_phdata == NULL) - return -ENOMEM; + error = -ENOMEM; + elf_phdata = (struct elf_phdr *) kmalloc(j, GFP_KERNEL); + if (!elf_phdata) + goto out_putf; + /* N.B. check for error return?? */ retval = read_exec(dentry, elf_ex.e_phoff, (char *) elf_phdata, sizeof(struct elf_phdr) * elf_ex.e_phnum, 1); - j = 0; - for(i=0; ip_type == PT_LOAD) j++; + if (j != 1) + goto out_free_ph; - if (j != 1) { - kfree(elf_phdata); - return -ENOEXEC; - } - - while(elf_phdata->p_type != PT_LOAD) elf_phdata++; + while (elf_phdata->p_type != PT_LOAD) elf_phdata++; /* Now use mmap to map the library into memory. */ error = do_mmap(file, @@ -888,25 +874,29 @@ do_load_elf_library(int fd){ MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, (elf_phdata->p_offset - 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; - if (k > elf_bss) elf_bss = k; - - if (error != ELF_PAGESTART(elf_phdata->p_vaddr)) { - kfree(elf_phdata); - return error; - } - + if (k > elf_bss) + elf_bss = k; 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; if (bss > len) - do_mmap(NULL, len, bss-len, - PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_FIXED|MAP_PRIVATE, 0); + do_mmap(NULL, len, bss - len, + PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_FIXED|MAP_PRIVATE, 0); + error = 0; + +out_free_ph: kfree(elf_phdata); - return 0; +out_putf: + fput(file); +out: + return error; } static int load_elf_library(int fd) diff --git a/fs/buffer.c b/fs/buffer.c index ef4d26a569db..07157f6a315a 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -332,31 +333,29 @@ asmlinkage int sys_fsync(unsigned int fd) lock_kernel(); err = -EBADF; - - if (fd >= NR_OPEN) - goto out; - - file = current->files->fd[fd]; + file = fget(fd); if (!file) goto out; dentry = file->f_dentry; if (!dentry) - goto out; + goto out_putf; inode = dentry->d_inode; if (!inode) - goto out; + goto out_putf; err = -EINVAL; if (!file->f_op || !file->f_op->fsync) - goto out; + goto out_putf; /* We need to protect against concurrent writers.. */ down(&inode->i_sem); - err = file->f_op->fsync(file, file->f_dentry); + err = file->f_op->fsync(file, dentry); up(&inode->i_sem); +out_putf: + fput(file); out: unlock_kernel(); return err; @@ -371,29 +370,27 @@ asmlinkage int sys_fdatasync(unsigned int fd) lock_kernel(); err = -EBADF; - - if (fd >= NR_OPEN) - goto out; - - file = current->files->fd[fd]; + file = fget(fd); if (!file) goto out; dentry = file->f_dentry; if (!dentry) - goto out; + goto out_putf; inode = dentry->d_inode; if (!inode) - goto out; + goto out_putf; err = -EINVAL; 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() */ - err = file->f_op->fsync(file, file->f_dentry); + err = file->f_op->fsync(file, dentry); +out_putf: + fput(file); out: unlock_kernel(); return err; @@ -1530,8 +1527,9 @@ void mark_buffer_uptodate(struct buffer_head * bh, int on) * mark_buffer_uptodate() functions propagate buffer state into the * 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; unsigned long block; int *p, nr[PAGE_SIZE/512]; diff --git a/fs/exec.c b/fs/exec.c index 813ac2c4836c..50df2f60d7b9 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -330,7 +330,7 @@ unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm) mpnt->vm_flags = VM_STACK_FLAGS; mpnt->vm_ops = NULL; mpnt->vm_offset = 0; - mpnt->vm_dentry = NULL; + mpnt->vm_file = NULL; mpnt->vm_pte = 0; insert_vm_struct(current->mm, mpnt); current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; diff --git a/fs/fat/mmap.c b/fs/fat/mmap.c index 641c414a7ede..886b20ccbf2d 100644 --- a/fs/fat/mmap.c +++ b/fs/fat/mmap.c @@ -32,7 +32,7 @@ static unsigned long fat_file_mmap_nopage( unsigned long address, 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 int clear; int pos; @@ -112,7 +112,8 @@ int fat_mmap(struct file * file, struct vm_area_struct * vma) mark_inode_dirty(inode); } - vma->vm_dentry = dget(file->f_dentry); + vma->vm_file = file; + file->f_count++; vma->vm_ops = &fat_file_mmap; return 0; } diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index eed15beadd72..585e2957fea5 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -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 */ lock->fl.fl_file = &file->f_file; - lock->fl.fl_owner = host; + lock->fl.fl_owner = (fl_owner_t) host; } return 0; diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index 9c23733ac863..7d41c8a663f2 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c @@ -128,7 +128,7 @@ nlm_decode_lock(u32 *p, struct nlm_lock *lock) return NULL; memset(fl, 0, sizeof(*fl)); - fl->fl_owner = current; + fl->fl_owner = current->files; fl->fl_pid = ntohl(*p++); fl->fl_flags = FL_POSIX; fl->fl_type = F_RDLCK; /* as good as anything else */ diff --git a/fs/locks.c b/fs/locks.c index 22c3b816f8fb..af48a7e55a3d 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -471,10 +471,9 @@ out: * This function is called when the file is being removed * 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; - void * owner = task->files; struct file_lock file_lock, *fl; struct file_lock **before; @@ -575,7 +574,7 @@ int locks_verify_area(int read_write, struct inode *inode, struct file *filp, int locks_mandatory_locked(struct inode *inode) { - void * owner = current->files; + fl_owner_t owner = current->files; struct file_lock *fl; /* Search the lock list for this inode for any POSIX locks. diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c index 2a140ea55dda..2c7610d0b80a 100644 --- a/fs/ncpfs/mmap.c +++ b/fs/ncpfs/mmap.c @@ -33,7 +33,8 @@ static inline int min(int a, int b) static unsigned long ncp_file_mmap_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; unsigned long page; unsigned int clear; @@ -136,7 +137,8 @@ int ncp_mmap(struct file *file, struct vm_area_struct *vma) 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; return 0; } diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 8f32a8ddbd1b..6f1fdd7ffae3 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -221,8 +221,9 @@ out_free: * - The server is congested. */ 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; int error = -1; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index e4bf46f41760..71bdcf6451fc 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -493,8 +493,9 @@ wait_on_write_request(struct nfs_wreq *req) * (for now), and we currently do this synchronously only. */ 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); } @@ -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). */ 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) { + struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; u8 *page_addr = (u8 *) page_address(page); struct nfs_wreq *req; diff --git a/fs/open.c b/fs/open.c index d0caedaa162f..5b0ff99244f8 100644 --- a/fs/open.c +++ b/fs/open.c @@ -770,7 +770,11 @@ int __fput(struct file *filp) 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; @@ -779,7 +783,7 @@ int close_fp(struct file *filp) return 0; } if (dentry->d_inode) - locks_remove_posix(current, filp); + locks_remove_posix(filp, id); return fput(filp); } @@ -801,7 +805,7 @@ asmlinkage int sys_close(unsigned int fd) put_unused_fd(fd); FD_CLR(fd, &files->close_on_exec); files->fd[fd] = NULL; - error = close_fp(filp); + error = close_fp(filp, files); } unlock_kernel(); return error; diff --git a/fs/proc/array.c b/fs/proc/array.c index ae477843b80e..530b21d2c231 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -651,7 +651,7 @@ static inline char * task_mem(struct task_struct *p, char *buffer) for (vma = mm->mmap; vma; vma = vma->vm_next) { unsigned long len = (vma->vm_end - vma->vm_start) >> 10; - if (!vma->vm_dentry) { + if (!vma->vm_file) { data += len; if (vma->vm_flags & VM_GROWSDOWN) stack += len; @@ -1049,10 +1049,10 @@ static ssize_t read_maps (int pid, struct file * file, char * buf, dev = 0; ino = 0; - if (map->vm_dentry != NULL) { - dev = map->vm_dentry->d_inode->i_dev; - ino = map->vm_dentry->d_inode->i_ino; - line = d_path(map->vm_dentry, buffer, PAGE_SIZE); + if (map->vm_file != NULL) { + dev = map->vm_file->f_dentry->d_inode->i_dev; + ino = map->vm_file->f_dentry->d_inode->i_ino; + line = d_path(map->vm_file->f_dentry, buffer, PAGE_SIZE); buffer[PAGE_SIZE-1] = '\n'; line -= maxlen; if(line < buffer) @@ -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, kdevname(dev), ino); - if(map->vm_dentry) { + if(map->vm_file) { for(i = len; i < maxlen; i++) line[i] = ' '; len = buffer + PAGE_SIZE - line; diff --git a/fs/proc/link.c b/fs/proc/link.c index 20acac98bf15..66a01e1afd94 100644 --- a/fs/proc/link.c +++ b/fs/proc/link.c @@ -105,8 +105,8 @@ static struct dentry * proc_follow_link(struct dentry *dentry, break; vma = p->mm->mmap; while (vma) { - if (vma->vm_flags & VM_EXECUTABLE) - return dget(vma->vm_dentry); + if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) + return dget(vma->vm_file->f_dentry); vma = vma->vm_next; } diff --git a/include/linux/fs.h b/include/linux/fs.h index ca31a13f9570..dc1389af0d68 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -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_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 *fl_next; /* singly linked list for this inode */ 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_nextblock; /* circular list of blocked processes */ struct file_lock *fl_prevblock; - void *fl_owner; /* usu. the process' task_struct */ + fl_owner_t fl_owner; unsigned int fl_pid; struct wait_queue *fl_wait; struct file *fl_file; @@ -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); /* 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 struct file_lock *posix_test_lock(struct file *, struct file_lock *); extern int posix_lock_file(struct file *, struct file_lock *, unsigned int); @@ -594,13 +601,13 @@ struct inode_operations { struct inode *, struct dentry *); int (*readlink) (struct dentry *, char *,int); struct dentry * (*follow_link) (struct dentry *, struct dentry *); - int (*readpage) (struct dentry *, struct page *); - int (*writepage) (struct dentry *, struct page *); + int (*readpage) (struct file *, struct page *); + int (*writepage) (struct file *, struct page *); int (*bmap) (struct inode *,int); void (*truncate) (struct inode *); int (*permission) (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); int (*revalidate) (struct dentry *); }; @@ -646,7 +653,7 @@ extern int do_truncate(struct dentry *, unsigned long); extern int get_unused_fd(void); extern void put_unused_fd(unsigned int); 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 void putname(char * name); @@ -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 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 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*); diff --git a/include/linux/mm.h b/include/linux/mm.h index 83aed68c8d94..e294c2f5bfa7 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -48,7 +48,7 @@ struct vm_area_struct { struct vm_operations_struct * vm_ops; unsigned long vm_offset; - struct dentry * vm_dentry; + struct file * vm_file; unsigned long vm_pte; /* shared mem */ }; diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 9a2d8a67f39b..a7b51b977c4b 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -210,20 +210,20 @@ extern int nfs_lock(struct file *, int, struct file_lock *); /* * 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_check_failed_request(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_truncate_dirty_pages(struct inode *, unsigned long); 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); /* * 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 diff --git a/ipc/shm.c b/ipc/shm.c index a476a0dbc4c8..c6c0f0d5b003 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -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 | VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC | ((shmflg & SHM_RDONLY) ? 0 : VM_MAYWRITE | VM_WRITE); - shmd->vm_dentry = NULL; + shmd->vm_file = NULL; shmd->vm_offset = 0; shmd->vm_ops = &shm_vm_ops; diff --git a/kernel/exit.c b/kernel/exit.c index 6f6441f7c946..dfa4c1c464b5 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -164,7 +164,7 @@ static inline void close_files(struct files_struct * files) struct file * file = files->fd[i]; if (file) { files->fd[i] = NULL; - close_fp(file); + close_fp(file, files); } } i++; diff --git a/kernel/fork.c b/kernel/fork.c index 07b03ebe4f21..38c98b0a8a92 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -211,7 +211,7 @@ static inline int dup_mmap(struct mm_struct * mm) flush_cache_mm(current->mm); pprev = &mm->mmap; for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) { - struct dentry *dentry; + struct file *file; retval = -ENOMEM; tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); @@ -222,11 +222,11 @@ static inline int dup_mmap(struct mm_struct * mm) tmp->vm_mm = mm; mm->map_count++; tmp->vm_next = NULL; - dentry = tmp->vm_dentry; - if (dentry) { - dget(dentry); + file = tmp->vm_file; + if (file) { + file->f_count++; 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 */ if((tmp->vm_next_share = mpnt->vm_next_share) != NULL) diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 9b85d2f934fc..3c7ba00695b5 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -197,6 +197,7 @@ EXPORT_SYMBOL(posix_lock_file); EXPORT_SYMBOL(posix_test_lock); EXPORT_SYMBOL(posix_block_lock); EXPORT_SYMBOL(posix_unblock_lock); +EXPORT_SYMBOL(locks_remove_flock); EXPORT_SYMBOL(dput); EXPORT_SYMBOL(get_cached_page); EXPORT_SYMBOL(put_cached_page); @@ -206,10 +207,6 @@ EXPORT_SYMBOL(shrink_dcache_parent); EXPORT_SYMBOL(find_inode_number); EXPORT_SYMBOL(is_subdir); -#ifdef CONFIG_AUTOFS_FS_MODULE -EXPORT_SYMBOL(locks_remove_flock); -#endif - #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE) EXPORT_SYMBOL(do_nfsservctl); #endif diff --git a/kernel/panic.c b/kernel/panic.c index 60e650d585dd..c2f62287f1a9 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -17,6 +17,7 @@ #include #include #include +#include asmlinkage void sys_sync(void); /* it's really int */ extern void unblank_console(void); @@ -42,6 +43,8 @@ NORET_TYPE void panic(const char * fmt, ...) printk(KERN_EMERG "Kernel panic: %s\n",buf); if (current == task[0]) printk(KERN_EMERG "In swapper task - not syncing\n"); + else if (in_interrupt()) + printk(KERN_EMERG "In interrupt handler - not syncing\n"); else sys_sync(); diff --git a/kernel/signal.c b/kernel/signal.c index 6149741a092e..cad8051f2832 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -758,6 +758,7 @@ sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo) Nor can they impersonate a kill(), which adds source info. */ if (info.si_code >= 0) return -EPERM; + info.si_signo = sig; /* POSIX.1b doesn't mention process groups. */ return kill_proc_info(sig, &info, pid); @@ -860,7 +861,7 @@ sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset) sigdelsetmask(¤t->blocked, new_set); break; case SIG_SETMASK: - siginitset(¤t->blocked, new_set); + current->blocked.sig[0] = new_set; break; } diff --git a/mm/filemap.c b/mm/filemap.c index 5cbaca5161f5..019a55c34ee1 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -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, * 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) { - struct inode *inode = dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; struct page * page; struct page ** hash; @@ -290,7 +291,7 @@ static unsigned long try_to_read_ahead(struct dentry * dentry, */ page = mem_map + MAP_NR(page_cache); add_to_page_cache(page, inode, offset, hash); - inode->i_op->readpage(dentry, page); + inode->i_op->readpage(file, page); page_cache = 0; } release_page(page); @@ -519,7 +520,7 @@ static inline unsigned long generic_file_readahead(int reada_ok, ahead = 0; while (ahead < max_ahead) { 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); } /* @@ -726,7 +727,7 @@ no_cached_page: if (reada_ok && 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) goto found_page; release_page(page); @@ -738,7 +739,7 @@ page_read_error: * Try to re-read it _once_. We do this synchronously, * because this happens only if there were errors. */ - error = inode->i_op->readpage(dentry, page); + error = inode->i_op->readpage(filp, page); if (!error) { wait_on_page(page); if (PageUptodate(page) && !PageError(page)) @@ -773,7 +774,8 @@ page_read_error: */ 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; unsigned long offset; struct page * page, **hash; @@ -857,14 +859,14 @@ no_cached_page: new_page = 0; 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; /* * Do a very limited read-ahead if appropriate */ 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; page_locked_wait: @@ -879,7 +881,7 @@ page_read_error: * because there really aren't any performance issues here * 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; wait_on_page(page); if (PageError(page)) @@ -935,7 +937,7 @@ static int filemap_write_page(struct vm_area_struct * vma, unsigned long page) { int result; - struct file file; + struct file * file; struct dentry * dentry; struct inode * inode; struct buffer_head * bh; @@ -955,27 +957,21 @@ static int filemap_write_page(struct vm_area_struct * vma, return 0; } - dentry = vma->vm_dentry; + file = vma->vm_file; + dentry = file->f_dentry; 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; - 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 - * 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); - result = do_write_page(inode, &file, (const char *) page, offset); + result = do_write_page(inode, file, (const char *) page, offset); up(&inode->i_sem); - dput(dentry); + fput(file); return result; } @@ -1210,7 +1206,8 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma) if (!inode->i_op || !inode->i_op->readpage) return -ENOEXEC; UPDATE_ATIME(inode); - vma->vm_dentry = dget(file->f_dentry); + vma->vm_file = file; + file->f_count++; vma->vm_ops = ops; return 0; } @@ -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, 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; error = vma->vm_ops->sync(vma, start, end-start, flags); if (!error && (flags & MS_SYNC)) { - struct dentry * dentry = vma->vm_dentry; - if (dentry) { + struct file * file = vma->vm_file; + if (file) { + struct dentry * dentry = file->f_dentry; struct inode * inode = dentry->d_inode; down(&inode->i_sem); - error = file_fsync(NULL,dentry); + error = file_fsync(file, dentry); up(&inode->i_sem); } } @@ -1382,7 +1380,7 @@ page_wait: status = -EIO; if (didread >= 2) goto done_with_page; - status = inode->i_op->readpage(dentry, page); + status = inode->i_op->readpage(file, page); if (status < 0) goto done_with_page; didread++; @@ -1402,7 +1400,7 @@ page_wait: do_update_page: /* 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); done_with_page: __free_page(page); diff --git a/mm/mlock.c b/mm/mlock.c index eea100addd2f..5bffab93f0b6 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -38,7 +38,8 @@ static inline int mlock_fixup_start(struct vm_area_struct * vma, n->vm_end = end; vma->vm_offset += vma->vm_start - n->vm_start; 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) n->vm_ops->open(n); insert_vm_struct(current->mm, n); @@ -58,7 +59,8 @@ static inline int mlock_fixup_end(struct vm_area_struct * vma, n->vm_start = start; n->vm_offset += n->vm_start - vma->vm_start; 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) n->vm_ops->open(n); insert_vm_struct(current->mm, n); @@ -87,8 +89,8 @@ static inline int mlock_fixup_middle(struct vm_area_struct * vma, vma->vm_offset += vma->vm_start - left->vm_start; right->vm_offset += right->vm_start - left->vm_start; vma->vm_flags = newflags; - if (vma->vm_dentry) - vma->vm_dentry->d_count += 2; + if (vma->vm_file) + vma->vm_file->f_count += 2; if (vma->vm_ops && vma->vm_ops->open) { vma->vm_ops->open(left); diff --git a/mm/mmap.c b/mm/mmap.c index b99229a87900..97ddd89bc6c4 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -74,11 +75,11 @@ static inline int vm_enough_memory(long pages) /* Remove one vm structure from the inode's i_mmap ring. */ 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) - dentry->d_inode->i_writecount++; + file->f_dentry->d_inode->i_writecount++; if(vma->vm_next_share) vma->vm_next_share->vm_pprev_share = vma->vm_pprev_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, vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f]; vma->vm_ops = NULL; vma->vm_offset = off; - vma->vm_dentry = NULL; + vma->vm_file = NULL; vma->vm_pte = 0; /* Clear old maps */ @@ -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 (area->vm_ops && area->vm_ops->close) area->vm_ops->close(area); - if (area->vm_dentry) - dput(area->vm_dentry); + if (area->vm_file) + fput(area->vm_file); return 0; } @@ -418,7 +419,9 @@ static int unmap_fixup(struct vm_area_struct *area, unsigned long addr, mpnt->vm_flags = area->vm_flags; mpnt->vm_ops = area->vm_ops; 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) mpnt->vm_ops->open(mpnt); area->vm_end = addr; /* Truncate area */ @@ -577,8 +580,8 @@ void exit_mmap(struct mm_struct * mm) mm->map_count--; remove_shared_vm_struct(mpnt); zap_page_range(mm, start, size); - if (mpnt->vm_dentry) - dput(mpnt->vm_dentry); + if (mpnt->vm_file) + fput(mpnt->vm_file); kmem_cache_free(vm_area_cachep, mpnt); mpnt = next; } @@ -594,7 +597,7 @@ void exit_mmap(struct mm_struct * mm) void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp) { struct vm_area_struct **pprev = &mm->mmap; - struct dentry * dentry; + struct file * file; mm->map_count++; @@ -608,9 +611,9 @@ void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp) *pprev = vmp; vmp->vm_pprev = pprev; - dentry = vmp->vm_dentry; - if (dentry) { - struct inode * inode = dentry->d_inode; + file = vmp->vm_file; + if (file) { + struct inode * inode = file->f_dentry->d_inode; if (vmp->vm_flags & VM_DENYWRITE) inode->i_writecount--; @@ -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) { next = mpnt->vm_next; - /* To share, we must have the same dentry, operations.. */ - if ((mpnt->vm_dentry != prev->vm_dentry)|| + /* To share, we must have the same file, operations.. */ + if ((mpnt->vm_file != prev->vm_file)|| (mpnt->vm_pte != prev->vm_pte) || (mpnt->vm_ops != prev->vm_ops) || (mpnt->vm_flags != prev->vm_flags) || @@ -666,10 +669,10 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l 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.. */ - 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; if (off != mpnt->vm_offset) continue; @@ -691,8 +694,8 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l } mm->map_count--; remove_shared_vm_struct(mpnt); - if (mpnt->vm_dentry) - dput(mpnt->vm_dentry); + if (mpnt->vm_file) + fput(mpnt->vm_file); kmem_cache_free(vm_area_cachep, mpnt); mpnt = prev; } diff --git a/mm/mprotect.c b/mm/mprotect.c index ddf4f4ed6842..a34225d83b13 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -110,7 +110,8 @@ static inline int mprotect_fixup_start(struct vm_area_struct * vma, vma->vm_offset += vma->vm_start - n->vm_start; n->vm_flags = newflags; 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) n->vm_ops->open(n); insert_vm_struct(current->mm, n); @@ -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_flags = newflags; 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) n->vm_ops->open(n); insert_vm_struct(current->mm, n); @@ -163,8 +165,8 @@ static inline int mprotect_fixup_middle(struct vm_area_struct * vma, right->vm_offset += right->vm_start - left->vm_start; vma->vm_flags = newflags; vma->vm_page_prot = prot; - if (vma->vm_dentry) - vma->vm_dentry->d_count += 2; + if (vma->vm_file) + vma->vm_file->f_count += 2; if (vma->vm_ops && vma->vm_ops->open) { vma->vm_ops->open(left); vma->vm_ops->open(right); diff --git a/mm/mremap.c b/mm/mremap.c index aaabde322f4b..a31a0ae14cf1 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -140,7 +140,9 @@ static inline unsigned long move_vma(struct vm_area_struct * vma, new_vma->vm_start = new_addr; new_vma->vm_end = new_addr+new_len; 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) new_vma->vm_ops->open(new_vma); insert_vm_struct(current->mm, new_vma); diff --git a/net/core/scm.c b/net/core/scm.c index d0d7d9eecc76..3c2beac1a168 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -111,7 +111,7 @@ void __scm_destroy(struct scm_cookie *scm) if (fpl) { scm->fp = NULL; for (i=fpl->count-1; i>=0; i--) - close_fp(fpl->fp[i]); + fput(fpl->fp[i]); kfree(fpl); } } diff --git a/net/netlink/netlink_dev.c b/net/netlink/netlink_dev.c index cbd48c1c0ed8..2a1dd160c05a 100644 --- a/net/netlink/netlink_dev.c +++ b/net/netlink/netlink_dev.c @@ -42,7 +42,7 @@ static unsigned int netlink_poll(struct file *file, poll_table * wait) if (sock->ops->poll==NULL) return 0; - return sock->ops->poll(sock, wait); + return sock->ops->poll(file, sock, wait); } /* diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 1b168e019112..f614cfa33da2 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -48,11 +48,11 @@ #include #include #include +#include + #include -#if LINUX_VERSION_CODE >= 0x020100 #include -#endif #define SOCK_HAS_USER_DATA @@ -319,7 +319,7 @@ xprt_close(struct rpc_xprt *xprt) sk->write_space = xprt->old_write_space; if (xprt->file) - close_fp(xprt->file); + fput(xprt->file); else sock_release(xprt->sock); } diff --git a/net/unix/garbage.c b/net/unix/garbage.c index d68f018fd92a..703fdd41ed78 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -44,11 +44,13 @@ #include #include #include +#include +#include +#include + #include #include #include -#include -#include #include /* Internal data structures and random procedures: */ @@ -275,7 +277,7 @@ tail: */ if(s->socket && s->socket->file && s->socket->file->f_count) - close_fp(s->socket->file); + fput(s->socket->file); } else s->protinfo.af_unix.marksweep&=~MARKED; /* unmark everything for next collection */ -- 2.39.5