]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.45pre8 2.1.45pre8
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:33 +0000 (15:13 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:33 +0000 (15:13 -0500)
62 files changed:
Documentation/binfmt_misc.txt
fs/autofs/dir.c
fs/autofs/inode.c
fs/autofs/root.c
fs/binfmt_misc.c
fs/ext2/ialloc.c
fs/ext2/inode.c
fs/ext2/namei.c
fs/ext2/super.c
fs/fat/cache.c
fs/fat/file.c
fs/fat/inode.c
fs/fat/misc.c
fs/fat/mmap.c
fs/fifo.c
fs/inode.c
fs/isofs/dir.c
fs/isofs/inode.c
fs/isofs/namei.c
fs/minix/bitmap.c
fs/minix/file.c
fs/minix/inode.c
fs/minix/namei.c
fs/minix/symlink.c
fs/minix/truncate.c
fs/msdos/namei.c
fs/namei.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/read.c
fs/nfs/write.c
fs/open.c
fs/pipe.c
fs/proc/Makefile
fs/proc/arbitrary.c [deleted file]
fs/proc/fd.c
fs/proc/inode.c
fs/proc/root.c
fs/stat.c
fs/sysv/dir.c
fs/sysv/file.c
fs/sysv/ialloc.c
fs/sysv/inode.c
fs/sysv/namei.c
fs/sysv/symlink.c
fs/sysv/truncate.c
fs/vfat/namei.c
include/linux/dcache.h
include/linux/ext2_fs.h
include/linux/fs.h
include/linux/iso_fs.h
include/linux/iso_fs_i.h
include/linux/minix_fs.h
include/linux/msdos_fs.h
include/linux/nfsd/nfsfh.h
include/linux/pipe_fs_i.h
include/linux/proc_fs.h
include/linux/sysv_fs.h
kernel/ksyms.c
net/socket.c
net/unix/af_unix.c

index 4fc550e9101591a3209c229a42733ba6db254df0..aef3b271ae4a6df23d2264869eae14da943bdc5d 100644 (file)
@@ -1,26 +1,26 @@
-       Kernel Support for miscellaneous (your favourite) Binary Formats v1.1
-       =====================================================================
+     Kernel Support for miscellaneous (your favourite) Binary Formats v1.1
+     =====================================================================
 
 This Kernel feature allows to invoke almost (for restrictions see below) every
-program by simply typing it's name in the shell.
+program by simply typing its name in the shell.
 This includes for example compiled Java(TM), Python or Emacs programs.
 
-To achieve this you must tell binfmt_misc which interpreter has to be invoked with
-which binary. Binfmt_misc recognises the binary-type by matching some bytes at the
-beginning of the file with a magic byte sequence (masking out specified bits) you
-have supplied. Binfmt_misc can also recognise a filename extension (aka .com) and
-optionally strip it off.
+To achieve this you must tell binfmt_misc which interpreter has to be invoked
+with which binary. Binfmt_misc recognises the binary-type by matching some bytes
+at the beginning of the file with a magic byte sequence (masking out specified
+bits) you have supplied. Binfmt_misc can also recognise a filename extension
+(aka .com) and optionally strip it off.
 
 To actually register a new binary type, you have to set up a string looking like
-:name:type:offset:magic:mask:interpreter: (where you can choose the ':' upon your
-needs) and echo it to /proc/sys/fs/binfmt_misc/register.
+:name:type:offset:magic:mask:interpreter: (where you can choose the ':' upon
+your needs) and echo it to /proc/sys/fs/binfmt_misc/register.
 Here is what the fields mean:
  - 'name' is an identifier string. A new /proc file will be created with this
-   this name below /proc/sys/fs/binfmt_misc
+   name below /proc/sys/fs/binfmt_misc
  - 'type' is the type of recognition. Give 'M' for magic and 'E' for extension.
-   Give the corresponding lowercase letter to let binfmt_misc strip of the
+   Give the corresponding lowercase letter to let binfmt_misc strip off the
    filename extension.
- - 'offset' is the offset of the magic/mask in the file counted in bytes. This
+ - 'offset' is the offset of the magic/mask in the file, counted in bytes. This
    defaults to 0 if you omit it (i.e. you write ':name:type::magic...')
  - 'magic' is the byte sequence binfmt_misc is matching for. The magic string
    may contain hex-encoded characters like \x0a or \xA4. In a shell environment
@@ -28,26 +28,23 @@ Here is what the fields mean:
    If you chose filename extension matching, this is the extension to be
    recognised (the \x0a specials are not allowed). Extension matching is case
    sensitive!
- - 'mask' is an (optional, defaults to all 0xff) mask. You can mask out some bits
-   from matching by supplying a string like magic and as long as magic. The
-   mask is anded with the byte sequence of the file.
+ - 'mask' is an (optional, defaults to all 0xff) mask. You can mask out some
+   bits from matching by supplying a string like magic and as long as magic.
+   The mask is anded with the byte sequence of the file.
  - 'interpreter' is the program that should be invoked with the binary as first
    argument (specify the full path)
 There are some restrictions:
  - the whole register string may not exceed 255 characters
- - the magic must resist in the first 128 bytes of the file, i.e. offset+size(magic)
-   has to be less than 128
+ - the magic must resist in the first 128 bytes of the file, i.e.
+   offset+size(magic) has to be less than 128
  - the interpreter string may not exceed 127 characters
-You may want to add the binary formats in one of your /etc/rc scripts during boot-up.
-Read the manual of your init program to figure out how to do this right.
+You may want to add the binary formats in one of your /etc/rc scripts during
+boot-up. Read the manual of your init program to figure out how to do this
+right.
 
 
 A few examples (assumed you are in /proc/sys/fs/binfmt_misc):
 
-- enable Java(TM)-support (like binfmt_java):
-  echo ":Java:M::\xca\xfe\xba\xbe::/usr/local/bin/java:" > register
-  echo :Applet:M::\<\!--applet::/usr/local/bin/appletviewer: > register
-
 - enable support for em86 (like binfmt_em86, for Alpha AXP only):
   echo ":i386:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:" > register
   echo ":i486:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:" > register
@@ -57,8 +54,9 @@ A few examples (assumed you are in /proc/sys/fs/binfmt_misc):
 
 - enable support for DOS/Windows executables (using mzloader and dosemu/wine):
   echo ":DOSWin:M::MZ::/usr/sbin/mzloader:" > register
-  echo ":DOS:E::com::/usr/sbin/mzloader:" > register
-  echo ":DOS2:E::exe::/usr/sbin/mzloader:" > register
+  echo ":DOScom:E::com::/usr/sbin/mzloader:" > register
+  echo ":DOSexe:E::exe::/usr/sbin/mzloader:" > register
+
 
 You can enable/disable binfmt_misc or one binary type by echoing 0 (to disable)
 or 1 (to enable) to /proc/sys/fs/binfmt_misc/status or /proc/.../the_name.
@@ -68,6 +66,25 @@ You can remove one entry or all entries by echoing -1 to /proc/.../the_name
 or /proc/sys/fs/binfmt_misc/status.
 
 
+Emulating binfmt_java:
+======================
+
+To emulate binfmt_java the following register-strings are necessary
+(the first two for byte-compiled Java binaries, the third for applets
+contained in a html-file). Register exactly in this order!
+  ":Java:M::\xca\xfe\xba\xbe::/usr/local/java/bin/java:"
+  ":JavaC:e::class::/usr/local/java/bin/java:"
+  ":Applet:E::html::/usr/local/java/bin/appletviewer:"
+
+To add a Java-executable to your path you can either make a symbolic
+link to the .class file elsewhere in your path (cut the .class-extension
+in the destination name for convenience) or add the directory of your
+.class files to your PATH environment. In both cases, ensure that the
+.class files are in your CLASSPATH environment!
+
+This is sort of ugly - Javas filename handling is just broken.
+
+
 HINTS:
 ======
 
index 226b180e8d21f4b85f6975fa2ab670244395fe66..61900c481732d9fb18bab5741fff2a5e022ad234 100644 (file)
@@ -37,9 +37,10 @@ static int autofs_dir_readdir(struct inode *inode, struct file *filp,
 /*
  * No entries except for "." and "..", both of which are handled by the VFS layer
  */
-static int autofs_dir_lookup(struct inode *dir, struct qstr *str, struct inode **result)
+static int autofs_dir_lookup(struct inode *dir, struct dentry * dentry)
 {
-       return -ENOENT;         /* No other entries */
+       d_add(dentry, NULL);
+       return 0;
 }
 
 static struct file_operations autofs_dir_operations = {
index be152d06e1fd8ee6d26a86904e38880b49ed63bc..870ff120da121880e4b5b2637c90374fac5dbfa5 100644 (file)
 #define __NO_VERSION__
 #include <linux/module.h>
 
+/*
+ * Dummy functions - do we ever actually want to do
+ * something here?
+ */
 static void autofs_put_inode(struct inode *inode)
 {
-       if (inode->i_nlink)
-               return;
+}
+
+static void autofs_delete_inode(struct inode *inode)
+{
        inode->i_size = 0;
 }
 
@@ -59,11 +65,12 @@ 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_delete_inode,
+       NULL,                   /* notify_change */
        autofs_put_super,
-       NULL,
+       NULL,                   /* write_super */
        autofs_statfs,
        NULL
 };
index 41104a9ea0c7d082f74028e1587abea01fcb5577..4ecc6520ee49f7213ee2e36bdad9eb27beca7172 100644 (file)
@@ -16,7 +16,7 @@
 #include "autofs_i.h"
 
 static int autofs_root_readdir(struct inode *,struct file *,void *,filldir_t);
-static int autofs_root_lookup(struct inode *,struct qstr *,struct inode **);
+static int autofs_root_lookup(struct inode *,struct dentry *);
 static int autofs_root_symlink(struct inode *,struct dentry *,const char *);
 static int autofs_root_unlink(struct inode *,struct dentry *);
 static int autofs_root_rmdir(struct inode *,struct dentry *);
@@ -93,64 +93,105 @@ static int autofs_root_readdir(struct inode *inode, struct file *filp,
        return 0;
 }
 
-static int autofs_root_lookup(struct inode *dir, struct qstr *str, struct inode **result)
+static int try_to_fill_dentry(struct dentry * dentry, struct super_block * sb, struct autofs_sb_info *sbi)
 {
-       struct autofs_sb_info *sbi;
+       struct inode * inode;
        struct autofs_dir_ent *ent;
+       
+       while (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name))) {
+               int status = autofs_wait(sbi, &dentry->d_name);
+
+               /* Turn this into a real negative dentry? */
+               if (status == -ENOENT) {
+                       dentry->d_flags = 0;
+                       return 0;
+               }
+               if (status)
+                       return status;
+       }
+
+       if (!dentry->d_inode) {
+               inode = iget(sb, ent->ino);
+               if (!inode)
+                       return -EACCES;
+
+               dentry->d_inode = inode;
+       }
+
+       if (S_ISDIR(dentry->d_inode->i_mode)) {
+               while (dentry == dentry->d_mounts)
+                       schedule();
+       }
+       dentry->d_flags = 0;
+       return 0;
+}
+
+
+/*
+ * Revalidate is called on every cache lookup.  Some of those
+ * cache lookups may actually happen while the dentry is not
+ * yet completely filled in, and revalidate has to delay such
+ * lookups..
+ */
+static struct dentry * autofs_revalidate(struct dentry * dentry)
+{
+       struct autofs_sb_info *sbi;
+       struct inode * dir = dentry->d_parent->d_inode;
+
+       sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
+
+       /* Incomplete dentry? */
+       if (dentry->d_flags) {
+               if (autofs_oz_mode(sbi))
+                       return dentry;
+
+               try_to_fill_dentry(dentry, dir->i_sb, sbi);
+               return dentry;
+       }
+
+       /* Negative dentry.. Should we time these out? */
+       if (!dentry->d_inode)
+               return dentry;
+
+       /* We should update the usage stuff here.. */
+       return dentry;
+}
+
+static int autofs_root_lookup(struct inode *dir, struct dentry * dentry)
+{
+       struct autofs_sb_info *sbi;
        struct inode *res;
-       int status, oz_mode;
+       int oz_mode;
 
        DPRINTK(("autofs_root_lookup: name = "));
-       autofs_say(str->name,str->len);
+       autofs_say(dentry->d_name.name,dentry->d_name.len);
 
-       *result = NULL;
-       if (!dir)
-               return -ENOENT;
        if (!S_ISDIR(dir->i_mode))
                return -ENOTDIR;
 
-       *result = res = NULL;
+       res = NULL;
        sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
 
        oz_mode = autofs_oz_mode(sbi);
        DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n", current->pid, current->pgrp, sbi->catatonic, oz_mode));
 
-       do {
-               while ( !(ent = autofs_hash_lookup(&sbi->dirhash,str)) ) {
-                       DPRINTK(("lookup failed, pid = %u, pgrp = %u\n", current->pid, current->pgrp));
-                       
-                       if ( oz_mode )
-                               return -ENOENT;
-                       up(&dir->i_sem);
-                       status = autofs_wait(sbi,str);
-                       down(&dir->i_sem);
-                       DPRINTK(("autofs_wait returned %d\n", status));
-                       if ( status )
-                               return status;
-               }
-
-               DPRINTK(("lookup successful, inode = %08x\n", (unsigned int)ent->ino));
-
-               if (!(res = iget(dir->i_sb,ent->ino))) {
-                       printk("autofs: iget returned null!\n");
-                       return -EACCES;
-               }
-               
-               if ( !oz_mode && S_ISDIR(res->i_mode) && i_dentry(res)->d_covers == i_dentry(res)) {
-                       /* Not a mount point yet, call 1-800-DAEMON */
-                       DPRINTK(("autofs: waiting on non-mountpoint dir, inode = %lu, pid = %u, pgrp = %u\n", res->i_ino, current->pid, current->pgrp));
-                       iput(res);
-                       res = NULL;
-                       up(&dir->i_sem);
-                       status = autofs_wait(sbi,str);
-                       down(&dir->i_sem);
-                       if ( status )
-                               return status;
-               }
-       } while(!res);
-       autofs_update_usage(&sbi->dirhash,ent);
-       
-       *result = res;
+       /*
+        * Mark the dentry incomplete, but add it. This is needed so
+        * that the VFS layer knows about the dentry, and we can count
+        * on catching any lookups through the revalidate.
+        *
+        * Let all the hard work be done by the revalidate function that
+        * needs to be able to do this anyway..
+        *
+        * We need to do this before we release the directory semaphore.
+        */
+       dentry->d_revalidate = autofs_revalidate;
+       dentry->d_flags = 1;
+       d_add(dentry, NULL);
+
+       up(&dir->i_sem);
+       autofs_revalidate(dentry);
+       down(&dir->i_sem);
        return 0;
 }
 
@@ -164,7 +205,7 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c
        struct autofs_symlink *sl;
 
        DPRINTK(("autofs_root_symlink: %s <- ", symname));
-       autofs_say(name,len);
+       autofs_say(dentry->d_name.name,dentry->d_name.len);
 
        if ( !autofs_oz_mode(sbi) )
                return -EPERM;
index 72ebd42de0c37a41c83a04aa48524795c1ec1a9e..ffca300d9b8179402af2c82d9c183d813c5d8209 100644 (file)
@@ -50,7 +50,7 @@ struct binfmt_entry {
 
 #define ENTRY_ENABLED 1                /* the old binfmt_entry.enabled */
 #define        ENTRY_MAGIC 8           /* not filename detection */
-#define ENTRY_STRIP_EXT 32     /* strip of last filename extension */
+#define ENTRY_STRIP_EXT 32     /* strip off last filename extension */
 
 static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs);
 static void entry_proc_cleanup(struct binfmt_entry *e);
@@ -162,6 +162,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        char *iname_addr = iname, *p;
        int retval, fmt_flags = 0;
 
+       MOD_INC_USE_COUNT;
        if (!enabled) {
                retval = -ENOEXEC;
                goto _ret;
@@ -208,6 +209,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        if (retval >= 0)
                retval = search_binary_handler(bprm, regs);
 _ret:
+       MOD_DEC_USE_COUNT;
        return retval;
 }
 
@@ -266,13 +268,18 @@ static int proc_write_register(struct file *file, const char *buffer,
        struct binfmt_entry *e;
        int memsize, cnt = count - 1, err = 0;
 
+       MOD_INC_USE_COUNT;
        /* some sanity checks */
-       if ((count < 11) || (count > 256))
-               return -EINVAL;
+       if ((count < 11) || (count > 256)) {
+               err = -EINVAL;
+               goto _err;
+       }
 
        memsize = sizeof(struct binfmt_entry) + count;
-       if (!(e = (struct binfmt_entry *) kmalloc(memsize, GFP_USER)))
-               return -ENOMEM;
+       if (!(e = (struct binfmt_entry *) kmalloc(memsize, GFP_USER))) {
+               err = -ENOMEM;
+               goto _err;
+       }
 
        sp = buffer + 1;
        del = buffer[0];
@@ -309,7 +316,8 @@ static int proc_write_register(struct file *file, const char *buffer,
            !(e->proc_name) || !(e->interpreter) ||
            entry_proc_setup(e)) {
                kfree(e);
-               return -EINVAL;
+               err = -EINVAL;
+               goto _err;
        }
 
        write_lock(&entries_lock);
@@ -317,7 +325,10 @@ static int proc_write_register(struct file *file, const char *buffer,
        entries = e;
        write_unlock(&entries_lock);
 
-       return count;
+       err = count;
+_err:
+       MOD_DEC_USE_COUNT;
+       return err;
 }
 
 /*
@@ -332,6 +343,7 @@ static int proc_read_status(char *page, char **start, off_t off,
        char *dp;
        int elen, i;
 
+       MOD_INC_USE_COUNT;
 #ifndef VERBOSE_STATUS
        if (data) {
                read_lock(&entries_lock);
@@ -391,6 +403,7 @@ _out:
        *eof = (elen <= count) ? 1 : 0;
        *start = page + off;
 
+       MOD_DEC_USE_COUNT;
        return elen;
 }
 
@@ -404,6 +417,7 @@ static int proc_write_status(struct file *file, const char *buffer,
        struct binfmt_entry *e;
        int res = count;
 
+       MOD_INC_USE_COUNT;
        if (((buffer[0] == '1') || (buffer[0] == '0')) &&
            ((count == 1) || ((count == 2) && (buffer[1] == '\n')))) {
                if (data) {
@@ -423,6 +437,7 @@ static int proc_write_status(struct file *file, const char *buffer,
        } else {
                res = -EINVAL;
        }
+       MOD_DEC_USE_COUNT;
        return res;
 }
 
index 3feac5bd81d304a88b885f9b3701502018ff75b5..46fce4b3ae9b4154d525af60d220efca06aeb87e 100644 (file)
@@ -171,9 +171,8 @@ void ext2_free_inode (struct inode * inode)
                printk ("ext2_free_inode: inode has no device\n");
                return;
        }
-       if (atomic_read(&inode->i_count) > 1) {
-               printk ("ext2_free_inode: inode has count=%d\n",
-                       atomic_read(&inode->i_count));
+       if (inode->i_count > 1) {
+               printk ("ext2_free_inode: inode has count=%d\n", inode->i_count);
                return;
        }
        if (inode->i_nlink) {
@@ -403,7 +402,6 @@ repeat:
        sb->s_dirt = 1;
        inode->i_mode = mode;
        inode->i_sb = sb;
-       atomic_set(&inode->i_count, 1);
        inode->i_nlink = 1;
        inode->i_dev = sb->s_dev;
        inode->i_uid = current->fsuid;
index d00d49e856b56d4b245ac03fb8a14a39b9666b88..0fa14cfe1d6926812601b0c51450eac8ccd418c4 100644 (file)
 
 static int ext2_update_inode(struct inode * inode, int do_sync);
 
+/*
+ * Called at each iput()
+ */
 void ext2_put_inode (struct inode * inode)
 {
        ext2_discard_prealloc (inode);
-       if (inode->i_nlink || inode->i_ino == EXT2_ACL_IDX_INO ||
+}
+
+/*
+ * Called at the last iput() if i_nlink is zero.
+ */
+void ext2_delete_inode (struct inode * inode)
+{
+       if (inode->i_ino == EXT2_ACL_IDX_INO ||
            inode->i_ino == EXT2_ACL_DATA_INO)
                return;
        inode->u.ext2_i.i_dtime = CURRENT_TIME;
index a4dd35526705ae56875bd2a9f9050327e5abb252..5793c98988c0c2f314c09430999dce70eb6def7a 100644 (file)
@@ -155,31 +155,26 @@ failure:
        return NULL;
 }
 
-int ext2_lookup(struct inode * dir, struct qstr *name, struct inode ** result)
+int ext2_lookup(struct inode * dir, struct dentry *dentry)
 {
-       unsigned long ino;
+       struct inode * inode;
        struct ext2_dir_entry * de;
        struct buffer_head * bh;
 
-       *result = NULL;
-       if (!dir)
-               return -ENOENT;
-
-       if (!S_ISDIR(dir->i_mode))
-               return -ENOTDIR;
-
-       if (name->len > EXT2_NAME_LEN)
+       if (dentry->d_name.len > EXT2_NAME_LEN)
                return -ENAMETOOLONG;
 
-       ino = dir->i_version;
-       if (!(bh = ext2_find_entry (dir, name->name, name->len, &de)))
-               return -ENOENT;
-
-       ino = le32_to_cpu(de->inode);
-       brelse (bh);
-       if (!(*result = iget (dir->i_sb, ino)))
-               return -EACCES;
+       bh = ext2_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
+       inode = NULL;
+       if (bh) {
+               unsigned long ino = le32_to_cpu(de->inode);
+               brelse (bh);
+               inode = iget(dir->i_sb, ino);
 
+               if (!inode)
+                       return -EACCES;
+       }
+       d_add(dentry, inode);
        return 0;
 }
 
@@ -613,7 +608,7 @@ int ext2_rmdir (struct inode * dir, struct dentry *dentry)
        else if (le32_to_cpu(de->inode) != inode->i_ino)
                retval = -ENOENT;
        else {
-               if (atomic_read(&inode->i_count) > 1) {
+               if (inode->i_count > 1) {
                /*
                 * Are we deleting the last instance of a busy directory?
                 * Better clean up if so.
@@ -809,32 +804,30 @@ int ext2_link (struct inode * inode, struct inode * dir, struct dentry *dentry)
        inode->i_nlink++;
        inode->i_ctime = CURRENT_TIME;
        mark_inode_dirty(inode);
-       atomic_inc(&inode->i_count);
+       inode->i_count++;
        d_instantiate(dentry, inode);
        return 0;
 }
 
-static int subdir (struct inode * new_inode, struct inode * old_inode)
+/*
+ * Trivially implemented using the dcache structure
+ */
+static int subdir (struct dentry * new_dentry, struct dentry * old_dentry)
 {
-       int ino;
        int result;
 
-       atomic_inc(&new_inode->i_count);
        result = 0;
        for (;;) {
-               if (new_inode == old_inode) {
-                       result = 1;
-                       break;
+               if (new_dentry != old_dentry) {
+                       struct dentry * parent = new_dentry->d_parent;
+                       if (parent == new_dentry)
+                               break;
+                       new_dentry = parent;
+                       continue;
                }
-               if (new_inode->i_dev != old_inode->i_dev)
-                       break;
-               ino = new_inode->i_ino;
-               if (ext2_lookup (new_inode, &(struct qstr) { "..", 2, 0 }, &new_inode))
-                       break;
-               if (new_inode->i_ino == ino)
-                       break;
+               result = 1;
+               break;
        }
-       iput (new_inode);
        return result;
 }
 
@@ -842,10 +835,6 @@ static int subdir (struct inode * new_inode, struct inode * old_inode)
        ((struct ext2_dir_entry *) ((char *) buffer + \
        le16_to_cpu(((struct ext2_dir_entry *) buffer)->rec_len)))->inode
 
-#define PARENT_NAME(buffer) \
-       ((struct ext2_dir_entry *) ((char *) buffer + \
-       le16_to_cpu(((struct ext2_dir_entry *) buffer)->rec_len)))->name
-
 /*
  * rename uses retrying to avoid race-conditions: at least they should be
  * minimal.
@@ -906,13 +895,13 @@ static int do_ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
                if (!S_ISDIR(old_inode->i_mode))
                        goto end_rename;
                retval = -EINVAL;
-               if (subdir (new_dir, old_inode))
+               if (subdir(new_dentry, old_dentry))
                        goto end_rename;
                retval = -ENOTEMPTY;
                if (!empty_dir (new_inode))
                        goto end_rename;
                retval = -EBUSY;
-               if (atomic_read(&new_inode->i_count) > 1)
+               if (new_inode->i_count > 1)
                        goto end_rename;
        }
        retval = -EPERM;
@@ -925,7 +914,7 @@ static int do_ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
                if (new_inode && !S_ISDIR(new_inode->i_mode))
                        goto end_rename;
                retval = -EINVAL;
-               if (subdir (new_dir, old_inode))
+               if (subdir(new_dentry, old_dentry))
                        goto end_rename;
                dir_bh = ext2_bread (old_inode, 0, 0, &retval);
                if (!dir_bh)
index c70fafb636115f68030438e22caef306b478e3b8..1adc8218567acf43534f6503a76c6373007249c6 100644 (file)
@@ -133,9 +133,10 @@ void ext2_put_super (struct super_block * sb)
 
 static struct super_operations ext2_sops = {
        ext2_read_inode,
-       NULL,
        ext2_write_inode,
        ext2_put_inode,
+       ext2_delete_inode,
+       NULL,
        ext2_put_super,
        ext2_write_super,
        ext2_statfs,
index 62ff8af1efac3a6c8569fcd2e40d46f2fe4425b8..6223c1c48ece9e48310656593c1e4bb1c49c432d 100644 (file)
@@ -280,7 +280,7 @@ int fat_free(struct inode *inode,int skip)
                    12 ? EOF_FAT12 : EOF_FAT16);
        else {
                MSDOS_I(inode)->i_start = 0;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
        }
        lock_fat(inode->i_sb);
        while (nr != -1) {
index 82787075ab84a94bf34e000b24b025a4481b90e7..ca35cc28fe6efcb9019f8961e94f9fa3fb094ba1 100644 (file)
@@ -52,6 +52,7 @@ struct inode_operations fat_file_inode_operations = {
        NULL,                   /* mknod */
        NULL,                   /* rename */
        NULL,                   /* readlink */
+       NULL,                   /* follow_link */
        generic_readpage,       /* readpage */
        NULL,                   /* writepage */
        fat_bmap,               /* bmap */
@@ -99,6 +100,7 @@ struct inode_operations fat_file_inode_operations_1024 = {
        NULL,                   /* mknod */
        NULL,                   /* rename */
        NULL,                   /* readlink */
+       NULL,                   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
@@ -355,7 +357,7 @@ long fat_file_write(
                filp->f_pos += written;
                if (filp->f_pos > inode->i_size) {
                        inode->i_size = filp->f_pos;
-                       inode->i_dirt = 1;
+                       mark_inode_dirty(inode);
                }
                fat_set_uptodate(sb, bh, 1);
                fat_mark_buffer_dirty(sb, bh, 0);
@@ -365,7 +367,7 @@ long fat_file_write(
                return error;
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        return buf-start;
 }
 
@@ -379,5 +381,5 @@ void fat_truncate(struct inode *inode)
        cluster = SECTOR_SIZE*MSDOS_SB(inode->i_sb)->cluster_size;
        (void) fat_free(inode,(inode->i_size+(cluster-1))/cluster);
        MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
 }
index cf14856d12527243f88958f9af3845f96b6702a3..e35722affc8ffb85c7d1cd88f92b268e8040cf1c 100644 (file)
@@ -196,6 +196,7 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
        int debug,error,fat;
        int blksize = 512;
        struct fat_mount_options opts;
+       struct inode *root_inode;
 
        MOD_INC_USE_COUNT;
        if (hardsect_size[MAJOR(sb->s_dev)] != NULL){
@@ -329,7 +330,10 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
        MSDOS_SB(sb)->fat_lock = 0;
        MSDOS_SB(sb)->prev_free = 0;
        memcpy(&(MSDOS_SB(sb)->options), &opts, sizeof(struct fat_mount_options));
-       if (!(sb->s_mounted = iget(sb,MSDOS_ROOT_INO))) {
+
+       root_inode = iget(sb,MSDOS_ROOT_INO);
+       sb->s_root = d_alloc_root(root_inode, NULL);
+       if (!sb->s_root) {
                sb->s_dev = 0;
                printk("get root inode failed\n");
                MOD_DEC_USE_COUNT;
@@ -339,7 +343,7 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
 }
 
 
-void fat_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
+int fat_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
 {
        int free,nr;
        struct statfs tmp;
@@ -362,7 +366,7 @@ void fat_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
        tmp.f_files = 0;
        tmp.f_ffree = 0;
        tmp.f_namelen = 12;
-       copy_to_user(buf, &tmp, bufsiz);
+       return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
 }
 
 
@@ -514,10 +518,9 @@ void fat_write_inode(struct inode *inode)
                linked->i_blocks = inode->i_blocks;
                linked->i_atime = inode->i_atime;
                MSDOS_I(linked)->i_attrs = MSDOS_I(inode)->i_attrs;
-               linked->i_dirt = 1;
+               mark_inode_dirty(linked);
        }
 
-       inode->i_dirt = 0;
        if (inode->i_ino == MSDOS_ROOT_INO || !inode->i_nlink) return;
        if (!(bh = fat_bread(sb, inode->i_ino >> MSDOS_DPB_BITS))) {
                printk("dev = %s, ino = %ld\n",
index dfd06929d2871b8535e00330afec5d9ad3bb286c..034f62c1f96492948259c3d568e8eeea9a19a123 100644 (file)
@@ -40,9 +40,7 @@ void fat_fs_panic(struct super_block *s,const char *msg)
 
        not_ro = !(s->s_flags & MS_RDONLY);
        if (not_ro) s->s_flags |= MS_RDONLY;
-       printk("Filesystem panic (dev %s, ", kdevname(s->s_dev));
-       printk("mounted on %s:%ld)\n  %s\n", /* note: kdevname returns & static char[] */
-              kdevname(s->s_covered->i_dev), s->s_covered->i_ino, msg);
+       printk("Filesystem panic (dev %s).", kdevname(s->s_dev));
        if (not_ro)
                printk("  File system has been set read-only\n");
 }
@@ -180,7 +178,7 @@ printk("last = %d\n",last);
        if (last) fat_access(sb,last,nr);
        else {
                MSDOS_I(inode)->i_start = nr;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
        }
 #ifdef DEBUG
 if (last) printk("next set to %d\n",fat_access(sb,last,-1));
@@ -217,7 +215,7 @@ if (last) printk("next set to %d\n",fat_access(sb,last,-1));
 #ifdef DEBUG
 printk("size is %d now (%x)\n",inode->i_size,inode);
 #endif
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
        }
        return 0;
 }
index 6a3515eef82c8420606bc67cb11e0af93d20760e..c3a51d28be8c50b31345bb08359c01159950cbca 100644 (file)
@@ -29,7 +29,7 @@ static unsigned long fat_file_mmap_nopage(
        unsigned long address,
        int error_code)
 {
-       struct inode * inode = area->vm_inode;
+       struct inode * inode = area->vm_dentry->d_inode;
        unsigned long page;
        unsigned int clear;
        int pos;
@@ -101,10 +101,10 @@ int fat_mmap(struct inode * inode, struct file * file, struct vm_area_struct * v
                return -EACCES;
        if (!IS_RDONLY(inode)) {
                inode->i_atime = CURRENT_TIME;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
        }
 
-       vma->vm_inode = inode;
+       vma->vm_dentry = dget(file->f_dentry);
        atomic_inc(&inode->i_count);
        vma->vm_ops = &fat_file_mmap;
        return 0;
index 16f4f7f61b4dfc3e4bfdcb4c81071e2a936e1c28..d2eb7a80ea5badc87232a7f0e0dca6db21d05369 100644 (file)
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -153,7 +153,6 @@ struct inode_operations fifo_inode_operations = {
 void init_fifo(struct inode * inode)
 {
        inode->i_op = &fifo_inode_operations;
-       inode->i_pipe = 1;
        PIPE_LOCK(*inode) = 0;
        PIPE_BASE(*inode) = NULL;
        PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
index 22a96ff17a971b8cd646bd9bd3a47b92b23952e3..6eb923b1a38099495ca6433e9eb909704aa8b251 100644 (file)
@@ -104,6 +104,7 @@ static inline void init_once(struct inode * inode)
        memset(inode, 0, sizeof(*inode));
        init_waitqueue(&inode->i_wait);
        INIT_LIST_HEAD(&inode->i_dentry);
+       INIT_LIST_HEAD(&inode->i_hash);
        sema_init(&inode->i_sem, 1);
 }
 
@@ -192,18 +193,13 @@ void clear_inode(struct inode *inode)
        if (IS_WRITABLE(inode) && inode->i_sb && inode->i_sb->dq_op)
                inode->i_sb->dq_op->drop(inode);
 
-       spin_lock(&inode_lock);
        inode->i_state = 0;
-       list_del(&inode->i_hash);
-       list_del(&inode->i_list);
-       list_add(&inode->i_list, &inode_unused);
-       spin_unlock(&inode_lock);
 }
 
 #define CAN_UNUSE(inode) \
-       ((atomic_read(&(inode)->i_count) == 0) && \
+       (((inode)->i_count == 0) && \
         ((inode)->i_nrpages == 0) && \
-        (!test_bit(I_LOCK, &(inode)->i_state)))
+        (!(inode)->i_state))
 
 static void invalidate_list(struct list_head *head, kdev_t dev)
 {
@@ -223,6 +219,7 @@ static void invalidate_list(struct list_head *head, kdev_t dev)
                if (!CAN_UNUSE(inode))
                        continue;
                list_del(&inode->i_hash);
+               INIT_LIST_HEAD(&inode->i_hash);
                list_del(&inode->i_list);
                list_add(&inode->i_list, &inode_unused);
        }
@@ -257,6 +254,7 @@ static void try_to_free_inodes(void)
                inode = list_entry(tmp, struct inode, i_list);
                if (CAN_UNUSE(inode)) {
                        list_del(&inode->i_hash);
+                       INIT_LIST_HEAD(&inode->i_hash);
                        head = &inode_unused;
                }
                list_add(tmp, head);
@@ -280,7 +278,7 @@ static struct inode * find_inode(struct super_block * sb, unsigned long ino, str
                        continue;
                if (inode->i_ino != ino)
                        continue;
-               atomic_inc(&inode->i_count);
+               inode->i_count++;
                break;
        }
        return inode;
@@ -296,10 +294,9 @@ static struct inode * find_inode(struct super_block * sb, unsigned long ino, str
 void clean_inode(struct inode *inode)
 {
        memset(&inode->u, 0, sizeof(inode->u));
-       inode->i_pipe = 0;
        inode->i_sock = 0;
        inode->i_op = NULL;
-       inode->i_nlink = 1;
+       inode->i_nlink = 0;
        inode->i_writecount = 0;
        memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
        sema_init(&inode->i_sem, 1);
@@ -322,15 +319,15 @@ struct inode * get_empty_inode(void)
        struct list_head * tmp;
 
        spin_lock(&inode_lock);
+       try_to_free_inodes();
        tmp = inode_unused.next;
        if (tmp != &inode_unused) {
                list_del(tmp);
                inode = list_entry(tmp, struct inode, i_list);
 add_new_inode:
-               INIT_LIST_HEAD(&inode->i_hash);
                inode->i_sb = NULL;
                inode->i_ino = ++last_ino;
-               atomic_set(&inode->i_count, 1);
+               inode->i_count = 1;
                list_add(&inode->i_list, &inode_in_use);
                inode->i_state = 0;
                spin_unlock(&inode_lock);
@@ -350,44 +347,6 @@ add_new_inode:
        return inode;
 }
 
-struct inode * get_pipe_inode(void)
-{
-       extern struct inode_operations pipe_inode_operations;
-       struct inode *inode = get_empty_inode();
-
-       if (inode) {
-               unsigned long page = __get_free_page(GFP_USER);
-
-               if (!page) {
-                       iput(inode);
-                       inode = NULL;
-               } else {
-                       PIPE_BASE(*inode) = (char *) page;
-                       inode->i_op = &pipe_inode_operations;
-                       atomic_set(&inode->i_count, 1);
-                       PIPE_WAIT(*inode) = NULL;
-                       PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
-                       PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
-                       PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
-                       PIPE_LOCK(*inode) = 0;
-                       /*
-                        * Mark the inode dirty from the very beginning,
-                        * that way it will never be moved to the dirty
-                        * list because "make_inode_dirty()" will think
-                        * that it already _is_ on the dirty list.
-                        */
-                       inode->i_state = 1 << I_DIRTY;
-                       inode->i_pipe = 1;
-                       inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR;
-                       inode->i_uid = current->fsuid;
-                       inode->i_gid = current->fsgid;
-                       inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-                       inode->i_blksize = PAGE_SIZE;
-               }
-       }
-       return inode;
-}
-
 /*
  * This is called with the inode lock held.. Be careful.
  */
@@ -406,7 +365,7 @@ add_new_inode:
                inode->i_dev = sb->s_dev;
                inode->i_ino = ino;
                inode->i_flags = sb->s_flags;
-               atomic_set(&inode->i_count, 1);
+               inode->i_count = 1;
                inode->i_state = 1 << I_LOCK;
                spin_unlock(&inode_lock);
                clean_inode(inode);
@@ -466,27 +425,31 @@ void insert_inode_hash(struct inode *inode)
 void iput(struct inode *inode)
 {
        if (inode) {
-               if (inode->i_pipe)
-                       wake_up_interruptible(&PIPE_WAIT(*inode));
+               struct super_operations *op = NULL;
 
-               /*
-                * Last user dropping the inode?
-                */
-               if (atomic_read(&inode->i_count) == 1) {
-                       void (*put)(struct inode *);
+               if (inode->i_sb && inode->i_sb->s_op)
+                       op = inode->i_sb->s_op;
+               if (op && op->put_inode)
+                       op->put_inode(inode);
 
-                       if (inode->i_pipe) {
-                               free_page((unsigned long)PIPE_BASE(*inode));
-                               PIPE_BASE(*inode)= NULL;
+               spin_lock(&inode_lock);
+               if (!--inode->i_count) {
+                       if (!inode->i_nlink) {
+                               list_del(&inode->i_hash);
+                               INIT_LIST_HEAD(&inode->i_hash);
+                               if (op && op->delete_inode) {
+                                       void (*delete)(struct inode *) = op->delete_inode;
+                                       spin_unlock(&inode_lock);
+                                       delete(inode);
+                                       spin_lock(&inode_lock);
+                               }
                        }
-
-                       if (inode->i_sb && inode->i_sb->s_op) {
-                               put = inode->i_sb->s_op->put_inode;
-                               if (put)
-                                       put(inode);
+                       if (list_empty(&inode->i_hash)) {
+                               list_del(&inode->i_list);
+                               list_add(&inode->i_list, &inode_unused);
                        }
                }
-               atomic_dec(&inode->i_count);
+               spin_unlock(&inode_lock);
        }
 }
 
index 4d3b7dc1508f164665d60064ab254ed88fb072d3..48321d356d2a92a436ce8d63bbaf25c1af264c1a 100644 (file)
@@ -62,20 +62,6 @@ struct inode_operations isofs_dir_inode_operations =
        NULL                    /* permission */
 };
 
-static int parent_inode_number(struct inode * inode, struct iso_directory_record * de)
-{
-       int inode_number = inode->i_ino;
-
-       if ((inode->i_sb->u.isofs_sb.s_firstdatazone) != inode->i_ino)
-               inode_number = inode->u.isofs_i.i_backlink;
-
-       if (inode_number != -1)
-               return inode_number;
-
-       /* This should never happen, but who knows.  Try to be forgiving */
-       return isofs_lookup_grandparent(inode, find_rock_ridge_relocation(de, inode));
-}
-
 static int isofs_name_translate(char * old, int len, char * new)
 {
        int i, c;
@@ -197,9 +183,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
 
                /* Handle the case of the '..' directory */
                if (de->name_len[0] == 1 && de->name[0] == 1) {
-                       inode_number = parent_inode_number(inode, de);
-                       if (inode_number == -1)
-                               break;
+                       inode_number = filp->f_dentry->d_parent->d_inode->i_ino;
                        if (filldir(dirent, "..", 2, filp->f_pos, inode_number) < 0)
                                break;
                        filp->f_pos += de_len;
index 3801055ca05b3b19a77497560e4b89b82f0c26af..436c221401a2321089ebebac5537875cf45fae9c 100644 (file)
@@ -54,9 +54,10 @@ void isofs_put_super(struct super_block *sb)
 
 static struct super_operations isofs_sops = {
        isofs_read_inode,
-       NULL,                   /* notify_change */
        NULL,                   /* write_inode */
        NULL,                   /* put_inode */
+       NULL,                   /* delete_inode */
+       NULL,                   /* notify_change */
        isofs_put_super,
        NULL,                   /* write_super */
        isofs_statfs,
@@ -663,7 +664,6 @@ void isofs_read_inode(struct inode * inode)
                                           isonum_711 (raw_inode->ext_attr_length))
          << inode -> i_sb -> u.isofs_sb.s_log_zone_size;
 
-       inode->u.isofs_i.i_backlink = 0xffffffff; /* Will be used for previous directory */
        switch (inode->i_sb->u.isofs_sb.s_conversion){
        case 'a':
          inode->u.isofs_i.i_file_format = ISOFS_FILE_UNKNOWN; /* File type */
@@ -735,7 +735,6 @@ void isofs_read_inode(struct inode * inode)
        /* With a data error we return this information */
        inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
        inode->u.isofs_i.i_first_extent = 0;
-       inode->u.isofs_i.i_backlink = 0xffffffff;
        inode->i_size = 0;
        inode->i_nlink = 1;
        inode->i_uid = inode->i_gid = 0;
index 909e8b25fd5b701b15bf2e09f285df6b11cef6a7..1c0be7fdefde3ef4cacbe0908f64a0acbb606724 100644 (file)
@@ -59,14 +59,13 @@ static int isofs_match(int len,const char * name, const char * compare, int dlen
  * entry - you'll have to do that yourself if you want to.
  */
 static struct buffer_head * isofs_find_entry(struct inode * dir,
-       const char * name, int namelen, unsigned long * ino, unsigned long * ino_back)
+       const char * name, int namelen, unsigned long * ino)
 {
        unsigned long bufsize = ISOFS_BUFFER_SIZE(dir);
        unsigned char bufbits = ISOFS_BUFFER_BITS(dir);
        unsigned int block, i, f_pos, offset, inode_number;
        struct buffer_head * bh;
        unsigned int old_offset;
-       unsigned int backlink;
        int dlen, rrflag, match;
        char * dpnt;
        struct iso_directory_record * de;
@@ -86,7 +85,6 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
   
        while (f_pos < dir->i_size) {
                de = (struct iso_directory_record *) (bh->b_data + offset);
-               backlink = dir->i_ino;
                inode_number = (block << bufbits) + (offset & (bufsize - 1));
 
                /* If byte is zero, this is the end of file, or time to move to
@@ -120,28 +118,6 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
                        return 0;
                }
                
-               /* Handle the '.' case */
-               
-               if (de->name[0]==0 && de->name_len[0]==1) {
-                       inode_number = dir->i_ino;
-                       backlink = 0;
-               }
-               
-               /* Handle the '..' case */
-
-               if (de->name[0]==1 && de->name_len[0]==1) {
-#if 0
-                       printk("Doing .. (%d %d)",
-                              dir->i_sb->s_firstdatazone,
-                              dir->i_ino);
-#endif
-                       if((dir->i_sb->u.isofs_sb.s_firstdatazone) != dir->i_ino)
-                               inode_number = dir->u.isofs_i.i_backlink;
-                       else
-                               inode_number = dir->i_ino;
-                       backlink = 0;
-               }
-    
                dlen = de->name_len[0];
                dpnt = de->name;
                /* Now convert the filename in the buffer to lower case */
@@ -183,16 +159,8 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
                                inode_number = 
                                        isofs_lookup_grandparent(dir,
                                           find_rock_ridge_relocation(de,dir));
-                               if(inode_number == -1){
-                                       /* Should never happen */
-                                       printk("Backlink not properly set %x %lx.\n",
-                                              isonum_733(de->extent),
-                                              dir->i_ino);
-                                       goto out;
-                               }
                        }
                        *ino = inode_number;
-                       *ino_back = backlink;
                        return bh;
                }
        }
@@ -201,16 +169,15 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
        return NULL;
 }
 
-int isofs_lookup(struct inode * dir, struct qstr *name,
-                struct inode ** result)
+int isofs_lookup(struct inode * dir, struct dentry * dentry)
 {
-       unsigned long ino, ino_back;
+       unsigned long ino;
        struct buffer_head * bh;
        char *lcname;
        struct inode *inode;
 
 #ifdef DEBUG
-       printk("lookup: %x %d\n",dir->i_ino, name->len);
+       printk("lookup: %x %d\n",dir->i_ino, dentry->d_name.len);
 #endif
        if (!dir)
                return -ENOENT;
@@ -222,39 +189,28 @@ int isofs_lookup(struct inode * dir, struct qstr *name,
         * then first convert this name to lower case.
         */
        if (dir->i_sb->u.isofs_sb.s_name_check == 'r' &&
-           (lcname = kmalloc(name->len, GFP_KERNEL)) != NULL) {
+           (lcname = kmalloc(dentry->d_name.len, GFP_KERNEL)) != NULL) {
                int i;
                char c;
 
-               for (i=0; i<name->len; i++) {
-                       c = name->name[i];
+               for (i=0; i<dentry->d_name.len; i++) {
+                       c = dentry->d_name.name[i];
                        if (c >= 'A' && c <= 'Z') c |= 0x20;
                        lcname[i] = c;
                }
-               bh = isofs_find_entry(dir, lcname, name->len,
-                                     &ino, &ino_back);
+               bh = isofs_find_entry(dir, lcname, dentry->d_name.len, &ino);
                kfree(lcname);
        } else
-               bh = isofs_find_entry(dir, name->name,
-                                     name->len, &ino, &ino_back);
+               bh = isofs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &ino);
 
-       if (!bh)
-               return -ENOENT;
-       brelse(bh);
+       inode = NULL;
+       if (bh) {
+               brelse(bh);
 
-       inode = iget(dir->i_sb,ino);
-       if (!inode)
-               return -EACCES;
-
-       /* We need this backlink for the ".." entry unless the name that we
-        * are looking up traversed a mount point (in which case the inode
-        * may not even be on an iso9660 filesystem, and writing to
-        * u.isofs_i would only cause memory corruption).
-        */
-       if (ino_back && !inode->i_pipe && inode->i_sb == dir->i_sb)
-               inode->u.isofs_i.i_backlink = ino_back;
-
-       *result = inode;
-       
+               inode = iget(dir->i_sb,ino);
+               if (!inode)
+                       return -EACCES;
+       }
+       d_add(dentry, inode);
        return 0;
 }
index 81ac9b047cda21c60424a9ef33005410b4f08909..48aefc6aa61b926158c35f630b631913778cebfd 100644 (file)
@@ -256,7 +256,7 @@ struct inode * minix_new_inode(const struct inode * dir)
        inode->i_dev = sb->s_dev;
        inode->i_uid = current->fsuid;
        inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        inode->i_ino = j;
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
        inode->i_op = NULL;
index 23aa70268a6ac8b0d2b84e14a2d13a361dd2ea6d..7ca7cb075c7351eeb5ec2c35cb3919b4a83550d8 100644 (file)
@@ -121,6 +121,6 @@ static long minix_file_write(struct inode * inode, struct file * filp,
                inode->i_size = pos;
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        filp->f_pos = pos;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        return written;
 }
index aeeb8eab1b505a9ca78cd8b5a1776bc41440a442..185fd28f957a6f1b2327c139c6cdec0e9c86cf6c 100644 (file)
@@ -307,7 +307,7 @@ struct super_block *minix_read_super(struct super_block *s,void *data,
        return s;
 }
 
-void minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+int minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
 {
        struct statfs tmp;
 
@@ -319,7 +319,7 @@ void minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
        tmp.f_files = sb->u.minix_sb.s_ninodes;
        tmp.f_ffree = minix_count_free_inodes(sb);
        tmp.f_namelen = sb->u.minix_sb.s_namelen;
-       copy_to_user(buf, &tmp, bufsiz);
+       return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
 }
 
 /*
@@ -472,7 +472,7 @@ repeat:
        }
        *p = tmp;
        inode->i_ctime = CURRENT_TIME;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        return result;
 }
 
@@ -585,7 +585,7 @@ repeat:
        }
        *p = tmp;
        inode->i_ctime = CURRENT_TIME;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        return result;
 }
 
@@ -833,14 +833,12 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode)
                printk("Bad inode number on dev %s"
                       ": %d is out of range\n",
                        kdevname(inode->i_dev), ino);
-               inode->i_dirt = 0;
                return 0;
        }
        block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
                (ino-1)/MINIX_INODES_PER_BLOCK;
        if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
                printk("unable to read i-node block\n");
-               inode->i_dirt = 0;
                return 0;
        }
        raw_inode = ((struct minix_inode *)bh->b_data) +
@@ -855,7 +853,6 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode)
                raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
        else for (block = 0; block < 9; block++)
                raw_inode->i_zone[block] = inode->u.minix_i.u.i1_data[block];
-       inode->i_dirt=0;
        mark_buffer_dirty(bh, 1);
        return bh;
 }
@@ -874,14 +871,12 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode)
                printk("Bad inode number on dev %s"
                       ": %d is out of range\n",
                        kdevname(inode->i_dev), ino);
-               inode->i_dirt = 0;
                return 0;
        }
        block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
                (ino-1)/MINIX2_INODES_PER_BLOCK;
        if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
                printk("unable to read i-node block\n");
-               inode->i_dirt = 0;
                return 0;
        }
        raw_inode = ((struct minix2_inode *)bh->b_data) +
@@ -898,7 +893,6 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode)
                raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
        else for (block = 0; block < 10; block++)
                raw_inode->i_zone[block] = inode->u.minix_i.u.i2_data[block];
-       inode->i_dirt=0;
        mark_buffer_dirty(bh, 1);
        return bh;
 }
index 1815cbb0c515afd92ccb01bb64459c78a26677fc..41113e2b882a19cb776091ad87a6606309a551ed 100644 (file)
@@ -173,7 +173,7 @@ static int minix_add_entry(struct inode * dir,
                if (block*bh->b_size + offset > dir->i_size) {
                        de->inode = 0;
                        dir->i_size = block*bh->b_size + offset;
-                       dir->i_dirt = 1;
+                       mark_inode_dirty(dir);
                }
                if (de->inode) {
                        if (namecompare(namelen, info->s_namelen, name, de->name)) {
@@ -182,7 +182,7 @@ static int minix_add_entry(struct inode * dir,
                        }
                } else {
                        dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-                       dir->i_dirt = 1;
+                       mark_inode_dirty(dir);
                        for (i = 0; i < info->s_namelen ; i++)
                                de->name[i] = (i < namelen) ? name[i] : 0;
                        dir->i_version = ++event;
@@ -215,12 +215,12 @@ int minix_create(struct inode * dir, struct dentry *dentry, int mode)
                return -ENOSPC;
        inode->i_op = &minix_file_inode_operations;
        inode->i_mode = mode;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        error = minix_add_entry(dir, dentry->d_name.name,
                                dentry->d_name.len, &bh ,&de);
        if (error) {
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                return error;
        }
@@ -269,11 +269,11 @@ int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
                init_fifo(inode);
        if (S_ISBLK(mode) || S_ISCHR(mode))
                inode->i_rdev = to_kdev_t(rdev);
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        error = minix_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de);
        if (error) {
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                return error;
        }
@@ -311,7 +311,7 @@ int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
        dir_block = minix_bread(inode,0,1);
        if (!dir_block) {
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                return -ENOSPC;
        }
@@ -327,7 +327,7 @@ int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
        inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
        if (dir->i_mode & S_ISGID)
                inode->i_mode |= S_ISGID;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        error = minix_add_entry(dir, dentry->d_name.name,
                                dentry->d_name.len, &bh, &de);
        if (error) {
@@ -338,7 +338,7 @@ int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
        de->inode = inode->i_ino;
        mark_buffer_dirty(bh, 1);
        dir->i_nlink++;
-       dir->i_dirt = 1;
+       mark_inode_dirty(dir);
        brelse(bh);
        d_instantiate(dentry, inode);
        return 0;
@@ -449,10 +449,10 @@ int minix_rmdir(struct inode * dir, struct dentry *dentry)
        dir->i_version = ++event;
        mark_buffer_dirty(bh, 1);
        inode->i_nlink=0;
-       inode->i_dirt=1;
+       mark_inode_dirty(inode);
        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
        dir->i_nlink--;
-       dir->i_dirt=1;
+       mark_inode_dirty(dir);
        d_delete(dentry);
        retval = 0;
 end_rmdir:
@@ -503,10 +503,10 @@ repeat:
        dir->i_version = ++event;
        mark_buffer_dirty(bh, 1);
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       dir->i_dirt = 1;
+       mark_inode_dirty(dir);
        inode->i_nlink--;
        inode->i_ctime = dir->i_ctime;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        d_delete(dentry);       /* This also frees the inode */
        retval = 0;
 end_unlink:
@@ -531,7 +531,7 @@ int minix_symlink(struct inode * dir, struct dentry *dentry,
        name_block = minix_bread(inode,0,1);
        if (!name_block) {
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                return -ENOSPC;
        }
@@ -542,12 +542,12 @@ int minix_symlink(struct inode * dir, struct dentry *dentry,
        mark_buffer_dirty(name_block, 1);
        brelse(name_block);
        inode->i_size = i;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        bh = minix_find_entry(dir, dentry->d_name.name,
                              dentry->d_name.len, &de);
        if (bh) {
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                brelse(bh);
                return -EEXIST;
@@ -556,7 +556,7 @@ int minix_symlink(struct inode * dir, struct dentry *dentry,
                            dentry->d_name.len, &bh, &de);
        if (i) {
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                return i;
        }
@@ -597,7 +597,7 @@ int minix_link(struct inode * inode, struct inode * dir,
        brelse(bh);
        inode->i_nlink++;
        inode->i_ctime = CURRENT_TIME;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        d_instantiate(dentry, inode);
        return 0;
 }
@@ -740,15 +740,15 @@ start_up:
        old_de->inode = 0;
        new_de->inode = old_inode->i_ino;
        old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
-       old_dir->i_dirt = 1;
+       mark_inode_dirty(old_dir);
        old_dir->i_version = ++event;
        new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
-       new_dir->i_dirt = 1;
+       mark_inode_dirty(new_dir);
        new_dir->i_version = ++event;
        if (new_inode) {
                new_inode->i_nlink--;
                new_inode->i_ctime = CURRENT_TIME;
-               new_inode->i_dirt = 1;
+               mark_inode_dirty(new_inode);
        }
        mark_buffer_dirty(old_bh, 1);
        mark_buffer_dirty(new_bh, 1);
@@ -756,13 +756,13 @@ start_up:
                PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
                mark_buffer_dirty(dir_bh, 1);
                old_dir->i_nlink--;
-               old_dir->i_dirt = 1;
+               mark_inode_dirty(old_dir);
                if (new_inode) {
                        new_inode->i_nlink--;
-                       new_inode->i_dirt = 1;
+                       mark_inode_dirty(new_inode);
                } else {
                        new_dir->i_nlink++;
-                       new_dir->i_dirt = 1;
+                       mark_inode_dirty(new_dir);
                }
        }
        /* Update the dcache */
index 92539cded01be87ab26f79f7c965b792c657b6b2..9f759ecc9ce05754f5189a36674b797f9d7ae5f6 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/uaccess.h>
 
 static int minix_readlink(struct inode *, char *, int);
+static struct dentry *minix_follow_link(struct inode *, struct dentry *);
 
 /*
  * symlinks can't do much...
@@ -31,6 +32,7 @@ struct inode_operations minix_symlink_inode_operations = {
        NULL,                   /* mknod */
        NULL,                   /* rename */
        minix_readlink,         /* readlink */
+       minix_follow_link,      /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
@@ -38,6 +40,21 @@ struct inode_operations minix_symlink_inode_operations = {
        NULL                    /* permission */
 };
 
+static struct dentry * minix_follow_link(struct inode * inode, struct dentry * base)
+{
+       struct buffer_head * bh;
+
+       bh = minix_bread(inode, 0, 0);
+       if (!bh) {
+               dput(base);
+               return ERR_PTR(-EIO);
+       }
+       UPDATE_ATIME(inode);
+       base = lookup_dentry(bh->b_data, base, 1);
+       brelse(bh);
+       return base;
+}
+
 static int minix_readlink(struct inode * inode, char * buffer, int buflen)
 {
        struct buffer_head * bh;
@@ -47,7 +64,6 @@ static int minix_readlink(struct inode * inode, char * buffer, int buflen)
        if (buflen > 1023)
                buflen = 1023;
        bh = minix_bread(inode, 0, 0);
-       iput(inode);
        if (!bh)
                return 0;
        i = 0;
index a6d3d4b5ea6ee78fc41f6deef1c89dd33dd254fb..298d6c155924ad80cf79d51fa123a6c683670b32 100644 (file)
@@ -58,7 +58,7 @@ repeat:
                        continue;
                }
                *p = 0;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                if (bh) {
                        mark_buffer_clean(bh);
                        brelse(bh);
@@ -167,7 +167,7 @@ repeat:
                else {
                        tmp = *p;
                        *p = 0;
-                       inode->i_dirt = 1;
+                       mark_inode_dirty(inode);
                        minix_free_block(inode->i_sb,tmp);
                }
        brelse(dind_bh);
@@ -191,7 +191,7 @@ void V1_minix_truncate(struct inode * inode)
                schedule();
        }
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
 }
 
 /*
@@ -220,7 +220,7 @@ repeat:
                        continue;
                }
                *p = 0;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                if (bh) {
                        mark_buffer_clean(bh);
                        brelse(bh);
@@ -329,7 +329,7 @@ repeat:
                else {
                        tmp = *p;
                        *p = 0;
-                       inode->i_dirt = 1;
+                       mark_inode_dirty(inode);
                        minix_free_block(inode->i_sb,tmp);
                }
        brelse(dind_bh);
@@ -374,7 +374,7 @@ repeat:
                 else {
                         tmp = *p;
                         *p = 0;
-                        inode->i_dirt = 1;
+                        mark_inode_dirty(inode);
                         minix_free_block(inode->i_sb,tmp);
                }
         brelse(tind_bh);
@@ -402,7 +402,7 @@ static void V2_minix_truncate(struct inode * inode)
                schedule();
        }
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
 }
 
 /*
index bcf6782d0b3617a363dea15d2ef09fcaabe52895..3a22eb986f20476d28bfb9a6ffa7d31869edee95 100644 (file)
@@ -280,7 +280,7 @@ static int msdos_create_entry(struct inode *dir, const char *name,int len,
         * XXX all times should be set by caller upon successful completion.
         */
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       dir->i_dirt = 1;
+       mark_inode_dirty(dir);
        memcpy(de->name,name,MSDOS_NAME);
        memset(de->unused, 0, sizeof(de->unused));
        de->attr = is_dir ? ATTR_DIR : ATTR_ARCH;
@@ -295,7 +295,7 @@ static int msdos_create_entry(struct inode *dir, const char *name,int len,
        if (!*result) return -EIO;
        (*result)->i_mtime = (*result)->i_atime = (*result)->i_ctime =
            CURRENT_TIME;
-       (*result)->i_dirt = 1;
+       mark_inode_dirty(*result);
        return 0;
 }
 
@@ -415,7 +415,8 @@ int msdos_rmdir(struct inode *dir,const char *name,int len)
        inode->i_nlink = 0;
        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
        dir->i_nlink--;
-       inode->i_dirt = dir->i_dirt = 1;
+       mark_inode_dirty(inode);
+       mark_inode_dirty(dir);
        de->name[0] = DELETED_FLAG;
        fat_mark_buffer_dirty(sb, bh, 1);
        res = 0;
@@ -465,7 +466,7 @@ int msdos_mkdir(struct inode *dir,const char *name,int len,int mode)
        dot->i_size = inode->i_size; /* doesn't grow in the 2nd create_entry */
        MSDOS_I(dot)->i_start = MSDOS_I(inode)->i_start;
        dot->i_nlink = inode->i_nlink;
-       dot->i_dirt = 1;
+       mark_inode_dirty(dot);
        iput(dot);
        if ((res = msdos_create_entry(inode,MSDOS_DOTDOT,2,1,0,&dot)) < 0)
                goto mkdir_error;
@@ -473,7 +474,7 @@ int msdos_mkdir(struct inode *dir,const char *name,int len,int mode)
        dot->i_size = dir->i_size;
        MSDOS_I(dot)->i_start = MSDOS_I(dir)->i_start;
        dot->i_nlink = dir->i_nlink;
-       dot->i_dirt = 1;
+       mark_inode_dirty(dot);
        MSDOS_I(inode)->i_busy = 0;
        iput(dot);
        iput(inode);
@@ -519,7 +520,8 @@ static int msdos_unlinkx(
        inode->i_nlink = 0;
        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
        MSDOS_I(inode)->i_busy = 1;
-       inode->i_dirt = dir->i_dirt = 1;
+       mark_inode_dirty(inode);
+       mark_inode_dirty(dir);
        de->name[0] = DELETED_FLAG;
        fat_mark_buffer_dirty(sb, bh, 1);
 unlink_done:
@@ -580,11 +582,11 @@ static int rename_same_dir(struct inode *old_dir,char *old_name,int old_len,
                }
                if (S_ISDIR(new_inode->i_mode)) {
                        new_dir->i_nlink--;
-                       new_dir->i_dirt = 1;
+                       mark_inode_dirty(new_dir);
                }
                new_inode->i_nlink = 0;
                MSDOS_I(new_inode)->i_busy = 1;
-               new_inode->i_dirt = 1;
+               mark_inode_dirty(new_inode);
                new_de->name[0] = DELETED_FLAG;
                fat_mark_buffer_dirty(sb, new_bh, 1);
                iput(new_inode);
@@ -675,7 +677,7 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,int old_len,
                }
                new_inode->i_nlink = 0;
                MSDOS_I(new_inode)->i_busy = 1;
-               new_inode->i_dirt = 1;
+               mark_inode_dirty(new_inode);
                new_de->name[0] = DELETED_FLAG;
                fat_mark_buffer_dirty(sb, new_bh, 1);
        }
@@ -696,14 +698,14 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,int old_len,
        }
        if (exists && S_ISDIR(new_inode->i_mode)) {
                new_dir->i_nlink--;
-               new_dir->i_dirt = 1;
+               mark_inode_dirty(new_dir);
        }
        msdos_read_inode(free_inode);
        MSDOS_I(old_inode)->i_busy = 1;
        MSDOS_I(old_inode)->i_linked = free_inode;
        MSDOS_I(free_inode)->i_oldlink = old_inode;
        fat_cache_inval_inode(old_inode);
-       old_inode->i_dirt = 1;
+       mark_inode_dirty(old_inode);
        old_de->name[0] = DELETED_FLAG;
        fat_mark_buffer_dirty(sb, old_bh, 1);
        fat_mark_buffer_dirty(sb, free_bh, 1);
@@ -726,7 +728,7 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,int old_len,
                }
                dotdot_de->start = MSDOS_I(dotdot_inode)->i_start =
                    MSDOS_I(new_dir)->i_start;
-               dotdot_inode->i_dirt = 1;
+               mark_inode_dirty(dotdot_inode);
                fat_mark_buffer_dirty(sb, dotdot_bh, 1);
                old_dir->i_nlink--;
                new_dir->i_nlink++;
@@ -793,6 +795,7 @@ struct inode_operations msdos_dir_inode_operations = {
        NULL,                   /* mknod */
        msdos_rename,           /* rename */
        NULL,                   /* readlink */
+       NULL,                   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        fat_bmap,               /* bmap */
index 3c0dbdc16df9698c01450f3a8fd92dbfe5f0b2bf..98070b8ac71339ff68123f6c5e7fed646d79b7e9 100644 (file)
@@ -237,38 +237,23 @@ void put_write_access(struct inode * inode)
  */
 static struct dentry * real_lookup(struct dentry * parent, struct qstr * name)
 {
+       struct dentry * result;
        struct inode *dir = parent->d_inode;
-       struct dentry *result;
-       struct inode *inode;
-       int error = -ENOTDIR;
-
-       down(&dir->i_sem);
-
-       error = -ENOTDIR;
-       if (dir->i_op && dir->i_op->lookup)
-               error = dir->i_op->lookup(dir, name, &inode);
-       result = ERR_PTR(error);
-
-       if (!error || error == -ENOENT) {
-               struct dentry *new;
-
-               if (error)
-                       inode = NULL;
-
-               new = d_alloc(parent, name);
 
-               /*
-                * Ok, now we can't sleep any more. Double-check that
-                * nobody else added this in the meantime..
-                */
+       result = ERR_PTR(-ENOTDIR);
+       if (dir->i_op && dir->i_op->lookup) {
+               down(&dir->i_sem);
                result = d_lookup(parent, name);
-               if (result) {
-                       d_free(new);
-                       iput(inode);
-               } else {
-                       d_add(new, inode);
-                       result = new;
+               if (!result) {
+                       int error;
+                       result = d_alloc(parent, name);
+                       error = dir->i_op->lookup(dir, result);
+                       if (error) {
+                               d_free(result);
+                               result = ERR_PTR(error);
+                       }
                }
+               up(&dir->i_sem);
        }
        up(&dir->i_sem);
        return result;
@@ -280,8 +265,11 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name)
        struct dentry * dentry = d_lookup(parent, name);
 
        if (dentry) {
-               if (dentry->d_revalidate)
+               if (dentry->d_revalidate) {
+                       /* spin_unlock(&dentry_lock); */
                        dentry = dentry->d_revalidate(dentry);
+                       /* spin_lock(&dentry_lock); */
+               }
 
                /*
                 * The parent d_count _should_ be at least 2: one for the
index 3347fc4e07ad2b4561addbf4923504748edb4729..b10331c6a9e60564de8263a35224f226b9bd83fd 100644 (file)
@@ -42,7 +42,7 @@ struct nfs_dirent {
 static int nfs_dir_open(struct inode * inode, struct file * file);
 static long nfs_dir_read(struct inode *, struct file *, char *, unsigned long);
 static int nfs_readdir(struct inode *, struct file *, void *, filldir_t);
-static int nfs_lookup(struct inode *, struct qstr *, struct inode **);
+static int nfs_lookup(struct inode *, struct dentry *);
 static int nfs_create(struct inode *, struct dentry *, int);
 static int nfs_mkdir(struct inode *, struct dentry *, int);
 static int nfs_rmdir(struct inode *, struct dentry *);
@@ -328,19 +328,17 @@ nfs_free_dircache(void)
 }
  
 
-static int nfs_lookup(struct inode *dir, struct qstr * __name,
-                     struct inode **result)
+static int nfs_lookup(struct inode *dir, struct dentry * dentry)
 {
+       struct inode *inode;
        struct nfs_fh fhandle;
        struct nfs_fattr fattr;
-       int len = __name->len;
-       char name[len > NFS_MAXNAMLEN? 1 : len+1];
+       int len = dentry->d_name.len;
        int error;
 
        dfprintk(VFS, "NFS: lookup(%x/%ld, %.*s)\n",
-                               dir->i_dev, dir->i_ino, len, __name->name);
+                               dir->i_dev, dir->i_ino, len, dentry->d_name.name);
 
-       *result = NULL;
        if (!dir || !S_ISDIR(dir->i_mode)) {
                printk("nfs_lookup: inode is NULL or not a directory\n");
                return -ENOENT;
@@ -349,17 +347,18 @@ static int nfs_lookup(struct inode *dir, struct qstr * __name,
        if (len > NFS_MAXNAMLEN)
                return -ENAMETOOLONG;
 
-       memcpy(name,__name->name,len);
-       name[len] = '\0';
+       error = nfs_proc_lookup(NFS_SERVER(dir), NFS_FH(dir), dentry->d_name.name, &fhandle, &fattr);
 
-       error = nfs_proc_lookup(NFS_SERVER(dir), NFS_FH(dir),
-               name, &fhandle, &fattr);
-       if (error)
+       inode = NULL;
+       if (!error) {
+               error = -ENOENT;
+               inode = nfs_fhget(dir->i_sb, &fhandle, &fattr);
+               if (!inode)
+                       return -EACCES;
+       } else if (error != -ENOENT)
                return error;
 
-       if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr)))
-               return -EACCES;
-
+       d_add(dentry, inode);
        return 0;
 }
 
@@ -587,7 +586,7 @@ static int nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentr
        if (error)
                return error;
 
-       atomic_inc(&inode->i_count);
+       inode->i_count++;
        d_instantiate(dentry, inode);
        return 0;
 }
@@ -647,8 +646,7 @@ void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
        int was_empty;
 
        dfprintk(VFS, "NFS: refresh_inode(%x/%ld ct=%d)\n",
-                inode->i_dev, inode->i_ino,
-                atomic_read(&inode->i_count));
+                inode->i_dev, inode->i_ino, inode->i_count);
 
        if (!inode || !fattr) {
                printk("nfs_refresh_inode: inode or fattr is NULL\n");
index 6e5d806bc8a44cd2f9a0bd28a571ee903cffc2e7..eb4735a6d93392a020dded3e7ff11459d504fecf 100644 (file)
@@ -143,7 +143,7 @@ nfs_file_write(struct inode *inode, struct file *file,
        int     result;
 
        dfprintk(VFS, "nfs: write(%x/%ld (%d), %lu@%lu)\n",
-                       inode->i_dev, inode->i_ino, atomic_read(&inode->i_count),
+                       inode->i_dev, inode->i_ino, inode->i_count,
                        count, (unsigned long) file->f_pos);
 
        if (!inode) {
index e4cf24393bc74cf6427baac11088e18eeeb17b17..cf52a0d568485cd5ba34e92743c28ef1be19729a 100644 (file)
 
 static int nfs_notify_change(struct inode *, struct iattr *);
 static void nfs_put_inode(struct inode *);
+static void nfs_delete_inode(struct inode *);
 static void nfs_put_super(struct super_block *);
 static void nfs_read_inode(struct inode *);
 static int nfs_statfs(struct super_block *, struct statfs *, int bufsiz);
 
 static struct super_operations nfs_sops = { 
        nfs_read_inode,         /* read inode */
-       nfs_notify_change,      /* notify change */
        NULL,                   /* write inode */
        nfs_put_inode,          /* put inode */
+       nfs_delete_inode,       /* delete inode */
+       nfs_notify_change,      /* notify change */
        nfs_put_super,          /* put superblock */
        NULL,                   /* write superblock */
        nfs_statfs,             /* stat filesystem */
@@ -73,9 +75,16 @@ static void
 nfs_put_inode(struct inode * inode)
 {
        dprintk("NFS: put_inode(%x/%ld)\n", inode->i_dev, inode->i_ino);
+}
 
-       if (inode->i_pipe)
-               clear_inode(inode);
+/*
+ * This should do any silly-rename cleanups once we
+ * get silly-renaming working again..
+ */
+static void
+nfs_delete_inode(struct inode * inode)
+{
+       dprintk("NFS: delete_inode(%x/%ld)\n", inode->i_dev, inode->i_ino);
 }
 
 void
@@ -316,7 +325,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,
        }
        dprintk("NFS: fhget(%x/%ld ct=%d)\n",
                inode->i_dev, inode->i_ino,
-               atomic_read(&inode->i_count));
+               inode->i_count);
 
        return inode;
 }
index 2c3b59036d55ff6daec9aa90c83ee6ecb8a08dcc..4ce61f73111be4b7911fddc1c1017c8d31f26c4d 100644 (file)
@@ -150,7 +150,6 @@ nfs_readpage_result(struct rpc_task *task)
                fail++;
                dprintk("NFS: %d successful reads, %d failures\n", succ, fail);
        }
-       iput(req->ra_inode);
        clear_bit(PG_locked, &page->flags);
        wake_up(&page->wait);
 
@@ -188,7 +187,6 @@ nfs_readpage_async(struct inode *inode, struct page *page)
                                nfs_readpage_result, req);
 
        if (result >= 0) {
-               atomic_inc(&inode->i_count);
                atomic_inc(&page->count);
                return 0;
        }
index f27d083e479efa72d5f3ea97627d86d529d5b01a..9241c679e9841f7509d93888e89342656e3f311f 100644 (file)
@@ -338,7 +338,7 @@ create_write_request(struct inode *inode, struct page *page,
        wreq->wb_page   = page;
        wreq->wb_offset = offset;
        wreq->wb_bytes  = bytes;
-       atomic_inc(&inode->i_count);
+
        atomic_inc(&page->count);
 
        append_write_request(&NFS_WRITEBACK(inode), wreq);
@@ -695,7 +695,6 @@ nfs_check_error(struct inode *inode)
 
        status = req->wb_task.tk_status;
        remove_write_request(&nfs_failed_requests, req);
-       iput(req->wb_inode);
        kfree(req);
        return status;
 }
@@ -788,7 +787,6 @@ nfs_wback_result(struct rpc_task *task)
                        dprintk("NFS: %4d saving write failure code\n",
                                                task->tk_pid);
                        append_write_request(&nfs_failed_requests, req);
-                       atomic_inc(&inode->i_count);
                }
                clear_bit(PG_uptodate, &page->flags);
        } else if (!WB_CANCELLED(req)) {
@@ -818,6 +816,5 @@ nfs_wback_result(struct rpc_task *task)
                kfree(req);
 
        free_page(page_address(page));
-       iput(inode);
        nr_write_requests--;
 }
index 4a3653e73b625b00cd2cce8a7d414236be15bf35..afbacd7246a9af7916bb18385c4686136c56dfc3 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -416,6 +416,7 @@ asmlinkage int sys_chroot(const char * filename)
        tmp = current->fs->root;
        current->fs->root = dentry;
        dentry = tmp;
+       error = 0;
 
 dput_and_out:
        dput(dentry);
index 61223f4eb62fc51a093e5e96223d84a6dedfeaa1..3fbbec934dc379a338ad63190701109e28a83b13 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -230,18 +230,26 @@ static unsigned int connect_poll(struct file * filp, poll_table * wait)
        return POLLOUT | POLLWRNORM;
 }
 
-static int pipe_read_release(struct inode * inode, struct file * filp)
+static int pipe_release(struct inode * inode)
 {
-       PIPE_READERS(*inode)--;
+       if (!PIPE_READERS(*inode) && !PIPE_READERS(*inode)) {
+               free_page((unsigned long) PIPE_BASE(*inode));
+               PIPE_BASE(*inode) = NULL;
+       }
        wake_up_interruptible(&PIPE_WAIT(*inode));
        return 0;
 }
 
+static int pipe_read_release(struct inode * inode, struct file * filp)
+{
+       PIPE_READERS(*inode)--;
+       return pipe_release(inode);
+}
+
 static int pipe_write_release(struct inode * inode, struct file * filp)
 {
        PIPE_WRITERS(*inode)--;
-       wake_up_interruptible(&PIPE_WAIT(*inode));
-       return 0;
+       return pipe_release(inode);
 }
 
 static int pipe_rdwr_release(struct inode * inode, struct file * filp)
@@ -250,8 +258,7 @@ static int pipe_rdwr_release(struct inode * inode, struct file * filp)
                PIPE_READERS(*inode)--;
        if (filp->f_mode & FMODE_WRITE)
                PIPE_WRITERS(*inode)--;
-       wake_up_interruptible(&PIPE_WAIT(*inode));
-       return 0;
+       return pipe_release(inode);
 }
 
 static int pipe_read_open(struct inode * inode, struct file * filp)
@@ -370,6 +377,43 @@ struct file_operations rdwr_pipe_fops = {
        NULL
 };
 
+static struct inode * get_pipe_inode(void)
+{
+       extern struct inode_operations pipe_inode_operations;
+       struct inode *inode = get_empty_inode();
+
+       if (inode) {
+               unsigned long page = __get_free_page(GFP_USER);
+
+               if (!page) {
+                       iput(inode);
+                       inode = NULL;
+               } else {
+                       PIPE_BASE(*inode) = (char *) page;
+                       inode->i_op = &pipe_inode_operations;
+                       inode->i_count = 1;
+                       PIPE_WAIT(*inode) = NULL;
+                       PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
+                       PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
+                       PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
+                       PIPE_LOCK(*inode) = 0;
+                       /*
+                        * Mark the inode dirty from the very beginning,
+                        * that way it will never be moved to the dirty
+                        * list because "make_inode_dirty()" will think
+                        * that it already _is_ on the dirty list.
+                        */
+                       inode->i_state = 1 << I_DIRTY;
+                       inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR;
+                       inode->i_uid = current->fsuid;
+                       inode->i_gid = current->fsgid;
+                       inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+                       inode->i_blksize = PAGE_SIZE;
+               }
+       }
+       return inode;
+}
+
 struct inode_operations pipe_inode_operations = {
        &rdwr_pipe_fops,
        NULL,                   /* create */
index 6f336245da76a325aa365201ca7bad598c1d4349..68e2a34853b97216dcf5e22048b14a261c054c73 100644 (file)
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
 O_TARGET := proc.o
-O_OBJS   := inode.o root.o base.o generic.o mem.o link.o arbitrary.o fd.o array.o \
+O_OBJS   := inode.o root.o base.o generic.o mem.o link.o fd.o array.o \
                kmsg.o scsi.o proc_tty.o
 ifdef CONFIG_OMIRR
 O_OBJS   := $(O_OBJS) omirr.o
diff --git a/fs/proc/arbitrary.c b/fs/proc/arbitrary.c
deleted file mode 100644 (file)
index 390934e..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * $Id: arbitrary.c,v 1.2 1997/06/05 01:27:47 davem Exp $
- *
- * linux/fs/proc/arbitrary.c - lookup() for arbitrary inodes.
- * Copyright (C) 1997, Thomas Schoebel-Theuer,
- * <schoebel@informatik.uni-stuttgart.de>.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/kdev_t.h>
-#include <linux/fs.h>
-
-/* Format of dev/inode pairs that can be used as file names:
- * [<dev_number_in_hex]:<inode_number_in_decimal>
- * (the same format that is already in use in /proc/<pid>/exe,
- * /proc/<pid>/cwd and /proc/<pid>/root).
- */
-/* Note that readdir does not supply such names, so they must be used
- * either "blind" or must be queried another way, for example
- * as result of a virtual symlink (see linux/proc/link.c).
- */
-int proc_arbitrary_lookup(struct inode * dir, const char * name,
-                         int len, struct inode ** result)
-{
-       int dev, ino;
-       char * ptr = (char*)name;
-       kdev_t kdev;
-       int i;
-       int error = -EINVAL;
-       
-       if(*ptr++ != '[')
-               goto done;
-       dev = simple_strtoul(ptr, &ptr, 16);
-       if(*ptr++ != ']')
-               goto done;
-       if(*ptr++ != ':')
-               goto done;
-       ino = simple_strtoul(ptr, &ptr, 0);
-       if((long)ptr - (long)name != len)
-               goto done;
-
-       error = -ENOENT;
-       kdev = to_kdev_t(dev);
-       if(!kdev)
-               goto done;
-       for(i = 0; i < NR_SUPER; i++)
-               if(super_blocks[i].s_dev == kdev)
-                       break;
-       if(i < NR_SUPER) {
-               *result = iget(&super_blocks[i], ino);
-               if(*result)
-                       error = 0;
-       }
-done:
-       return error;
-}
index e57131d3fe3514fe9c3bb6d2baf64eb2ef7e9a23..1e1fb494f768d281ebc7426337fa515d35ebba0e 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/stat.h>
 
 static int proc_readfd(struct inode *, struct file *, void *, filldir_t);
-static int proc_lookupfd(struct inode *,struct qstr *,struct inode **);
+static int proc_lookupfd(struct inode *, struct dentry *);
 
 static struct file_operations proc_fd_operations = {
        NULL,                   /* lseek - default */
@@ -52,15 +52,24 @@ struct inode_operations proc_fd_inode_operations = {
        NULL                    /* permission */
 };
 
-static int proc_lookupfd(struct inode * dir, struct qstr *str, struct inode ** result)
+/*
+ * NOTE! Normally we'd indicate that a file does not
+ * exist by creating a negative dentry and returning
+ * a successful return code. However, for this case
+ * we do not want to create negative dentries, because
+ * the state of the world can change behind our backs.
+ *
+ * Thus just return -ENOENT instead.
+ */
+static int proc_lookupfd(struct inode * dir, struct dentry * dentry)
 {
        unsigned int ino, pid, fd, c;
        struct task_struct * p;
        struct super_block * sb;
+       struct inode *inode;
        const char *name;
        int len;
 
-       *result = NULL;
        ino = dir->i_ino;
        pid = ino >> 16;
        ino &= 0x0000ffff;
@@ -71,8 +80,8 @@ static int proc_lookupfd(struct inode * dir, struct qstr *str, struct inode ** r
                return -ENOENT;
 
        fd = 0;
-       len = str->len;
-       name = str->name;
+       len = dentry->d_name.len;
+       name = dentry->d_name.name;
        while (len-- > 0) {
                c = *name - '0';
                name++;
@@ -105,8 +114,11 @@ static int proc_lookupfd(struct inode * dir, struct qstr *str, struct inode ** r
 
        ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
 
-       if (!(*result = proc_get_inode(sb, ino, NULL)))
+       inode = proc_get_inode(sb, ino, NULL);
+       if (!inode)
                return -ENOENT;
+
+       d_add(dentry, inode);
        return 0;
 }
 
index 9ec25bec3f0fc2f377e7297a0528cd552822f363..4bc4a4f1765b63542563e9a52654092ae911f757 100644 (file)
@@ -25,8 +25,14 @@ static void proc_put_inode(struct inode *inode)
            && proc_openprom_use)
                (*proc_openprom_use)(inode, 0);
 #endif 
-       if (inode->i_nlink)
-               return;
+}
+
+/*
+ * Does this ever happen?
+ */
+static void proc_delete_inode(struct inode *inode)
+{
+       printk("proc_delete_inode()?\n");
        inode->i_size = 0;
 }
 
@@ -39,9 +45,10 @@ static void proc_put_super(struct super_block *sb)
 
 static struct super_operations proc_sops = { 
        proc_read_inode,
-       NULL,
        proc_write_inode,
        proc_put_inode,
+       proc_delete_inode,
+       NULL,
        proc_put_super,
        NULL,
        proc_statfs,
index ab6fcab1638b0c8d59dc2538ded227a328a1b867..2b456ca5729fb66e3bef28a189722862d8b46fe4 100644 (file)
@@ -24,7 +24,7 @@
 #define FIRST_PROCESS_ENTRY 256
 
 static int proc_root_readdir(struct inode *, struct file *, void *, filldir_t);
-static int proc_root_lookup(struct inode *,struct qstr *,struct inode **);
+static int proc_root_lookup(struct inode *,struct dentry *);
 
 static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8] = {0};
 
@@ -227,7 +227,6 @@ proc_openprom_deflookup(struct inode * dir, struct qstr *str, struct inode ** re
            proc_openprom_deflookup)
                return proc_openprom_inode_operations.lookup 
                                (dir, str, result);
-       iput(dir);
        return -ENOENT;
 }
 #endif
@@ -622,45 +621,50 @@ void proc_root_init(void)
        proc_tty_init();
 }
 
-
-int proc_lookup(struct inode * dir, struct qstr * str, struct inode ** result)
+/*
+ * Don't create negative dentries here, return -ENOENT by hand
+ * instead.
+ */
+int proc_lookup(struct inode * dir, struct dentry *dentry)
 {
+       struct inode *inode;
        struct proc_dir_entry * de;
 
-       *result = NULL;
        if (!dir || !S_ISDIR(dir->i_mode))
                return -ENOTDIR;
 
        de = (struct proc_dir_entry *) dir->u.generic_ip;
-       if (!de)
-               return -EINVAL;
-
-       *result = NULL;
-       for (de = de->subdir; de ; de = de->next) {
-               if (!de || !de->low_ino)
-                       continue;
-               if (de->namelen != str->len)
-                       continue;
-               if (!memcmp(str->name, de->name, str->len)) {
-                       int ino = de->low_ino | (dir->i_ino & ~(0xffff));
-                       if (!(*result = proc_get_inode(dir->i_sb, ino, de)))
-                               return -EINVAL;
-                       return 0;
+       inode = NULL;
+       if (de) {
+               for (de = de->subdir; de ; de = de->next) {
+                       if (!de || !de->low_ino)
+                               continue;
+                       if (de->namelen != dentry->d_name.len)
+                               continue;
+                       if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
+                               int ino = de->low_ino | (dir->i_ino & ~(0xffff));
+                               inode = proc_get_inode(dir->i_sb, ino, de);
+                               if (!inode)
+                                       return -EINVAL;
+                               break;
+                       }
                }
        }
-       return -ENOENT;
+       if (!inode)
+               return -ENOENT;
+
+       d_add(dentry, inode);
+       return 0;
 }
 
-static int proc_root_lookup(struct inode * dir,struct qstr *str, struct inode ** result)
+static int proc_root_lookup(struct inode * dir, struct dentry * dentry)
 {
        unsigned int pid, c;
-       int ino, retval;
        struct task_struct *p;
        const char *name;
+       struct inode *inode;
        int len;
 
-       atomic_inc(&dir->i_count);
-
        if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */
                dir->i_nlink = proc_root.nlink;
 
@@ -672,13 +676,12 @@ static int proc_root_lookup(struct inode * dir,struct qstr *str, struct inode **
                read_unlock(&tasklist_lock);
        }
 
-       retval = proc_lookup(dir, str, result);
-       if (retval != -ENOENT)
-               return retval;
+       if (!proc_lookup(dir, dentry))
+               return 0;
        
        pid = 0;
-       name = str->name;
-       len = str->len;
+       name = dentry->d_name.name;
+       len = dentry->d_name.len;
        while (len-- > 0) {
                c = *name - '0';
                name++;
@@ -694,12 +697,14 @@ static int proc_root_lookup(struct inode * dir,struct qstr *str, struct inode **
                }
        }
        p = find_task_by_pid(pid);
-       if (!pid || !p)
-               return -ENOENT;
-
-       ino = (pid << 16) + PROC_PID_INO;
-       if (!(*result = proc_get_inode(dir->i_sb, ino, &proc_pid)))
-               return -EINVAL;
+       inode = NULL;
+       if (pid && p) {
+               unsigned long ino = (pid << 16) + PROC_PID_INO;
+               inode = proc_get_inode(dir->i_sb, ino, &proc_pid);
+               if (!inode)
+                       return -EINVAL;
+       }
+       d_add(dentry, inode);
        return 0;
 }
 
index 59f918e7b4c913cd0f39e124fdd720516158e9f1..b17c6bb13d52ae669069948163e00d863511dd4b 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -48,8 +48,6 @@ static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf)
        tmp.st_gid = inode->i_gid;
        tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
        tmp.st_size = inode->i_size;
-       if (inode->i_pipe)
-               tmp.st_size = PIPE_SIZE(*inode);
        tmp.st_atime = inode->i_atime;
        tmp.st_mtime = inode->i_mtime;
        tmp.st_ctime = inode->i_ctime;
@@ -72,8 +70,6 @@ static int cp_new_stat(struct inode * inode, struct stat * statbuf)
        tmp.st_gid = inode->i_gid;
        tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
        tmp.st_size = inode->i_size;
-       if (inode->i_pipe)
-               tmp.st_size = PIPE_SIZE(*inode);
        tmp.st_atime = inode->i_atime;
        tmp.st_mtime = inode->i_mtime;
        tmp.st_ctime = inode->i_ctime;
index 8b942a5b14e56f17ce2f69706b13a53125c5d2ea..3dd0931cf1ef9321a6dc4d8f5610940f6644c690 100644 (file)
@@ -57,6 +57,7 @@ struct inode_operations sysv_dir_inode_operations = {
        sysv_mknod,             /* mknod */
        sysv_rename,            /* rename */
        NULL,                   /* readlink */
+       NULL,                   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
index da07ef7a8f42ba22483972745448d16e2171e084..1a28e4c2a6c8c9decded30201565eb183e6586b4 100644 (file)
@@ -64,6 +64,7 @@ struct inode_operations sysv_file_inode_operations = {
        NULL,                   /* mknod */
        NULL,                   /* rename */
        NULL,                   /* readlink */
+       NULL,                   /* follow_link */
        generic_readpage,       /* readpage */
        NULL,                   /* writepage */
        sysv_bmap,              /* bmap */
@@ -194,7 +195,7 @@ long sysv_file_read(struct inode * inode, struct file * filp,
        filp->f_reada = 1;
        if (!IS_RDONLY(inode)) {
                inode->i_atime = CURRENT_TIME;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
        }
        return read;
 }
@@ -255,7 +256,7 @@ static long sysv_file_write(struct inode * inode, struct file * filp,
                pos += c;
                if (pos > inode->i_size) {
                        inode->i_size = pos;
-                       inode->i_dirt = 1;
+                       mark_inode_dirty(inode);
                }
                written += c;
                buf += c;
@@ -265,6 +266,6 @@ static long sysv_file_write(struct inode * inode, struct file * filp,
        }
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        filp->f_pos = pos;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        return written;
 }
index 97bc7284fa643f972b95a3c649622e2de7e35ba4..565a4c9cdda1ce9feecc457f1ebb3cf1cab0abdc 100644 (file)
@@ -155,7 +155,7 @@ struct inode * sysv_new_inode(const struct inode * dir)
        inode->i_dev = sb->s_dev;
        inode->i_uid = current->fsuid;
        inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        inode->i_ino = ino;
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
        inode->i_op = NULL;
@@ -166,7 +166,7 @@ struct inode * sysv_new_inode(const struct inode * dir)
        inode->i_size = 0;              /* ditto */
        sysv_write_inode(inode);        /* ensure inode not allocated again */
                                        /* FIXME: caller may call this too. */
-       inode->i_dirt = 1;              /* cleared by sysv_write_inode() */
+       mark_inode_dirty(inode);        /* cleared by sysv_write_inode() */
        /* That's it. */
        (*sb->sv_sb_total_free_inodes)--;
        mark_buffer_dirty(sb->sv_bh2, 1); /* super-block has been modified again */
index f8c6a1b388e5391eb3c19a1c9d9510574e00c336..b2d7edfbc77d982d69a657970889bf82f4b27363 100644 (file)
@@ -344,6 +344,7 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
        struct buffer_head *bh;
        const char *found;
        kdev_t dev = sb->s_dev;
+       struct inode *root_inode;
 
        if (1024 != sizeof (struct xenix_super_block))
                panic("Xenix FS: bad super-block size");
@@ -483,9 +484,10 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
        /* set up enough so that it can read an inode */
        sb->s_dev = dev;
        sb->s_op = &sysv_sops;
-       sb->s_mounted = iget(sb,SYSV_ROOT_INO);
+       root_inode = iget(sb,SYSV_ROOT_INO);
+       sb->s_root = d_alloc_root(root_inode, NULL);
        unlock_super(sb);
-       if (!sb->s_mounted) {
+       if (!sb->s_root) {
                printk("SysV FS: get root inode failed\n");
                sysv_put_super(sb);
                return NULL;
@@ -534,7 +536,7 @@ void sysv_put_super(struct super_block *sb)
        MOD_DEC_USE_COUNT;
 }
 
-void sysv_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+int sysv_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
 {
        struct statfs tmp;
 
@@ -547,7 +549,7 @@ void sysv_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
        tmp.f_ffree = sysv_count_free_inodes(sb);       /* free file nodes in fs */
        tmp.f_namelen = SYSV_NAMELEN;
        /* Don't know what value to put in tmp.f_fsid */ /* file system id */
-       copy_to_user(buf, &tmp, bufsiz);
+       return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
 }
 
 
@@ -667,7 +669,7 @@ repeat:
        }
        *p = tmp;
        inode->i_ctime = CURRENT_TIME;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        return result;
 }
 
@@ -900,13 +902,11 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
                printk("Bad inode number on dev %s"
                       ": %d is out of range\n",
                       kdevname(inode->i_dev), ino);
-               inode->i_dirt = 0;
                return 0;
        }
        block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
        if (!(bh = sv_bread(sb,inode->i_dev,block))) {
                printk("unable to read i-node block\n");
-               inode->i_dirt = 0;
                return 0;
        }
        raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
@@ -937,7 +937,6 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
        else
                for (block = 0; block < 10+1+1+1; block++)
                        write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
-       inode->i_dirt=0;
        mark_buffer_dirty(bh, 1);
        return bh;
 }
index d1b67ab5f580b22e1d92d0ae7c53a22bb2253c8f..ffe8c76b9822c694942815f14cb4bfe0f26a68f5 100644 (file)
@@ -175,7 +175,7 @@ static int sysv_add_entry(struct inode * dir,
                if (pos > dir->i_size) {
                        de->inode = 0;
                        dir->i_size = pos;
-                       dir->i_dirt = 1;
+                       mark_inode_dirty(dir);
                }
                if (de->inode) {
                        if (namecompare(namelen, SYSV_NAMELEN, name, de->name)) {
@@ -184,7 +184,7 @@ static int sysv_add_entry(struct inode * dir,
                        }
                } else {
                        dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-                       dir->i_dirt = 1;
+                       mark_inode_dirty(dir);
                        for (i = 0; i < SYSV_NAMELEN ; i++)
                                de->name[i] = (i < namelen) ? name[i] : 0;
                        mark_buffer_dirty(bh, 1);
@@ -219,11 +219,11 @@ int sysv_create(struct inode * dir,const char * name, int len, int mode,
        }
        inode->i_op = &sysv_file_inode_operations;
        inode->i_mode = mode;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        error = sysv_add_entry(dir,name,len, &bh ,&de);
        if (error) {
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                iput(dir);
                return error;
@@ -276,11 +276,11 @@ int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rde
                init_fifo(inode);
        if (S_ISBLK(mode) || S_ISCHR(mode))
                inode->i_rdev = to_kdev_t(rdev);
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        error = sysv_add_entry(dir, name, len, &bh, &de);
        if (error) {
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                iput(dir);
                return error;
@@ -325,7 +325,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
        if (!dir_block) {
                iput(dir);
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                return -ENOSPC;
        }
@@ -341,7 +341,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
        inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
        if (dir->i_mode & S_ISGID)
                inode->i_mode |= S_ISGID;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        error = sysv_add_entry(dir, name, len, &bh, &de);
        if (error) {
                iput(dir);
@@ -352,7 +352,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
        de->inode = inode->i_ino;
        mark_buffer_dirty(bh, 1);
        dir->i_nlink++;
-       dir->i_dirt = 1;
+       mark_inode_dirty(dir);
        iput(dir);
        iput(inode);
        brelse(bh);
@@ -463,10 +463,10 @@ int sysv_rmdir(struct inode * dir, const char * name, int len)
        de->inode = 0;
        mark_buffer_dirty(bh, 1);
        inode->i_nlink=0;
-       inode->i_dirt=1;
+       mark_inode_dirty(inode);
        dir->i_nlink--;
        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       dir->i_dirt=1;
+       mark_inode_dirty(dir);
        retval = 0;
 end_rmdir:
        iput(dir);
@@ -517,10 +517,10 @@ repeat:
        de->inode = 0;
        mark_buffer_dirty(bh, 1);
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       dir->i_dirt = 1;
+       mark_inode_dirty(dir);
        inode->i_nlink--;
        inode->i_ctime = dir->i_ctime;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        retval = 0;
 end_unlink:
        brelse(bh);
@@ -550,7 +550,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
        if (!name_block) {
                iput(dir);
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                return -ENOSPC;
        }
@@ -563,11 +563,11 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
        mark_buffer_dirty(name_block, 1);
        brelse(name_block);
        inode->i_size = i;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
        bh = sysv_find_entry(dir,name,len,&de);
        if (bh) {
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                brelse(bh);
                iput(dir);
@@ -576,7 +576,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
        i = sysv_add_entry(dir, name, len, &bh, &de);
        if (i) {
                inode->i_nlink--;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                iput(inode);
                iput(dir);
                return i;
@@ -624,7 +624,7 @@ int sysv_link(struct inode * oldinode, struct inode * dir, const char * name, in
        iput(dir);
        oldinode->i_nlink++;
        oldinode->i_ctime = CURRENT_TIME;
-       oldinode->i_dirt = 1;
+       mark_inode_dirty(oldinode);
        iput(oldinode);
        return 0;
 }
@@ -667,8 +667,8 @@ static int subdir(struct inode * new_inode, struct inode * old_inode)
  * Anybody can rename anything with this: the permission checks are left to the
  * higher-level routines.
  */
-static int do_sysv_rename(struct inode * old_dir, const char * old_name, int old_len,
-                         struct inode * new_dir, const char * new_name, int new_len)
+static int do_sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
+                         struct inode * new_dir, struct dentry * new_dentry)
 {
        struct inode * old_inode, * new_inode;
        struct buffer_head * old_bh, * new_bh, * dir_bh;
@@ -687,21 +687,21 @@ try_again:
 start_up:
        old_inode = new_inode = NULL;
        old_bh = new_bh = dir_bh = NULL;
-       old_bh = sysv_find_entry(old_dir,old_name,old_len,&old_de);
+       old_bh = sysv_find_entry(old_dir,old_dentry->d_name.name,
+                               old_dentry->d_name.len,&old_de);
        retval = -ENOENT;
        if (!old_bh)
                goto end_rename;
-       old_inode = __iget(old_dir->i_sb, old_de->inode, 0); /* don't cross mnt-points */
-       if (!old_inode)
-               goto end_rename;
+       old_inode = old_dentry->d_inode;/* don't cross mnt-points */
        retval = -EPERM;
        if ((old_dir->i_mode & S_ISVTX) && 
            current->fsuid != old_inode->i_uid &&
            current->fsuid != old_dir->i_uid && !fsuser())
                goto end_rename;
-       new_bh = sysv_find_entry(new_dir,new_name,new_len,&new_de);
+       new_inode = new_dentry->d_inode;
+       new_bh = sysv_find_entry(new_dir,new_dentry->d_name.name,
+                               new_dentry->d_name.len,&new_de);
        if (new_bh) {
-               new_inode = __iget(new_dir->i_sb, new_de->inode, 0);
                if (!new_inode) {
                        brelse(new_bh);
                        new_bh = NULL;
@@ -748,7 +748,8 @@ start_up:
                        goto end_rename;
        }
        if (!new_bh) {
-               retval = sysv_add_entry(new_dir,new_name,new_len,&new_bh,&new_de);
+               retval = sysv_add_entry(new_dir,new_dentry->d_name.name,
+                                       new_dentry->d_name.len,&new_bh,&new_de);
                if (retval)
                        goto end_rename;
        }
@@ -763,13 +764,13 @@ start_up:
        old_de->inode = 0;
        new_de->inode = old_inode->i_ino;
        old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
-       old_dir->i_dirt = 1;
+       mark_inode_dirty(old_dir);
        new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
-       new_dir->i_dirt = 1;
+       mark_inode_dirty(new_dir);
        if (new_inode) {
                new_inode->i_nlink--;
                new_inode->i_ctime = CURRENT_TIME;
-               new_inode->i_dirt = 1;
+               mark_inode_dirty(new_inode);
        }
        mark_buffer_dirty(old_bh, 1);
        mark_buffer_dirty(new_bh, 1);
@@ -777,13 +778,13 @@ start_up:
                PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
                mark_buffer_dirty(dir_bh, 1);
                old_dir->i_nlink--;
-               old_dir->i_dirt = 1;
+               mark_inode_dirty(old_dir);
                if (new_inode) {
                        new_inode->i_nlink--;
-                       new_inode->i_dirt = 1;
+                       mark_inode_dirty(new_inode);
                } else {
                        new_dir->i_nlink++;
-                       new_dir->i_dirt = 1;
+                       mark_inode_dirty(new_dir);
                }
        }
        retval = 0;
@@ -807,8 +808,8 @@ end_rename:
  * the same device that races occur: many renames can happen at once, as long
  * as they are on different partitions.
  */
-int sysv_rename(struct inode * old_dir, const char * old_name, int old_len,
-               struct inode * new_dir, const char * new_name, int new_len)
+int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
+               struct inode * new_dir, struct dentry * new_dentry)
 {
        static struct wait_queue * wait = NULL;
        static int lock = 0;
@@ -817,8 +818,8 @@ int sysv_rename(struct inode * old_dir, const char * old_name, int old_len,
        while (lock)
                sleep_on(&wait);
        lock = 1;
-       result = do_sysv_rename(old_dir, old_name, old_len,
-                               new_dir, new_name, new_len);
+       result = do_sysv_rename(old_dir, old_dentry,
+                               new_dir, new_dentry);
        lock = 0;
        wake_up(&wait);
        return result;
index 4e8a5e349687d40f5c046f5e43d6e3d6fc11a35a..d76c3fa6611f90541bb306e56bb0eee4b8224c95 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/uaccess.h>
 
 static int sysv_readlink(struct inode *, char *, int);
+static struct dentry *sysv_follow_link(struct inode *, struct dentry *);
 
 /*
  * symlinks can't do much...
@@ -37,6 +38,7 @@ struct inode_operations sysv_symlink_inode_operations = {
        NULL,                   /* mknod */
        NULL,                   /* rename */
        sysv_readlink,          /* readlink */
+       sysv_follow_link,       /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
@@ -44,6 +46,21 @@ struct inode_operations sysv_symlink_inode_operations = {
        NULL                    /* permission */
 };
 
+static struct dentry *sysv_follow_link(struct inode * inode, struct dentry * base)
+{
+       struct buffer_head * bh;
+
+       bh = sysv_file_bread(inode, 0, 0);
+       if (!bh) {
+               dput(base);
+               return ERR_PTR(-EIO);
+       }
+       UPDATE_ATIME(inode);
+       base = lookup_dentry(bh->b_data, base, 1);
+       brelse(bh);
+       return base;
+}
+
 static int sysv_readlink(struct inode * inode, char * buffer, int buflen)
 {
        struct buffer_head * bh;
@@ -54,7 +71,6 @@ static int sysv_readlink(struct inode * inode, char * buffer, int buflen)
        if (buflen > inode->i_sb->sv_block_size_1)
                buflen = inode->i_sb->sv_block_size_1;
        bh = sysv_file_bread(inode, 0, 0);
-       iput(inode);
        if (!bh)
                return 0;
        bh_data = bh->b_data;
index 0eeb10d30bddce2d1172f068d0d505c2dfc430ed..433c39caea7b1ee35ddd475ad064a0284ab8394b 100644 (file)
@@ -64,7 +64,7 @@ repeat:
                        continue;
                }
                *p = 0;
-               inode->i_dirt = 1;
+               mark_inode_dirty(inode);
                brelse(bh);
                sysv_free_block(sb,block);
        }
@@ -257,12 +257,14 @@ done:
 static int trunc_all(struct inode * inode)
 {
        struct super_block * sb;
+       char * res;
 
        sb = inode->i_sb;
+       res = (char *)test_bit(I_DIRTY,&inode->i_state);
        return trunc_direct(inode)
-            | trunc_indirect(inode,sb->sv_ind0_size,&inode->u.sysv_i.i_data[10],0,&inode->i_dirt)
-            | trunc_dindirect(inode,sb->sv_ind1_size,&inode->u.sysv_i.i_data[11],0,&inode->i_dirt)
-            | trunc_tindirect(inode,sb->sv_ind2_size,&inode->u.sysv_i.i_data[12],0,&inode->i_dirt);
+            | trunc_indirect(inode,sb->sv_ind0_size,&inode->u.sysv_i.i_data[10],0,res)
+            | trunc_dindirect(inode,sb->sv_ind1_size,&inode->u.sysv_i.i_data[11],0,res)
+            | trunc_tindirect(inode,sb->sv_ind2_size,&inode->u.sysv_i.i_data[12],0,res);
 }
 
 
@@ -285,5 +287,5 @@ void sysv_truncate(struct inode * inode)
                schedule();
        }
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-       inode->i_dirt = 1;
+       mark_inode_dirty(inode);
 }
index 161bc791e41ca4d7981edfa720d34ad77cca5c65..a688b47a370b8b05c15f13b42bef975f807d8a38 100644 (file)
@@ -877,7 +877,7 @@ static int vfat_find(struct inode *dir,const char *name,int len,
 
                PRINTK(("vfat_find: create file 4\n"));
                dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;
-               dir->i_dirt = 1;
+               mark_inode_dirty(dir);
 
                PRINTK(("vfat_find: create file 5\n"));
 
@@ -1010,7 +1010,7 @@ static int vfat_create_entry(struct inode *dir,const char *name,int len,
                return -EIO;
        (*result)->i_mtime = (*result)->i_atime = (*result)->i_ctime =
            CURRENT_TIME;
-       (*result)->i_dirt = 1;
+       mark_inode_dirty(*result);
        (*result)->i_version = ++event;
        dir->i_version = event;
 
@@ -1046,7 +1046,7 @@ static int vfat_create_a_dotdir(struct inode *dir,struct inode *parent,
         * XXX all times should be set by caller upon successful completion.
         */
        dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       dir->i_dirt = 1;
+       mark_inode_dirty(dir);
        memcpy(de->name,name,MSDOS_NAME);
        memset(de->unused, 0, sizeof(de->unused));
        de->lcase = 0;
@@ -1062,7 +1062,7 @@ static int vfat_create_a_dotdir(struct inode *dir,struct inode *parent,
                vfat_read_inode(dot);
        if (!dot) return -EIO;
        dot->i_mtime = dot->i_atime = CURRENT_TIME;
-       dot->i_dirt = 1;
+       mark_inode_dirty(dot);
        if (isdot) {
                dot->i_size = dir->i_size;
                MSDOS_I(dot)->i_start = MSDOS_I(dir)->i_start;
@@ -1173,7 +1173,8 @@ static int vfat_rmdir_free_ino(struct inode *dir,struct buffer_head *bh,
        inode->i_mtime = dir->i_mtime = CURRENT_TIME;
        inode->i_atime = dir->i_atime = CURRENT_TIME;
        dir->i_nlink--;
-       inode->i_dirt = dir->i_dirt = 1;
+       mark_inode_dirty(dir);
+       mark_inode_dirty(inode);
        de->name[0] = DELETED_FLAG;
        fat_mark_buffer_dirty(sb, bh, 1);
        iput(inode);
@@ -1196,7 +1197,8 @@ static int vfat_unlink_free_ino(struct inode *dir,struct buffer_head *bh,
        inode->i_atime = dir->i_atime = CURRENT_TIME;
        dir->i_version = ++event;
        MSDOS_I(inode)->i_busy = 1;
-       inode->i_dirt = dir->i_dirt = 1;
+       mark_inode_dirty(dir);
+       mark_inode_dirty(inode);
        de->name[0] = DELETED_FLAG;
        fat_mark_buffer_dirty(sb, bh, 1);
 
@@ -1478,7 +1480,7 @@ int vfat_rename(struct inode *old_dir,const char *old_name,int old_len,
        MSDOS_I(new_inode)->i_oldlink = old_inode;
        fat_cache_inval_inode(old_inode);
        PRINTK(("vfat_rename 15: old_slots=%d\n",old_slots));
-       old_inode->i_dirt = 1;
+       mark_inode_dirty(old_inode);
        old_dir->i_version = ++event;
 
        /* remove the old entry */
@@ -1511,7 +1513,7 @@ int vfat_rename(struct inode *old_dir,const char *old_name,int old_len,
                }
                dotdot_de->start = MSDOS_I(dotdot_inode)->i_start =
                    MSDOS_I(new_dir)->i_start;
-               dotdot_inode->i_dirt = 1;
+               mark_inode_dirty(dotdot_inode);
                fat_mark_buffer_dirty(sb, dotdot_bh, 1);
                old_dir->i_nlink--;
                new_dir->i_nlink++;
index 51800cab01a13d98d73c275a27cd674d85c52faa..1ca8af0d7b24243ed0fcd3df3ba1f290594802dc 100644 (file)
@@ -65,7 +65,7 @@ struct dentry {
  * to invalidate a dentry for some reason (NFS
  * timeouts or autofs deletes).
  */
-inline void d_drop(struct dentry * dentry)
+static inline void d_drop(struct dentry * dentry)
 {
        list_del(&dentry->d_hash);
        INIT_LIST_HEAD(&dentry->d_hash);
index f8376d4103b05738ff997c5b0bace14abcc6360a..2831b18504bb425de247e69e11911f445f4787ed 100644 (file)
@@ -483,6 +483,7 @@ extern int ext2_getcluster (struct inode * inode, long block);
 extern void ext2_read_inode (struct inode *);
 extern void ext2_write_inode (struct inode *);
 extern void ext2_put_inode (struct inode *);
+extern void ext2_delete_inode (struct inode *);
 extern int ext2_sync_inode (struct inode *);
 extern void ext2_discard_prealloc (struct inode *);
 
@@ -492,7 +493,7 @@ extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
 
 /* namei.c */
 extern void ext2_release (struct inode *, struct file *);
-extern int ext2_lookup (struct inode *,struct qstr *, struct inode **);
+extern int ext2_lookup (struct inode *, struct dentry *);
 extern int ext2_create (struct inode *,struct dentry *,int);
 extern int ext2_mkdir (struct inode *,struct dentry *,int);
 extern int ext2_rmdir (struct inode *,struct dentry *);
index f09303ae8bd4b5f5606e8d71e2310bddc265cd1a..a4c924e9290f6964da7e9302ea3cf8083953408b 100644 (file)
@@ -304,7 +304,7 @@ struct inode {
 
        unsigned long           i_ino;
        kdev_t                  i_dev;
-       atomic_t                i_count;
+       unsigned short          i_count;
        umode_t                 i_mode;
        nlink_t                 i_nlink;
        uid_t                   i_uid;
@@ -358,6 +358,7 @@ struct inode {
 /* Inode state bits.. */
 #define I_DIRTY                0
 #define I_LOCK         1
+#define I_FREEING      2
 
 extern void __mark_inode_dirty(struct inode *);
 static inline void mark_inode_dirty(struct inode *inode)
@@ -542,7 +543,7 @@ struct file_operations {
 struct inode_operations {
        struct file_operations * default_file_ops;
        int (*create) (struct inode *,struct dentry *,int);
-       int (*lookup) (struct inode *,struct qstr *name,struct inode **);
+       int (*lookup) (struct inode *,struct dentry *);
        int (*link) (struct inode *,struct inode *,struct dentry *);
        int (*unlink) (struct inode *,struct dentry *);
        int (*symlink) (struct inode *,struct dentry *,const char *);
@@ -565,9 +566,10 @@ struct inode_operations {
 
 struct super_operations {
        void (*read_inode) (struct inode *);
-       int (*notify_change) (struct inode *, struct iattr *);
        void (*write_inode) (struct inode *);
        void (*put_inode) (struct inode *);
+       void (*delete_inode) (struct inode *);
+       int (*notify_change) (struct inode *, struct iattr *);
        void (*put_super) (struct super_block *);
        void (*write_super) (struct super_block *);
        int (*statfs) (struct super_block *, struct statfs *, int);
@@ -744,7 +746,6 @@ extern struct inode * get_empty_inode(void);
 extern struct inode * get_empty_inode_hashed(dev_t i_dev, unsigned long i_ino);
 
 extern void insert_inode_hash(struct inode *);
-extern struct inode * get_pipe_inode(void);
 extern int get_unused_fd(void);
 extern void put_unused_fd(int);
 extern struct file * get_empty_filp(void);
index 0374eebf7da505da9a1da8a947e0368e0b5adb49..011edfe6fb08d337b7aab77195a39cb3796ebe1e 100644 (file)
@@ -152,8 +152,7 @@ extern int find_rock_ridge_relocation(struct iso_directory_record *, struct inod
 
 extern int isofs_open(struct inode * inode, struct file * filp);
 extern void isofs_release(struct inode * inode, struct file * filp);
-extern int isofs_lookup(struct inode * dir, struct qstr *dentry,
-                       struct inode ** result);
+extern int isofs_lookup(struct inode * dir, struct dentry *);
 extern unsigned long isofs_count_free_inodes(struct super_block *sb);
 extern int isofs_new_block(int dev);
 extern int isofs_free_block(int dev, int block);
index d8065500ffe1a7d03b81ccadfe5997817fb3b07f..a1343a6360d3b633a4b525b6de31d631a3f63061 100644 (file)
@@ -6,7 +6,6 @@
  */
 struct iso_inode_info {
        unsigned int i_first_extent;
-       unsigned int i_backlink;
        unsigned char i_file_format;
 };
 
index 4c9410691f52fb0967a68ade1bdf8257fca6b564..4a410735c1647d1b8c852b32d2a34af3e507c469 100644 (file)
@@ -121,7 +121,7 @@ extern int minix_remount (struct super_block * sb, int * flags, char * data);
 extern void minix_read_inode(struct inode *);
 extern void minix_write_inode(struct inode *);
 extern void minix_put_inode(struct inode *);
-extern void minix_statfs(struct super_block *, struct statfs *, int);
+extern int minix_statfs(struct super_block *, struct statfs *, int);
 extern int minix_sync_inode(struct inode *);
 extern int minix_sync_file(struct inode *, struct file *);
 
index 36ed2a8908d56cd93547f30a10afb011d2faea76..0badd9ebe148037eba56d850d18ace364a315474 100644 (file)
@@ -215,7 +215,7 @@ extern void fat_put_super(struct super_block *sb);
 extern void fat_read_inode(struct inode *inode, struct inode_operations *dir_ops);
 extern struct super_block *fat_read_super(struct super_block *s, void *data, int silent);
 extern void msdos_put_super(struct super_block *sb);
-extern void fat_statfs(struct super_block *sb,struct statfs *buf, int);
+extern int fat_statfs(struct super_block *sb,struct statfs *buf, int);
 extern void fat_write_inode(struct inode *inode);
 
 /* dir.c */
index 489762a36e7afb08d5d0fa6c4b0ee63755ba971b..75c2c91b2b2677812389cf12ce0a699bc4f0c8aa 100644 (file)
@@ -57,7 +57,7 @@ struct knfs_fh {
 typedef struct svc_fh {
        struct knfs_fh          fh_handle;      /* FH data */
        struct svc_export *     fh_export;      /* export pointer */
-       struct inode *          fh_inode;       /* inode */
+       struct dentry *         fh_dentry;      /* file */
        size_t                  fh_pre_size;    /* size before operation */
        time_t                  fh_pre_mtime;   /* mtime before oper */
        time_t                  fh_pre_ctime;   /* ctime before oper */
@@ -98,7 +98,7 @@ fh_init(struct svc_fh *fhp)
 static inline void
 fh_lock(struct svc_fh *fhp)
 {
-       struct inode    *inode = fhp->fh_inode;
+       struct inode    *inode = fhp->fh_dentry->d_inode;
 
        /*
        dfprintk(FILEOP, "nfsd: fh_lock(%x/%ld) locked = %d\n",
@@ -118,7 +118,7 @@ fh_lock(struct svc_fh *fhp)
 static inline void
 fh_unlock(struct svc_fh *fhp)
 {
-       struct inode    *inode = fhp->fh_inode;
+       struct inode    *inode = fhp->fh_dentry->d_inode;
 
        if (fhp->fh_locked) {
                if (!fhp->fh_post_version)
@@ -135,9 +135,9 @@ fh_unlock(struct svc_fh *fhp)
 static inline void
 fh_put(struct svc_fh *fhp)
 {
-       if (fhp->fh_inode) {
+       if (fhp->fh_dentry) {
                fh_unlock(fhp);
-               iput(fhp->fh_inode);
+               dput(fhp->fh_dentry);
        }
 }
 #else
@@ -146,19 +146,19 @@ fh_put(struct svc_fh *fhp)
 static inline void
 __fh_put(struct svc_fh *fhp, char *file, int line)
 {
-       struct inode    *inode;
+       struct dentry   *dentry;
 
-       if (!(inode = fhp->fh_inode))
+       if (!(dentry = fhp->fh_dentry))
                return;
 
-       if (!atomic_read(&inode->i_count)) {
-               printk("nfsd: trying to free free inode in %s:%d\n"
-                      "      dev %04x ino %ld, mode %07o\n",
-                      file, line, inode->i_dev,
-                      inode->i_ino, inode->i_mode);
+       if (!dentry->d_count) {
+               printk("nfsd: trying to free free dentry in %s:%d\n"
+                      "      file %s/%s\n",
+                      file, line,
+                      dentry->d_parent->d_name.name, dentry->d_name.name);
        } else {
                fh_unlock(fhp);
-               iput(inode);
+               dput(dentry);
        }
 }
 #endif
index 21b39d628a370c28693ff92b44d0240a428ca5af..3a847d72c4640a55d0a6c4f35ddd789c8fe1f574 100644 (file)
@@ -5,7 +5,6 @@ struct pipe_inode_info {
        struct wait_queue * wait;
        char * base;
        unsigned int start;
-       unsigned int len;
        unsigned int lock;
        unsigned int rd_openers;
        unsigned int wr_openers;
@@ -16,7 +15,7 @@ struct pipe_inode_info {
 #define PIPE_WAIT(inode)       ((inode).u.pipe_i.wait)
 #define PIPE_BASE(inode)       ((inode).u.pipe_i.base)
 #define PIPE_START(inode)      ((inode).u.pipe_i.start)
-#define PIPE_LEN(inode)                ((inode).u.pipe_i.len)
+#define PIPE_LEN(inode)                ((inode).i_size)
 #define PIPE_RD_OPENERS(inode) ((inode).u.pipe_i.rd_openers)
 #define PIPE_WR_OPENERS(inode) ((inode).u.pipe_i.wr_openers)
 #define PIPE_READERS(inode)    ((inode).u.pipe_i.readers)
index a7c51bab2613eee0b8818706428219b25cac52e7..1acb56c8c44e7a09fc371a948e82171a545344c6 100644 (file)
@@ -323,7 +323,7 @@ extern int proc_match(int, const char *,struct proc_dir_entry *);
  * of the /proc/<pid> subdirectories.
  */
 extern int proc_readdir(struct inode *, struct file *, void *, filldir_t);
-extern int proc_lookup(struct inode *, struct qstr *, struct inode **);
+extern int proc_lookup(struct inode *, struct dentry *);
 
 struct openpromfs_dev {
        struct openpromfs_dev *next;
index e68f5d5f110b96f790b8629efd55ef96fc8c4723..53ead0c99c2ee391c4f9c9425cdec8fa155767b6 100644 (file)
@@ -372,8 +372,8 @@ extern int sysv_symlink(struct inode * inode, const char * name, int len,
        const char * symname);
 extern int sysv_link(struct inode * oldinode, struct inode * dir, const char * name, int len);
 extern int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rdev);
-extern int sysv_rename(struct inode * old_dir, const char * old_name, int old_len,
-                      struct inode * new_dir, const char * new_name, int new_len);
+extern int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
+                      struct inode * new_dir, struct dentry * new_dentry);
 extern struct inode * sysv_new_inode(const struct inode * dir);
 extern void sysv_free_inode(struct inode * inode);
 extern unsigned long sysv_count_free_inodes(struct super_block *sb);
@@ -396,7 +396,7 @@ extern void sysv_read_inode(struct inode *);
 extern int sysv_notify_change(struct inode *, struct iattr *);
 extern void sysv_write_inode(struct inode *);
 extern void sysv_put_inode(struct inode *);
-extern void sysv_statfs(struct super_block *, struct statfs *, int);
+extern int sysv_statfs(struct super_block *, struct statfs *, int);
 extern int sysv_sync_inode(struct inode *);
 extern int sysv_sync_file(struct inode *, struct file *);
 extern int sysv_mmap(struct inode *, struct file *, struct vm_area_struct *);
index 1aa495384ce70a3a727adfd8f270f7440bec62c4..5235f9d39508300dbd27acf2b54f58d936a5a5d9 100644 (file)
@@ -180,6 +180,7 @@ EXPORT_SYMBOL(posix_lock_file);
 EXPORT_SYMBOL(posix_test_lock);
 EXPORT_SYMBOL(posix_block_lock);
 EXPORT_SYMBOL(posix_unblock_lock);
+EXPORT_SYMBOL(dput);
 
 #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
 EXPORT_SYMBOL(do_nfsservctl);
index 4f706d4ef15da8fbe58121c8022d97f6a3d01ff5..271d932d72f2720877c041bd12391ad60c1b7ed5 100644 (file)
@@ -206,6 +206,19 @@ static int get_fd(struct inode *inode)
                        return -ENFILE;
                }
 
+               file->f_dentry = d_alloc_root(inode, NULL);
+               if (!file->f_dentry) {
+                       put_filp(file);
+                       put_unused_fd(fd);
+                       return -ENOMEM;
+               }
+
+               /*
+                * The socket maintains a reference to the inode, so we
+                * have to increment the count.
+                */
+               inode->i_count++;
+
                current->files->fd[fd] = file;
                file->f_op = &socket_file_ops;
                file->f_mode = 3;
index 481be1dc50b9483934cec4d8c359dbfd6ee52c3b..596e6d6dab146275c10bc03035598c4d659e4b27 100644 (file)
@@ -544,7 +544,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        err = PTR_ERR(dentry);
        if (!IS_ERR(dentry)) {
                inode = dentry->d_inode;
-               atomic_inc(&inode->i_count);
+               inode->i_count++;       /* HATEFUL - we should use the dentry */
                dput(dentry);
                err = 0;
        }
@@ -794,7 +794,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
        }
        if (sk->protinfo.af_unix.inode)
        {
-               atomic_inc(&sk->protinfo.af_unix.inode->i_count);
+               sk->protinfo.af_unix.inode->i_count++;  /* Should use dentry */
                newsk->protinfo.af_unix.inode=sk->protinfo.af_unix.inode;
        }