Whamcloud - gitweb
b=7264
[fs/lustre-release.git] / lustre / kernel_patches / patches / iopen-2.6-vanilla.patch
index 597cb89..88e0843 100644 (file)
@@ -1,4 +1,3 @@
- Documentation/filesystems/ext2.txt |   16 ++
  fs/ext3/inode.c                    |    3 
  fs/ext3/iopen.c                    |  239 +++++++++++++++++++++++++++++++++++++
  fs/ext3/iopen.h                    |   15 ++
@@ -7,10 +6,23 @@
  include/linux/ext3_fs.h            |    2 
  7 files changed, 304 insertions(+), 1 deletion(-)
 
-Index: linux-2.6.4-51.1/fs/ext3/inode.c
+Index: linux-stage/fs/ext3/Makefile
 ===================================================================
---- linux-2.6.4-51.1.orig/fs/ext3/inode.c      2004-04-06 00:31:14.000000000 -0400
-+++ linux-2.6.4-51.1/fs/ext3/inode.c   2004-04-06 00:31:24.000000000 -0400
+--- linux-stage.orig/fs/ext3/Makefile  2004-06-22 21:12:15.000000000 -0400
++++ linux-stage/fs/ext3/Makefile       2004-06-22 21:13:20.000000000 -0400
+@@ -4,7 +4,7 @@
+ obj-$(CONFIG_EXT3_FS) += ext3.o
+-ext3-y        := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
++ext3-y        := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
+          ioctl.o namei.o super.o symlink.o hash.o
+ ext3-$(CONFIG_EXT3_FS_XATTR)   += xattr.o xattr_user.o xattr_trusted.o
+Index: linux-stage/fs/ext3/inode.c
+===================================================================
+--- linux-stage.orig/fs/ext3/inode.c   2004-06-22 21:12:16.000000000 -0400
++++ linux-stage/fs/ext3/inode.c        2004-06-22 21:13:20.000000000 -0400
 @@ -37,6 +37,7 @@
  #include <linux/mpage.h>
  #include <linux/uio.h>
@@ -19,22 +31,21 @@ Index: linux-2.6.4-51.1/fs/ext3/inode.c
  #include "acl.h"
  
  /*
-@@ -2472,6 +2473,8 @@
+@@ -2470,6 +2471,9 @@
        ei->i_acl = EXT3_ACL_NOT_CACHED;
        ei->i_default_acl = EXT3_ACL_NOT_CACHED;
  #endif
 +      if (ext3_iopen_get_inode(inode))
 +              return;
++
        if (ext3_get_inode_loc(inode, &iloc, 0))
                goto bad_inode;
        bh = iloc.bh;
-Index: linux-2.6.4-51.1/fs/ext3/iopen.c
+Index: linux-stage/fs/ext3/iopen.c
 ===================================================================
---- linux-2.6.4-51.1.orig/fs/ext3/iopen.c      2004-04-06 00:31:24.000000000 -0400
-+++ linux-2.6.4-51.1/fs/ext3/iopen.c   2004-04-06 00:31:24.000000000 -0400
-@@ -0,0 +1,223 @@
-+
-+
+--- linux-stage.orig/fs/ext3/iopen.c   1969-12-31 19:00:00.000000000 -0500
++++ linux-stage/fs/ext3/iopen.c        2004-06-22 21:13:20.000000000 -0400
+@@ -0,0 +1,274 @@
 +/*
 + * linux/fs/ext3/iopen.c
 + *
@@ -44,6 +55,25 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c
 + *
 + * This file may be redistributed under the terms of the GNU General
 + * Public License.
++ *
++ *
++ * Invariants:
++ *   - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias
++ *     for an inode at one time.
++ *   - there are never both connected and DCACHE_NFSD_DISCONNECTED dentry
++ *     aliases on an inode at the same time.
++ *
++ * If we have any connected dentry aliases for an inode, use one of those
++ * in iopen_lookup().  Otherwise, we instantiate a single NFSD_DISCONNECTED
++ * dentry for this inode, which thereafter will be found by the dcache
++ * when looking up this inode number in __iopen__, so we don't return here
++ * until it is gone.
++ *
++ * If we get an inode via a regular name lookup, then we "rename" the
++ * NFSD_DISCONNECTED dentry to the proper name and parent.  This ensures
++ * existing users of the disconnected dentry will continue to use the same
++ * dentry as the connected users, and there will never be both kinds of
++ * dentry aliases at one time.
 + */
 +
 +#include <linux/sched.h>
@@ -52,6 +82,8 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c
 +#include <linux/jbd.h>
 +#include <linux/ext3_fs.h>
 +#include <linux/smp_lock.h>
++#include <linux/dcache.h>
++#include <linux/security.h>
 +#include "iopen.h"
 +
 +#ifndef assert
@@ -63,14 +95,15 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c
 +/*
 + * This implements looking up an inode by number.
 + */
-+static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
++static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry,
++                                 struct nameidata *nd)
 +{
-+      struct inode * inode;
++      struct inode *inode;
 +      unsigned long ino;
 +      struct list_head *lp;
 +      struct dentry *alternate;
 +      char buf[IOPEN_NAME_LEN];
-+      
++
 +      if (dentry->d_name.len >= IOPEN_NAME_LEN)
 +              return ERR_PTR(-ENAMETOOLONG);
 +
@@ -99,6 +132,9 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c
 +              return ERR_PTR(-ENOENT);
 +      }
 +
++      assert(list_empty(&dentry->d_alias));           /* d_instantiate */
++      assert(d_unhashed(dentry));             /* d_rehash */
++
 +      /* preferrably return a connected dentry */
 +      spin_lock(&dcache_lock);
 +      list_for_each(lp, &inode->i_dentry) {
@@ -110,15 +146,22 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c
 +              alternate = list_entry(inode->i_dentry.next,
 +                                     struct dentry, d_alias);
 +              dget_locked(alternate);
-+              alternate->d_vfs_flags |= DCACHE_REFERENCED;
++              spin_lock(&alternate->d_lock);
++              alternate->d_flags |= DCACHE_REFERENCED;
++              spin_unlock(&alternate->d_lock);
 +              iput(inode);
 +              spin_unlock(&dcache_lock);
 +              return alternate;
 +      }
 +      dentry->d_flags |= DCACHE_DISCONNECTED;
++
++      /* d_add(), but don't drop dcache_lock before adding dentry to inode */
++      list_add(&dentry->d_alias, &inode->i_dentry);   /* d_instantiate */
++      dentry->d_inode = inode;
++
++      __d_rehash(dentry);                             /* d_rehash */
 +      spin_unlock(&dcache_lock);
 +
-+      d_add(dentry, inode);
 +      return NULL;
 +}
 +
@@ -126,11 +169,11 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c
 +      __typeof__ (x) __tmp = x; \
 +      x = y; y = __tmp; } while (0)
 +
-+static inline void switch_names(struct dentry * dentry, struct dentry * target)
++static inline void switch_names(struct dentry *dentry, struct dentry *target)
 +{
 +      const unsigned char *old_name, *new_name;
 +
-+      memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN);
++      memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN_MIN);
 +      old_name = target->d_name.name;
 +      new_name = dentry->d_name.name;
 +      if (old_name == target->d_iname)
@@ -141,20 +184,27 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c
 +      dentry->d_name.name = old_name;
 +}
 +
-+
-+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode)
++/* This function is spliced into ext3_lookup and does the move of a
++ * disconnected dentry (if it exists) to a connected dentry.
++ */
++struct dentry *iopen_connect_dentry(struct dentry *dentry, struct inode *inode,
++                                  int rehash)
 +{
 +      struct dentry *tmp, *goal = NULL;
 +      struct list_head *lp;
 +
-+      /* preferrably return a connected dentry */
-+      spin_lock(&dcache_lock);
 +      /* verify this dentry is really new */
-+      assert(!de->d_inode);
-+      assert(list_empty(&de->d_subdirs));
-+      assert(list_empty(&de->d_alias));
++      assert(dentry->d_inode == NULL);
++      assert(list_empty(&dentry->d_alias));           /* d_instantiate */
++      if (rehash)
++              assert(d_unhashed(dentry));     /* d_rehash */
++      assert(list_empty(&dentry->d_subdirs));
 +
++      spin_lock(&dcache_lock);
++      if (!inode)
++              goto do_rehash;
 +
++      /* preferrably return a connected dentry */
 +      list_for_each(lp, &inode->i_dentry) {
 +              tmp = list_entry(lp, struct dentry, d_alias);
 +              if (tmp->d_flags & DCACHE_DISCONNECTED) {
@@ -165,16 +215,30 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c
 +                      break;
 +              }
 +      }
-+      spin_unlock(&dcache_lock);
 +
 +      if (!goal)
-+              return NULL;
++              goto do_instantiate;
 +
-+      goal->d_flags &= ~DCACHE_DISCONNECTED;
-+      d_rehash(de);
-+      d_move(goal, de);
++      /* Move the goal to the de hash queue */
++      goal->d_flags &= ~ DCACHE_DISCONNECTED;
++      security_d_instantiate(goal, inode);
++      __d_rehash(dentry);
++      __d_move(goal, dentry);
++      spin_unlock(&dcache_lock);
++      iput(inode);
 +
 +      return goal;
++
++      /* d_add(), but don't drop dcache_lock before adding dentry to inode */
++do_instantiate:
++      list_add(&dentry->d_alias, &inode->i_dentry);   /* d_instantiate */
++      dentry->d_inode = inode;
++do_rehash:
++      if (rehash)
++              __d_rehash(dentry);                     /* d_rehash */
++      spin_unlock(&dcache_lock);
++
++      return NULL;
 +}
 +
 +/*
@@ -205,9 +269,9 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c
 + * This function is spliced into ext3_lookup and returns 1 the file
 + * name is __iopen__ and dentry has been filled in appropriately.
 + */
-+int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry)
++int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry)
 +{
-+      struct inode * inode;
++      struct inode *inode;
 +
 +      if (dir->i_ino != EXT3_ROOT_INO ||
 +          !test_opt(dir->i_sb, IOPEN) ||
@@ -227,7 +291,7 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c
 + * number is the one for /__iopen__, in which case the inode is filled
 + * in appropriately.  Otherwise, this fuction returns 0.
 + */
-+int ext3_iopen_get_inode(struct inode * inode)
++int ext3_iopen_get_inode(struct inode *inode)
 +{
 +      if (inode->i_ino != EXT3_BAD_INO)
 +              return 0;
@@ -256,10 +320,10 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c
 +
 +      return 1;
 +}
-Index: linux-2.6.4-51.1/fs/ext3/iopen.h
+Index: linux-stage/fs/ext3/iopen.h
 ===================================================================
---- linux-2.6.4-51.1.orig/fs/ext3/iopen.h      2004-04-06 00:31:24.000000000 -0400
-+++ linux-2.6.4-51.1/fs/ext3/iopen.h   2004-04-06 00:31:24.000000000 -0400
+--- linux-stage.orig/fs/ext3/iopen.h   1969-12-31 19:00:00.000000000 -0500
++++ linux-stage/fs/ext3/iopen.h        2004-06-22 21:13:20.000000000 -0400
 @@ -0,0 +1,15 @@
 +/*
 + * iopen.h
@@ -272,14 +336,14 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.h
 + * Public License.
 + */
 +
-+extern int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry);
-+extern int ext3_iopen_get_inode(struct inode * inode);
-+
-+
-Index: linux-2.6.4-51.1/fs/ext3/namei.c
++extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry);
++extern int ext3_iopen_get_inode(struct inode *inode);
++extern struct dentry *iopen_connect_dentry(struct dentry *dentry,
++                                         struct inode *inode, int rehash);
+Index: linux-stage/fs/ext3/namei.c
 ===================================================================
---- linux-2.6.4-51.1.orig/fs/ext3/namei.c      2004-04-06 00:31:11.000000000 -0400
-+++ linux-2.6.4-51.1/fs/ext3/namei.c   2004-04-06 00:31:24.000000000 -0400
+--- linux-stage.orig/fs/ext3/namei.c   2004-06-22 21:12:16.000000000 -0400
++++ linux-stage/fs/ext3/namei.c        2004-06-22 21:13:20.000000000 -0400
 @@ -37,6 +37,7 @@
  #include <linux/buffer_head.h>
  #include <linux/smp_lock.h>
@@ -288,108 +352,125 @@ Index: linux-2.6.4-51.1/fs/ext3/namei.c
  #include "acl.h"
  
  /*
-@@ -970,15 +971,21 @@
- }
- #endif
-+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode);
-+
- static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
- {
-       struct inode * inode;
-       struct ext3_dir_entry_2 * de;
-       struct buffer_head * bh;
-+      struct dentry *alternate = NULL;
+@@ -979,6 +980,9 @@
        if (dentry->d_name.len > EXT3_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
  
-+      if (ext3_check_for_iopen(dir, dentry))
-+              return NULL;
++      if (ext3_check_for_iopen(dir, dentry))
++              return NULL;
 +
-       bh = ext3_find_entry(dentry, &de);
+       bh = ext3_find_entry(dentry, &de, 0, &lock);
        inode = NULL;
        if (bh) {
-@@ -989,8 +996,14 @@
+@@ -989,10 +993,8 @@
                if (!inode)
                        return ERR_PTR(-EACCES);
        }
-+      if (inode && (alternate = iopen_connect_dentry(dentry, inode))) {
-+              iput(inode);
-+              return alternate;
-+      }
+-      if (inode)
+-              return d_splice_alias(inode, dentry);
+-      d_add(dentry, inode);
+-      return NULL;
 +
-       if (inode)
-               return d_splice_alias(inode, dentry);
++      return iopen_connect_dentry(dentry, inode, 1);
+ }
+@@ -2022,10 +2024,6 @@
+                             inode->i_nlink);
+       inode->i_version++;
+       inode->i_nlink = 0;
+-      /* There's no need to set i_disksize: the fact that i_nlink is
+-       * zero will ensure that the right thing happens during any
+-       * recovery. */
+-      inode->i_size = 0;
+       ext3_orphan_add(handle, inode);
+       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+       ext3_mark_inode_dirty(handle, inode);
+@@ -2145,6 +2143,23 @@
+       return err;
+ }
++/* Like ext3_add_nondir() except for call to iopen_connect_dentry */
++static int ext3_add_link(handle_t *handle, struct dentry *dentry,
++                       struct inode *inode)
++{
++      int err = ext3_add_entry(handle, dentry, inode);
++      if (!err) {
++              err = ext3_mark_inode_dirty(handle, inode);
++              if (err == 0) {
++                      dput(iopen_connect_dentry(dentry, inode, 0));
++                      return 0;
++              }
++      }
++      ext3_dec_count(handle, inode);
++      iput(inode);
++      return err;
++}
 +
-       d_add(dentry, inode);
-       return NULL;
+ static int ext3_link (struct dentry * old_dentry,
+               struct inode * dir, struct dentry *dentry)
+ {
+@@ -2167,7 +2182,8 @@
+       ext3_inc_count(handle, inode);
+       atomic_inc(&inode->i_count);
+-      err = ext3_add_nondir(handle, dentry, inode);
++      err = ext3_add_link(handle, dentry, inode);
++      ext3_orphan_del(handle,inode);
+       ext3_journal_stop(handle);
+       return err;
  }
-Index: linux-2.6.4-51.1/fs/ext3/super.c
+Index: linux-stage/fs/ext3/super.c
 ===================================================================
---- linux-2.6.4-51.1.orig/fs/ext3/super.c      2004-04-06 00:31:14.000000000 -0400
-+++ linux-2.6.4-51.1/fs/ext3/super.c   2004-04-06 00:31:24.000000000 -0400
-@@ -536,7 +536,7 @@
+--- linux-stage.orig/fs/ext3/super.c   2004-06-22 21:12:16.000000000 -0400
++++ linux-stage/fs/ext3/super.c        2004-06-22 21:13:51.000000000 -0400
+@@ -583,6 +583,7 @@
        Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
        Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
-       Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0,
--      Opt_ignore, Opt_err,
-+      Opt_ignore, Opt_err, Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
+       Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_pdirops,
++      Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
+       Opt_ignore, Opt_err,
  };
  
- static match_table_t tokens = {
-@@ -575,6 +575,9 @@
-       {Opt_ignore, "noquota"},
+@@ -628,6 +629,9 @@
        {Opt_ignore, "quota"},
        {Opt_ignore, "usrquota"},
+       {Opt_pdirops, "pdirops"},
 +      {Opt_iopen,  "iopen"},
 +      {Opt_noiopen,  "noiopen"},
 +      {Opt_iopen_nopriv,  "iopen_nopriv"},
        {Opt_err, NULL}
  };
  
-@@ -762,6 +765,18 @@
+@@ -893,6 +897,18 @@
                case Opt_abort:
                        set_opt(sbi->s_mount_opt, ABORT);
                        break;
 +              case Opt_iopen:
-+                      set_opt (sbi->s_mount_opt, IOPEN);
-+                      clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++                      set_opt (sbi->s_mount_opt, IOPEN);
++                      clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
 +                      break;
 +              case Opt_noiopen:
 +                      clear_opt (sbi->s_mount_opt, IOPEN);
-+                      clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++                      clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
 +                      break;
 +              case Opt_iopen_nopriv:
-+                      set_opt (sbi->s_mount_opt, IOPEN);
-+                      set_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++                      set_opt (sbi->s_mount_opt, IOPEN);
++                      set_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
 +                      break;
                case Opt_ignore:
                        break;
                default:
-Index: linux-2.6.4-51.1/include/linux/ext3_fs.h
+Index: linux-stage/include/linux/ext3_fs.h
 ===================================================================
---- linux-2.6.4-51.1.orig/include/linux/ext3_fs.h      2004-04-06 00:31:11.000000000 -0400
-+++ linux-2.6.4-51.1/include/linux/ext3_fs.h   2004-04-06 00:31:24.000000000 -0400
+--- linux-stage.orig/include/linux/ext3_fs.h   2004-06-22 21:12:16.000000000 -0400
++++ linux-stage/include/linux/ext3_fs.h        2004-06-22 21:13:20.000000000 -0400
 @@ -325,6 +325,8 @@
  #define EXT3_MOUNT_NO_UID32           0x2000  /* Disable 32-bit UIDs */
  #define EXT3_MOUNT_XATTR_USER         0x4000  /* Extended user attributes */
  #define EXT3_MOUNT_POSIX_ACL          0x8000  /* POSIX Access Control Lists */
-+#define EXT3_MOUNT_IOPEN             0x10000  /* Allow access via iopen */
-+#define EXT3_MOUNT_IOPEN_NOPRIV              0x20000  /* Make iopen world-readable */
++#define EXT3_MOUNT_IOPEN              0x40000 /* Allow access via iopen */
++#define EXT3_MOUNT_IOPEN_NOPRIV               0x80000 /* Make iopen world-readable */
  
  /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
  #ifndef _LINUX_EXT2_FS_H
-Index: linux-2.6.4-51.1/fs/ext3/Makefile
-===================================================================
---- linux-2.6.4-51.1.orig/fs/ext3/Makefile     2004-04-06 00:27:21.000000000 -0400
-+++ linux-2.6.4-51.1/fs/ext3/Makefile  2004-04-06 00:31:42.000000000 -0400
-@@ -5,7 +5,7 @@
- obj-$(CONFIG_EXT3_FS) += ext3.o
- ext3-y        := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
--         ioctl.o namei.o super.o symlink.o hash.o
-+         ioctl.o namei.o super.o symlink.o hash.o iopen.o
- ext3-$(CONFIG_EXT3_FS_XATTR)   += xattr.o xattr_user.o xattr_trusted.o
- ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o