]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.45pre4 2.1.45pre4
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:30 +0000 (15:13 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:30 +0000 (15:13 -0500)
72 files changed:
arch/alpha/defconfig
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/process.c
arch/alpha/kernel/traps.c
arch/alpha/mm/fault.c
arch/i386/kernel/process.c
arch/i386/mm/fault.c
drivers/block/rd.c
drivers/char/mem.c
drivers/char/n_tty.c
drivers/char/tty_io.c
drivers/net/8390.c
fs/autofs/inode.c
fs/binfmt_aout.c
fs/binfmt_elf.c
fs/binfmt_em86.c
fs/binfmt_misc.c
fs/binfmt_script.c
fs/buffer.c
fs/dcache.c
fs/dquot.c
fs/exec.c
fs/ext2/super.c
fs/fcntl.c
fs/file_table.c
fs/ioctl.c
fs/isofs/inode.c
fs/lockd/clntlock.c
fs/lockd/clntproc.c
fs/lockd/svclock.c
fs/locks.c
fs/namei.c
fs/nfs/file.c
fs/nfs/inode.c
fs/open.c
fs/pipe.c
fs/proc/array.c
fs/proc/fd.c
fs/proc/inode.c
fs/proc/link.c
fs/read_write.c
fs/readdir.c
fs/stat.c
fs/super.c
include/linux/binfmts.h
include/linux/dcache.h
include/linux/ext2_fs.h
include/linux/file.h
include/linux/fs.h
include/linux/iso_fs.h
include/linux/list.h
include/linux/lockd/lockd.h
include/linux/mm.h
include/linux/proc_fs.h
include/linux/swap.h
ipc/shm.c
kernel/fork.c
kernel/ksyms.c
kernel/sys.c
mm/filemap.c
mm/mlock.c
mm/mmap.c
mm/mprotect.c
mm/mremap.c
mm/page_io.c
mm/swapfile.c
mm/vmscan.c
net/core/scm.c
net/netlink.c
net/socket.c
net/unix/af_unix.c
net/unix/garbage.c

index a32aa827fee0cab7711238718c2b733a1d8fc794..a36ec98a9e150cc190314938e9cf3d2f85bbbdcb 100644 (file)
@@ -66,7 +66,7 @@ CONFIG_BLK_DEV_FD=y
 #
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_RAM=y
+# CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_EZ is not set
index 96ecca700bcd46b4d84929219d3f7e1d82853fb2..f725e2aba563ba351df5cc65358a029eb018fe34 100644 (file)
@@ -135,30 +135,46 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
 {
        int error;
        struct file *file;
+       struct dentry *dentry;
+       struct inode *inode;
        struct osf_dirent_callback buf;
 
-       if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
-               return -EBADF;
-       if (!file->f_op || !file->f_op->readdir)
-               return -ENOTDIR;
-       error = verify_area(VERIFY_WRITE, dirent, count);
-       if (error)
-               return error;
-       if (basep) {
-               error = verify_area(VERIFY_WRITE, basep, sizeof(long));
-               if (error)
-                       return error;
-       }
+       error = -EBADF;
+       if (fd >= NR_OPEN)
+               goto out;
+
+       file = current->files->fd[fd];
+       if (!file)
+               goto out;
+
+       dentry = file->f_dentry;
+       if (!dentry)
+               goto out;
+
+       inode = dentry->d_inode;
+       if (!inode)
+               goto out;
+
        buf.dirent = dirent;
        buf.basep = basep;
        buf.count = count;
        buf.error = 0;
-       error = file->f_op->readdir(file->f_inode, file, &buf, osf_filldir);
+
+       error = -ENOTDIR;
+       if (!file->f_op || !file->f_op->readdir)
+               goto out;
+
+       error = file->f_op->readdir(inode, file, &buf, osf_filldir);
        if (error < 0)
-               return error;
+               goto out;
+
+       error = buf.error;
        if (count == buf.count)
-               return buf.error;
-       return count - buf.count;
+               goto out;
+
+       error = count - buf.count;
+out:
+       return error;
 }
 
 /*
@@ -267,76 +283,73 @@ struct osf_statfs {
        __kernel_fsid_t f_fsid;
 } *osf_stat;
 
-static void linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf_stat)
+static int linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf_stat, unsigned long bufsiz)
 {
-       osf_stat->f_type = linux_stat->f_type;
-       osf_stat->f_flags = 0;  /* mount flags */
+       struct osf_statfs tmp_stat;
+
+       tmp_stat.f_type = linux_stat->f_type;
+       tmp_stat.f_flags = 0;   /* mount flags */
        /* Linux doesn't provide a "fundamental filesystem block size": */
-       osf_stat->f_fsize = linux_stat->f_bsize;
-       osf_stat->f_bsize = linux_stat->f_bsize;
-       osf_stat->f_blocks = linux_stat->f_blocks;
-       osf_stat->f_bfree = linux_stat->f_bfree;
-       osf_stat->f_bavail = linux_stat->f_bavail;
-       osf_stat->f_files = linux_stat->f_files;
-       osf_stat->f_ffree = linux_stat->f_ffree;
-       osf_stat->f_fsid = linux_stat->f_fsid;
+       tmp_stat.f_fsize = linux_stat->f_bsize;
+       tmp_stat.f_bsize = linux_stat->f_bsize;
+       tmp_stat.f_blocks = linux_stat->f_blocks;
+       tmp_stat.f_bfree = linux_stat->f_bfree;
+       tmp_stat.f_bavail = linux_stat->f_bavail;
+       tmp_stat.f_files = linux_stat->f_files;
+       tmp_stat.f_ffree = linux_stat->f_ffree;
+       tmp_stat.f_fsid = linux_stat->f_fsid;
+       if (bufsiz > sizeof(tmp_stat))
+               bufsiz = sizeof(tmp_stat);
+       return copy_to_user(osf_stat, &tmp_stat, bufsiz) ? -EFAULT : 0;
 }
 
+static int do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer, unsigned long bufsiz)
+{
+       struct statfs linux_stat;
+       struct inode * inode = dentry->d_inode;
+       struct super_block * sb = inode->i_sb;
+       int error;
+
+       error = -ENOSYS;
+       if (sb->s_op->statfs) {
+               set_fs(KERNEL_DS);
+               error = sb->s_op->statfs(sb, &linux_stat, sizeof(linux_stat));
+               set_fs(USER_DS);
+               if (!error)
+                       error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz);
+       }
+       return error;   
+}
 
 asmlinkage int osf_statfs(char *path, struct osf_statfs *buffer, unsigned long bufsiz)
 {
-       struct statfs linux_stat;
-       struct inode *inode;
+       struct dentry *dentry;
        int retval;
 
        lock_kernel();
-       if (bufsiz > sizeof(struct osf_statfs))
-                bufsiz = sizeof(struct osf_statfs);
-       retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
-       if (retval)
-               goto out;
-       retval = namei(path, &inode);
-       if (retval)
-               goto out;
-       retval = -ENOSYS;
-       if (!inode->i_sb->s_op->statfs) {
-               iput(inode);
-               goto out;
+       dentry = namei(path);
+       retval = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+               retval = do_osf_statfs(dentry, buffer, bufsiz);
+               dput(dentry);
        }
-       inode->i_sb->s_op->statfs(inode->i_sb, &linux_stat, sizeof(linux_stat));
-       linux_to_osf_statfs(&linux_stat, buffer);
-       iput(inode);
-       retval = 0;
-out:
        unlock_kernel();
        return retval;
 }
 
 asmlinkage int osf_fstatfs(unsigned long fd, struct osf_statfs *buffer, unsigned long bufsiz)
 {
-       struct statfs linux_stat;
        struct file *file;
-       struct inode *inode;
+       struct dentry *dentry;
        int retval;
 
        lock_kernel();
-       retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
-       if (retval)
-               goto out;
-       if (bufsiz > sizeof(struct osf_statfs))
-                bufsiz = sizeof(struct osf_statfs);
        retval = -EBADF;
        if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
                goto out;
-       retval = -ENOENT;
-       if (!(inode = file->f_inode))
-               goto out;
-       retval = -ENOSYS;
-       if (!inode->i_sb->s_op->statfs)
-               goto out;
-       inode->i_sb->s_op->statfs(inode->i_sb, &linux_stat, sizeof(linux_stat));
-       linux_to_osf_statfs(&linux_stat, buffer);
-       retval = 0;
+       dentry = file->f_dentry;
+       if (dentry)
+               retval = do_osf_statfs(dentry, buffer, bufsiz);
 out:
        unlock_kernel();
        return retval;
@@ -369,56 +382,60 @@ struct procfs_args {
        uid_t exroot;
 };
 
-static int getdev(const char *name, int rdonly, struct inode **ino)
+static int getdev(const char *name, int rdonly, struct dentry **dp)
 {
        kdev_t dev;
+       struct dentry *dentry;
        struct inode *inode;
        struct file_operations *fops;
        int retval;
 
-       retval = namei(name, &inode);
-       if (retval)
+       dentry = namei(name);
+       retval = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
                return retval;
+
+       inode = dentry->d_inode;
        if (!S_ISBLK(inode->i_mode)) {
-               iput(inode);
+               dput(dentry);
                return -ENOTBLK;
        }
        if (IS_NODEV(inode)) {
-               iput(inode);
+               dput(dentry);
                return -EACCES;
        }
        dev = inode->i_rdev;
        if (MAJOR(dev) >= MAX_BLKDEV) {
-               iput(inode);
+               dput(dentry);
                return -ENXIO;
        }
        fops = get_blkfops(MAJOR(dev));
        if (!fops) {
-               iput(inode);
+               dput(dentry);
                return -ENODEV;
        }
        if (fops->open) {
                struct file dummy;
                memset(&dummy, 0, sizeof(dummy));
-               dummy.f_inode = inode;
+               dummy.f_dentry = dentry;
                dummy.f_mode = rdonly ? 1 : 3;
                retval = fops->open(inode, &dummy);
                if (retval) {
-                       iput(inode);
+                       dput(dentry);
                        return retval;
                }
        }
-       *ino = inode;
+       *dp = dentry;
        return 0;
 }
 
-static void putdev(struct inode *inode)
+static void putdev(struct dentry *dentry)
 {
        struct file_operations *fops;
 
-       fops = get_blkfops(MAJOR(inode->i_rdev));
+       fops = get_blkfops(MAJOR(dentry->d_inode->i_rdev));
        if (fops->release)
-               fops->release(inode, NULL);
+               fops->release(dentry->d_inode, NULL);
 }
 
 /*
@@ -429,40 +446,40 @@ static void putdev(struct inode *inode)
 static int osf_ufs_mount(char *dirname, struct ufs_args *args, int flags)
 {
        int retval;
-       struct inode *inode;
+       struct dentry *dentry;
        struct cdfs_args tmp;
 
        retval = verify_area(VERIFY_READ, args, sizeof(*args));
        if (retval)
                return retval;
        copy_from_user(&tmp, args, sizeof(tmp));
-       retval = getdev(tmp.devname, 0, &inode);
+       retval = getdev(tmp.devname, 0, &dentry);
        if (retval)
                return retval;
-       retval = do_mount(inode->i_rdev, tmp.devname, dirname, "ext2", flags, NULL);
+       retval = do_mount(dentry->d_inode->i_rdev, tmp.devname, dirname, "ext2", flags, NULL);
        if (retval)
-               putdev(inode);
-       iput(inode);
+               putdev(dentry);
+       dput(dentry);
        return retval;
 }
 
 static int osf_cdfs_mount(char *dirname, struct cdfs_args *args, int flags)
 {
        int retval;
-       struct inode *inode;
+       struct dentry * dentry;
        struct cdfs_args tmp;
 
        retval = verify_area(VERIFY_READ, args, sizeof(*args));
        if (retval)
                return retval;
        copy_from_user(&tmp, args, sizeof(tmp));
-       retval = getdev(tmp.devname, 1, &inode);
+       retval = getdev(tmp.devname, 1, &dentry);
        if (retval)
                return retval;
-       retval = do_mount(inode->i_rdev, tmp.devname, dirname, "iso9660", flags, NULL);
+       retval = do_mount(dentry->d_inode->i_rdev, tmp.devname, dirname, "iso9660", flags, NULL);
        if (retval)
-               putdev(inode);
-       iput(inode);
+               putdev(dentry);
+       dput(dentry);
        return retval;
 }
 
index b6c97e726310ac7b04dab69531261cdc7b0bc2b5..81744663de7df4611b03ca54fba045819ab23b3f 100644 (file)
@@ -308,8 +308,9 @@ asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
        char * filename;
 
        lock_kernel();
-       error = getname((char *) a0, &filename);
-       if (error)
+       filename = getname((char *) a0);
+       error = PTR_ERR(filename);
+       if (IS_ERR(filename))
                goto out;
        error = do_execve(filename, (char **) a1, (char **) a2, &regs);
        putname(filename);
index 02fa5a35d09072b7952bc22c39ac09c67f6de784..c3838a8bbbcc9acc383be75364cf3dbbfdb07d95 100644 (file)
@@ -24,13 +24,14 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err,
                   unsigned long *r9_15)
 {
        long i;
-       unsigned long sp, ra;
+       unsigned long ra;
        unsigned int * pc;
+       unsigned long * sp;
 
        if (regs->ps & 8)
                return;
        printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
-       sp = (unsigned long) (regs+1);
+       sp = (unsigned long *) (regs+1);
        __get_user(ra, (unsigned long *)sp);
        printk("pc = [<%016lx>] ps = %04lx\n", regs->pc, regs->ps);
        printk("rp = [<%016lx>] ra = [<%016lx>]\n", regs->r26, ra);
@@ -54,7 +55,7 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err,
        printk("r22= %016lx  r23= %016lx\n", regs->r22, regs->r23);
        printk("r24= %016lx  r25= %016lx\n", regs->r24, regs->r25);
        printk("r27= %016lx  r28= %016lx\n", regs->r27, regs->r28);
-       printk("gp = %016lx  sp = %016lx\n", regs->gp, sp);
+       printk("gp = %016lx  sp = %p\n", regs->gp, sp);
 
        printk("Code:");
        pc = (unsigned int *) regs->pc;
@@ -65,6 +66,19 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err,
                printk("%c%08x%c",i?' ':'<',insn,i?' ':'>');
        }
        printk("\n");
+       printk("Trace:");
+       while (0x1ff8 & (unsigned long) sp) {
+               extern unsigned long _stext, _etext;
+               unsigned long tmp = *sp;
+               sp++;
+               if (tmp < (unsigned long) &_stext)
+                       continue;
+               if (tmp >= (unsigned long) &_etext)
+                       continue;
+               printk(" [<%lx>]", tmp);
+       }
+       printk("\n");
+                   
        do_exit(SIGSEGV);
 }
 
index a8bc3410819db5589ff2679b477f5006bc2b942b..891dc5ff8905d37e8e07c458736a341f2a7d9bb7 100644 (file)
@@ -108,6 +108,11 @@ good_area:
 bad_area:
        up(&mm->mmap_sem);
 
+       if (user_mode(regs)) {
+               force_sig(SIGSEGV, tsk);
+               return;
+       }
+
        /* Are we prepared to handle this fault as an exception?  */
        if ((fixup = search_exception_table(regs->pc)) != 0) {
                unsigned long newpc;
@@ -117,14 +122,6 @@ bad_area:
                return;
        }
 
-       if (user_mode(regs)) {
-               printk("%s: memory violation at pc=%08lx ra=%08lx "
-                      "(bad address = %08lx)\n",
-                       tsk->comm, regs->pc, regs->r26, address);
-               die_if_kernel("oops", regs, cause, (unsigned long*)regs - 16);
-               force_sig(SIGSEGV, tsk);
-               return;
-       }
 /*
  * Oops. The kernel tried to access some bad page. We'll have to
  * terminate things with extreme prejudice.
index 33842a21fdf80f033bca511eaa575f38d88106c5..eec1ba62ee0d7f6b04a286a4ebfc50c4bd61831c 100644 (file)
@@ -623,8 +623,9 @@ asmlinkage int sys_execve(struct pt_regs regs)
        char * filename;
 
        lock_kernel();
-       error = getname((char *) regs.ebx, &filename);
-       if (error)
+       filename = getname((char *) regs.ebx);
+       error = PTR_ERR(filename);
+       if (IS_ERR(filename)
                goto out;
        error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, &regs);
        putname(filename);
index b0404a6a97637dfb0e4551c7cf4cdf32725e06b7..d0b2d58fed0caf7302d550f260e2f298ebe3e72b 100644 (file)
@@ -161,7 +161,16 @@ good_area:
 bad_area:
        up(&mm->mmap_sem);
 
-       /* Are we prepared to handle this fault?  */
+       /* User mode accesses just cause a SIGSEGV */
+       if (error_code & 4) {
+               tsk->tss.cr2 = address;
+               tsk->tss.error_code = error_code;
+               tsk->tss.trap_no = 14;
+               force_sig(SIGSEGV, tsk);
+               goto out;
+       }
+
+       /* Are we prepared to handle this kernel fault?  */
        if ((fixup = search_exception_table(regs->eip)) != 0) {
                printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n",
                        current->comm,
@@ -171,13 +180,6 @@ bad_area:
                goto out;
        }
 
-       if (error_code & 4) {
-               tsk->tss.cr2 = address;
-               tsk->tss.error_code = error_code;
-               tsk->tss.trap_no = 14;
-               force_sig(SIGSEGV, tsk);
-               goto out;
-       }
 /*
  * Oops. The kernel tried to access some bad page. We'll have to
  * terminate things with extreme prejudice.
index 4ac6c0c41a47addf0152ff05910ce22516688b2b..fea666f7cfb332ba51fb5ded1e12092d338070e7 100644 (file)
@@ -360,10 +360,10 @@ identify_ramdisk_image(kdev_t device, struct file *fp, int start_block))
         * Read block 0 to test for gzipped kernel
         */
        if (fp->f_op->llseek)
-               fp->f_op->llseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
+               fp->f_op->llseek(fp->f_dentry->d_inode, fp, start_block * BLOCK_SIZE, 0);
        fp->f_pos = start_block * BLOCK_SIZE;
        
-       fp->f_op->read(fp->f_inode, fp, buf, size);
+       fp->f_op->read(fp->f_dentry->d_inode, fp, buf, size);
 
        /*
         * If it matches the gzip magic numbers, return -1
@@ -390,11 +390,11 @@ identify_ramdisk_image(kdev_t device, struct file *fp, int start_block))
         * Read block 1 to test for minix and ext2 superblock
         */
        if (fp->f_op->llseek)
-               fp->f_op->llseek(fp->f_inode, fp,
+               fp->f_op->llseek(fp->f_dentry->d_inode, fp,
                                (start_block+1) * BLOCK_SIZE, 0);
        fp->f_pos = (start_block+1) * BLOCK_SIZE;
 
-       fp->f_op->read(fp->f_inode, fp, buf, size);
+       fp->f_op->read(fp->f_dentry->d_inode, fp, buf, size);
                
        /* Try minix */
        if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
@@ -421,7 +421,7 @@ identify_ramdisk_image(kdev_t device, struct file *fp, int start_block))
        
 done:
        if (fp->f_op->llseek)
-               fp->f_op->llseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
+               fp->f_op->llseek(fp->f_dentry->d_inode, fp, start_block * BLOCK_SIZE, 0);
        fp->f_pos = start_block * BLOCK_SIZE;   
 
        if ((nblocks > 0) && blk_size[MAJOR(device)]) {
index 499132bf8940eb9217298cd8fccd544df173fe59..3ea9d3b8612fbfdc93bfa36f785c5cef6c6b5c6c 100644 (file)
@@ -134,8 +134,7 @@ static int mmap_mem(struct inode * inode, struct file * file, struct vm_area_str
 #endif
        if (remap_page_range(vma->vm_start, offset, vma->vm_end - vma->vm_start, vma->vm_page_prot))
                return -EAGAIN;
-       vma->vm_inode = inode;
-       atomic_inc(&inode->i_count);
+       vma->vm_dentry = dget(file->f_dentry);
        return 0;
 }
 
index a5f37f507758081e6d628ac91cf4df46f5fe481d..9603237908dac8a72555f43cc667a00edb26d332 100644 (file)
@@ -854,7 +854,7 @@ do_it_again:
        /* NOTE: not yet done after every sleep pending a thorough
           check of the logic of this change. -- jlc */
        /* don't stop on /dev/console */
-       if (file->f_inode->i_rdev != CONSOLE_DEV &&
+       if (file->f_dentry->d_inode->i_rdev != CONSOLE_DEV &&
            current->tty == tty) {
                if (tty->pgrp <= 0)
                        printk("read_chan: tty->pgrp <= 0!\n");
@@ -1013,7 +1013,7 @@ static int write_chan(struct tty_struct * tty, struct file * file,
        int retval = 0;
 
        /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
-       if (L_TOSTOP(tty) && file->f_inode->i_rdev != CONSOLE_DEV) {
+       if (L_TOSTOP(tty) && file->f_dentry->d_inode->i_rdev != CONSOLE_DEV) {
                retval = tty_check_change(tty);
                if (retval)
                        return retval;
index be5e75fe8bedc1cc2876cae351b4a88c2355043d..3bef39f0007c0fd0503fb981d049c9c228b824dd 100644 (file)
@@ -373,13 +373,15 @@ void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops)
        for (filp = inuse_filps; filp; filp = filp->f_next) {
                if (filp->private_data != tty)
                        continue;
-               if (!filp->f_inode)
+               if (!filp->f_dentry)
                        continue;
-               if (filp->f_inode->i_rdev == CONSOLE_DEV)
+               if (!filp->f_dentry->d_inode)
+                       continue;
+               if (filp->f_dentry->d_inode->i_rdev == CONSOLE_DEV)
                        continue;
                if (filp->f_op != &tty_fops)
                        continue;
-               tty_fasync(filp->f_inode, filp, 0);
+               tty_fasync(filp->f_dentry->d_inode, filp, 0);
                filp->f_op = fops;
        }
        
@@ -919,12 +921,12 @@ static void release_dev(struct file * filp)
        int     idx;
        
        tty = (struct tty_struct *)filp->private_data;
-       if (tty_paranoia_check(tty, filp->f_inode->i_rdev, "release_dev"))
+       if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "release_dev"))
                return;
 
        check_tty_count(tty, "release_dev");
 
-       tty_fasync(filp->f_inode, filp, 0);
+       tty_fasync(filp->f_dentry->d_inode, filp, 0);
 
        idx = MINOR(tty->device) - tty->driver.minor_start;
        pty_master = (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
@@ -1248,7 +1250,7 @@ static unsigned int tty_poll(struct file * filp, poll_table * wait)
        struct tty_struct * tty;
 
        tty = (struct tty_struct *)filp->private_data;
-       if (tty_paranoia_check(tty, filp->f_inode->i_rdev, "tty_poll"))
+       if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "tty_poll"))
                return 0;
 
        if (tty->ldisc.poll)
index fbf67cb423b51f9b9b97a774eecdde7be8a4b666..1150ddcf465bb6e1c5510a78597ee0c7f5c330e1 100644 (file)
@@ -186,6 +186,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
 
     /* Mask interrupts from the ethercard. */
     outb_p(0x00, e8390_base + EN0_IMR);
+    synchronize_irq();
     if (dev->interrupt) {
        printk("%s: Tx request while isr active.\n",dev->name);
        outb_p(ENISR_ALL, e8390_base + EN0_IMR);
index d52633024deb9f8bb6f775bc71a6f638d530ebe9..f7c8977c5e236ce6f58c01f28fa6774f49cf2597 100644 (file)
@@ -21,9 +21,9 @@
 
 static void autofs_put_inode(struct inode *inode)
 {
-        if (inode->i_nlink)
-                return;
-        inode->i_size = 0;
+       if (inode->i_nlink)
+               return;
+       inode->i_size = 0;
 }
 
 static void autofs_put_super(struct super_block *sb)
@@ -35,16 +35,16 @@ static void autofs_put_super(struct super_block *sb)
        if ( !sbi->catatonic )
                autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */
 
-        lock_super(sb);
+       lock_super(sb);
        autofs_hash_nuke(&sbi->dirhash);
        for ( n = 0 ; n < AUTOFS_MAX_SYMLINKS ; n++ ) {
                if ( test_bit(n, sbi->symlink_bitmap) )
                        kfree(sbi->symlink[n].data);
        }
 
-        sb->s_dev = 0;
+       sb->s_dev = 0;
        kfree(sb->u.generic_sbp);
-        unlock_super(sb);
+       unlock_super(sb);
 
        DPRINTK(("autofs: shutting down\n"));
        
@@ -53,95 +53,95 @@ static void autofs_put_super(struct super_block *sb)
 #endif
 }
 
-static void autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
+static int autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
 static void autofs_read_inode(struct inode *inode);
 static void autofs_write_inode(struct inode *inode);
 
 static struct super_operations autofs_sops = {
-        autofs_read_inode,
-        NULL,
-        autofs_write_inode,
-        autofs_put_inode,
-        autofs_put_super,
-        NULL,
-        autofs_statfs,
-        NULL
+       autofs_read_inode,
+       NULL,
+       autofs_write_inode,
+       autofs_put_inode,
+       autofs_put_super,
+       NULL,
+       autofs_statfs,
+       NULL
 };
 
 static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid_t *pgrp, int *minproto, int *maxproto)
 {
-        char *this_char, *value;
-        
-        *uid = current->uid;
-        *gid = current->gid;
+       char *this_char, *value;
+       
+       *uid = current->uid;
+       *gid = current->gid;
        *pgrp = current->pgrp;
 
        *minproto = *maxproto = AUTOFS_PROTO_VERSION;
 
-        *pipefd = -1;
+       *pipefd = -1;
 
-        if ( !options ) return 1;
-        for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
-                if ((value = strchr(this_char,'=')) != NULL)
-                        *value++ = 0;
-                if (!strcmp(this_char,"fd")) {
-                        if (!value || !*value)
-                                return 1;
-                        *pipefd = simple_strtoul(value,&value,0);
-                        if (*value)
-                                return 1;
-                }
-                else if (!strcmp(this_char,"uid")) {
-                        if (!value || !*value)
-                                return 1;
-                        *uid = simple_strtoul(value,&value,0);
-                        if (*value)
-                                return 1;
-                }
-                else if (!strcmp(this_char,"gid")) {
-                        if (!value || !*value)
-                                return 1;
-                        *gid = simple_strtoul(value,&value,0);
-                        if (*value)
-                                return 1;
-                }
-                else if (!strcmp(this_char,"pgrp")) {
-                        if (!value || !*value)
-                                return 1;
-                        *pgrp = simple_strtoul(value,&value,0);
-                        if (*value)
-                                return 1;
-                }
-                else if (!strcmp(this_char,"minproto")) {
-                        if (!value || !*value)
-                                return 1;
-                        *minproto = simple_strtoul(value,&value,0);
-                        if (*value)
-                                return 1;
-                }
-                else if (!strcmp(this_char,"maxproto")) {
-                        if (!value || !*value)
-                                return 1;
-                        *maxproto = simple_strtoul(value,&value,0);
-                        if (*value)
-                                return 1;
-                }
-                else break;
-        }
-        return (*pipefd < 0);
+       if ( !options ) return 1;
+       for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
+               if ((value = strchr(this_char,'=')) != NULL)
+                       *value++ = 0;
+               if (!strcmp(this_char,"fd")) {
+                       if (!value || !*value)
+                               return 1;
+                       *pipefd = simple_strtoul(value,&value,0);
+                       if (*value)
+                               return 1;
+               }
+               else if (!strcmp(this_char,"uid")) {
+                       if (!value || !*value)
+                               return 1;
+                       *uid = simple_strtoul(value,&value,0);
+                       if (*value)
+                               return 1;
+               }
+               else if (!strcmp(this_char,"gid")) {
+                       if (!value || !*value)
+                               return 1;
+                       *gid = simple_strtoul(value,&value,0);
+                       if (*value)
+                               return 1;
+               }
+               else if (!strcmp(this_char,"pgrp")) {
+                       if (!value || !*value)
+                               return 1;
+                       *pgrp = simple_strtoul(value,&value,0);
+                       if (*value)
+                               return 1;
+               }
+               else if (!strcmp(this_char,"minproto")) {
+                       if (!value || !*value)
+                               return 1;
+                       *minproto = simple_strtoul(value,&value,0);
+                       if (*value)
+                               return 1;
+               }
+               else if (!strcmp(this_char,"maxproto")) {
+                       if (!value || !*value)
+                               return 1;
+                       *maxproto = simple_strtoul(value,&value,0);
+                       if (*value)
+                               return 1;
+               }
+               else break;
+       }
+       return (*pipefd < 0);
 }
 
 struct super_block *autofs_read_super(struct super_block *s, void *data,
-                                      int silent)
+                                     int silent)
 {
-        int pipefd;
+       int pipefd;
        struct autofs_sb_info *sbi;
        int minproto, maxproto;
 
        MOD_INC_USE_COUNT;
 
-        lock_super(s);
-        sbi = (struct autofs_sb_info *) kmalloc(sizeof(struct autofs_sb_info), GFP_KERNEL);
+       lock_super(s);
+       sbi = (struct autofs_sb_info *) kmalloc(sizeof(struct autofs_sb_info), GFP_KERNEL);
        if ( !sbi ) {
                s->s_dev = 0;
                MOD_DEC_USE_COUNT;
@@ -158,28 +158,28 @@ struct super_block *autofs_read_super(struct super_block *s, void *data,
        sbi->queues = NULL;
        memset(sbi->symlink_bitmap, 0, sizeof(u32)*AUTOFS_SYMLINK_BITMAP_LEN);
        sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO;
-        s->s_blocksize = 1024;
-        s->s_blocksize_bits = 10;
-        s->s_magic = AUTOFS_SUPER_MAGIC;
-        s->s_op = &autofs_sops;
-        unlock_super(s);
-        s->s_root = d_alloc_root(iget(s, AUTOFS_ROOT_INO), NULL);
-        if (!s->s_root) {
-                s->s_dev = 0;
+       s->s_blocksize = 1024;
+       s->s_blocksize_bits = 10;
+       s->s_magic = AUTOFS_SUPER_MAGIC;
+       s->s_op = &autofs_sops;
+       unlock_super(s);
+       s->s_root = d_alloc_root(iget(s, AUTOFS_ROOT_INO), NULL);
+       if (!s->s_root) {
+               s->s_dev = 0;
                kfree(sbi);
-                printk("autofs: get root inode failed\n");
+               printk("autofs: get root inode failed\n");
                MOD_DEC_USE_COUNT;
-                return NULL;
-        }
+               return NULL;
+       }
 
-        if ( parse_options(data,&pipefd,&s->s_root->d_inode->i_uid,&s->s_root->d_inode->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) {
-               d_delete(s->s_root);
-                s->s_dev = 0;
+       if ( parse_options(data,&pipefd,&s->s_root->d_inode->i_uid,&s->s_root->d_inode->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) {
+               d_delete(s->s_root);
+               s->s_dev = 0;
                kfree(sbi);
-                printk("autofs: called with bogus options\n");
+               printk("autofs: called with bogus options\n");
                MOD_DEC_USE_COUNT;
-                return NULL;
-        }
+               return NULL;
+       }
 
        if ( minproto > AUTOFS_PROTO_VERSION || maxproto < AUTOFS_PROTO_VERSION ) {
                d_delete(s->s_root);
@@ -205,49 +205,49 @@ struct super_block *autofs_read_super(struct super_block *s, void *data,
                MOD_DEC_USE_COUNT;
                return NULL;
        }
-        return s;
+       return s;
 }
 
-static void autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+static int autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
 {
-        struct statfs tmp;
+       struct statfs tmp;
 
-        tmp.f_type = AUTOFS_SUPER_MAGIC;
-        tmp.f_bsize = 1024;
-        tmp.f_blocks = 0;
-        tmp.f_bfree = 0;
-        tmp.f_bavail = 0;
-        tmp.f_files = 0;
-        tmp.f_ffree = 0;
-        tmp.f_namelen = NAME_MAX;
-        copy_to_user(buf, &tmp, bufsiz);
+       tmp.f_type = AUTOFS_SUPER_MAGIC;
+       tmp.f_bsize = 1024;
+       tmp.f_blocks = 0;
+       tmp.f_bfree = 0;
+       tmp.f_bavail = 0;
+       tmp.f_files = 0;
+       tmp.f_ffree = 0;
+       tmp.f_namelen = NAME_MAX;
+       return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
 }
 
 static void autofs_read_inode(struct inode *inode)
 {
-        ino_t ino = inode->i_ino;
+       ino_t ino = inode->i_ino;
        unsigned int n;
-        struct autofs_sb_info *sbi =
+       struct autofs_sb_info *sbi =
                (struct autofs_sb_info *) inode->i_sb->u.generic_sbp;
 
-        inode->i_op = NULL;
-        inode->i_mode = 0;
-        inode->i_nlink = 2;
-        inode->i_size = 0;
-        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-        inode->i_blocks = 0;
-        inode->i_blksize = 1024;
+       inode->i_op = NULL;
+       inode->i_mode = 0;
+       inode->i_nlink = 2;
+       inode->i_size = 0;
+       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+       inode->i_blocks = 0;
+       inode->i_blksize = 1024;
 
-        if ( ino == AUTOFS_ROOT_INO ) {
-                inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
-                inode->i_op = &autofs_root_inode_operations;
+       if ( ino == AUTOFS_ROOT_INO ) {
+               inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
+               inode->i_op = &autofs_root_inode_operations;
                inode->i_uid = inode->i_gid = 0; /* Changed in read_super */
-                return;
-        } 
+               return;
+       } 
+       
+       inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
+       inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
        
-        inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
-        inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
-        
        if ( ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO ) {
                /* Symlink inode - should be in symlink list */
                struct autofs_symlink *sl;
index c5d3b299d834ed0cec5f28cae676064fd47f53d9..ca5c98014ad9262a56c7cd027edbc294c42da3b2 100644 (file)
@@ -79,6 +79,7 @@ if (file.f_op->llseek) { \
 static inline int
 do_aout_core_dump(long signr, struct pt_regs * regs)
 {
+       struct dentry * dentry = NULL;
        struct inode * inode = NULL;
        struct file file;
        unsigned short fs;
@@ -114,10 +115,12 @@ do_aout_core_dump(long signr, struct pt_regs * regs)
 #else
        corefile[4] = '\0';
 #endif
-       if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode)) {
-               inode = NULL;
+       dentry = open_namei(corefile,O_CREAT | 2 | O_TRUNC, 0600);
+       if (IS_ERR(dentry)) {
+               dentry = NULL;
                goto end_coredump;
        }
+       inode = dentry->d_inode;
        if (!S_ISREG(inode->i_mode))
                goto end_coredump;
        if (!inode->i_op || !inode->i_op->default_file_ops)
@@ -127,7 +130,7 @@ do_aout_core_dump(long signr, struct pt_regs * regs)
        file.f_mode = 3;
        file.f_flags = 0;
        file.f_count = 1;
-       file.f_inode = inode;
+       file.f_dentry = dentry;
        file.f_pos = 0;
        file.f_reada = 0;
        file.f_op = inode->i_op->default_file_ops;
@@ -221,7 +224,7 @@ done_coredump:
        put_write_access(inode);
 end_coredump:
        set_fs(fs);
-       iput(inode);
+       dput(dentry);
        return has_dumped;
 }
 
@@ -317,7 +320,7 @@ static inline int do_load_aout_binary(struct linux_binprm * bprm, struct pt_regs
        if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
             N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) ||
            N_TRSIZE(ex) || N_DRSIZE(ex) ||
-           bprm->inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
+           bprm->dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
                return -ENOEXEC;
        }
 
@@ -331,7 +334,7 @@ static inline int do_load_aout_binary(struct linux_binprm * bprm, struct pt_regs
        }
 
        if (N_MAGIC(ex) == ZMAGIC && ex.a_text &&
-           (fd_offset < bprm->inode->i_sb->s_blocksize)) {
+           (fd_offset < bprm->dentry->d_inode->i_sb->s_blocksize)) {
                printk(KERN_NOTICE "N_TXTOFF < BLOCK_SIZE. Please convert binary.\n");
                return -ENOEXEC;
        }
@@ -371,12 +374,12 @@ static inline int do_load_aout_binary(struct linux_binprm * bprm, struct pt_regs
                error = do_mmap(NULL, N_TXTADDR(ex), ex.a_text,
                                PROT_READ|PROT_WRITE|PROT_EXEC,
                                MAP_FIXED|MAP_PRIVATE, 0);
-               read_exec(bprm->inode, fd_offset, (char *) N_TXTADDR(ex),
+               read_exec(bprm->dentry, fd_offset, (char *) N_TXTADDR(ex),
                          ex.a_text, 0);
                error = do_mmap(NULL, N_DATADDR(ex), ex.a_data,
                                PROT_READ|PROT_WRITE|PROT_EXEC,
                                MAP_FIXED|MAP_PRIVATE, 0);
-               read_exec(bprm->inode, fd_offset + ex.a_text, (char *) N_DATADDR(ex),
+               read_exec(bprm->dentry, fd_offset + ex.a_text, (char *) N_DATADDR(ex),
                          ex.a_data, 0);
                goto beyond_if;
        }
@@ -388,20 +391,20 @@ static inline int do_load_aout_binary(struct linux_binprm * bprm, struct pt_regs
                        ex.a_text+ex.a_data + PAGE_SIZE - 1,
                        PROT_READ|PROT_WRITE|PROT_EXEC,
                        MAP_FIXED|MAP_PRIVATE, 0);
-               read_exec(bprm->inode, fd_offset, (char *) N_TXTADDR(ex),
+               read_exec(bprm->dentry, fd_offset, (char *) N_TXTADDR(ex),
                          ex.a_text+ex.a_data, 0);
 #else
                do_mmap(NULL, 0, ex.a_text+ex.a_data,
                        PROT_READ|PROT_WRITE|PROT_EXEC,
                        MAP_FIXED|MAP_PRIVATE, 0);
-               read_exec(bprm->inode, 32, (char *) 0, ex.a_text+ex.a_data, 0);
+               read_exec(bprm->dentry, 32, (char *) 0, ex.a_text+ex.a_data, 0);
 #endif
        } else {
                if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
                    (N_MAGIC(ex) != NMAGIC))
                        printk(KERN_NOTICE "executable not page aligned\n");
 
-               fd = open_inode(bprm->inode, O_RDONLY);
+               fd = open_dentry(bprm->dentry, O_RDONLY);
 
                if (fd < 0)
                        return fd;
@@ -411,7 +414,7 @@ static inline int do_load_aout_binary(struct linux_binprm * bprm, struct pt_regs
                        do_mmap(NULL, 0, ex.a_text+ex.a_data,
                                PROT_READ|PROT_WRITE|PROT_EXEC,
                                MAP_FIXED|MAP_PRIVATE, 0);
-                       read_exec(bprm->inode, fd_offset,
+                       read_exec(bprm->dentry, fd_offset,
                                  (char *) N_TXTADDR(ex), ex.a_text+ex.a_data, 0);
                        goto beyond_if;
                }
@@ -481,18 +484,21 @@ do_load_aout_library(int fd)
 {
         struct file * file;
        struct exec ex;
-       struct  inode * inode;
+       struct dentry * dentry;
+       struct inode * inode;
        unsigned int len;
        unsigned int bss;
        unsigned int start_addr;
        unsigned long error;
 
        file = current->files->fd[fd];
-       inode = file->f_inode;
 
        if (!file || !file->f_op)
                return -EACCES;
 
+       dentry = file->f_dentry;
+       inode = dentry->d_inode;
+
        /* Seek into the file */
        if (file->f_op->llseek) {
                if ((error = file->f_op->llseek(inode, file, 0, 0)) != 0)
index bdd53409e1287f620184c8c2e48c849f7fc1ab5d..e85c286f32b7c2a3840e75890267ae55753a4fd7 100644 (file)
@@ -186,7 +186,7 @@ create_elf_tables(char *p, int argc, int envc,
    an ELF header */
 
 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
-                                    struct inode * interpreter_inode,
+                                    struct dentry * interpreter_dentry,
                                     unsigned long *interp_load_addr)
 {
        struct file * file;
@@ -208,8 +208,8 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
        if ((interp_elf_ex->e_type != ET_EXEC &&
            interp_elf_ex->e_type != ET_DYN) ||
           !elf_check_arch(interp_elf_ex->e_machine) ||
-          (!interpreter_inode->i_op ||
-           !interpreter_inode->i_op->default_file_ops->mmap)){
+          (!interpreter_dentry->d_inode->i_op ||
+           !interpreter_dentry->d_inode->i_op->default_file_ops->mmap)){
                return ~0UL;
        }
 
@@ -236,7 +236,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
            return ~0UL;
          }
 
-       retval = read_exec(interpreter_inode, interp_elf_ex->e_phoff,
+       retval = read_exec(interpreter_dentry, interp_elf_ex->e_phoff,
                           (char *) elf_phdata,
                           sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, 1);
 
@@ -245,7 +245,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
                return retval;
        }
 
-       elf_exec_fileno = open_inode(interpreter_inode, O_RDONLY);
+       elf_exec_fileno = open_dentry(interpreter_dentry, O_RDONLY);
        if (elf_exec_fileno < 0) {
          kfree(elf_phdata);
          return ~0UL;
@@ -333,7 +333,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
 }
 
 static unsigned long load_aout_interp(struct exec * interp_ex,
-                            struct inode * interpreter_inode)
+                            struct dentry * interpreter_dentry)
 {
   int retval;
   unsigned long elf_entry;
@@ -348,13 +348,13 @@ static unsigned long load_aout_interp(struct exec * interp_ex,
     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_inode, 32, (char *) 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_inode,
+    retval = read_exec(interpreter_dentry,
                       N_TXTOFF(*interp_ex) ,
                       (char *) N_TXTADDR(*interp_ex),
                       interp_ex->a_text+interp_ex->a_data, 0);
@@ -389,7 +389,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        struct elfhdr interp_elf_ex;
        struct file * file;
        struct exec interp_ex;
-       struct inode *interpreter_inode;
+       struct dentry *interpreter_dentry;
        unsigned long load_addr;
        int load_addr_set = 0;
        unsigned int interpreter_type = INTERPRETER_NONE;
@@ -423,8 +423,8 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        if ((elf_ex.e_type != ET_EXEC &&
            elf_ex.e_type != ET_DYN) ||
           (! elf_check_arch(elf_ex.e_machine)) ||
-          (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
-           !bprm->inode->i_op->default_file_ops->mmap)){
+          (!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;
        }
 
@@ -436,7 +436,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                return -ENOMEM;
        }
 
-       retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata,
+       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);
@@ -448,7 +448,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        elf_bss = 0;
        elf_brk = 0;
 
-       elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
+       elf_exec_fileno = open_dentry(bprm->dentry, O_RDONLY);
 
        if (elf_exec_fileno < 0) {
                kfree (elf_phdata);
@@ -486,7 +486,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                                return -ENOMEM;
                        }
 
-                       retval = read_exec(bprm->inode,elf_ppnt->p_offset,
+                       retval = read_exec(bprm->dentry,elf_ppnt->p_offset,
                                           elf_interpreter,
                                           elf_ppnt->p_filesz, 1);
                        /* If the program interpreter is one of these two,
@@ -501,12 +501,14 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                        if (retval >= 0) {
                                old_fs = get_fs(); /* This could probably be optimized */
                                set_fs(get_ds());
-                               retval = open_namei(elf_interpreter, 0, 0, &interpreter_inode);
+                               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_inode,0,bprm->buf,128, 1);
+                               retval = read_exec(interpreter_dentry,0,bprm->buf,128, 1);
 
                        if (retval >= 0) {
                                interp_ex = *((struct exec *) bprm->buf);               /* exec-header */
@@ -642,13 +644,13 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        if (elf_interpreter) {
                if (interpreter_type & 1)
                        elf_entry = load_aout_interp(&interp_ex,
-                                                    interpreter_inode);
+                                                    interpreter_dentry);
                else if (interpreter_type & 2)
                        elf_entry = load_elf_interp(&interp_elf_ex,
-                                                   interpreter_inode,
+                                                   interpreter_dentry,
                                                    &interp_load_addr);
 
-               iput(interpreter_inode);
+               dput(interpreter_dentry);
                kfree(elf_interpreter);
 
                if (elf_entry == ~0UL) {
@@ -676,8 +678,8 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                __MOD_INC_USE_COUNT(current->binfmt->module);
 
 #ifndef VM_STACK_FLAGS
-       current->executable = bprm->inode;
-       atomic_inc(&bprm->inode->i_count);
+       current->executable = bprm->dentry;
+       atomic_inc(&bprm->dentry->i_count);
 #endif
 #ifdef LOW_ELF_STACK
        current->start_stack = bprm->p = elf_stack - 4;
@@ -762,7 +764,8 @@ do_load_elf_library(int fd){
        struct file * file;
        struct elfhdr elf_ex;
        struct elf_phdr *elf_phdata  =  NULL;
-       struct  inode * inode;
+       struct dentry * dentry;
+       struct inode * inode;
        unsigned long len;
        int elf_bss;
        int retval;
@@ -772,7 +775,8 @@ do_load_elf_library(int fd){
 
        len = 0;
        file = current->files->fd[fd];
-       inode = file->f_inode;
+       dentry = file->f_dentry;
+       inode = dentry->d_inode;
        elf_bss = 0;
 
        if (!file || !file->f_op)
@@ -811,7 +815,7 @@ do_load_elf_library(int fd){
        if (elf_phdata == NULL)
                return -ENOMEM;
 
-       retval = read_exec(inode, 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);
 
        j = 0;
@@ -883,13 +887,13 @@ static int load_elf_library(int fd)
  */
 static int dump_write(struct file *file, const void *addr, int nr)
 {
-       return file->f_op->write(file->f_inode, file, addr, nr) == nr;
+       return file->f_op->write(file->f_dentry->d_inode, file, addr, nr) == nr;
 }
 
 static int dump_seek(struct file *file, off_t off)
 {
        if (file->f_op->llseek) {
-               if (file->f_op->llseek(file->f_inode, file, off, 0) != off)
+               if (file->f_op->llseek(file->f_dentry->d_inode, file, off, 0) != off)
                        return 0;
        } else
                file->f_pos = off;
@@ -1004,6 +1008,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs)
 {
        int has_dumped = 0;
        struct file file;
+       struct dentry *dentry;
        struct inode *inode;
        unsigned short fs;
        char corefile[6+sizeof(current->comm)];
@@ -1077,10 +1082,12 @@ static int elf_core_dump(long signr, struct pt_regs * regs)
 #else
        corefile[4] = '\0';
 #endif
-       if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode)) {
-               inode = NULL;
+       dentry = open_namei(corefile, O_CREAT | 2 | O_TRUNC, 0600);
+       if (IS_ERR(dentry)) {
+               dentry = NULL;
                goto end_coredump;
        }
+       inode = dentry->d_inode;
        if (!S_ISREG(inode->i_mode))
                goto end_coredump;
        if (!inode->i_op || !inode->i_op->default_file_ops)
@@ -1088,7 +1095,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs)
        file.f_mode = 3;
        file.f_flags = 0;
        file.f_count = 1;
-       file.f_inode = inode;
+       file.f_dentry = dentry;
        file.f_pos = 0;
        file.f_reada = 0;
        file.f_op = inode->i_op->default_file_ops;
@@ -1285,7 +1292,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs)
 
  end_coredump:
        set_fs(fs);
-       iput(inode);
+       dput(dentry);
 #ifndef CONFIG_BINFMT_ELF
        MOD_DEC_USE_COUNT;
 #endif
index b1c4bc02379a0ea8f9a67e2186f12b44acd37ce2..133586e69f247ccbbf89b34b37fd3392fb7bb3e0 100644 (file)
@@ -23,6 +23,7 @@
 static int do_load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
 {
        char *interp, *i_name, *i_arg;
+       struct dentry * dentry;
        int retval;
        struct elfhdr   elf_ex;
 
@@ -39,14 +40,14 @@ static int do_load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
         if ((elf_ex.e_type != ET_EXEC &&
             elf_ex.e_type != ET_DYN) ||
            (!((elf_ex.e_machine == EM_386) || (elf_ex.e_machine == EM_486))) ||
-           (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
-            !bprm->inode->i_op->default_file_ops->mmap)){
+           (!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;
         }
 
        bprm->sh_bang++;        /* Well, the bang-shell is implicit... */
-       iput(bprm->inode);
-       bprm->dont_iput = 1;
+       dput(bprm->dentry);
+       bprm->dentry = NULL;
 
        /* Unlike in the script case, we don't have to do any hairy
         * parsing to find our interpreter... it's hardcoded!
@@ -79,14 +80,17 @@ static int do_load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
         * Note that we use open_namei() as the name is now in kernel
         * space, and we don't need to copy it.
         */
-       retval = open_namei(interp, 0, 0, &bprm->inode);
-       if (retval)
-               return retval;
-       bprm->dont_iput=0;
-       retval=prepare_binprm(bprm);
-       if(retval<0)
+       dentry = open_namei(interp, 0, 0);
+       if (IS_ERR(dentry))
+               return PTR_ERR(dentry);
+
+       bprm->dentry = dentry;
+
+       retval = prepare_binprm(bprm);
+       if (retval < 0)
                return retval;
-       return search_binary_handler(bprm,regs);
+
+       return search_binary_handler(bprm, regs);
 }
 
 static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
index 5ef090761bb5032f3a7c3fd75f4426b1452cab4b..27499e1f1d58f22dbae0a960b02b1ede5f8a490a 100644 (file)
@@ -197,7 +197,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        }
        bprm->filename = iname; /* for binfmt_script */
 
-       if ((retval = open_namei(iname, 0, 0, &bprm->inode, NULL)))
+       if ((retval = open_namei(iname, 0, 0, &bprm->inode)))
                goto _ret;
        bprm->dont_iput = 0;
 
index c826fa00f4a412defccda338971f3e1b7f6f3577..5a38cf545eea815a677b4ca196a80d7ce7431723 100644 (file)
 static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 {
        char *cp, *i_name, *i_name_start, *i_arg;
+       struct dentry * dentry;
        char interp[128];
        int retval;
+
        if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) 
                return -ENOEXEC;
        /*
@@ -25,8 +27,8 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
         */
 
        bprm->sh_bang++;
-       iput(bprm->inode);
-       bprm->dont_iput=1;
+       dput(bprm->dentry);
+       bprm->dentry = NULL;
 
        bprm->buf[127] = '\0';
        if ((cp = strchr(bprm->buf, '\n')) == NULL)
@@ -75,14 +77,15 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
        if (!bprm->p) 
                return -E2BIG;
        /*
-        * OK, now restart the process with the interpreter's inode.
+        * OK, now restart the process with the interpreter's dentry.
         */
-       retval = open_namei(interp, 0, 0, &bprm->inode);
-       if (retval)
-               return retval;
-       bprm->dont_iput=0;
-       retval=prepare_binprm(bprm);
-       if(retval<0)
+       dentry = open_namei(interp, 0, 0);
+       if (IS_ERR(dentry))
+               return PTR_ERR(dentry);
+
+       bprm->dentry = dentry;
+       retval = prepare_binprm(bprm);
+       if (retval < 0)
                return retval;
        return search_binary_handler(bprm,regs);
 }
index 96f47d2630584ab3662ea275fd369bdadca9aad6..3e1b5cc354268499a25bc67df15497761230c4e9 100644 (file)
@@ -289,16 +289,35 @@ int file_fsync (struct inode *inode, struct file *filp)
 asmlinkage int sys_fsync(unsigned int fd)
 {
        struct file * file;
+       struct dentry * dentry;
        struct inode * inode;
-       int err = 0;
+       int err;
 
        lock_kernel();
-       if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode))
-               err = -EBADF;
-       else if (!file->f_op || !file->f_op->fsync)
-               err = -EINVAL;
-       else if (file->f_op->fsync(inode,file))
-               err = -EIO;
+       err = -EBADF;
+
+       if (fd >= NR_OPEN)
+               goto out;
+
+       file = current->files->fd[fd];
+       if (!file)
+               goto out;
+
+       dentry = file->f_dentry;
+       if (!dentry)
+               goto out;
+
+       inode = dentry->d_inode;
+       if (!inode)
+               goto out;
+
+       err = -EINVAL;
+       if (!file->f_op || !file->f_op->fsync)
+               goto out;
+
+       err = file->f_op->fsync(inode,file);
+
+out:
        unlock_kernel();
        return err;
 }
@@ -306,20 +325,35 @@ asmlinkage int sys_fsync(unsigned int fd)
 asmlinkage int sys_fdatasync(unsigned int fd)
 {
        struct file * file;
+       struct dentry * dentry;
        struct inode * inode;
-       int err = -EBADF;
+       int err;
 
        lock_kernel();
-       if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode))
+       err = -EBADF;
+
+       if (fd >= NR_OPEN)
+               goto out;
+
+       file = current->files->fd[fd];
+       if (!file)
+               goto out;
+
+       dentry = file->f_dentry;
+       if (!dentry)
                goto out;
+
+       inode = dentry->d_inode;
+       if (!inode)
+               goto out;
+
        err = -EINVAL;
        if (!file->f_op || !file->f_op->fsync)
                goto out;
+
        /* this needs further work, at the moment it is identical to fsync() */
-       if (file->f_op->fsync(inode,file))
-               err = -EIO;
-       else
-               err = 0;
+       err = file->f_op->fsync(inode,file);
+
 out:
        unlock_kernel();
        return err;
index 0ff58164852cfbb1844cc1ba90dcc488106350a1..6147b006d69c18f4516f9e178beab9e913d49487 100644 (file)
 static struct list_head dentry_hashtable[D_HASHSIZE];
 static LIST_HEAD(dentry_unused);
 
-void dput(struct dentry *dentry)
-{
-       if (dentry) {
-               dentry->d_count--;
-               if (dentry->d_count < 0) {
-                       printk("dentry->count = %d for %s\n",
-                               dentry->d_count, dentry->d_name.name);
-                       return;
-               }
-               if (!dentry->d_count) {
-                       list_del(&dentry->d_lru);
-                       list_add(&dentry->d_lru, &dentry_unused);
-               }
-       }
-}
-
 void d_free(struct dentry *dentry)
 {
        kfree(dentry->d_name.name);
@@ -56,91 +40,116 @@ void d_free(struct dentry *dentry)
 }
 
 /*
- * Note! This tries to free the last entry on the dentry
- * LRU list. The dentries are put on the LRU list when
- * they are free'd, but that doesn't actually mean that
- * all LRU entries have d_count == 0 - it might have been
- * re-allocated. If so we delete it from the LRU list
- * here.
+ * dput()
  *
- * Rationale:
- * - keep "dget()" extremely simple
- * - if there have been a lot of lookups in the LRU list
- *   we want to make freeing more unlikely anyway, and
- *   keeping used dentries on the LRU list in that case
- *   will make the algorithm less likely to free an entry.
+ * This is complicated by the fact that we do not want to put
+ * dentries that are no longer on any hash chain on the unused
+ * list: we'd much rather just get rid of them immediately.
+ *
+ * However, that implies that we have to traverse the dentry
+ * tree upwards to the parents which might _also_ now be
+ * scheduled for deletion (it may have been only waiting for
+ * its last child to go away).
+ *
+ * This tail recursion is done by hand as we don't want to depend
+ * on the compiler to always get this right (gcc generally doesn't).
+ * Real recursion would eat up our stack space.
  */
-static inline struct dentry * free_one_dentry(struct dentry * dentry)
-{
-       struct dentry * parent;
-
-       list_del(&dentry->d_hash);
-       parent = dentry->d_parent;
-       if (parent != dentry)
-               dput(parent);
-       return dentry;
-}
-
-static inline struct dentry * try_free_one_dentry(struct dentry * dentry)
+void dput(struct dentry *dentry)
 {
-       struct inode * inode = dentry->d_inode;
-
-       if (inode) {
-               if (atomic_read(&inode->i_count) != 1) {
+       if (dentry) {
+               int count;
+repeat:
+               count = dentry->d_count-1;
+               if (count < 0) {
+                       printk("Negative d_count (%d) for %s/%s\n",
+                               count,
+                               dentry->d_parent->d_name.name,
+                               dentry->d_name.name);
+                       *(int *)0 = 0;
+               }
+               dentry->d_count = count;
+               if (!count) {
+                       list_del(&dentry->d_lru);
+                       if (list_empty(&dentry->d_hash)) {
+                               struct inode *inode = dentry->d_inode;
+                               struct dentry * parent;
+                               if (inode) {
+                                       list_del(&dentry->d_alias);
+                                       iput(inode);
+                               }
+                               parent = dentry->d_parent;
+                               d_free(dentry);
+                               if (dentry == parent)
+                                       return;
+                               dentry = parent;
+                               goto repeat;
+                       }
                        list_add(&dentry->d_lru, &dentry_unused);
-                       return NULL;
                }
-               list_del(&dentry->d_alias);
-               iput(inode);
-               dentry->d_inode = NULL;
        }
-       return free_one_dentry(dentry);
 }
 
-static struct dentry * try_free_dentries(void)
+/*
+ * Shrink the dcache. This is done when we need
+ * more memory, or simply when we need to unmount
+ * something (at which point we need to unuse
+ * all dentries).
+ *
+ * "priority" is a value between 0-6, 0 means that
+ * we should work really hard on releasing stuff..
+ */
+void shrink_dcache(int priority)
 {
-       struct list_head * tmp = dentry_unused.next;
+       int nr = 42;    /* "random" number */
 
-       if (tmp != &dentry_unused) {
-               struct dentry * dentry;
+       nr <<= 6; nr >>= priority;
+       do {
+               struct dentry *dentry;
+               struct list_head *tmp = dentry_unused.prev;
 
+               if (tmp == &dentry_unused)
+                       break;
                list_del(tmp);
+               INIT_LIST_HEAD(tmp);
                dentry = list_entry(tmp, struct dentry, d_lru);
-               if (dentry->d_count == 0)
-                       return try_free_one_dentry(dentry);
-       }
-       return NULL;
+               if (!dentry->d_count) {
+                       struct dentry * parent;
+
+                       list_del(&dentry->d_hash);
+                       if (dentry->d_inode) {
+                               struct inode * inode = dentry->d_inode;
+
+                               list_del(&dentry->d_alias);
+                               dentry->d_inode = NULL;
+                               iput(inode);
+                       }
+                       parent = dentry->d_parent;
+                       d_free(dentry);
+                       dput(parent);
+               }
+       } while (--nr);
 }
 
 #define NAME_ALLOC_LEN(len)    ((len+16) & ~15)
 
 struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
 {
-       int len;
        char * str;
        struct dentry *dentry;
 
-       dentry = try_free_dentries();
-       len = NAME_ALLOC_LEN(name->len);
-       if (dentry) {
-               str = (char *) dentry->d_name.name;
-               if (len == NAME_ALLOC_LEN(dentry->d_name.len))
-                       goto right_size;
-               kfree(dentry->d_name.name);
-       } else {
-               dentry = kmalloc(sizeof(struct dentry), GFP_KERNEL);
-               if (!dentry)
-                       return NULL;
-       }
-       str = kmalloc(len, GFP_KERNEL);
+       dentry = kmalloc(sizeof(struct dentry), GFP_KERNEL);
+       if (!dentry)
+               return NULL;
+
+       str = kmalloc(NAME_ALLOC_LEN(name->len), GFP_KERNEL);
        if (!str) {
                kfree(dentry);
                return NULL;
        }
-right_size:
-       len = name->len;
-       memcpy(str, name->name, len);
-       str[len] = 0;
+
+       memcpy(str, name->name, name->len);
+       str[name->len] = 0;
 
        dentry->d_count = 0;
        dentry->d_flags = 0;
@@ -237,22 +246,38 @@ static inline void d_remove_from_parent(struct dentry * dentry, struct dentry *
 }
 
 /*
- * Remove the inode from the dentry.. This removes
- * it from the parent hashes but otherwise leaves it
- * around - it may be a "zombie", part of a path
- * that is still in use...
+ * When a file is deleted, we have two options:
+ * - turn this dentry into a negative dentry
+ * - unhash this dentry and free it.
  *
- * "The Night of the Living Dead IV - the Dentry"
+ * Usually, we want to just turn this into
+ * a negative dentry, but if anybody else is
+ * currently using the dentry or the inode
+ * we can't do that and we fall back on removing
+ * it from the hash queues and waiting for
+ * it to be deleted later when it has no users
  */
 void d_delete(struct dentry * dentry)
 {
-       list_del(&dentry->d_hash);
        /*
-        * Make the hash lists point to itself.. When we
-        * later dput this, we want the list_del() there
-        * to not do anything strange..
+        * Are we the only user?
         */
+       if (dentry->d_count == 1) {
+               struct inode * inode = dentry->d_inode;
+
+               dentry->d_inode = NULL;
+               list_del(&dentry->d_alias);
+               iput(inode);
+               return;
+       }
+
+       /*
+        * If not, just unhash us and wait for dput()
+        * to pick up the tab..
+        */
+       list_del(&dentry->d_hash);
        INIT_LIST_HEAD(&dentry->d_hash);
+
 }
 
 void d_add(struct dentry * entry, struct inode * inode)
index 20747f05187f3be4258e498f7cb5f1421710ca64..9f3d186b55e7e2652a91e3c019369ae8772b6d4b 100644 (file)
@@ -227,7 +227,7 @@ static void write_dquot(struct dquot *dquot)
        lock_dquot(dquot);
        down(&dquot->dq_mnt->mnt_sem);
        if (filp->f_op->llseek) {
-               if (filp->f_op->llseek(filp->f_inode, filp,
+               if (filp->f_op->llseek(filp->f_dentry->d_inode, filp,
                    dqoff(dquot->dq_id), 0) != dqoff(dquot->dq_id)) {
                        up(&dquot->dq_mnt->mnt_sem);
                        unlock_dquot(dquot);
@@ -238,7 +238,7 @@ static void write_dquot(struct dquot *dquot)
        fs = get_fs();
        set_fs(KERNEL_DS);
 
-       if (filp->f_op->write(filp->f_inode, filp,
+       if (filp->f_op->write(filp->f_dentry->d_inode, filp,
           (char *)&dquot->dq_dqb, sizeof(struct dqblk)) == sizeof(struct dqblk))
                dquot->dq_flags &= ~DQ_MOD;
 
@@ -259,7 +259,7 @@ static void read_dquot(struct dquot *dquot)
        lock_dquot(dquot);
        down(&dquot->dq_mnt->mnt_sem);
        if (filp->f_op->llseek) {
-               if (filp->f_op->llseek(filp->f_inode, filp,
+               if (filp->f_op->llseek(filp->f_dentry->d_inode, filp,
                    dqoff(dquot->dq_id), 0) != dqoff(dquot->dq_id)) {
                        up(&dquot->dq_mnt->mnt_sem);
                        unlock_dquot(dquot);
@@ -269,7 +269,7 @@ static void read_dquot(struct dquot *dquot)
                filp->f_pos = dqoff(dquot->dq_id);
        fs = get_fs();
        set_fs(KERNEL_DS);
-       filp->f_op->read(filp->f_inode, filp, (char *)&dquot->dq_dqb, sizeof(struct dqblk));
+       filp->f_op->read(filp->f_dentry->d_inode, filp, (char *)&dquot->dq_dqb, sizeof(struct dqblk));
        up(&dquot->dq_mnt->mnt_sem);
        set_fs(fs);
        if (dquot->dq_bhardlimit == 0 && dquot->dq_bsoftlimit == 0 &&
@@ -946,39 +946,53 @@ int quota_off(kdev_t dev, short type)
 
 int quota_on(kdev_t dev, short type, char *path)
 {
-       struct file *filp = (struct file *)NULL;
+       struct file *filp = NULL;
+       struct dentry *dentry;
        struct vfsmount *vfsmnt;
        struct inode *inode;
        struct dquot *dquot;
        char *tmp;
        int error;
 
-       if ((vfsmnt = lookup_vfsmnt(dev)) == (struct vfsmount *)NULL)
-               return(-ENODEV);
-       if (vfsmnt->mnt_quotas[type] != (struct file *)NULL)
-               return(-EBUSY);
-       if ((error = getname(path, &tmp)) != 0)
-               return(error);
-       error = open_namei(tmp, O_RDWR, 0600, &inode);
+       vfsmnt = lookup_vfsmnt(dev);
+       if (vfsmnt == NULL)
+               return -ENODEV;
+
+       if (vfsmnt->mnt_quotas[type] != NULL)
+               return -EBUSY;
+
+       tmp = getname(path);
+       error = PTR_ERR(tmp);
+       if (IS_ERR(tmp))
+               return error;
+
+       dentry = open_namei(tmp, O_RDWR, 0600);
        putname(tmp);
-       if (error)
-               return(error);
+
+       error = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
+               return error;
+       inode = dentry->d_inode;
+
        if (!S_ISREG(inode->i_mode)) {
-               iput(inode);
-               return(-EACCES);
+               dput(dentry);
+               return -EACCES;
        }
-       if ((filp = get_empty_filp()) != (struct file *)NULL) {
+
+       filp = get_empty_filp();
+       if (filp != NULL) {
                filp->f_mode = (O_RDWR + 1) & O_ACCMODE;
                filp->f_flags = O_RDWR;
-               filp->f_inode = inode;
+               filp->f_dentry = dentry;
                filp->f_pos = 0;
                filp->f_reada = 0;
                filp->f_op = inode->i_op->default_file_ops;
                if (filp->f_op->read || filp->f_op->write) {
-                       if ((error = get_write_access(inode)) == 0) {
+                       error = get_write_access(inode);
+                       if (!error) {
                                if (filp->f_op && filp->f_op->open)
                                        error = filp->f_op->open(inode, filp);
-                               if (error == 0) {
+                               if (!error) {
                                        vfsmnt->mnt_quotas[type] = filp;
                                        dquot = dqget(dev, 0, type);
                                        vfsmnt->mnt_iexp[type] = (dquot) ? dquot->dq_itime : MAX_IQ_TIME;
@@ -986,7 +1000,7 @@ int quota_on(kdev_t dev, short type, char *path)
                                        dqput(dquot);
                                        vfsmnt->mnt_sb->dq_op = &dquot_operations;
                                        add_dquot_ref(dev, type);
-                                       return(0);
+                                       return 0;
                                }
                                put_write_access(inode);
                        }
@@ -995,8 +1009,8 @@ int quota_on(kdev_t dev, short type, char *path)
                put_filp(filp);
        } else
                error = -EMFILE;
-       iput(inode);
-       return(error);
+       dput(dentry);
+       return error;
 }
 
 /*
@@ -1008,7 +1022,6 @@ int quota_on(kdev_t dev, short type, char *path)
 asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
 {
        int cmds = 0, type = 0, flags = 0;
-       struct inode *ino;
        kdev_t dev;
        int ret = -EINVAL;
 
@@ -1034,19 +1047,22 @@ asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
        }
 
        ret = -EINVAL;
-       if (special == (char *)NULL && (cmds == Q_SYNC || cmds == Q_GETSTATS))
-               dev = 0;
-       else {
-               int error = namei(special, &ino);
-               if(error)
+       dev = 0;
+       if (special != NULL || (cmds != Q_SYNC && cmds != Q_GETSTATS)) {
+               mode_t mode;
+               struct dentry * dentry;
+
+               dentry = namei(special);
+               if (IS_ERR(dentry))
                        goto out;
-               dev = ino->i_rdev;
+
+               dev = dentry->d_inode->i_rdev;
+               mode = dentry->d_inode->i_mode;
+               dput(dentry);
+
                ret = -ENOTBLK;
-               if (!S_ISBLK(ino->i_mode)) {
-                       iput(ino);
+               if (!S_ISBLK(mode))
                        goto out;
-               }
-               iput(ino);
        }
 
        ret = -EINVAL;
index d2eadb3303a738e5629e319831ae0c23d4cd244f..25e73af4a1fe3810eeae796236b09528c2ff0f27 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -130,22 +130,24 @@ int unregister_binfmt(struct linux_binfmt * fmt)
 }
 #endif /* CONFIG_MODULES */
 
-int open_inode(struct inode * inode, int mode)
+int open_dentry(struct dentry * dentry, int mode)
 {
        int fd;
+       struct inode * inode = dentry->d_inode;
 
        if (!inode->i_op || !inode->i_op->default_file_ops)
                return -EINVAL;
        fd = get_unused_fd();
        if (fd >= 0) {
                struct file * f = get_empty_filp();
+
                if (!f) {
                        put_unused_fd(fd);
                        return -ENFILE;
                }
                f->f_flags = mode;
                f->f_mode = (mode+1) & O_ACCMODE;
-               f->f_inode = inode;
+               f->f_dentry = dentry;
                f->f_pos = 0;
                f->f_reada = 0;
                f->f_op = inode->i_op->default_file_ops;
@@ -158,7 +160,7 @@ int open_inode(struct inode * inode, int mode)
                        }
                }
                current->files->fd[fd] = f;
-               atomic_inc(&inode->i_count);
+               dget(dentry);
        }
        return fd;
 }
@@ -182,7 +184,7 @@ asmlinkage int sys_uselib(const char * library)
                goto out;
        file = current->files->fd[fd];
        retval = -ENOEXEC;
-       if (file && file->f_inode && file->f_op && file->f_op->read) {
+       if (file && file->f_dentry && file->f_op && file->f_op->read) {
                for (fmt = formats ; fmt ; fmt = fmt->next) {
                        int (*fn)(int) = fmt->load_shlib;
                        if (!fn)
@@ -316,7 +318,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_inode = NULL;
+               mpnt->vm_dentry = NULL;
                mpnt->vm_pte = 0;
                insert_vm_struct(current->mm, mpnt);
                current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
@@ -337,10 +339,11 @@ unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm)
  * that aren't on a block boundary, and for files on filesystems
  * without bmap support.
  */
-int read_exec(struct inode *inode, unsigned long offset,
+int read_exec(struct dentry *dentry, unsigned long offset,
        char * addr, unsigned long count, int to_kmem)
 {
        struct file file;
+       struct inode * inode = dentry->d_inode;
        int result = -ENOEXEC;
 
        if (!inode->i_op || !inode->i_op->default_file_ops)
@@ -348,7 +351,7 @@ int read_exec(struct inode *inode, unsigned long offset,
        file.f_mode = 1;
        file.f_flags = 0;
        file.f_count = 1;
-       file.f_inode = inode;
+       file.f_dentry = dentry;
        file.f_pos = 0;
        file.f_reada = 0;
        file.f_op = inode->i_op->default_file_ops;
@@ -477,7 +480,7 @@ void flush_old_exec(struct linux_binprm * bprm)
        flush_thread();
 
        if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
-           permission(bprm->inode,MAY_READ))
+           permission(bprm->dentry->d_inode,MAY_READ))
                current->dumpable = 0;
 
        flush_old_signals(current->sig);
@@ -492,20 +495,21 @@ int prepare_binprm(struct linux_binprm *bprm)
 {
        int mode;
        int retval,id_change;
+       struct inode * inode = bprm->dentry->d_inode;
 
-       mode = bprm->inode->i_mode;
+       mode = inode->i_mode;
        if (!S_ISREG(mode))                     /* must be regular file */
                return -EACCES;
        if (!(mode & 0111))                     /* with at least _one_ execute bit set */
                return -EACCES;
-       if (IS_NOEXEC(bprm->inode))             /* FS mustn't be mounted noexec */
+       if (IS_NOEXEC(inode))                   /* FS mustn't be mounted noexec */
                return -EACCES;
-       if (!bprm->inode->i_sb)
+       if (!inode->i_sb)
                return -EACCES;
-       if ((retval = permission(bprm->inode, MAY_EXEC)) != 0)
+       if ((retval = permission(inode, MAY_EXEC)) != 0)
                return retval;
        /* better not execute files which are being written to */
-       if (bprm->inode->i_writecount > 0)
+       if (inode->i_writecount > 0)
                return -ETXTBSY;
 
        bprm->e_uid = current->euid;
@@ -514,7 +518,7 @@ int prepare_binprm(struct linux_binprm *bprm)
 
        /* Set-uid? */
        if (mode & S_ISUID) {
-               bprm->e_uid = bprm->inode->i_uid;
+               bprm->e_uid = inode->i_uid;
                if (bprm->e_uid != current->euid)
                        id_change = 1;
        }
@@ -526,7 +530,7 @@ int prepare_binprm(struct linux_binprm *bprm)
         * executable.
         */
        if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
-               bprm->e_gid = bprm->inode->i_gid;
+               bprm->e_gid = inode->i_gid;
                if (!in_group_p(bprm->e_gid))
                        id_change = 1;
        }
@@ -535,7 +539,7 @@ int prepare_binprm(struct linux_binprm *bprm)
                /* We can't suid-execute if we're sharing parts of the executable */
                /* or if we're being traced (or if suid execs are not allowed)    */
                /* (current->mm->count > 1 is ok, as we'll get a new mm anyway)   */
-               if (IS_NOSUID(bprm->inode)
+               if (IS_NOSUID(inode)
                    || (current->flags & PF_PTRACED)
                    || (current->fs->count > 1)
                    || (atomic_read(&current->sig->count) > 1)
@@ -546,7 +550,7 @@ int prepare_binprm(struct linux_binprm *bprm)
        }
 
        memset(bprm->buf,0,sizeof(bprm->buf));
-       return read_exec(bprm->inode,0,bprm->buf,128,1);
+       return read_exec(bprm->dentry,0,bprm->buf,128,1);
 }
 
 void remove_arg_zero(struct linux_binprm *bprm)
@@ -581,16 +585,19 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
                (eh->fh.f_flags & 0x3000) == 0x3000)
            {
                char * dynloader[] = { "/sbin/loader" };
-               iput(bprm->inode);
-               bprm->dont_iput = 1;
+               struct dentry * dentry;
+
+               dput(bprm->dentry);
+               bprm->dentry = NULL;
                remove_arg_zero(bprm);
                bprm->p = copy_strings(1, dynloader, bprm->page, bprm->p, 2);
                bprm->argc++;
                bprm->loader = bprm->p;
-               retval = open_namei(dynloader[0], 0, 0, &bprm->inode);
-               if (retval)
+               dentry = open_namei(dynloader[0], 0, 0);
+               retval = PTR_ERR(dentry);
+               if (IS_ERR(dentry))
                        return retval;
-               bprm->dont_iput = 0;
+               bprm->dentry = dentry;
                retval = prepare_binprm(bprm);
                if (retval<0)
                        return retval;
@@ -606,15 +613,15 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
                                continue;
                        retval = fn(bprm, regs);
                        if (retval >= 0) {
-                               if(!bprm->dont_iput)
-                                       iput(bprm->inode);
-                               bprm->dont_iput=1;
+                               if (bprm->dentry)
+                                       dput(bprm->dentry);
+                               bprm->dentry = NULL;
                                current->did_exec = 1;
                                return retval;
                        }
                        if (retval != -ENOEXEC)
                                break;
-                       if (bprm->dont_iput) /* We don't have the inode anymore*/
+                       if (!bprm->dentry) /* We don't have the dentry anymore */
                                return retval;
                }
                if (retval != -ENOEXEC) {
@@ -643,29 +650,38 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
 int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
 {
        struct linux_binprm bprm;
+       struct dentry * dentry;
        int retval;
        int i;
 
        bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
        for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
                bprm.page[i] = 0;
-       retval = open_namei(filename, 0, 0, &bprm.inode);
-       if (retval)
+
+       dentry = open_namei(filename, 0, 0);
+       retval = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
                return retval;
+
+       bprm.dentry = dentry;
        bprm.filename = filename;
        bprm.sh_bang = 0;
        bprm.java = 0;
        bprm.loader = 0;
        bprm.exec = 0;
-       bprm.dont_iput = 0;
-       if ((bprm.argc = count(argv)) < 0)
+       if ((bprm.argc = count(argv)) < 0) {
+               dput(dentry);
                return bprm.argc;
-       if ((bprm.envc = count(envp)) < 0)
+       }
+
+       if ((bprm.envc = count(envp)) < 0) {
+               dput(dentry);
                return bprm.envc;
+       }
 
        retval = prepare_binprm(&bprm);
        
-       if(retval>=0) {
+       if (retval >= 0) {
                bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
                bprm.exec = bprm.p;
                bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
@@ -674,16 +690,18 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
                        retval = -E2BIG;
        }
 
-       if(retval>=0)
+       if (retval >= 0)
                retval = search_binary_handler(&bprm,regs);
-       if(retval>=0)
+       if (retval >= 0)
                /* execve success */
                return retval;
 
        /* Something went wrong, return the inode and free the argument pages*/
-       if(!bprm.dont_iput)
-               iput(bprm.inode);
+       if (bprm.dentry)
+               dput(bprm.dentry);
+
        for (i=0 ; i<MAX_ARG_PAGES ; i++)
                free_page(bprm.page[i]);
-       return(retval);
+
+       return retval;
 }
index 5a654f686b71ee578c9ce9cc2757f1a1309ca089..c70fafb636115f68030438e22caef306b478e3b8 100644 (file)
@@ -762,7 +762,7 @@ void cleanup_module(void)
 
 #endif
 
-void ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
+int ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
 {
        unsigned long overhead;
        unsigned long overhead_per_group;
@@ -793,5 +793,5 @@ void ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
        tmp.f_files = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count);
        tmp.f_ffree = ext2_count_free_inodes (sb);
        tmp.f_namelen = EXT2_NAME_LEN;
-       copy_to_user(buf, &tmp, bufsiz);
+       return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
 }
index 6418a5d83a7d53c4d099cc3e750cf276461d0829..57eef2530fb8f49c30a3321c33db3dc37f85b71d 100644 (file)
@@ -67,6 +67,34 @@ asmlinkage int sys_dup(unsigned int fildes)
        return ret;
 }
 
+#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC)
+
+static int setfl(struct file * filp, unsigned long arg)
+{
+       struct inode * inode = filp->f_dentry->d_inode;
+
+       /*
+        * In the case of an append-only file, O_APPEND
+        * cannot be cleared
+        */
+       if (!(arg & O_APPEND) && IS_APPEND(inode))
+               return -EPERM;
+
+       /* Did FASYNC state change? */
+       if ((arg ^ filp->f_flags) & FASYNC) {
+               if (filp->f_op->fasync)
+                       filp->f_op->fasync(inode, filp, (arg & FASYNC) != 0);
+       }
+
+       /* required for strict SunOS emulation */
+       if (O_NONBLOCK != O_NDELAY)
+              if (arg & O_NDELAY)
+                  arg |= O_NONBLOCK;
+
+       filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
+       return 0;
+}
+
 asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {      
        struct file * filp;
@@ -95,28 +123,7 @@ asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
                        err = filp->f_flags;
                        break;
                case F_SETFL:
-                       /*
-                        * In the case of an append-only file, O_APPEND
-                        * cannot be cleared
-                        */
-                       err = -EPERM;
-                       if (IS_APPEND(filp->f_inode) && !(arg & O_APPEND))
-                               break;
-                       err = 0;
-                       if ((arg & FASYNC) && !(filp->f_flags & FASYNC) &&
-                           filp->f_op->fasync)
-                               filp->f_op->fasync(filp->f_inode, filp, 1);
-                       if (!(arg & FASYNC) && (filp->f_flags & FASYNC) &&
-                           filp->f_op->fasync)
-                               filp->f_op->fasync(filp->f_inode, filp, 0);
-                       /* required for strict SunOS emulation */
-                       if (O_NONBLOCK != O_NDELAY)
-                              if (arg & O_NDELAY)
-                                  arg |= O_NONBLOCK;
-                       filp->f_flags &= ~(O_APPEND | O_NONBLOCK | 
-                                          O_NDELAY | FASYNC);
-                       filp->f_flags |= arg & (O_APPEND | O_NONBLOCK |
-                                               O_NDELAY | FASYNC);
+                       err = setfl(filp, arg);
                        break;
                case F_GETLK:
                        err = fcntl_getlk(fd, (struct flock *) arg);
@@ -186,12 +193,12 @@ asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
                fasync_ok:
                        err = 0;
                        filp->f_owner = arg;
-                       if (S_ISSOCK (filp->f_inode->i_mode))
+                       if (S_ISSOCK (filp->f_dentry->d_inode->i_mode))
                                err = sock_fcntl (filp, F_SETOWN, arg);
                        break;
                default:
                        /* sockets need a few special fcntls. */
-                       if (S_ISSOCK (filp->f_inode->i_mode))
+                       if (S_ISSOCK (filp->f_dentry->d_inode->i_mode))
                                err = sock_fcntl (filp, cmd, arg);
                        else
                                err = -EINVAL;
index b8c8d4155145343fc9ba7a22ce53e9a378ae8027..cbcdd596434e1d4ea304a6d6e1035c0f17336bd3 100644 (file)
@@ -109,11 +109,15 @@ void add_dquot_ref(kdev_t dev, short type)
        struct file *filp;
 
        for (filp = inuse_filps; filp; filp = filp->f_next) {
-               if (!filp->f_inode || filp->f_inode->i_dev != dev)
+               struct inode * inode;
+               if (!filp->f_dentry)
                        continue;
-               if (filp->f_mode & FMODE_WRITE && filp->f_inode->i_sb->dq_op) {
-                       filp->f_inode->i_sb->dq_op->initialize(filp->f_inode, type);
-                       filp->f_inode->i_flags |= S_WRITE;
+               inode = filp->f_dentry->d_inode;
+               if (!inode || inode->i_dev != dev)
+                       continue;
+               if (filp->f_mode & FMODE_WRITE && inode->i_sb->dq_op) {
+                       inode->i_sb->dq_op->initialize(inode, type);
+                       inode->i_flags |= S_WRITE;
                }
        }
 }
@@ -123,11 +127,15 @@ void reset_dquot_ptrs(kdev_t dev, short type)
        struct file *filp;
 
        for (filp = inuse_filps; filp; filp = filp->f_next) {
-               if (!filp->f_inode || filp->f_inode->i_dev != dev)
+               struct inode * inode;
+               if (!filp->f_dentry)
+                       continue;
+               inode = filp->f_dentry->d_inode;
+               if (!inode || inode->i_dev != dev)
                        continue;
-               if (IS_WRITABLE(filp->f_inode)) {
-                       filp->f_inode->i_dquot[type] = NODQUOT;
-                       filp->f_inode->i_flags &= ~S_WRITE;
+               if (IS_WRITABLE(inode)) {
+                       inode->i_dquot[type] = NODQUOT;
+                       inode->i_flags &= ~S_WRITE;
                }
        }
 }
index 6766506a86e9b86378cbde35abc8da09ed36a585..11798a238a1afc00f8814dc8404f6c6b70c87997 100644 (file)
@@ -20,28 +20,27 @@ static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
 {
        int error;
        int block;
+       struct inode * inode = filp->f_dentry->d_inode;
 
        switch (cmd) {
                case FIBMAP:
-                       if (filp->f_inode->i_op == NULL)
+                       if (inode->i_op == NULL)
                                return -EBADF;
-                       if (filp->f_inode->i_op->bmap == NULL)
+                       if (inode->i_op->bmap == NULL)
                                return -EINVAL;
                        if ((error = get_user(block, (int *) arg)) != 0)
                                return error;
-                       block = filp->f_inode->i_op->bmap(filp->f_inode,block);
+                       block = inode->i_op->bmap(inode,block);
                        return put_user(block, (int *) arg);
                case FIGETBSZ:
-                       if (filp->f_inode->i_sb == NULL)
+                       if (inode->i_sb == NULL)
                                return -EBADF;
-                       return put_user(filp->f_inode->i_sb->s_blocksize,
-                                       (int *) arg);
+                       return put_user(inode->i_sb->s_blocksize, (int *) arg);
                case FIONREAD:
-                       return put_user(filp->f_inode->i_size - filp->f_pos,
-                                       (int *) arg);
+                       return put_user(inode->i_size - filp->f_pos, (int *) arg);
        }
        if (filp->f_op && filp->f_op->ioctl)
-               return filp->f_op->ioctl(filp->f_inode, filp, cmd, arg);
+               return filp->f_op->ioctl(inode, filp, cmd, arg);
        return -ENOTTY;
 }
 
@@ -91,10 +90,10 @@ asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
                        break;
 
                default:
-                       if (filp->f_inode && S_ISREG(filp->f_inode->i_mode))
+                       if (filp->f_dentry && filp->f_dentry->d_inode && S_ISREG(filp->f_dentry->d_inode->i_mode))
                                error = file_ioctl(filp, cmd, arg);
                        else if (filp->f_op && filp->f_op->ioctl)
-                               error = filp->f_op->ioctl(filp->f_inode, filp, cmd, arg);
+                               error = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
                        else
                                error = -ENOTTY;
        }
index 4a63d4eb01ddd97d6b9856cb87305ee98b8a0d8e..3801055ca05b3b19a77497560e4b89b82f0c26af 100644 (file)
@@ -504,7 +504,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
        return NULL;
 }
 
-void isofs_statfs (struct super_block *sb, struct statfs *buf, int bufsiz)
+int isofs_statfs (struct super_block *sb, struct statfs *buf, int bufsiz)
 {
        struct statfs tmp;
 
@@ -517,7 +517,7 @@ void isofs_statfs (struct super_block *sb, struct statfs *buf, int bufsiz)
        tmp.f_files = sb->u.isofs_sb.s_ninodes;
        tmp.f_ffree = 0;
        tmp.f_namelen = NAME_MAX;
-       copy_to_user(buf, &tmp, bufsiz);
+       return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
 }
 
 int isofs_bmap(struct inode * inode,int block)
index 8c41d2f39d60ac798e5d3c0d442b64aaea17c115..98814d220f4ed98c145a0c9da110266b2242639a 100644 (file)
@@ -172,7 +172,7 @@ reclaimer(void *ptr)
        /* First, reclaim all locks that have been granted previously. */
        do {
                for (fl = file_lock_table; fl; fl = fl->fl_next) {
-                       inode = fl->fl_file->f_inode;
+                       inode = fl->fl_file->f_dentry->d_inode;
                        if (inode->i_sb->s_magic == NFS_SUPER_MAGIC
                         && nlm_cmp_addr(NFS_ADDR(inode), &host->h_addr)
                         && fl->fl_u.nfs_fl.state != host->h_state
index 1506a2ba632d8819f12e58dda260c8396fbcb78e..d219de5ea0bdb8e8bdcb9db30048aeb1a8729fb0 100644 (file)
@@ -42,7 +42,7 @@ nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
        memset(argp, 0, sizeof(*argp));
        argp->cookie  = nlm_cookie++;
        argp->state   = nsm_local_state;
-       lock->fh      = *NFS_FH(fl->fl_file->f_inode);
+       lock->fh      = *NFS_FH(fl->fl_file->f_dentry->d_inode);
        lock->caller  = system_utsname.nodename;
        lock->oh.data = req->a_owner;
        lock->oh.len  = sprintf(req->a_owner, "%d@%s",
index b4d74f7459861830b3ce7d4deb5cd11000cbffb7..69a9eeb219036037b5e196c2c60f8d56cfa0180f 100644 (file)
@@ -274,8 +274,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
        int                     error;
 
        dprintk("lockd: nlmsvc_lock(%04x/%ld, ty=%d, pi=%d, %ld-%ld, bl=%d)\n",
-                               file->f_file.f_inode->i_dev,
-                               file->f_file.f_inode->i_ino,
+                               file->f_file.f_dentry->d_inode->i_dev,
+                               file->f_file.f_dentry->d_inode->i_ino,
                                lock->fl.fl_type, lock->fl.fl_pid,
                                lock->fl.fl_start,
                                lock->fl.fl_end,
@@ -344,8 +344,8 @@ nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock,
        struct file_lock        *fl;
 
        dprintk("lockd: nlmsvc_testlock(%04x/%ld, ty=%d, %ld-%ld)\n",
-                               file->f_file.f_inode->i_dev,
-                               file->f_file.f_inode->i_ino,
+                               file->f_file.f_dentry->d_inode->i_dev,
+                               file->f_file.f_dentry->d_inode->i_ino,
                                lock->fl.fl_type,
                                lock->fl.fl_start,
                                lock->fl.fl_end);
@@ -375,8 +375,8 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
        int     error;
 
        dprintk("lockd: nlmsvc_unlock(%04x/%ld, pi=%d, %ld-%ld)\n",
-                               file->f_file.f_inode->i_dev,
-                               file->f_file.f_inode->i_ino,
+                               file->f_file.f_dentry->d_inode->i_dev,
+                               file->f_file.f_dentry->d_inode->i_ino,
                                lock->fl.fl_pid,
                                lock->fl.fl_start,
                                lock->fl.fl_end);
@@ -403,8 +403,8 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
        struct nlm_block        *block;
 
        dprintk("lockd: nlmsvc_cancel(%04x/%ld, pi=%d, %ld-%ld)\n",
-                               file->f_file.f_inode->i_dev,
-                               file->f_file.f_inode->i_ino,
+                               file->f_file.f_dentry->d_inode->i_dev,
+                               file->f_file.f_dentry->d_inode->i_ino,
                                lock->fl.fl_pid,
                                lock->fl.fl_start,
                                lock->fl.fl_end);
index 8ca8aa1830aa6d08a14b01332ae1c9b9773fdbec..909c2eacb426785b87e7dd35744ddcecde6214e9 100644 (file)
@@ -297,25 +297,34 @@ int fcntl_getlk(unsigned int fd, struct flock *l)
 {
        struct flock flock;
        struct file *filp;
+       struct dentry *dentry;
+       struct inode *inode;
        struct file_lock *fl,file_lock;
        int error;
 
        if ((fd >= NR_OPEN) || !(filp = current->files->fd[fd]))
-               return (-EBADF);
+               return -EBADF;
        if (copy_from_user(&flock, l, sizeof(flock)))
-               return (-EFAULT);
+               return -EFAULT;
 
        if ((flock.l_type != F_RDLCK) && (flock.l_type != F_WRLCK))
-               return (-EINVAL);
+               return -EINVAL;
 
-       if (!filp->f_inode || !posix_make_lock(filp, &file_lock, &flock))
-               return (-EINVAL);
+       dentry = filp->f_dentry;
+       if (!dentry)
+               return -EINVAL;
+
+       inode = dentry->d_inode;
+       if (!inode)
+               return -EINVAL;
+
+       if (!posix_make_lock(filp, &file_lock, &flock))
+               return -EINVAL;
 
        if (filp->f_op->lock) {
-               error = filp->f_op->lock(filp->f_inode, filp,
-                                        F_GETLK, &file_lock);
+               error = filp->f_op->lock(inode, filp, F_GETLK, &file_lock);
                if (error < 0)
-                       return (error);
+                       return error;
                fl = &file_lock;
        } else {
                fl = posix_test_lock(filp, &file_lock);
@@ -344,6 +353,7 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
        struct file *filp;
        struct file_lock file_lock;
        struct flock flock;
+       struct dentry * dentry;
        struct inode *inode;
        int error;
 
@@ -351,10 +361,13 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
         */
 
        if ((fd >= NR_OPEN) || !(filp = current->files->fd[fd]))
-               return (-EBADF);
-       
-       if (!(inode = filp->f_inode))
-               return (-EINVAL);
+               return -EBADF;
+
+       if (!(dentry = filp->f_dentry))
+               return -EINVAL;
+
+       if (!(inode = dentry->d_inode))
+               return -EINVAL;
        
        /* Don't allow mandatory locks on files that may be memory mapped
         * and shared.
@@ -407,7 +420,7 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
        }
 
        if (filp->f_op->lock != NULL) {
-               error = filp->f_op->lock(filp->f_inode, filp, cmd, &file_lock);
+               error = filp->f_op->lock(inode, filp, cmd, &file_lock);
                if (error < 0)
                        return (error);
        }
@@ -421,12 +434,14 @@ void locks_remove_locks(struct task_struct *task, struct file *filp)
 {
        struct file_lock file_lock, *fl;
        struct file_lock **before;
+       struct inode * inode;
 
        /* For POSIX locks we free all locks on this file for the given task.
         * For FLOCK we only free locks on this *open* file if it is the last
         * close on that file.
         */
-       before = &filp->f_inode->i_flock;
+       inode = filp->f_dentry->d_inode;
+       before = &inode->i_flock;
 
        while ((fl = *before) != NULL) {
                if (((fl->fl_flags & FL_POSIX) && (fl->fl_owner == task)) ||
@@ -436,10 +451,9 @@ void locks_remove_locks(struct task_struct *task, struct file *filp)
                        locks_delete_lock(before, 0);
                        if (filp->f_op->lock) {
                                file_lock.fl_type = F_UNLCK;
-                               filp->f_op->lock(filp->f_inode, filp,
-                                                F_SETLK, &file_lock);
+                               filp->f_op->lock(inode, filp, F_SETLK, &file_lock);
                                /* List may have changed: */
-                               before = &filp->f_inode->i_flock;
+                               before = &inode->i_flock;
                        }
                } else {
                        before = &fl->fl_next;
@@ -454,7 +468,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
 {
        struct file_lock *cfl;
 
-       for (cfl = filp->f_inode->i_flock; cfl; cfl = cfl->fl_next) {
+       for (cfl = filp->f_dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
                if (!(cfl->fl_flags & FL_POSIX))
                        continue;
                if (posix_locks_conflict(cfl, fl))
@@ -585,7 +599,7 @@ static int posix_make_lock(struct file *filp, struct file_lock *fl,
                start = filp->f_pos;
                break;
        case 2: /*SEEK_END*/
-               start = filp->f_inode->i_size;
+               start = filp->f_dentry->d_inode->i_size;
                break;
        default:
                return (0);
@@ -612,7 +626,7 @@ static int flock_make_lock(struct file *filp, struct file_lock *fl,
 {
        memset(fl, 0, sizeof(*fl));
 
-       if (!filp->f_inode)     /* just in case */
+       if (!filp->f_dentry)    /* just in case */
                return (0);
 
        switch (cmd & ~LOCK_NB) {
@@ -750,9 +764,10 @@ static int flock_lock_file(struct file *filp, struct file_lock *caller,
        struct file_lock *fl;
        struct file_lock *new_fl;
        struct file_lock **before;
+       struct inode * inode = filp->f_dentry->d_inode;
        int change = 0;
 
-       before = &filp->f_inode->i_flock;
+       before = &inode->i_flock;
        while (((fl = *before) != NULL) && (fl->fl_flags & FL_FLOCK)) {
                if (caller->fl_file == fl->fl_file) {
                        if (caller->fl_type == fl->fl_type)
@@ -772,7 +787,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *caller,
        if ((new_fl = locks_alloc_lock(caller)) == NULL)
                return (-ENOLCK);
 repeat:
-       for (fl = filp->f_inode->i_flock; (fl != NULL) && (fl->fl_flags & FL_FLOCK);
+       for (fl = inode->i_flock; (fl != NULL) && (fl->fl_flags & FL_FLOCK);
             fl = fl->fl_next) {
                if (!flock_locks_conflict(new_fl, fl))
                        continue;
@@ -801,7 +816,7 @@ repeat:
                }
                goto repeat;
        }
-       locks_insert_lock(&filp->f_inode->i_flock, new_fl);
+       locks_insert_lock(&inode->i_flock, new_fl);
        return (0);
 }
 
@@ -825,11 +840,12 @@ int posix_lock_file(struct file *filp, struct file_lock *caller,
        struct file_lock *left = NULL;
        struct file_lock *right = NULL;
        struct file_lock **before;
+       struct inode * inode = filp->f_dentry->d_inode;
        int added = 0;
 
        if (caller->fl_type != F_UNLCK) {
   repeat:
-               for (fl = filp->f_inode->i_flock; fl != NULL; fl = fl->fl_next) {
+               for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
                        if (!(fl->fl_flags & FL_POSIX))
                                continue;
                        if (!posix_locks_conflict(caller, fl))
@@ -852,7 +868,7 @@ int posix_lock_file(struct file *filp, struct file_lock *caller,
        /* Find the first old lock with the same owner as the new lock.
         */
        
-       before = &filp->f_inode->i_flock;
+       before = &inode->i_flock;
 
        /* First skip locks owned by other processes.
         */
@@ -1054,7 +1070,7 @@ static char *lock_get_status(struct file_lock *fl, int id, char *pfx)
        char *p = temp;
        struct inode *inode;
 
-       inode = fl->fl_file->f_inode;
+       inode = fl->fl_file->f_dentry->d_inode;
 
        p += sprintf(p, "%d:%s ", id, pfx);
        if (fl->fl_flags & FL_POSIX) {
index d17a6e3016e2dcabd7308e5910a6c30c5b33be4e..c53dd99667adaceaa4cd108d127bd015c73b376b 100644 (file)
@@ -158,20 +158,22 @@ static inline int do_getname(const char *filename, char *page)
        return retval;
 }
 
-int getname(const char * filename, char **result)
+char * getname(const char * filename)
 {
-       char *tmp;
-       int retval;
+       char *tmp, *result;
 
+       result = ERR_PTR(-ENOMEM);
        tmp = get_page();
-       if (!tmp)
-               return -ENOMEM;
-       retval = do_getname(filename, tmp);
-       if (retval < 0)
-               putname(tmp);
-       else
-               *result = tmp;
-       return retval;
+       if (tmp)  {
+               int retval = do_getname(filename, tmp);
+
+               result = tmp;
+               if (retval < 0) {
+                       putname(tmp);
+                       result = ERR_PTR(retval);
+               }
+       }
+       return result;
 }
 
 /*
@@ -262,6 +264,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name)
                result = d_lookup(parent, name);
                if (result) {
                        d_free(new);
+                       iput(inode);
                } else {
                        d_add(new, inode);
                        result = new;
@@ -294,7 +297,7 @@ static inline struct dentry * cached_lookup(struct dentry * parent, struct qstr
                 */
                if (parent->d_count <= 1) {
                        printk("lookup of %s success in %s, but parent count is %d\n",
-                               dentry->d_name, parent->d_name, parent->d_count);
+                               dentry->d_name.name, parent->d_name.name, parent->d_count);
                }
        }
        return dentry;
@@ -466,32 +469,24 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
  * namei exists in two versions: namei/lnamei. The only difference is
  * that namei follows links, while lnamei does not.
  */
-int __namei(const char *pathname, struct inode **res_inode, int follow_link)
+struct dentry * __namei(const char *pathname, int follow_link)
 {
-       int error;
-       char * name;
-
-       error = getname(pathname, &name);
-       if (!error) {
-               struct dentry * dentry;
+       char *name;
+       struct dentry *dentry;
 
+       name = getname(pathname);
+       dentry = (struct dentry *) name;
+       if (!IS_ERR(name)) {
                dentry = lookup_dentry(name, NULL, follow_link);
                putname(name);
-               error = PTR_ERR(dentry);
                if (!IS_ERR(dentry)) {
-                       error = -ENOENT;
-                       if (dentry) {
-                               struct inode *inode = dentry->d_inode;
-                               if (inode) {
-                                       atomic_inc(&inode->i_count);
-                                       *res_inode = inode;
-                                       error = 0;
-                               }
+                       if (!dentry->d_inode) {
                                dput(dentry);
+                               dentry = ERR_PTR(-ENOENT);
                        }
                }
        }
-       return error;
+       return dentry;
 }
 
 static inline struct inode *get_parent(struct dentry *dentry)
@@ -524,10 +519,9 @@ static inline struct inode *lock_parent(struct dentry *dentry)
  * which is a lot more logical, and also allows the "no perm" needed
  * for symlinks (where the permissions are checked later).
  */
-int open_namei(const char * pathname, int flag, int mode, struct inode ** res_inode)
+struct dentry * open_namei(const char * pathname, int flag, int mode)
 {
-       int error;
-       int acc_mode;
+       int acc_mode, error;
        struct inode *inode;
        struct dentry *dentry;
 
@@ -536,7 +530,7 @@ int open_namei(const char * pathname, int flag, int mode, struct inode ** res_in
 
        dentry = lookup_dentry(pathname, NULL, 1);
        if (IS_ERR(dentry))
-               return PTR_ERR(dentry);
+               return dentry;
 
        acc_mode = ACC_MODE(flag);
        if (flag & O_CREAT) {
@@ -629,56 +623,55 @@ int open_namei(const char * pathname, int flag, int mode, struct inode ** res_in
                        if (inode->i_sb && inode->i_sb->dq_op)
                                inode->i_sb->dq_op->initialize(inode, -1);
 
-       *res_inode = inode;
-       atomic_inc(&inode->i_count);
-       error = 0;
+       return dentry;
 
 exit:
        dput(dentry);
-       return error;
+       return ERR_PTR(error);
 }
 
-int do_mknod(const char * filename, int mode, dev_t dev)
+struct dentry * do_mknod(const char * filename, int mode, dev_t dev)
 {
        int error;
        struct inode *dir;
-       struct dentry *dentry;
+       struct dentry *dentry, *retval;
 
        mode &= ~current->fs->umask;
        dentry = lookup_dentry(filename, NULL, 1);
-
-       error = PTR_ERR(dentry);
        if (IS_ERR(dentry))
-               goto exit;
+               return dentry;
 
        dir = lock_parent(dentry);
 
-       error = -EEXIST;
+       retval = ERR_PTR(-EEXIST);
        if (dentry->d_inode)
                goto exit_lock;
 
-       error = -EROFS;
+       retval = ERR_PTR(-EROFS);
        if (IS_RDONLY(dir))
                goto exit_lock;
 
        error = permission(dir,MAY_WRITE | MAY_EXEC);
+       retval = ERR_PTR(error);
        if (error)
                goto exit_lock;
 
-       error = -EPERM;
+       retval = ERR_PTR(-EPERM);
        if (!dir->i_op || !dir->i_op->mknod)
                goto exit_lock;
 
        if (dir->i_sb && dir->i_sb->dq_op)
                dir->i_sb->dq_op->initialize(dir, -1);
        error = dir->i_op->mknod(dir, dentry, mode, dev);
+       retval = ERR_PTR(error);
+       if (!error)
+               retval = dget(dentry);
 
 exit_lock:
        up(&dir->i_sem);
        iput(dir);
        dput(dentry);
-exit:
-       return error;
+       return retval;
 }
 
 asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev)
@@ -700,10 +693,16 @@ asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev)
        default:
                goto out;
        }
-       error = getname(filename,&tmp);
-       if (!error) {
-               error = do_mknod(tmp,mode,dev);
+       tmp = getname(filename);
+       error = PTR_ERR(tmp);
+       if (!IS_ERR(tmp)) {
+               struct dentry * dentry = do_mknod(tmp,mode,dev);
                putname(tmp);
+               error = PTR_ERR(dentry);
+               if (!IS_ERR(dentry)) {
+                       dput(dentry);
+                       error = 0;
+               }
        }
 out:
        unlock_kernel();
@@ -762,8 +761,9 @@ asmlinkage int sys_mkdir(const char * pathname, int mode)
        char * tmp;
 
        lock_kernel();
-       error = getname(pathname,&tmp);
-       if (!error) {
+       tmp = getname(pathname);
+       error = PTR_ERR(tmp);
+       if (!IS_ERR(tmp)) {
                error = do_mkdir(tmp,mode);
                putname(tmp);
        }
@@ -830,8 +830,9 @@ asmlinkage int sys_rmdir(const char * pathname)
        char * tmp;
 
        lock_kernel();
-       error = getname(pathname,&tmp);
-       if (!error) {
+       tmp = getname(pathname);
+       error = PTR_ERR(tmp);
+       if (!IS_ERR(tmp)) {
                error = do_rmdir(tmp);
                putname(tmp);
        }
@@ -890,8 +891,9 @@ asmlinkage int sys_unlink(const char * pathname)
        char * tmp;
 
        lock_kernel();
-       error = getname(pathname,&tmp);
-       if (!error) {
+       tmp = getname(pathname);
+       error = PTR_ERR(tmp);
+       if (!IS_ERR(tmp)) {
                error = do_unlink(tmp);
                putname(tmp);
        }
@@ -944,13 +946,16 @@ exit:
 asmlinkage int sys_symlink(const char * oldname, const char * newname)
 {
        int error;
-       char * from, * to;
+       char * from;
 
        lock_kernel();
-       error = getname(oldname,&from);
-       if (!error) {
-               error = getname(newname,&to);
-               if (!error) {
+       from = getname(oldname);
+       error = PTR_ERR(from);
+       if (!IS_ERR(from)) {
+               char * to;
+               to = getname(newname);
+               error = PTR_ERR(to);
+               if (!IS_ERR(to)) {
                        error = do_symlink(from,to);
                        putname(to);
                }
@@ -1027,13 +1032,16 @@ exit:
 asmlinkage int sys_link(const char * oldname, const char * newname)
 {
        int error;
-       char * from, * to;
+       char * from;
 
        lock_kernel();
-       error = getname(oldname,&from);
-       if (!error) {
-               error = getname(newname,&to);
-               if (!error) {
+       from = getname(oldname);
+       error = PTR_ERR(from);
+       if (!IS_ERR(from)) {
+               char * to;
+               to = getname(newname);
+               error = PTR_ERR(to);
+               if (!IS_ERR(to)) {
                        error = do_link(from,to);
                        putname(to);
                }
@@ -1142,13 +1150,16 @@ exit:
 asmlinkage int sys_rename(const char * oldname, const char * newname)
 {
        int error;
-       char * from, * to;
+       char * from;
 
        lock_kernel();
-       error = getname(oldname,&from);
-       if (!error) {
-               error = getname(newname,&to);
-               if (!error) {
+       from = getname(oldname);
+       error = PTR_ERR(from);
+       if (!IS_ERR(from)) {
+               char * to;
+               to = getname(newname);
+               error = PTR_ERR(to);
+               if (!IS_ERR(to)) {
                        error = do_rename(from,to);
                        putname(to);
                }
index 4688954762c0f47f927dd81245a35686991fddf6..6e5d806bc8a44cd2f9a0bd28a571ee903cffc2e7 100644 (file)
@@ -180,11 +180,11 @@ nfs_lock(struct inode *inode, struct file *filp, int cmd, struct file_lock *fl)
        int     status;
 
        dprintk("NFS: nfs_lock(f=%4x/%ld, t=%x, fl=%x, r=%ld:%ld)\n",
-                       filp->f_inode->i_dev, filp->f_inode->i_ino,
+                       filp->f_dentry->d_inode->i_dev, filp->f_dentry->d_inode->i_ino,
                        fl->fl_type, fl->fl_flags,
                        fl->fl_start, fl->fl_end);
 
-       if (!(inode = filp->f_inode))
+       if (!(inode = filp->f_dentry->d_inode))
                return -EINVAL;
 
        /* No mandatory locks over NFS */
index c6162be453d2d58cb93d9743a679cf3716cac54c..e4cf24393bc74cf6427baac11088e18eeeb17b17 100644 (file)
@@ -38,7 +38,7 @@ static int nfs_notify_change(struct inode *, struct iattr *);
 static void nfs_put_inode(struct inode *);
 static void nfs_put_super(struct super_block *);
 static void nfs_read_inode(struct inode *);
-static void nfs_statfs(struct super_block *, struct statfs *, int bufsiz);
+static int nfs_statfs(struct super_block *, struct statfs *, int bufsiz);
 
 static struct super_operations nfs_sops = { 
        nfs_read_inode,         /* read inode */
@@ -249,7 +249,7 @@ failure:
        return NULL;
 }
 
-static void
+static int
 nfs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
 {
        int error;
@@ -270,7 +270,7 @@ nfs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
        tmp.f_files = 0;
        tmp.f_ffree = 0;
        tmp.f_namelen = NAME_MAX;
-       copy_to_user(buf, &tmp, bufsiz);
+       return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
 }
 
 /*
index f2ebc8110c62791444102e707232b8b32882f021..4a3653e73b625b00cd2cce8a7d414236be15bf35 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
 
 asmlinkage int sys_statfs(const char * path, struct statfs * buf)
 {
-       struct inode * inode;
+       struct dentry * dentry;
        int error;
 
        lock_kernel();
-       error = verify_area(VERIFY_WRITE, buf, sizeof(struct statfs));
-       if (error)
-               goto out;
-       error = namei(path, &inode);
-       if (error)
-               goto out;
-       error = -ENOSYS;
-       if (!inode->i_sb->s_op->statfs) {
-               iput(inode);
-               goto out;
+       dentry = namei(path);
+       error = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+               struct inode * inode = dentry->d_inode;
+
+               error = -ENOSYS;
+               if (inode->i_sb->s_op->statfs)
+                       error = inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs));
+
+               dput(dentry);
        }
-       inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs));
-       iput(inode);
-       error = 0;
-out:
        unlock_kernel();
        return error;
 }
@@ -52,6 +48,7 @@ out:
 asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf)
 {
        struct inode * inode;
+       struct dentry * dentry;
        struct file * file;
        int error;
 
@@ -61,7 +58,9 @@ asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf)
                goto out;
        if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
                error = -EBADF;
-       else if (!(inode = file->f_inode))
+       else if (!(dentry = file->f_dentry))
+               error = -ENOENT;
+       else if (!(inode = dentry->d_inode))
                error = -ENOENT;
        else if (!inode->i_sb)
                error = -ENODEV;
@@ -95,33 +94,37 @@ int do_truncate(struct inode *inode, unsigned long length)
 
 asmlinkage int sys_truncate(const char * path, unsigned long length)
 {
+       struct dentry * dentry;
        struct inode * inode;
        int error;
 
        lock_kernel();
-       error = namei(path, &inode);
-       if (error)
+       dentry = namei(path);
+
+       error = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
                goto out;
+       inode = dentry->d_inode;
 
        error = -EACCES;
        if (S_ISDIR(inode->i_mode))
-               goto iput_and_out;
+               goto dput_and_out;
 
        error = permission(inode,MAY_WRITE);
        if (error)
-               goto iput_and_out;
+               goto dput_and_out;
 
        error = -EROFS;
        if (IS_RDONLY(inode))
-               goto iput_and_out;
+               goto dput_and_out;
 
        error = -EPERM;
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               goto iput_and_out;
+               goto dput_and_out;
 
        error = get_write_access(inode);
        if (error)
-               goto iput_and_out;
+               goto dput_and_out;
 
        error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, NULL,
                                  length < inode->i_size ? length : inode->i_size,
@@ -132,8 +135,8 @@ asmlinkage int sys_truncate(const char * path, unsigned long length)
                error = do_truncate(inode, length);
        }
        put_write_access(inode);
-iput_and_out:
-       iput(inode);
+dput_and_out:
+       dput(dentry);
 out:
        unlock_kernel();
        return error;
@@ -142,13 +145,16 @@ out:
 asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length)
 {
        struct inode * inode;
+       struct dentry *dentry;
        struct file * file;
        int error;
 
        lock_kernel();
        if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
                error = -EBADF;
-       else if (!(inode = file->f_inode))
+       else if (!(dentry = file->f_dentry))
+               error = -ENOENT;
+       else if (!(inode = dentry->d_inode))
                error = -ENOENT;
        else if (S_ISDIR(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
                error = -EACCES;
@@ -181,17 +187,21 @@ asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length)
 asmlinkage int sys_utime(char * filename, struct utimbuf * times)
 {
        int error;
+       struct dentry * dentry;
        struct inode * inode;
        struct iattr newattrs;
 
        lock_kernel();
-       /* Hmm, should I always follow symlinks or not ? */
-       error = namei(filename, &inode);
-       if (error)
+       dentry = namei(filename);
+
+       error = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
                goto out;
+       inode = dentry->d_inode;
+
        error = -EROFS;
        if (IS_RDONLY(inode))
-               goto iput_and_out;
+               goto dput_and_out;
 
        /* Don't worry, the checks are done in inode_change_ok() */
        newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
@@ -200,17 +210,17 @@ asmlinkage int sys_utime(char * filename, struct utimbuf * times)
                if (!error) 
                        error = get_user(newattrs.ia_mtime, &times->modtime);
                if (error)
-                       goto iput_and_out;
+                       goto dput_and_out;
 
                newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
        } else {
                if (current->fsuid != inode->i_uid &&
                    (error = permission(inode,MAY_WRITE)) != 0)
-                       goto iput_and_out;
+                       goto dput_and_out;
        }
        error = notify_change(inode, &newattrs);
-iput_and_out:
-       iput(inode);
+dput_and_out:
+       dput(dentry);
 out:
        unlock_kernel();
        return error;
@@ -225,33 +235,39 @@ out:
 asmlinkage int sys_utimes(char * filename, struct timeval * utimes)
 {
        int error;
+       struct dentry * dentry;
        struct inode * inode;
        struct iattr newattrs;
 
        lock_kernel();
-       error = namei(filename, &inode);
-       if (error)
+       dentry = namei(filename);
+
+       error = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
                goto out;
+       inode = dentry->d_inode;
+
        error = -EROFS;
        if (IS_RDONLY(inode))
-               goto iput_and_out;
+               goto dput_and_out;
+
        /* Don't worry, the checks are done in inode_change_ok() */
        newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
        if (utimes) {
                struct timeval times[2];
                error = -EFAULT;
                if (copy_from_user(&times, utimes, sizeof(times)))
-                       goto iput_and_out;
+                       goto dput_and_out;
                newattrs.ia_atime = times[0].tv_sec;
                newattrs.ia_mtime = times[1].tv_sec;
                newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
        } else {
                if ((error = permission(inode,MAY_WRITE)) != 0)
-                       goto iput_and_out;
+                       goto dput_and_out;
        }
        error = notify_change(inode, &newattrs);
-iput_and_out:
-       iput(inode);
+dput_and_out:
+       dput(dentry);
 out:
        unlock_kernel();
        return error;
@@ -263,7 +279,7 @@ out:
  */
 asmlinkage int sys_access(const char * filename, int mode)
 {
-       struct inode * inode;
+       struct dentry * dentry;
        int old_fsuid, old_fsgid;
        int res = -EINVAL;
 
@@ -274,11 +290,14 @@ asmlinkage int sys_access(const char * filename, int mode)
        old_fsgid = current->fsgid;
        current->fsuid = current->uid;
        current->fsgid = current->gid;
-       res = namei(filename, &inode);
-       if (!res) {
-               res = permission(inode, mode);
-               iput(inode);
+
+       dentry = namei(filename);
+       res = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+               res = permission(dentry->d_inode, mode);
+               dput(dentry);
        }
+
        current->fsuid = old_fsuid;
        current->fsgid = old_fsgid;
 out:
@@ -327,6 +346,7 @@ out:
 asmlinkage int sys_fchdir(unsigned int fd)
 {
        struct file *file;
+       struct dentry *dentry;
        struct inode *inode;
        int error;
 
@@ -337,7 +357,9 @@ asmlinkage int sys_fchdir(unsigned int fd)
                goto out;
 
        error = -ENOENT;
-       if (!(inode = file->f_inode))
+       if (!(dentry = file->f_dentry))
+               goto out;
+       if (!(inode = dentry->d_inode))
                goto out;
 
        error = -ENOTDIR;
@@ -349,11 +371,10 @@ asmlinkage int sys_fchdir(unsigned int fd)
                goto out;
 
        {
-               struct dentry *dentry, *tmp;
+               struct dentry *tmp;
        
-               dentry = dget(i_dentry(inode));
                tmp = current->fs->pwd;
-               current->fs->pwd = dentry;
+               current->fs->pwd = dget(dentry);
                dput(tmp);
        }
 out:
@@ -406,6 +427,7 @@ out:
 asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
 {
        struct inode * inode;
+       struct dentry * dentry;
        struct file * file;
        struct iattr newattrs;
        int err = -EBADF;
@@ -414,7 +436,9 @@ asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
        if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
                goto out;
        err = -ENOENT;
-       if (!(inode = file->f_inode))
+       if (!(dentry = file->f_dentry))
+               goto out;
+       if (!(inode = dentry->d_inode))
                goto out;
        err = -EROFS;
        if (IS_RDONLY(inode))
@@ -434,31 +458,35 @@ out:
 
 asmlinkage int sys_chmod(const char * filename, mode_t mode)
 {
+       struct dentry * dentry;
        struct inode * inode;
        int error;
        struct iattr newattrs;
 
        lock_kernel();
-       /* I'm not sure whether to use NAM_FOLLOW_TRAILSLASH instead,
-        * because permissions on symlinks now can never be changed,
-        * but on the other hand they are never needed.
-        */
-       error = namei(filename, &inode);
-       if (error)
+       dentry = namei(filename);
+
+       error = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
                goto out;
+       inode = dentry->d_inode;
+
        error = -EROFS;
        if (IS_RDONLY(inode))
-               goto iput_and_out;
+               goto dput_and_out;
+
        error = -EPERM;
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               goto iput_and_out;
+               goto dput_and_out;
+
        if (mode == (mode_t) -1)
                mode = inode->i_mode;
        newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
        newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
        error = notify_change(inode, &newattrs);
-iput_and_out:
-       iput(inode);
+
+dput_and_out:
+       dput(dentry);
 out:
        unlock_kernel();
        return error;
@@ -467,6 +495,7 @@ out:
 asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
 {
        struct inode * inode;
+       struct dentry * dentry;
        struct file * file;
        struct iattr newattrs;
        int error = -EBADF;
@@ -475,7 +504,9 @@ asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
        if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
                goto out;
        error = -ENOENT;
-       if (!(inode = file->f_inode))
+       if (!(dentry = file->f_dentry))
+               goto out;
+       if (!(inode = dentry->d_inode))
                goto out;
        error = -EROFS;
        if (IS_RDONLY(inode))
@@ -525,20 +556,27 @@ out:
 
 asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
 {
+       struct dentry * dentry;
        struct inode * inode;
        int error;
        struct iattr newattrs;
 
        lock_kernel();
-       error = namei(filename, &inode);
-       if (error)
+       dentry = namei(filename);
+
+       error = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
                goto out;
+       inode = dentry->d_inode;
+
        error = -EROFS;
        if (IS_RDONLY(inode))
-               goto iput_and_out;
+               goto dput_and_out;
+
        error = -EPERM;
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               goto iput_and_out;
+               goto dput_and_out;
+
        if (user == (uid_t) -1)
                user = inode->i_uid;
        if (group == (gid_t) -1)
@@ -568,14 +606,14 @@ asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
                inode->i_sb->dq_op->initialize(inode, -1);
                error = -EDQUOT;
                if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0))
-                       goto iput_and_out;
+                       goto dput_and_out;
                error = notify_change(inode, &newattrs);
                if (error)
                        inode->i_sb->dq_op->transfer(inode, &newattrs, 1);
        } else
                error = notify_change(inode, &newattrs);
-iput_and_out:
-       iput(inode);
+dput_and_out:
+       dput(dentry);
 out:
        unlock_kernel();
        return(error);
@@ -598,6 +636,7 @@ out:
 static int do_open(const char * filename,int flags,int mode, int fd)
 {
        struct inode * inode;
+       struct dentry * dentry;
        struct file * f;
        int flag,error;
 
@@ -610,16 +649,18 @@ static int do_open(const char * filename,int flags,int mode, int fd)
                flag++;
        if (flag & O_TRUNC)
                flag |= 2;
-       error = open_namei(filename,flag,mode,&inode);
-       if (error)
+       dentry = open_namei(filename,flag,mode);
+       error = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
                goto cleanup_file;
+       inode = dentry->d_inode;
        if (f->f_mode & FMODE_WRITE) {
                error = get_write_access(inode);
                if (error)
-                       goto cleanup_inode;
+                       goto cleanup_dentry;
        }
 
-       f->f_inode = inode;
+       f->f_dentry = dentry;
        f->f_pos = 0;
        f->f_reada = 0;
        f->f_op = NULL;
@@ -638,8 +679,8 @@ static int do_open(const char * filename,int flags,int mode, int fd)
 cleanup_all:
        if (f->f_mode & FMODE_WRITE)
                put_write_access(inode);
-cleanup_inode:
-       iput(inode);
+cleanup_dentry:
+       dput(dentry);
 cleanup_file:
        put_filp(f);
        return error;
@@ -673,14 +714,15 @@ asmlinkage int sys_open(const char * filename,int flags,int mode)
        int fd, error;
 
        lock_kernel();
-       fd = get_unused_fd();
-       if (fd < 0) {
-               error = fd;
+       error = get_unused_fd();
+       if (error < 0)
                goto out;
-       }
-       error = getname(filename, &tmp);
-       if (!error) {
-               error = do_open(tmp,flags,mode, fd);
+
+       fd = error;
+       tmp = getname(filename);
+       error = PTR_ERR(tmp);
+       if (!IS_ERR(tmp)) {
+               error = do_open(tmp,flags,mode,fd);
                putname(tmp);
                if (!error) {
                        error = fd;
@@ -711,31 +753,35 @@ asmlinkage int sys_creat(const char * pathname, int mode)
 
 #endif
 
-int __fput(struct file *filp, struct inode *inode)
+int __fput(struct file *filp)
 {
        int     error = 0;
+       struct dentry * dentry = filp->f_dentry;
+       struct inode * inode = dentry->d_inode;
 
        if (filp->f_op && filp->f_op->release)
                error = filp->f_op->release(inode,filp);
-       filp->f_inode = NULL;
+       filp->f_dentry = NULL;
        if (filp->f_mode & FMODE_WRITE)
                put_write_access(inode);
-       iput(inode);
+       dput(dentry);
        return error;
 }
 
 int close_fp(struct file *filp)
 {
+       struct dentry *dentry;
        struct inode *inode;
 
        if (filp->f_count == 0) {
                printk("VFS: Close: file count is 0\n");
                return 0;
        }
-       inode = filp->f_inode;
+       dentry = filp->f_dentry;
+       inode = dentry->d_inode;
        if (inode)
                locks_remove_locks(current, filp);
-       return fput(filp, inode);
+       return fput(filp);
 }
 
 asmlinkage int sys_close(unsigned int fd)
index 260237cb43aecb3e823fdf72cd6e0b42506f0b46..7361d619d7640cd87b2744bbd20d17033bdfb762 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -165,7 +165,7 @@ static int pipe_ioctl(struct inode *pino, struct file * filp,
 static unsigned int pipe_poll(struct file * filp, poll_table * wait)
 {
        unsigned int mask;
-       struct inode * inode = filp->f_inode;
+       struct inode * inode = filp->f_dentry->d_inode;
 
        poll_wait(&PIPE_WAIT(*inode), wait);
        mask = POLLIN | POLLRDNORM;
@@ -186,7 +186,7 @@ static unsigned int pipe_poll(struct file * filp, poll_table * wait)
 static unsigned int fifo_poll(struct file * filp, poll_table * wait)
 {
        unsigned int mask;
-       struct inode * inode = filp->f_inode;
+       struct inode * inode = filp->f_dentry->d_inode;
 
        poll_wait(&PIPE_WAIT(*inode), wait);
        mask = POLLIN | POLLRDNORM;
@@ -218,7 +218,7 @@ static long connect_read(struct inode * inode, struct file * filp,
 
 static unsigned int connect_poll(struct file * filp, poll_table * wait)
 {
-       struct inode * inode = filp->f_inode;
+       struct inode * inode = filp->f_dentry->d_inode;
 
        poll_wait(&PIPE_WAIT(*inode), wait);
        if (!PIPE_EMPTY(*inode)) {
@@ -419,7 +419,7 @@ int do_pipe(int *fd)
                goto close_f12_inode_i;
        j = error;
 
-       f1->f_inode = f2->f_inode = inode;
+       f1->f_dentry = f2->f_dentry = d_alloc_root(inode, NULL);
 
        /* read file */
        f1->f_pos = f2->f_pos = 0;
@@ -440,7 +440,6 @@ int do_pipe(int *fd)
 close_f12_inode_i:
        put_unused_fd(i);
 close_f12_inode:
-       atomic_dec(&inode->i_count);
        iput(inode);
 close_f12:
        put_filp(f2);
index 82a3257d2056d32c46ce424c66c64a4c4e385d18..a17100943c9a4f3a57c474f2123af3fbc7916dea 100644 (file)
@@ -591,7 +591,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_inode) {
+                       if (!vma->vm_dentry) {
                                data += len;
                                if (vma->vm_flags & VM_GROWSDOWN)
                                        stack += len;
@@ -949,12 +949,11 @@ static long read_maps (int pid, struct file * file,
                *cp++ = flags & VM_MAYSHARE ? 's' : 'p';
                *cp++ = 0;
 
-               if (map->vm_inode != NULL) {
-                       dev = map->vm_inode->i_dev;
-                       ino = map->vm_inode->i_ino;
-               } else {
-                       dev = 0;
-                       ino = 0;
+               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;
                }
 
                len = sprintf(line,
index 1249c14809e1acee3e7257b5800dc6c6b39ad8fb..e57131d3fe3514fe9c3bb6d2baf64eb2ef7e9a23 100644 (file)
@@ -100,7 +100,7 @@ static int proc_lookupfd(struct inode * dir, struct qstr *str, struct inode ** r
        if (fd >= NR_OPEN       ||
            !p->files           ||
            !p->files->fd[fd]   ||
-           !p->files->fd[fd]->f_inode)
+           !p->files->fd[fd]->f_dentry)
                return -ENOENT;
 
        ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
@@ -144,7 +144,7 @@ static int proc_readfd(struct inode * inode, struct file * filp,
        for (fd -= 2 ; fd < NR_OPEN; fd++, filp->f_pos++) {
                if (!p->files)
                        break;
-               if (!p->files->fd[fd] || !p->files->fd[fd]->f_inode)
+               if (!p->files->fd[fd] || !p->files->fd[fd]->f_dentry)
                        continue;
 
                j = NUMBUF;
index 0a5397830aade19d4b207c1d73f3ffbb0443b07b..9ec25bec3f0fc2f377e7297a0528cd552822f363 100644 (file)
@@ -141,7 +141,7 @@ struct super_block *proc_read_super(struct super_block *s,void *data,
        return s;
 }
 
-void proc_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+int proc_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
 {
        struct statfs tmp;
 
@@ -153,7 +153,7 @@ void proc_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
        tmp.f_files = 0;
        tmp.f_ffree = 0;
        tmp.f_namelen = NAME_MAX;
-       copy_to_user(buf, &tmp, bufsiz);
+       return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
 }
 
 void proc_read_inode(struct inode * inode)
index 87ff290bb0d693ffe53827e44b74f28cb07d5290..c25fd702b9a23b3c3bd95ed0358af9eeef075c27 100644 (file)
@@ -104,7 +104,7 @@ static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base
                        vma = p->mm->mmap;
                        while (vma) {
                                if (vma->vm_flags & VM_EXECUTABLE)
-                                       return dget(i_dentry(vma->vm_inode));
+                                       return dget(vma->vm_dentry);
 
                                vma = vma->vm_next;
                        }
@@ -120,9 +120,9 @@ static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base
                                        break;
                                if (!p->files->fd[ino])
                                        break;
-                               if (!p->files->fd[ino]->f_inode)
+                               if (!p->files->fd[ino]->f_dentry)
                                        break;
-                               result = dget(i_dentry(p->files->fd[ino]->f_inode));
+                               result = dget(p->files->fd[ino]->f_dentry);
                                break;
                        }
        }
index eafabcfbd217fb4a96fb8b79449f759d33d38ef2..6c422b7f4f814dda8faa02d12033fd14f80e3c8e 100644 (file)
@@ -60,13 +60,15 @@ asmlinkage long sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
 {
        long retval;
        struct file * file;
+       struct dentry * dentry;
        struct inode * inode;
 
        lock_kernel();
        retval = -EBADF;
        if (fd >= NR_OPEN ||
            !(file = current->files->fd[fd]) ||
-           !(inode = file->f_inode))
+           !(dentry = file->f_dentry) ||
+           !(inode = dentry->d_inode))
                goto bad;
        retval = -EINVAL;
        if (origin > 2)
@@ -83,6 +85,7 @@ asmlinkage int sys_llseek(unsigned int fd, unsigned long offset_high,
 {
        long retval;
        struct file * file;
+       struct dentry * dentry;
        struct inode * inode;
        long long offset;
 
@@ -90,7 +93,8 @@ asmlinkage int sys_llseek(unsigned int fd, unsigned long offset_high,
        retval = -EBADF;
        if (fd >= NR_OPEN ||
            !(file = current->files->fd[fd]) ||
-           !(inode = file->f_inode))
+           !(dentry = file->f_dentry) ||
+           !(inode = dentry->d_inode))
                goto bad;
        retval = -EINVAL;
        if (origin > 2)
@@ -115,6 +119,7 @@ asmlinkage long sys_read(unsigned int fd, char * buf, unsigned long count)
 {
        int error;
        struct file * file;
+       struct dentry * dentry;
        struct inode * inode;
        long (*read)(struct inode *, struct file *, char *, unsigned long);
 
@@ -123,7 +128,10 @@ asmlinkage long sys_read(unsigned int fd, char * buf, unsigned long count)
        file = fget(fd);
        if (!file)
                goto bad_file;
-       inode = file->f_inode;
+       dentry = file->f_dentry;
+       if (!dentry)
+               goto bad_file;
+       inode = dentry->d_inode;
        if (!inode)
                goto out;
        error = -EBADF;
@@ -137,7 +145,7 @@ asmlinkage long sys_read(unsigned int fd, char * buf, unsigned long count)
                goto out;
        error = read(inode,file,buf,count);
 out:
-       fput(file, inode);
+       fput(file);
 bad_file:
        unlock_kernel();
        return error;
@@ -147,6 +155,7 @@ asmlinkage long sys_write(unsigned int fd, const char * buf, unsigned long count
 {
        int error;
        struct file * file;
+       struct dentry * dentry;
        struct inode * inode;
        long (*write)(struct inode *, struct file *, const char *, unsigned long);
 
@@ -155,7 +164,10 @@ asmlinkage long sys_write(unsigned int fd, const char * buf, unsigned long count
        file = fget(fd);
        if (!file)
                goto bad_file;
-       inode = file->f_inode;
+       dentry = file->f_dentry;
+       if (!dentry)
+               goto out;
+       inode = dentry->d_inode;
        if (!inode)
                goto out;
        if (!(file->f_mode & 2))
@@ -170,7 +182,7 @@ asmlinkage long sys_write(unsigned int fd, const char * buf, unsigned long count
        error = write(inode,file,buf,count);
        up(&inode->i_sem);
 out:
-       fput(file, inode);
+       fput(file);
 bad_file:
        unlock_kernel();
        return error;
@@ -271,14 +283,30 @@ static long do_readv_writev(int type, struct inode * inode, struct file * file,
 asmlinkage long sys_readv(unsigned long fd, const struct iovec * vector, unsigned long count)
 {
        struct file * file;
+       struct dentry * dentry;
        struct inode * inode;
-       long err = -EBADF;
+       long err;
 
        lock_kernel();
-       if (fd >= NR_OPEN || !(file = current->files->fd[fd]) || !(inode=file->f_inode))
+       err = -EBADF;
+       if (fd >= NR_OPEN)
+               goto out;
+
+       file = current->files->fd[fd];
+       if (!file)
                goto out;
+
        if (!(file->f_mode & 1))
                goto out;
+
+       dentry = file->f_dentry;
+       if (!dentry)
+               goto out;
+
+       inode = dentry->d_inode;
+       if (!inode)
+               goto out;
+
        err = do_readv_writev(VERIFY_WRITE, inode, file, vector, count);
 out:
        unlock_kernel();
@@ -287,15 +315,32 @@ out:
 
 asmlinkage long sys_writev(unsigned long fd, const struct iovec * vector, unsigned long count)
 {
-       int error = -EBADF;
+       long error;
        struct file * file;
+       struct dentry * dentry;
        struct inode * inode;
 
        lock_kernel();
-       if (fd >= NR_OPEN || !(file = current->files->fd[fd]) || !(inode=file->f_inode))
+       error = -EBADF;
+
+       if (fd >= NR_OPEN)
+               goto out;
+
+       file = current->files->fd[fd];
+       if (!file)
                goto out;
+
        if (!(file->f_mode & 2))
                goto out;
+
+       dentry = file->f_dentry;
+       if (!dentry)
+               goto out;
+
+       inode = dentry->d_inode;
+       if (!inode)
+               goto out;
+
        down(&inode->i_sem);
        error = do_readv_writev(VERIFY_READ, inode, file, vector, count);
        up(&inode->i_sem);
index aaea5b45fca26306b1e5aefe9de04c78f8e8f35e..2a2b0a707caacca054eecf9e7c382c2dda5b36c5 100644 (file)
@@ -57,22 +57,37 @@ static int fillonedir(void * __buf, const char * name, int namlen, off_t offset,
 
 asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count)
 {
-       int error = -EBADF;
+       int error;
        struct file * file;
+       struct dentry * dentry;
+       struct inode * inode;
        struct readdir_callback buf;
 
        lock_kernel();
-       if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+       error = -EBADF;
+       if (fd >= NR_OPEN)
                goto out;
-       error = -ENOTDIR;
-       if (!file->f_op || !file->f_op->readdir)
+
+       file = current->files->fd[fd];
+       if (!file)
                goto out;
-       error = verify_area(VERIFY_WRITE, dirent, sizeof(struct old_linux_dirent));
-       if (error)
+
+       dentry = file->f_dentry;
+       if (!dentry)
+               goto out;
+
+       inode = dentry->d_inode;
+       if (!inode)
                goto out;
+
        buf.count = 0;
        buf.dirent = dirent;
-       error = file->f_op->readdir(file->f_inode, file, &buf, fillonedir);
+
+       error = -ENOTDIR;
+       if (!file->f_op || !file->f_op->readdir)
+               goto out;
+
+       error = file->f_op->readdir(inode, file, &buf, fillonedir);
        if (error < 0)
                goto out;
        error = buf.count;
@@ -126,30 +141,44 @@ static int filldir(void * __buf, const char * name, int namlen, off_t offset, in
 asmlinkage int sys_getdents(unsigned int fd, void * dirent, unsigned int count)
 {
        struct file * file;
+       struct dentry * dentry;
+       struct inode * inode;
        struct linux_dirent * lastdirent;
        struct getdents_callback buf;
-       int error = -EBADF;
+       int error;
 
        lock_kernel();
-       if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+       error = -EBADF;
+       if (fd >= NR_OPEN)
                goto out;
-       error = -ENOTDIR;
-       if (!file->f_op || !file->f_op->readdir)
+
+       file = current->files->fd[fd];
+       if (!file)
                goto out;
-       error = verify_area(VERIFY_WRITE, dirent, count);
-       if (error)
+
+       dentry = file->f_dentry;
+       if (!dentry)
+               goto out;
+
+       inode = dentry->d_inode;
+       if (!inode)
                goto out;
+
        buf.current_dir = (struct linux_dirent *) dirent;
        buf.previous = NULL;
        buf.count = count;
        buf.error = 0;
-       error = file->f_op->readdir(file->f_inode, file, &buf, filldir);
+
+       error = -ENOTDIR;
+       if (!file->f_op || !file->f_op->readdir)
+               goto out;
+
+       error = file->f_op->readdir(inode, file, &buf, filldir);
        if (error < 0)
                goto out;
        lastdirent = buf.previous;
-       if (!lastdirent) {
-               error = buf.error;
-       } else {
+       error = buf.error;
+       if (lastdirent) {
                put_user(file->f_pos, &lastdirent->d_off);
                error = count - buf.count;
        }
index 8959810a1787dca378bdfe879ba5ff73e3770779..59f918e7b4c913cd0f39e124fdd720516158e9f1 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -116,6 +116,7 @@ static int cp_new_stat(struct inode * inode, struct stat * statbuf)
        return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
 }
 
+
 #if !defined(__alpha__) && !defined(__sparc__)
 /*
  * For backward compatibility?  Maybe this should be moved
@@ -123,17 +124,21 @@ static int cp_new_stat(struct inode * inode, struct stat * statbuf)
  */
 asmlinkage int sys_stat(char * filename, struct __old_kernel_stat * statbuf)
 {
-       struct inode * inode;
+       struct dentry * dentry;
        int error;
 
        lock_kernel();
-       error = namei(filename, &inode);
-       if (error)
-               goto out;
-       if ((error = do_revalidate(inode)) == 0)
-               error = cp_old_stat(inode,statbuf);
-       iput(inode);
-out:
+       dentry = namei(filename);
+
+       error = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+               struct inode * inode = dentry->d_inode;
+               error = do_revalidate(inode);
+               if (!error)
+                       error = cp_old_stat(inode, statbuf);
+
+               dput(dentry);
+       }
        unlock_kernel();
        return error;
 }
@@ -141,17 +146,21 @@ out:
 
 asmlinkage int sys_newstat(char * filename, struct stat * statbuf)
 {
-       struct inode * inode;
+       struct dentry * dentry;
        int error;
 
        lock_kernel();
-       error = namei(filename, &inode);
-       if (error)
-               goto out;
-       if ((error = do_revalidate(inode)) == 0)
-               error = cp_new_stat(inode,statbuf);
-       iput(inode);
-out:
+       dentry = namei(filename);
+
+       error = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+               struct inode * inode = dentry->d_inode;
+               error = do_revalidate(inode);
+               if (!error)
+                       error = cp_new_stat(inode,statbuf);
+
+               dput(dentry);
+       }
        unlock_kernel();
        return error;
 }
@@ -164,17 +173,21 @@ out:
  */
 asmlinkage int sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
 {
-       struct inode * inode;
+       struct dentry * dentry;
        int error;
 
        lock_kernel();
-       error = lnamei(filename, &inode);
-       if (error)
-               goto out;
-       if ((error = do_revalidate(inode)) == 0)
-               error = cp_old_stat(inode,statbuf);
-       iput(inode);
-out:
+       dentry = lnamei(filename);
+
+       error = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+               struct inode * inode = dentry->d_inode;
+               error = do_revalidate(inode);
+               if (!error)
+                       error = cp_old_stat(inode, statbuf);
+
+               dput(dentry);
+       }
        unlock_kernel();
        return error;
 }
@@ -183,17 +196,21 @@ out:
 
 asmlinkage int sys_newlstat(char * filename, struct stat * statbuf)
 {
-       struct inode * inode;
+       struct dentry * dentry;
        int error;
 
        lock_kernel();
-       error = lnamei(filename, &inode);
-       if (error)
-               goto out;
-       if ((error = do_revalidate(inode)) == 0)
-               error = cp_new_stat(inode,statbuf);
-       iput(inode);
-out:
+       dentry = lnamei(filename);
+
+       error = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+               struct inode * inode = dentry->d_inode;
+               error = do_revalidate(inode);
+               if (!error)
+                       error = cp_new_stat(inode,statbuf);
+
+               dput(dentry);
+       }
        unlock_kernel();
        return error;
 }
@@ -207,17 +224,19 @@ out:
 asmlinkage int sys_fstat(unsigned int fd, struct __old_kernel_stat * statbuf)
 {
        struct file * f;
-       struct inode * inode;
-       int ret = -EBADF;
+       int err = -EBADF;
 
        lock_kernel();
-       if (fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))
-               goto out;
-       if ((ret = do_revalidate(inode)) == 0)
-               ret = cp_old_stat(inode,statbuf);
-out:
+       if (fd < NR_OPEN && (f = current->files->fd[fd]) != NULL) {
+               struct dentry * dentry = f->f_dentry;
+               struct inode * inode = dentry->d_inode;
+
+               err = do_revalidate(inode);
+               if (!err)
+                       err = cp_old_stat(inode,statbuf);
+       }
        unlock_kernel();
-       return ret;
+       return err;
 }
 
 #endif
@@ -225,41 +244,43 @@ out:
 asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf)
 {
        struct file * f;
-       struct inode * inode;
        int err = -EBADF;
 
        lock_kernel();
-       if (fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))
-               goto out;
-       if ((err = do_revalidate(inode)) == 0)
-               err = cp_new_stat(inode,statbuf);
-out:
+       if (fd < NR_OPEN && (f = current->files->fd[fd]) != NULL) {
+               struct dentry * dentry = f->f_dentry;
+               struct inode * inode = dentry->d_inode;
+
+               err = do_revalidate(inode);
+               if (!err)
+                       err = cp_new_stat(inode,statbuf);
+       }
        unlock_kernel();
        return err;
 }
 
 asmlinkage int sys_readlink(const char * path, char * buf, int bufsiz)
 {
-       struct inode * inode;
+       struct dentry * dentry;
        int error;
 
        if (bufsiz <= 0)
                return -EINVAL;
 
        lock_kernel();
-       error = lnamei(path, &inode);
-       if (error)
-               goto out;
-       error = -EINVAL;
-       if (!inode->i_op || !inode->i_op->readlink ||
-           !S_ISLNK(inode->i_mode) || (error = do_revalidate(inode)) < 0) {
-               iput(inode);
-               goto out;
+       dentry = lnamei(path);
+
+       error = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+               struct inode * inode = dentry->d_inode;
+
+               error = -EINVAL;
+               if (inode->i_op && inode->i_op->readlink && !(error = do_revalidate(inode))) {
+                       UPDATE_ATIME(inode);
+                       error = inode->i_op->readlink(inode,buf,bufsiz);
+               }
+               dput(dentry);
        }
-       UPDATE_ATIME(inode);
-       error = inode->i_op->readlink(inode,buf,bufsiz);
-       iput(inode);
-out:
        unlock_kernel();
        return error;
 }
index 802613c6a755e30d536619f5aea2b249c243f571..933b36bb92a22c54f414195dd7a7be5e14050d7f 100644 (file)
@@ -101,13 +101,13 @@ struct vfsmount *add_vfsmnt(kdev_t dev, const char *dev_name, const char *dir_na
 
        lptr->mnt_dev = dev;
        sema_init(&lptr->mnt_sem, 1);
-       if (dev_name && !getname(dev_name, &tmp)) {
+       if (dev_name && !IS_ERR(tmp = getname(dev_name))) {
                if ((lptr->mnt_devname =
                    (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
                        strcpy(lptr->mnt_devname, tmp);
                putname(tmp);
        }
-       if (dir_name && !getname(dir_name, &tmp)) {
+       if (dir_name && !IS_ERR(tmp = getname(dir_name))) {
                if ((lptr->mnt_dirname =
                    (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
                        strcpy(lptr->mnt_dirname, tmp);
@@ -197,9 +197,11 @@ static int fs_index(const char * __name)
        char * name;
        int err, index;
 
-       err = getname(__name, &name);
-       if (err)
+       name = getname(__name);
+       err = PTR_ERR(name);
+       if (IS_ERR(name))
                return err;
+
        index = 0;
        for (tmp = file_systems ; tmp ; tmp = tmp->next) {
                if (strcmp(tmp->name, name) == 0) {
@@ -659,36 +661,43 @@ static int do_umount(kdev_t dev,int unmount_root)
 
 asmlinkage int sys_umount(char * name)
 {
+       struct dentry * dentry;
        struct inode * inode;
        kdev_t dev;
        struct inode * dummy_inode = NULL;
-       int retval = -EPERM;
+       int retval;
 
-       lock_kernel();
        if (!suser())
+               return -EPERM;
+
+       lock_kernel();
+       dentry = namei(name);
+       retval = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
                goto out;
-       retval = namei(name, &inode);
+
+       inode = dentry->d_inode;
        if (S_ISBLK(inode->i_mode)) {
                dev = inode->i_rdev;
                retval = -EACCES;
                if (IS_NODEV(inode)) {
-                       iput(inode);
+                       dput(dentry);
                        goto out;
                }
        } else {
                retval = -EINVAL;
                if (!inode->i_sb || inode != inode->i_sb->s_root->d_inode) {
-                       iput(inode);
+                       dput(dentry);
                        goto out;
                }
                dev = inode->i_sb->s_dev;
-               iput(inode);
+               dput(dentry);
                inode = dummy_inode = get_empty_inode();
                inode->i_rdev = dev;
        }
        retval = -ENXIO;
        if (MAJOR(dev) >= MAX_BLKDEV) {
-               iput(inode);
+               dput(dentry);
                goto out;
        }
        retval = do_umount(dev,0);
@@ -699,7 +708,7 @@ asmlinkage int sys_umount(char * name)
                        put_unnamed_dev(dev);
                }
        }
-       iput(inode);
+       dput(dentry);
        if (!retval)
                fsync_dev(dev);
 out:
@@ -814,18 +823,19 @@ static int do_remount_sb(struct super_block *sb, int flags, char *data)
 
 static int do_remount(const char *dir,int flags,char *data)
 {
-       struct inode *dir_i;
+       struct dentry *dentry;
        int retval;
 
-       retval = namei(dir, &dir_i);
-       if (retval)
-               return retval;
-       if (dir_i != dir_i->i_sb->s_root->d_inode) {
-               iput(dir_i);
-               return -EINVAL;
+       dentry = namei(dir);
+       retval = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+               struct super_block * sb = dentry->d_inode->i_sb;
+
+               retval = -EINVAL;
+               if (dentry == sb->s_root)
+                       retval = do_remount_sb(sb, flags, data);
+               dput(dentry);
        }
-       retval = do_remount_sb(dir_i->i_sb, flags, data);
-       iput(dir_i);
        return retval;
 }
 
@@ -876,7 +886,8 @@ asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
        unsigned long new_flags, void * data)
 {
        struct file_system_type * fstype;
-       struct inode * inode;
+       struct dentry * dentry = NULL;
+       struct inode * inode = NULL;
        struct file_operations * fops;
        kdev_t dev;
        int retval = -EPERM;
@@ -908,58 +919,54 @@ asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
                goto out;
        t = fstype->name;
        fops = NULL;
-       if ((fstype->fs_flags & FS_REQUIRES_DEV)) {
-               retval = namei(dev_name, &inode);
-               if (retval)
+       if (fstype->fs_flags & FS_REQUIRES_DEV) {
+               dentry = namei(dev_name);
+               retval = PTR_ERR(dentry);
+               if (IS_ERR(dentry))
                        goto out;
+
+               inode = dentry->d_inode;
                retval = -ENOTBLK;
-               if (!S_ISBLK(inode->i_mode)) {
-                       iput(inode);
-                       goto out;
-               }
+               if (!S_ISBLK(inode->i_mode))
+                       goto dput_and_out;
+
                retval = -EACCES;
-               if (IS_NODEV(inode)) {
-                       iput(inode);
-                       goto out;
-               }
+               if (IS_NODEV(inode))
+                       goto dput_and_out;
+
                dev = inode->i_rdev;
                retval = -ENXIO;
-               if (MAJOR(dev) >= MAX_BLKDEV) {
-                       iput(inode);
-                       goto out;
-               }
+               if (MAJOR(dev) >= MAX_BLKDEV)
+                       goto dput_and_out;
+
                fops = get_blkfops(MAJOR(dev));
                retval = -ENOTBLK;
-               if (!fops) {
-                       iput(inode);
-                       goto out;
-               }
+               if (!fops)
+                       goto dput_and_out;
+
                if (fops->open) {
                        struct file dummy;      /* allows read-write or read-only flag */
                        memset(&dummy, 0, sizeof(dummy));
-                       dummy.f_inode = inode;
+                       dummy.f_dentry = dentry;
                        dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3;
                        retval = fops->open(inode, &dummy);
-                       if (retval) {
-                               iput(inode);
-                               goto out;
-                       }
+                       if (retval)
+                               goto dput_and_out;
                }
 
        } else {
                retval = -EMFILE;
                if (!(dev = get_unnamed_dev()))
                        goto out;
-               inode = NULL;
        }
+
        page = 0;
        if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
                flags = new_flags & ~MS_MGC_MSK;
                retval = copy_mount_options(data, &page);
                if (retval < 0) {
                        put_unnamed_dev(dev);
-                       iput(inode);
-                       goto out;
+                       goto dput_and_out;
                }
        }
        retval = do_mount(dev,dev_name,dir_name,t,flags,(void *) page);
@@ -968,7 +975,8 @@ asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
                fops->release(inode, NULL);
                put_unnamed_dev(dev);
        }
-       iput(inode);
+dput_and_out:
+       dput(dentry);
 out:
        unlock_kernel();
        return retval;
@@ -1035,7 +1043,7 @@ __initfunc(static void do_mount_root(void))
        memset(&filp, 0, sizeof(filp));
        d_inode = get_empty_inode();
        d_inode->i_rdev = ROOT_DEV;
-       filp.f_inode = d_inode;
+       filp.f_dentry = NULL;
        if ( root_mountflags & MS_RDONLY)
                filp.f_mode = 1; /* read only */
        else
index 1a8e027cc2fa7d63ff0cca8e3147e191503773e7..7feef8ad58bfffc7d6774e54b7864de5bf476e7e 100644 (file)
@@ -19,12 +19,11 @@ struct linux_binprm{
        unsigned long p;
        int sh_bang;
        int java;               /* Java binary, prevent recursive invocation */
-       struct inode * inode;
+       struct dentry * dentry;
        int e_uid, e_gid;
        int argc, envc;
        char * filename;        /* Name of binary */
        unsigned long loader, exec;
-       int dont_iput;          /* binfmt handler has put inode */
 };
 
 /*
@@ -42,10 +41,10 @@ struct linux_binfmt {
 extern int register_binfmt(struct linux_binfmt *);
 extern int unregister_binfmt(struct linux_binfmt *);
 
-extern int read_exec(struct inode *inode, unsigned long offset,
+extern int read_exec(struct dentry *, unsigned long offset,
        char * addr, unsigned long count, int to_kmem);
 
-extern int open_inode(struct inode * inode, int mode);
+extern int open_dentry(struct dentry *, int mode);
 
 extern int init_elf_binfmt(void);
 extern int init_elf32_binfmt(void);
index c2c0f5c069af39b9c9f18c9c53ff795d06f27e64..7caacef5659253360fdd4047d9f4d9f901867e32 100644 (file)
@@ -58,14 +58,10 @@ extern void d_instantiate(struct dentry *, struct inode *);
 extern void d_delete(struct dentry *);
 
 
-/* Note that all these routines must be called with vfs_lock() held */
-
-/* get inode, if necessary retrieve it with iget() */
-extern struct inode * d_inode(struct dentry ** changing_entry);
-
 /* allocate/de-allocate */
 extern void d_free(struct dentry *);
 extern struct dentry * d_alloc(struct dentry * parent, const struct qstr *name);
+extern void shrink_dcache(int);
 
 /* only used at mount-time */
 extern struct dentry * d_alloc_root(struct inode * root_inode, struct dentry * old_root);
index f3087fb44aa232f2f0049360f20eefe259bc2ec4..f8376d4103b05738ff997c5b0bace14abcc6360a 100644 (file)
@@ -515,7 +515,7 @@ extern void ext2_write_super (struct super_block *);
 extern int ext2_remount (struct super_block *, int *, char *);
 extern struct super_block * ext2_read_super (struct super_block *,void *,int);
 extern int init_ext2_fs(void);
-extern void ext2_statfs (struct super_block *, struct statfs *, int);
+extern int ext2_statfs (struct super_block *, struct statfs *, int);
 
 /* truncate.c */
 extern void ext2_truncate (struct inode *);
index 0cb531c0c6f1e0fe93a268cb2311e44ad6e55448..b8cc01f0a05eea43b671370909e6b2d951b83a7e 100644 (file)
@@ -12,7 +12,7 @@ extern inline struct file * fget(unsigned long fd)
        return file;
 }
 
-extern int __fput(struct file *, struct inode *);
+extern int __fput(struct file *);
 extern void insert_file_free(struct file *file);
 
 /* It does not matter which list it is on. */
@@ -23,13 +23,13 @@ extern inline void remove_filp(struct file *file)
        *file->f_pprev = file->f_next;
 }
 
-extern inline int fput(struct file *file, struct inode *inode)
+extern inline int fput(struct file *file)
 {
        int count = file->f_count-1;
        int error = 0;
 
        if (!count) {
-               error = __fput(file, inode);
+               error = __fput(file);
                file->f_count = 0;
                remove_filp(file);
                insert_file_free(file);
index d3e65f6fb46bef6115cf7d6a4134003b6344b230..6c3bb69a1675037c8aaf5d08731b30e000791901 100644 (file)
@@ -368,7 +368,7 @@ static inline void mark_inode_dirty(struct inode *inode)
 
 struct file {
        struct file             *f_next, **f_pprev;
-       struct inode            *f_inode;
+       struct dentry           *f_dentry;
        struct file_operations  *f_op;
        mode_t                  f_mode;
        loff_t                  f_pos;
@@ -570,7 +570,7 @@ struct super_operations {
        void (*put_inode) (struct inode *);
        void (*put_super) (struct super_block *);
        void (*write_super) (struct super_block *);
-       void (*statfs) (struct super_block *, struct statfs *, int);
+       int (*statfs) (struct super_block *, struct statfs *, int);
        int (*remount_fs) (struct super_block *, int *, char *);
 };
 
@@ -599,7 +599,7 @@ asmlinkage int sys_close(unsigned int);             /* yes, it's really unsigned */
 
 extern void kill_fasync(struct fasync_struct *fa, int sig);
 
-extern int getname(const char * filename, char **result);
+extern char * getname(const char * filename);
 extern void putname(char * name);
 extern int do_truncate(struct inode *, unsigned long);
 extern int register_blkdev(unsigned int, const char *, struct file_operations *);
@@ -681,8 +681,8 @@ extern int notify_change(struct inode *, struct iattr *);
 extern int permission(struct inode * inode,int mask);
 extern int get_write_access(struct inode *inode);
 extern void put_write_access(struct inode *inode);
-extern int open_namei(const char * pathname, int flag, int mode, struct inode ** res_inode);
-extern int do_mknod(const char * filename, int mode, dev_t dev);
+extern struct dentry * open_namei(const char * pathname, int flag, int mode);
+extern struct dentry * do_mknod(const char * filename, int mode, dev_t dev);
 extern int do_pipe(int *);
 
 /*
@@ -698,10 +698,10 @@ extern int do_pipe(int *);
 #define IS_ERR(ptr)    ((unsigned long)(ptr) > (unsigned long)(-1000))
 
 extern struct dentry * lookup_dentry(const char *, struct dentry *, int);
-extern int __namei(const char *, struct inode **, int);
+extern struct dentry * __namei(const char *, int);
 
-#define namei(pathname, inode_p)       __namei(pathname, inode_p, 1)
-#define lnamei(pathname, inode_p)      __namei(pathname, inode_p, 0)
+#define namei(pathname)                __namei(pathname, 1)
+#define lnamei(pathname)       __namei(pathname, 0)
 
 #include <asm/semaphore.h>
 
index 3d65cb3e160cdf634fdc37ec343448f7f7935de0..0374eebf7da505da9a1da8a947e0368e0b5adb49 100644 (file)
@@ -164,7 +164,7 @@ extern struct super_block *isofs_read_super(struct super_block *,void *,int);
 extern int init_iso9660_fs(void);
 extern void isofs_read_inode(struct inode *);
 extern void isofs_put_inode(struct inode *);
-extern void isofs_statfs(struct super_block *, struct statfs *, int);
+extern int isofs_statfs(struct super_block *, struct statfs *, int);
 
 extern int isofs_lseek(struct inode *, struct file *, off_t, int);
 extern int isofs_read(struct inode *, struct file *, char *, int);
index 9c3c4fef57f1aba126709540c542e99d42fcde5e..84a0ecef628bb035eb63765affe562a0755767f8 100644 (file)
@@ -33,6 +33,30 @@ static inline void list_del(struct list_head *entry)
        prev->next = next;
 }
 
+static inline int list_empty(struct list_head *head)
+{
+       return head->next == head;
+}
+
+/*
+ * Splice in "list" into "head"
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+       struct list_head *first = list->next;
+
+       if (first != list) {
+               struct list_head *last = list->prev;
+               struct list_head *at = head->next;
+
+               first->prev = head;
+               head->next = first;
+
+               last->next = at;
+               at->prev = last;
+       }
+}
+
 #define list_entry(ptr, type, member) \
        ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
 
index 72035cc5c325d2684c16b431f88c0b9d21b2accf..5c1d0e4cc79173aaaa17629f7ba05253b08a7dcb 100644 (file)
@@ -166,7 +166,7 @@ void                  nlmsvc_free_host_resources(struct nlm_host *);
 extern __inline__ struct inode *
 nlmsvc_file_inode(struct nlm_file *file)
 {
-       return file->f_file.f_inode;
+       return file->f_file.f_dentry->d_inode;
 }
 
 /*
index c8b9046a730ec8fcfe9c371ac02b5081b855eb50..98765857a9e48b9706fcf9ed39d9ddce13eb6bc2 100644 (file)
@@ -48,7 +48,7 @@ struct vm_area_struct {
 
        struct vm_operations_struct * vm_ops;
        unsigned long vm_offset;
-       struct inode * vm_inode;
+       struct dentry * vm_dentry;
        unsigned long vm_pte;                   /* shared mem */
 };
 
index d95e99211da87d6dcd750c1010f38692259b6188..a7c51bab2613eee0b8818706428219b25cac52e7 100644 (file)
@@ -309,7 +309,7 @@ static inline int proc_scsi_unregister(struct proc_dir_entry *driver, int x)
 extern struct super_block *proc_read_super(struct super_block *,void *,int);
 extern int init_proc_fs(void);
 extern struct inode * proc_get_inode(struct super_block *, int, struct proc_dir_entry *);
-extern void proc_statfs(struct super_block *, struct statfs *, int);
+extern int proc_statfs(struct super_block *, struct statfs *, int);
 extern void proc_read_inode(struct inode *);
 extern void proc_write_inode(struct inode *);
 
index 56fef7a214331bea33afc1e718ec445eb8437761..7faaccf759fef931dd78271e0900d1a2a7daaefe 100644 (file)
@@ -19,8 +19,7 @@
 struct swap_info_struct {
        unsigned int flags;
        kdev_t swap_device;
-       char *swap_filename;
-       struct inode * swap_file;
+       struct dentry * swap_file;
        unsigned char * swap_map;
        unsigned char * swap_lockmap;
        unsigned int lowest_bit;
index d2afb7d2f1de74c94c5055ff4158248f3eecd15e..b306922ec9a4be27186e8e7f5192abefe57e97a4 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -555,7 +555,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_inode = NULL;
+       shmd->vm_dentry = NULL;
        shmd->vm_offset = 0;
        shmd->vm_ops = &shm_vm_ops;
 
index 97837db6571405272ba196fd160848df2eb69da2..900d6015cba72d2733ec40709b5f6d39da035311 100644 (file)
@@ -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 inode *inode;
+               struct dentry *dentry;
 
                tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
                if (!tmp) {
@@ -223,11 +223,11 @@ static inline int dup_mmap(struct mm_struct * mm)
                tmp->vm_flags &= ~VM_LOCKED;
                tmp->vm_mm = mm;
                tmp->vm_next = NULL;
-               inode = tmp->vm_inode;
-               if (inode) {
-                       atomic_inc(&inode->i_count);
+               dentry = tmp->vm_dentry;
+               if (dentry) {
+                       dentry->d_count++;
                        if (tmp->vm_flags & VM_DENYWRITE)
-                               inode->i_writecount--;
+                               dentry->d_inode->i_writecount--;
       
                        /* insert tmp into the share list, just after mpnt */
                        if((tmp->vm_next_share = mpnt->vm_next_share) != NULL)
index 3e66053b71aadd46b6bd1b8f68ea47307732eeb0..84dcdac28a2b91fa8fe8ae2b2ce08eaac2b7a035 100644 (file)
@@ -330,7 +330,7 @@ EXPORT_SYMBOL(setup_arg_pages);
 EXPORT_SYMBOL(copy_strings);
 EXPORT_SYMBOL(do_execve);
 EXPORT_SYMBOL(flush_old_exec);
-EXPORT_SYMBOL(open_inode);
+EXPORT_SYMBOL(open_dentry);
 EXPORT_SYMBOL(read_exec);
 
 /* Miscellaneous access points */
index 570d18ba89353b721e70daa42ad7e60ce6094d16..27d41eed1eb03def359c8648826b830d2f222cd0 100644 (file)
@@ -396,7 +396,7 @@ int acct_process(long exitcode)
       fs = get_fs();
       set_fs(KERNEL_DS);
 
-      acct_file.f_op->write(acct_file.f_inode, &acct_file,
+      acct_file.f_op->write(acct_file.f_dentry->d_inode, &acct_file,
                              (char *)&ac, sizeof(struct acct));
       set_fs(fs);
    }
@@ -405,8 +405,6 @@ int acct_process(long exitcode)
 
 asmlinkage int sys_acct(const char *name)
 {
-       struct inode *inode = (struct inode *)0;
-       char *tmp;
        int error = -EPERM;
 
        lock_kernel();
@@ -416,10 +414,10 @@ asmlinkage int sys_acct(const char *name)
        if (name == (char *)0) {
                if (acct_active) {
                        if (acct_file.f_op->release)
-                               acct_file.f_op->release(acct_file.f_inode, &acct_file);
+                               acct_file.f_op->release(acct_file.f_dentry->d_inode, &acct_file);
 
-                       if (acct_file.f_inode != (struct inode *) 0)
-                               iput(acct_file.f_inode);
+                       if (acct_file.f_dentry != NULL)
+                               dput(acct_file.f_dentry);
 
                        acct_active = 0;
                }
@@ -427,40 +425,51 @@ asmlinkage int sys_acct(const char *name)
        } else {
                error = -EBUSY;
                if (!acct_active) {
-                       if ((error = getname(name, &tmp)) != 0)
+                       struct dentry *dentry;
+                       struct inode *inode;
+                       char *tmp;
+
+                       tmp = getname(name);
+                       error = PTR_ERR(tmp);
+                       if (IS_ERR(tmp))
                                goto out;
 
-                       error = open_namei(tmp, O_RDWR, 0600, &inode);
+                       dentry = open_namei(tmp, O_RDWR, 0600);
                        putname(tmp);
-                       if (error)
+
+                       error = PTR_ERR(dentry);
+                       if (IS_ERR(dentry))
                                goto out;
+                       inode = dentry->d_inode;
 
                        error = -EACCES;
                        if (!S_ISREG(inode->i_mode)) {
-                               iput(inode);
+                               dput(dentry);
                                goto out;
                        }
 
                        error = -EIO;
                        if (!inode->i_op || !inode->i_op->default_file_ops || 
                            !inode->i_op->default_file_ops->write) {
-                               iput(inode);
+                               dput(dentry);
                                goto out;
                        }
 
                        acct_file.f_mode = 3;
                        acct_file.f_flags = 0;
                        acct_file.f_count = 1;
-                       acct_file.f_inode = inode;
+                       acct_file.f_dentry = dentry;
                        acct_file.f_pos = inode->i_size;
                        acct_file.f_reada = 0;
                        acct_file.f_op = inode->i_op->default_file_ops;
 
-                       if(acct_file.f_op->open)
-                               if(acct_file.f_op->open(acct_file.f_inode, &acct_file)) {
-                                       iput(inode);
+                       if(acct_file.f_op->open) {
+                               error = acct_file.f_op->open(inode, &acct_file);
+                               if (error) {
+                                       dput(dentry);
                                        goto out;
                                }
+                       }
 
                        acct_active = 1;
                        error = 0;
index b4d2fb814a642dd1df341547d51836801ac234ac..5d801958b146d0da624415d422247270994eb6cc 100644 (file)
@@ -772,7 +772,7 @@ static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long
 {
        unsigned long offset;
        struct page * page, **hash;
-       struct inode * inode = area->vm_inode;
+       struct inode * inode = area->vm_dentry->d_inode;
        unsigned long old_page, new_page;
 
        new_page = 0;
@@ -926,6 +926,7 @@ static int filemap_write_page(struct vm_area_struct * vma,
 {
        int result;
        struct file file;
+       struct dentry * dentry;
        struct inode * inode;
        struct buffer_head * bh;
 
@@ -940,14 +941,15 @@ static int filemap_write_page(struct vm_area_struct * vma,
                return 0;
        }
 
-       inode = vma->vm_inode;
+       dentry = vma->vm_dentry;
+       inode = dentry->d_inode;
        file.f_op = inode->i_op->default_file_ops;
        if (!file.f_op->write)
                return -EIO;
        file.f_mode = 3;
        file.f_flags = 0;
        file.f_count = 1;
-       file.f_inode = inode;
+       file.f_dentry = dentry;
        file.f_pos = offset;
        file.f_reada = 0;
 
@@ -1186,8 +1188,7 @@ int generic_file_mmap(struct inode * inode, struct file * file, struct vm_area_s
        if (!inode->i_op || !inode->i_op->readpage)
                return -ENOEXEC;
        UPDATE_ATIME(inode);
-       vma->vm_inode = inode;
-       atomic_inc(&inode->i_count);
+       vma->vm_dentry = dget(file->f_dentry);
        vma->vm_ops = ops;
        return 0;
 }
@@ -1200,7 +1201,7 @@ int generic_file_mmap(struct inode * inode, struct file * file, struct vm_area_s
 static int msync_interval(struct vm_area_struct * vma,
        unsigned long start, unsigned long end, int flags)
 {
-       if (!vma->vm_inode)
+       if (!vma->vm_dentry)
                return 0;
        if (vma->vm_ops->sync) {
                int error;
@@ -1208,7 +1209,7 @@ static int msync_interval(struct vm_area_struct * vma,
                if (error)
                        return error;
                if (flags & MS_SYNC)
-                       return file_fsync(vma->vm_inode, NULL);
+                       return file_fsync(vma->vm_dentry->d_inode, NULL);
                return 0;
        }
        return 0;
index 5a69e4b551e5c9087ca197315a7a8d367d305ae2..eea100addd2f2adf5abda08ff3b6677d567c08e3 100644 (file)
@@ -38,8 +38,7 @@ 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;
-       if (n->vm_inode)
-               atomic_inc(&n->vm_inode->i_count);
+       n->vm_dentry = dget(vma->vm_dentry);
        if (n->vm_ops && n->vm_ops->open)
                n->vm_ops->open(n);
        insert_vm_struct(current->mm, n);
@@ -59,8 +58,7 @@ 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;
-       if (n->vm_inode)
-               atomic_inc(&n->vm_inode->i_count);
+       n->vm_dentry = dget(vma->vm_dentry);
        if (n->vm_ops && n->vm_ops->open)
                n->vm_ops->open(n);
        insert_vm_struct(current->mm, n);
@@ -89,8 +87,9 @@ 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_inode)
-               atomic_add(2, &vma->vm_inode->i_count);
+       if (vma->vm_dentry)
+               vma->vm_dentry->d_count += 2;
+
        if (vma->vm_ops && vma->vm_ops->open) {
                vma->vm_ops->open(left);
                vma->vm_ops->open(right);
index 4386adcb82439ada4cb39e7ec65d7f31bd4fe0c4..9c9dcdff3ab0f6a9ebf2bbd0623ba3eeb9409d5f 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -74,11 +74,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 inode * inode = vma->vm_inode;
+       struct dentry * dentry = vma->vm_dentry;
 
-       if (inode) {
+       if (dentry) {
                if (vma->vm_flags & VM_DENYWRITE)
-                       inode->i_writecount++;
+                       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;
@@ -194,7 +194,7 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
                                return -EACCES;
 
                        /* make sure there are no mandatory locks on the file. */
-                       if (locks_verify_locked(file->f_inode))
+                       if (locks_verify_locked(file->f_dentry->d_inode))
                                return -EAGAIN;
                        /* fall through */
                case MAP_PRIVATE:
@@ -259,7 +259,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_inode = NULL;
+       vma->vm_dentry = NULL;
        vma->vm_pte = 0;
 
        do_munmap(addr, len);   /* Clear old maps */
@@ -283,7 +283,7 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
        if (file) {
                int error = 0;
                if (vma->vm_flags & VM_DENYWRITE) {
-                       if (file->f_inode->i_writecount > 0)
+                       if (file->f_dentry->d_inode->i_writecount > 0)
                                error = -ETXTBSY;
                        else {
                                /* f_op->mmap might possibly sleep
@@ -291,16 +291,16 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
                                 * might). In any case, this takes care of any
                                 * race that this might cause.
                                 */
-                               file->f_inode->i_writecount--;
+                               file->f_dentry->d_inode->i_writecount--;
                                correct_wcount = 1;
                        }
                }
                if (!error)
-                       error = file->f_op->mmap(file->f_inode, file, vma);
+                       error = file->f_op->mmap(file->f_dentry->d_inode, file, vma);
        
                if (error) {
                        if (correct_wcount)
-                               file->f_inode->i_writecount++;
+                               file->f_dentry->d_inode->i_writecount++;
                        kmem_cache_free(vm_area_cachep, vma);
                        return error;
                }
@@ -309,7 +309,7 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
        flags = vma->vm_flags;
        insert_vm_struct(mm, vma);
        if (correct_wcount)
-               file->f_inode->i_writecount++;
+               file->f_dentry->d_inode->i_writecount++;
        merge_segments(mm, vma->vm_start, vma->vm_end);
        
        addr = vma->vm_start;
@@ -389,8 +389,8 @@ static void unmap_fixup(struct vm_area_struct *area,
        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_inode)
-                       iput(area->vm_inode);
+               if (area->vm_dentry)
+                       dput(area->vm_dentry);
                return;
        }
 
@@ -407,11 +407,14 @@ static void unmap_fixup(struct vm_area_struct *area,
 
                if (!mpnt)
                        return;
-               *mpnt = *area;
-               mpnt->vm_offset += (end - area->vm_start);
+               mpnt->vm_mm = area->vm_mm;
                mpnt->vm_start = end;
-               if (mpnt->vm_inode)
-                       atomic_inc(&mpnt->vm_inode->i_count);
+               mpnt->vm_end = area->vm_end;
+               mpnt->vm_page_prot = area->vm_page_prot;
+               mpnt->vm_flags = area->vm_flags;
+               mpnt->vm_ops = area->vm_ops;
+               mpnt->vm_offset += (end - area->vm_start);
+               mpnt->vm_dentry = dget(area->vm_dentry);
                if (mpnt->vm_ops && mpnt->vm_ops->open)
                        mpnt->vm_ops->open(mpnt);
                area->vm_end = addr;    /* Truncate area */
@@ -544,8 +547,8 @@ void exit_mmap(struct mm_struct * mm)
                }
                remove_shared_vm_struct(mpnt);
                zap_page_range(mm, start, size);
-               if (mpnt->vm_inode)
-                       iput(mpnt->vm_inode);
+               if (mpnt->vm_dentry)
+                       dput(mpnt->vm_dentry);
                kmem_cache_free(vm_area_cachep, mpnt);
                mpnt = next;
        }
@@ -557,7 +560,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 inode * inode;
+       struct dentry * dentry;
 
        /* Find where to link it in. */
        while(*pprev && (*pprev)->vm_start <= vmp->vm_start)
@@ -569,8 +572,9 @@ void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp)
        *pprev = vmp;
        vmp->vm_pprev = pprev;
 
-       inode = vmp->vm_inode;
-       if (inode) {
+       dentry = vmp->vm_dentry;
+       if (dentry) {
+               struct inode * inode = dentry->d_inode;
                if (vmp->vm_flags & VM_DENYWRITE)
                        inode->i_writecount--;
       
@@ -617,16 +621,19 @@ 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 inode, operations.. */
-               if ((mpnt->vm_inode != prev->vm_inode)  ||
+               /* To share, we must have the same dentry, operations.. */
+               if ((mpnt->vm_dentry != prev->vm_dentry)||
                    (mpnt->vm_pte != prev->vm_pte)      ||
                    (mpnt->vm_ops != prev->vm_ops)      ||
                    (mpnt->vm_flags != prev->vm_flags)  ||
                    (prev->vm_end != mpnt->vm_start))
                        continue;
 
-               /* and if we have an inode, the offsets must be contiguous.. */
-               if ((mpnt->vm_inode != NULL) || (mpnt->vm_flags & VM_SHM)) {
+               /*
+                * If we have a dentry or it's a shared memory area
+                * the offsets must be contiguous..
+                */
+               if ((mpnt->vm_dentry != NULL) || (mpnt->vm_flags & VM_SHM)) {
                        unsigned long off = prev->vm_offset+prev->vm_end-prev->vm_start;
                        if (off != mpnt->vm_offset)
                                continue;
@@ -647,8 +654,8 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l
                        mpnt->vm_ops->close(mpnt);
                }
                remove_shared_vm_struct(mpnt);
-               if (mpnt->vm_inode)
-                       atomic_dec(&mpnt->vm_inode->i_count);
+               if (mpnt->vm_dentry)
+                       dput(mpnt->vm_dentry);
                kmem_cache_free(vm_area_cachep, mpnt);
                mpnt = prev;
        }
index 2e46ca1429c43626eb6c9eb15362af0f6c4baeee..ddf4f4ed6842828ce0de0c0b83a2aa70ede6df62 100644 (file)
@@ -110,8 +110,7 @@ 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;
-       if (n->vm_inode)
-               atomic_inc(&n->vm_inode->i_count);
+       n->vm_dentry = dget(n->vm_dentry);
        if (n->vm_ops && n->vm_ops->open)
                n->vm_ops->open(n);
        insert_vm_struct(current->mm, n);
@@ -133,8 +132,7 @@ 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;
-       if (n->vm_inode)
-               atomic_inc(&n->vm_inode->i_count);
+       n->vm_dentry = dget(n->vm_dentry);
        if (n->vm_ops && n->vm_ops->open)
                n->vm_ops->open(n);
        insert_vm_struct(current->mm, n);
@@ -165,8 +163,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_inode)
-               atomic_add(2, &vma->vm_inode->i_count);
+       if (vma->vm_dentry)
+               vma->vm_dentry->d_count += 2;
        if (vma->vm_ops && vma->vm_ops->open) {
                vma->vm_ops->open(left);
                vma->vm_ops->open(right);
index a52db58de696d710883459dae165cca59206922f..aaabde322f4b58554a047b417cd34251e3a25860 100644 (file)
@@ -140,8 +140,7 @@ 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);
-                       if (new_vma->vm_inode)
-                               atomic_inc(&new_vma->vm_inode->i_count);
+                       new_vma->vm_dentry = dget(vma->vm_dentry);
                        if (new_vma->vm_ops && new_vma->vm_ops->open)
                                new_vma->vm_ops->open(new_vma);
                        insert_vm_struct(current->mm, new_vma);
index 30d0c882ea22a179b62608276037eecd010507ac..5ebea3f090c67b0ff56ec32e6decb46887252c18 100644 (file)
@@ -98,7 +98,7 @@ void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
                        return;
                wait_on_page(page);
        } else if (p->swap_file) {
-               struct inode *swapf = p->swap_file;
+               struct inode *swapf = p->swap_file->d_inode;
                unsigned int zones[PAGE_SIZE/512];
                int i;
                if (swapf->i_op->bmap == NULL
index eae481821becb60140965b8da92c834f2f50ad80..e88aa8187b7de5b0dcbc8d626b42a06ac2b3e796 100644 (file)
@@ -326,7 +326,7 @@ again:
 asmlinkage int sys_swapoff(const char * specialfile)
 {
        struct swap_info_struct * p = NULL;
-       struct inode * inode;
+       struct dentry * dentry;
        struct file filp;
        int i, type, prev;
        int err = -EPERM;
@@ -334,19 +334,22 @@ asmlinkage int sys_swapoff(const char * specialfile)
        lock_kernel();
        if (!suser())
                goto out;
-       err = namei(specialfile, &inode);
-       if (err)
+
+       dentry = namei(specialfile);
+       err = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
                goto out;
+
        prev = -1;
        for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
                p = swap_info + type;
                if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
                        if (p->swap_file) {
-                               if (p->swap_file == inode)
+                               if (p->swap_file == dentry)
                                  break;
                        } else {
-                               if (S_ISBLK(inode->i_mode)
-                                   && (p->swap_device == inode->i_rdev))
+                               if (S_ISBLK(dentry->d_inode->i_mode)
+                                   && (p->swap_device == dentry->d_inode->i_rdev))
                                  break;
                        }
                }
@@ -354,7 +357,7 @@ asmlinkage int sys_swapoff(const char * specialfile)
        }
        err = -EINVAL;
        if (type < 0){
-               iput(inode);
+               dput(dentry);
                goto out;
        }
        if (prev < 0) {
@@ -369,7 +372,7 @@ asmlinkage int sys_swapoff(const char * specialfile)
        p->flags = SWP_USED;
        err = try_to_unuse(type);
        if (err) {
-               iput(inode);
+               dput(dentry);
                /* re-insert swap space back into swap_list */
                for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next)
                        if (p->prio >= swap_info[i].prio)
@@ -384,21 +387,19 @@ asmlinkage int sys_swapoff(const char * specialfile)
        }
        if(p->swap_device){
                memset(&filp, 0, sizeof(filp));         
-               filp.f_inode = inode;
+               filp.f_dentry = dentry;
                filp.f_mode = 3; /* read write */
                /* open it again to get fops */
-               if( !blkdev_open(inode, &filp) &&
+               if( !blkdev_open(dentry->d_inode, &filp) &&
                   filp.f_op && filp.f_op->release){
-                       filp.f_op->release(inode,&filp);
-                       filp.f_op->release(inode,&filp);
+                       filp.f_op->release(dentry->d_inode,&filp);
+                       filp.f_op->release(dentry->d_inode,&filp);
                }
        }
-       iput(inode);
+       dput(dentry);
 
        nr_swap_pages -= p->pages;
-       iput(p->swap_file);
-       if (p->swap_filename)
-               kfree(p->swap_filename);
+       dput(p->swap_file);
        p->swap_file = NULL;
        p->swap_device = 0;
        vfree(p->swap_map);
@@ -420,10 +421,8 @@ int get_swaparea_info(char *buf)
        len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n");
        for (i = 0 ; i < nr_swapfiles ; i++, ptr++)
                if (ptr->flags & SWP_USED) {
-                       if (ptr->swap_filename)
-                               len += sprintf(buf + len, "%-31s ", ptr->swap_filename);
-                       else
-                               len += sprintf(buf + len, "(null)\t\t\t");
+                       len += sprintf(buf + len, "%-31s ", ptr->swap_file->d_name.name);
+
                        if (ptr->swap_file)
                                len += sprintf(buf + len, "file\t\t");
                        else
@@ -451,11 +450,10 @@ int get_swaparea_info(char *buf)
 asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
 {
        struct swap_info_struct * p;
-       struct inode * swap_inode;
+       struct dentry * swap_dentry;
        unsigned int type;
        int i, j, prev;
        int error = -EPERM;
-       char *tmp;
        struct file filp;
        static int least_priority = 0;
 
@@ -472,7 +470,6 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
        if (type >= nr_swapfiles)
                nr_swapfiles = type+1;
        p->flags = SWP_USED;
-       p->swap_filename = NULL;
        p->swap_file = NULL;
        p->swap_device = 0;
        p->swap_map = NULL;
@@ -488,22 +485,22 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
        } else {
                p->prio = --least_priority;
        }
-       error = namei(specialfile, &swap_inode);
-       if (error)
+       swap_dentry = namei(specialfile);
+       error = PTR_ERR(swap_dentry);
+       if (IS_ERR(swap_dentry))
                goto bad_swap_2;
-       p->swap_file = swap_inode;
+
+       p->swap_file = swap_dentry;
        error = -EINVAL;
 
-       if (S_ISBLK(swap_inode->i_mode)) {
-               p->swap_device = swap_inode->i_rdev;
+       if (S_ISBLK(swap_dentry->d_inode->i_mode)) {
+               p->swap_device = swap_dentry->d_inode->i_rdev;
                set_blocksize(p->swap_device, PAGE_SIZE);
                
-               filp.f_inode = swap_inode;
+               filp.f_dentry = swap_dentry;
                filp.f_mode = 3; /* read write */
-               error = blkdev_open(swap_inode, &filp);
-               p->swap_file = NULL;
-               iput(swap_inode);
-               if(error)
+               error = blkdev_open(swap_dentry->d_inode, &filp);
+               if (error)
                        goto bad_swap_2;
                error = -ENODEV;
                if (!p->swap_device ||
@@ -517,7 +514,7 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
                        if (p->swap_device == swap_info[i].swap_device)
                                goto bad_swap;
                }
-       } else if (!S_ISREG(swap_inode->i_mode))
+       } else if (!S_ISREG(swap_dentry->d_inode->i_mode))
                goto bad_swap;
        p->swap_lockmap = (unsigned char *) get_free_page(GFP_USER);
        if (!p->swap_lockmap) {
@@ -577,12 +574,6 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
                prev = i;
        }
        p->next = i;
-       if (!getname(specialfile, &tmp)) {
-               if ((p->swap_filename =
-                   (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
-                       strcpy(p->swap_filename, tmp);
-               putname(tmp);
-       }
        if (prev < 0) {
                swap_list.head = swap_list.next = p - swap_info;
        } else {
@@ -592,11 +583,11 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
        goto out;
 bad_swap:
        if(filp.f_op && filp.f_op->release)
-               filp.f_op->release(filp.f_inode,&filp);
+               filp.f_op->release(filp.f_dentry->d_inode,&filp);
 bad_swap_2:
        free_page((long) p->swap_lockmap);
        vfree(p->swap_map);
-       iput(p->swap_file);
+       dput(p->swap_file);
        p->swap_device = 0;
        p->swap_file = NULL;
        p->swap_map = NULL;
index 21c178159d2f75092a8945a1dc0ca34ef344df91..716d1f2450246e9fb8f6cab633f08add78b1b530 100644 (file)
@@ -369,6 +369,9 @@ static inline int do_try_to_free_page(int priority, int dma, int wait)
                        if (shm_swap(i, dma))
                                return 1;
                        state = 3;
+               case 3:
+                       shrink_dcache(i);
+                       state = 4;
                default:
                        if (swap_out(i, dma, wait))
                                return 1;
index d88ab0ae758ed4594393cc3e56721ab26d607daf..e5fa793a705206483edfa136fa2bcf24652e6ac0 100644 (file)
@@ -172,9 +172,9 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
                                if (acc_fd < 0 || acc_fd >= NR_OPEN ||
                                    (file=current->files->fd[acc_fd])==NULL)
                                        return -EBADF;
-                               if (!file->f_inode || !file->f_inode->i_sock)
+                               if (!file->f_dentry->d_inode || !file->f_dentry->d_inode->i_sock)
                                        return -ENOTSOCK;
-                               p->sock = &file->f_inode->u.socket_i;
+                               p->sock = &file->f_dentry->d_inode->u.socket_i;
                                if (p->sock->state != SS_UNCONNECTED) 
                                        return -EINVAL;
                        }
index 539ec42957d8e81071483878c10304672da8e4a6..2c7eb9dd0c41656340c2b94a36b8301aee71b992 100644 (file)
@@ -68,7 +68,7 @@ int netlink_donothing(int minor, struct sk_buff *skb)
 static unsigned int netlink_poll(struct file *file, poll_table * wait)
 {
        unsigned int mask;
-       unsigned int minor = MINOR(file->f_inode->i_rdev);
+       unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
 
        poll_wait(&read_space_wait[minor], wait);
        mask = POLLOUT | POLLWRNORM;
index 3856746425878c4c902b051ecdaffeb0e6a2926f..4f706d4ef15da8fbe58121c8022d97f6a3d01ff5 100644 (file)
@@ -210,9 +210,7 @@ static int get_fd(struct inode *inode)
                file->f_op = &socket_file_ops;
                file->f_mode = 3;
                file->f_flags = O_RDWR;
-               file->f_inode = inode;
-               if (inode) 
-                       atomic_inc(&inode->i_count);
+               file->f_dentry = d_alloc_root(inode, NULL);
                file->f_pos = 0;
        }
        return fd;
@@ -238,11 +236,11 @@ extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
                return NULL;
        }
 
-       inode = file->f_inode;
+       inode = file->f_dentry->d_inode;
        if (!inode || !inode->i_sock || !socki_lookup(inode))
        {
                *err = -ENOTSOCK;
-               fput(file,inode);
+               fput(file);
                return NULL;
        }
 
@@ -251,7 +249,7 @@ extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
 
 extern __inline__ void sockfd_put(struct socket *sock)
 {
-       fput(sock->file,sock->inode);
+       fput(sock->file);
 }
 
 /*
@@ -460,7 +458,7 @@ static unsigned int sock_poll(struct file *file, poll_table * wait)
 {
        struct socket *sock;
 
-       sock = socki_lookup(file->f_inode);
+       sock = socki_lookup(file->f_dentry->d_inode);
 
        /*
         *      We can't return errors to poll, so it's either yes or no. 
@@ -1292,7 +1290,7 @@ int sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct socket *sock;
 
-       sock = socki_lookup (filp->f_inode);
+       sock = socki_lookup (filp->f_dentry->d_inode);
        if (sock && sock->ops && sock->ops->fcntl)
                return sock->ops->fcntl(sock, cmd, arg);
        return(-EINVAL);
index 88f4e47885f64a159eacdc361466787279c30311..481be1dc50b9483934cec4d8c359dbfd6ee52c3b 100644 (file)
@@ -450,24 +450,18 @@ retry:
 static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len,
                                    int type, unsigned hash, int *error)
 {
-       unsigned long old_fs;
-       int err;
-       struct inode *inode;
        unix_socket *u;
        
        if (sunname->sun_path[0])
        {
-               old_fs=get_fs();
-               set_fs(get_ds());
-               err = open_namei(sunname->sun_path, 2, S_IFSOCK, &inode);
-               set_fs(old_fs);
-               if(err<0)
-               {
-                       *error=err;
+               struct dentry *dentry;
+               dentry = open_namei(sunname->sun_path, 2, S_IFSOCK);
+               if (IS_ERR(dentry)) {
+                       *error = PTR_ERR(dentry);
                        return NULL;
                }
-               u=unix_find_socket_byinode(inode);
-               iput(inode);
+               u=unix_find_socket_byinode(dentry->d_inode);
+               dput(dentry);
                if (u && u->type != type)
                {
                        *error=-EPROTOTYPE;
@@ -491,8 +485,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
        struct sock *sk = sock->sk;
        struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
-       struct inode * inode;
-       int old_fs;
+       struct dentry * dentry;
+       struct inode * inode = NULL;
        int err;
        unsigned hash;
        struct unix_address *addr;
@@ -545,15 +539,16 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        addr->hash = UNIX_HASH_SIZE;
        sk->protinfo.af_unix.addr = addr;
        
-       old_fs=get_fs();
-       set_fs(get_ds());
 
-       err=do_mknod(sunaddr->sun_path, S_IFSOCK|S_IRWXUGO, 0);
-       if (!err)
-               err=open_namei(sunaddr->sun_path, 2, S_IFSOCK, &inode);
-       
-       set_fs(old_fs);
-       
+       dentry = do_mknod(sunaddr->sun_path, S_IFSOCK|S_IRWXUGO, 0);
+       err = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+               inode = dentry->d_inode;
+               atomic_inc(&inode->i_count);
+               dput(dentry);
+               err = 0;
+       }
+
        if(err<0)
        {
                unix_release_addr(addr);
index 2a10304dfe77231980065e91cd31ed8cb504f178..cf0d634bcd18f22fc3c9ca728cbe281ac9d20290 100644 (file)
@@ -68,7 +68,7 @@ static int in_stack = 0;      /* first free entry in stack */
 extern inline unix_socket *unix_get_socket(struct file *filp)
 {
        unix_socket * u_sock = NULL;
-       struct inode *inode = filp->f_inode;
+       struct inode *inode = filp->f_dentry->d_inode;
 
        /*
         *      Socket ?