Whamcloud - gitweb
Fix for failed assertion in iopen_connect_dentry (2.4 kernels only, from b1_0).
[fs/lustre-release.git] / lustre / kernel_patches / patches / iopen-2.4.19-suse.patch
index ab267bb..ad213c9 100644 (file)
@@ -16,7 +16,7 @@ Index: linux-2.4.19.SuSE/Documentation/filesystems/ext2.txt
  
  sb=n                          Use alternate superblock at this location.
  
-+iopen                         Makes an invisible pseudo-directory called 
++iopen                         Makes an invisible pseudo-directory called
 +                              __iopen__ available in the root directory
 +                              of the filesystem.  Allows open-by-inode-
 +                              number.  i.e., inode 3145 can be accessed
@@ -66,7 +66,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/inode.c
        
 +      if (ext3_iopen_get_inode(inode))
 +              return;
-+      
++
        if(ext3_get_inode_loc(inode, &iloc))
                goto bad_inode;
        bh = iloc.bh;
@@ -74,17 +74,17 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 ===================================================================
 --- linux-2.4.19.SuSE.orig/fs/ext3/iopen.c     Sun Nov 16 01:27:31 2003
 +++ linux-2.4.19.SuSE/fs/ext3/iopen.c  Sun Nov 16 01:27:31 2003
-@@ -0,0 +1,259 @@
+@@ -0,0 +1,258 @@
 +/*
 + * linux/fs/ext3/iopen.c
 + *
 + * Special support for open by inode number
 + *
 + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
-+ * 
++ *
 + * 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
@@ -130,7 +130,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 +      struct list_head *lp;
 +      struct dentry *alternate;
 +      char buf[IOPEN_NAME_LEN];
-+      
++
 +      if (dentry->d_name.len >= IOPEN_NAME_LEN)
 +              return ERR_PTR(-ENAMETOOLONG);
 +
@@ -159,6 +159,9 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 +              return ERR_PTR(-ENOENT);
 +      }
 +
++      assert(list_empty(&dentry->d_alias));           /* d_instantiate */
++      assert(list_empty(&dentry->d_hash));            /* d_rehash */
++
 +      /* preferrably return a connected dentry */
 +      spin_lock(&dcache_lock);
 +      list_for_each(lp, &inode->i_dentry) {
@@ -167,7 +170,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 +      }
 +
 +      if (!list_empty(&inode->i_dentry)) {
-+              alternate = list_entry(inode->i_dentry.next, 
++              alternate = list_entry(inode->i_dentry.next,
 +                                     struct dentry, d_alias);
 +              dget_locked(alternate);
 +              alternate->d_vfs_flags |= DCACHE_REFERENCED;
@@ -176,9 +179,14 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 +              return alternate;
 +      }
 +      dentry->d_flags |= DCACHE_NFSD_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, 0);                          /* d_rehash */
 +      spin_unlock(&dcache_lock);
 +
-+      d_add(dentry, inode);
 +      return NULL;
 +}
 +
@@ -190,7 +198,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 +{
 +      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);
 +      old_name = target->d_name.name;
 +      new_name = dentry->d_name.name;
 +      if (old_name == target->d_iname)
@@ -203,6 +211,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 +
 +/* This function is spliced into ext3_lookup and does the move of a
 + * disconnected dentry (if it exists) to a connected dentry.
++ * Caller must hold dcache_lock.
 + */
 +struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode)
 +{
@@ -210,13 +219,6 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 +      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));
-+
-+
 +      list_for_each(lp, &inode->i_dentry) {
 +              tmp = list_entry(lp, struct dentry, d_alias);
 +              if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) {
@@ -228,10 +230,8 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 +              }
 +      }
 +
-+      if (!goal) { 
-+              spin_unlock(&dcache_lock);
-+              return NULL; 
-+      }
++      if (!goal)
++              return NULL;
 +
 +      /* Move the goal to the de hash queue - like d_move() */
 +      goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED;
@@ -250,7 +250,6 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 +      list_add(&goal->d_child, &goal->d_parent->d_subdirs);
 +      list_add(&de->d_child, &de->d_parent->d_subdirs);
 +      __d_rehash(goal, 0);
-+      spin_unlock(&dcache_lock);
 +
 +      return goal;
 +}
@@ -294,7 +293,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 +
 +      inode = iget(dir->i_sb, EXT3_BAD_INO);
 +
-+      if (!inode) 
++      if (!inode)
 +              return 0;
 +      d_add(dentry, inode);
 +      return 1;
@@ -323,7 +322,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
 +      inode->u.ext3_i.i_dtime = 0;
 +      inode->i_blksize = PAGE_SIZE;   /* This is the optimal IO size
 +                                       * (for stat), not the fs block
-+                                       * size */  
++                                       * size */
 +      inode->i_blocks = 0;
 +      inode->i_version = 1;
 +      inode->i_generation = 0;
@@ -338,20 +337,22 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.h
 ===================================================================
 --- linux-2.4.19.SuSE.orig/fs/ext3/iopen.h     Sun Nov 16 01:27:31 2003
 +++ linux-2.4.19.SuSE/fs/ext3/iopen.h  Sun Nov 16 01:27:31 2003
-@@ -0,0 +1,13 @@
+@@ -0,0 +1,15 @@
 +/*
 + * iopen.h
 + *
 + * Special support for opening files by inode number.
-+ * 
++ *
 + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
-+ * 
++ *
 + * This file may be redistributed under the terms of the GNU General
 + * Public License.
 + */
 +
 +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 *de,
++                                         struct inode *inode);
 Index: linux-2.4.19.SuSE/fs/ext3/namei.c
 ===================================================================
 --- linux-2.4.19.SuSE.orig/fs/ext3/namei.c     Sun Nov 16 01:23:20 2003
@@ -365,14 +366,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/namei.c
  
  /*
   * define how far ahead to read directories while searching them.
-@@ -922,16 +922,21 @@
-       return NULL;
- }
- #endif
-+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode);
- static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
- {
+@@ -922,10 +922,14 @@
        struct inode * inode;
        struct ext3_dir_entry_2 * de;
        struct buffer_head * bh;
@@ -387,31 +381,49 @@ Index: linux-2.4.19.SuSE/fs/ext3/namei.c
        bh = ext3_find_entry(dentry, &de);
        inode = NULL;
        if (bh) {
-@@ -943,6 +948,12 @@
+@@ -943,7 +948,28 @@
                        return ERR_PTR(-EACCES);
                }
        }
+-      d_add(dentry, inode);
++
++      /* verify this dentry is really new */
++      assert(!dentry->d_inode);
++      assert(list_empty(&dentry->d_alias));           /* d_instantiate */
++      assert(list_empty(&dentry->d_hash));            /* d_rehash */
++      assert(list_empty(&dentry->d_subdirs));
 +
++      spin_lock(&dcache_lock);
 +      if (inode && (alternate = iopen_connect_dentry(dentry, inode))) {
++              spin_unlock(&dcache_lock);
 +              iput(inode);
 +              return alternate;
 +      }
 +
-       d_add(dentry, inode);
++      /* d_add(), but don't drop dcache_lock before adding dentry to inode */
++      if (inode)                                      /* d_instantiate */
++              list_add(&dentry->d_alias, &inode->i_dentry);
++      dentry->d_inode = inode;
++
++      __d_rehash(dentry, 0);                          /* d_rehash */
++      spin_unlock(&dcache_lock);
++
        return NULL;
  }
 Index: linux-2.4.19.SuSE/fs/ext3/super.c
 ===================================================================
 --- linux-2.4.19.SuSE.orig/fs/ext3/super.c     Sun Nov 16 01:19:22 2003
 +++ linux-2.4.19.SuSE/fs/ext3/super.c  Sun Nov 16 01:27:31 2003
-@@ -864,6 +864,17 @@
+@@ -864,6 +864,18 @@
                         || !strcmp (this_char, "quota")
                         || !strcmp (this_char, "usrquota"))
                        /* Don't do anything ;-) */ ;
 +              else if (!strcmp (this_char, "iopen")) {
 +                      set_opt (sbi->s_mount_opt, IOPEN);
 +                      clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
-+              } else if (!strcmp (this_char, "noiopen")) {
++              }
++              else if (!strcmp (this_char, "noiopen")) {
 +                      clear_opt (sbi->s_mount_opt, IOPEN);
 +                      clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
 +              }