Whamcloud - gitweb
- ext3_stop_delete_thread() has to wait for nullified s_delete_list,
authoralex <alex>
Tue, 13 Jan 2004 18:56:05 +0000 (18:56 +0000)
committeralex <alex>
Tue, 13 Jan 2004 18:56:05 +0000 (18:56 +0000)
  not for emptyness
- ext3_stop_delete_thread() must not be called from ->put_super() context,
  because ->put_super() is called with sb being locked. so, that
  routine is called from ->sync_fs() context
- chaos-2.4.18 should drop sb lock before calling ->sync_fs()
- virgin 2.4.20 has no ->sync_fs(), so introduce it by delete-thread patch
- kernel_text_address patch has been added to rh-2.4.22 series

13 files changed:
lustre/kernel_patches/patches/ext3-delete_thread-2.4.18.patch
lustre/kernel_patches/patches/ext3-delete_thread-2.4.20-hp.patch [new file with mode: 0644]
lustre/kernel_patches/patches/ext3-delete_thread-2.4.20.patch
lustre/kernel_patches/patches/ext3-delete_thread-2.4.21-chaos.patch
lustre/kernel_patches/patches/ext3-delete_thread-2.4.24.patch
lustre/kernel_patches/patches/ext3-delete_thread-suse.patch
lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos.patch
lustre/kernel_patches/patches/ext3_delete_thread_2.4.20_chaos.patch
lustre/kernel_patches/series/chaos-2.4.18
lustre/kernel_patches/series/hp-pnnl-2.4.20
lustre/kernel_patches/series/rh-2.4.20
lustre/kernel_patches/series/rh-2.4.22
lustre/kernel_patches/series/vanilla-2.4.20

index a173981..a6a64de 100644 (file)
@@ -9,9 +9,11 @@ long latency while truncating very large files.
  include/linux/ext3_fs_sb.h |   10 +
  4 files changed, 362 insertions(+)
 
---- linux-2.4.18-18.8.0-l15/fs/ext3/super.c~ext3-delete_thread-2.4.18  Tue Jun  3 17:26:21 2003
-+++ linux-2.4.18-18.8.0-l15-adilger/fs/ext3/super.c    Wed Jul  2 23:49:40 2003
-@@ -396,6 +396,220 @@ static void dump_orphan_list(struct supe
+Index: linux-2.4.18-chaos/fs/ext3/super.c
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/super.c    2004-01-13 15:39:03.000000000 +0300
++++ linux-2.4.18-chaos/fs/ext3/super.c 2004-01-13 16:35:05.000000000 +0300
+@@ -398,6 +398,221 @@
        }
  }
  
@@ -125,7 +127,8 @@ long latency while truncating very large files.
 +
 +      clear_opt(sbi->s_mount_opt, ASYNCDEL);
 +      wake_up(&sbi->s_delete_thread_queue);
-+      wait_event(sbi->s_delete_waiter_queue, list_empty(&sbi->s_delete_list));
++      wait_event(sbi->s_delete_waiter_queue,
++                      sbi->s_delete_list.next == 0 && sbi->s_delete_inodes == 0);
 +}
 +
 +/* Instead of playing games with the inode flags, destruction, etc we just
@@ -232,15 +235,16 @@ long latency while truncating very large files.
  void ext3_put_super (struct super_block * sb)
  {
        struct ext3_sb_info *sbi = EXT3_SB(sb);
-@@ -403,6 +617,7 @@ void ext3_put_super (struct super_block 
+@@ -405,6 +620,8 @@
        kdev_t j_dev = sbi->s_journal->j_dev;
        int i;
  
-+      ext3_stop_delete_thread(sbi);
++      J_ASSERT(sbi->s_delete_inodes == 0);
++
        ext3_xattr_put_super(sb);
        journal_destroy(sbi->s_journal);
        if (!(sb->s_flags & MS_RDONLY)) {
-@@ -451,7 +666,11 @@ static struct super_operations ext3_sops
+@@ -453,7 +670,11 @@
        write_inode:    ext3_write_inode,       /* BKL not held.  Don't need */
        dirty_inode:    ext3_dirty_inode,       /* BKL not held.  We take it */
        put_inode:      ext3_put_inode,         /* BKL not held.  Don't need */
@@ -251,8 +255,8 @@ long latency while truncating very large files.
 +#endif
        put_super:      ext3_put_super,         /* BKL held */
        write_super:    ext3_write_super,       /* BKL held */
-       write_super_lockfs: ext3_write_super_lockfs, /* BKL not held. Take it */
-@@ -511,6 +730,14 @@ static int parse_options (char * options
+       sync_fs:        ext3_sync_fs,
+@@ -514,6 +735,14 @@
             this_char = strtok (NULL, ",")) {
                if ((value = strchr (this_char, '=')) != NULL)
                        *value++ = 0;
@@ -267,7 +271,7 @@ long latency while truncating very large files.
                if (!strcmp (this_char, "bsddf"))
                        clear_opt (*mount_options, MINIX_DF);
                else if (!strcmp (this_char, "nouid32")) {
-@@ -1206,6 +1433,7 @@ struct super_block * ext3_read_super (st
+@@ -1209,6 +1438,7 @@
        }
  
        ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
@@ -275,7 +279,21 @@ long latency while truncating very large files.
        /*
         * akpm: core read_super() calls in here with the superblock locked.
         * That deadlocks, because orphan cleanup needs to lock the superblock
-@@ -1648,6 +1876,9 @@ int ext3_remount (struct super_block * s
+@@ -1585,7 +1815,12 @@
+ static int ext3_sync_fs(struct super_block *sb)
+ {
+       tid_t target;
+-      
++
++      if (atomic_read(&sb->s_active) == 0) {
++              /* fs is being umounted: time to stop delete thread */
++              ext3_stop_delete_thread(EXT3_SB(sb));
++      }
++
+       sb->s_dirt = 0;
+       target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
+       log_wait_commit(EXT3_SB(sb)->s_journal, target);
+@@ -1649,6 +1884,9 @@
        if (!parse_options(data, &tmp, sbi, &tmp, 1))
                return -EINVAL;
  
@@ -285,9 +303,11 @@ long latency while truncating very large files.
        if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
                ext3_abort(sb, __FUNCTION__, "Abort forced by user");
  
---- linux/fs/ext3/file.c.orig  Fri Jan 17 10:57:31 2003
-+++ linux/fs/ext3/file.c       Mon Jun 30 13:28:52 2003
-@@ -121,7 +121,11 @@ struct file_operations ext3_file_operati
+Index: linux-2.4.18-chaos/fs/ext3/file.c
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/file.c     2003-07-28 17:52:04.000000000 +0400
++++ linux-2.4.18-chaos/fs/ext3/file.c  2004-01-13 16:26:01.000000000 +0300
+@@ -121,7 +121,11 @@
  };
  
  struct inode_operations ext3_file_inode_operations = {
@@ -299,10 +319,12 @@ long latency while truncating very large files.
        setattr:        ext3_setattr,           /* BKL held */
  };
  
---- linux-2.4.18-18.8.0-l15/fs/ext3/inode.c~ext3-delete_thread-2.4.18  Wed Jul  2 23:13:58 2003
-+++ linux-2.4.18-18.8.0-l15-adilger/fs/ext3/inode.c    Wed Jul  2 23:50:29 2003
-@@ -2004,6 +2004,118 @@ out_stop:
-       ext3_journal_stop(handle, inode);
+Index: linux-2.4.18-chaos/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/inode.c    2004-01-13 15:39:03.000000000 +0300
++++ linux-2.4.18-chaos/fs/ext3/inode.c 2004-01-13 16:26:01.000000000 +0300
+@@ -2041,6 +2041,118 @@
+       return;         /* AKPM: return what? */
  }
  
 +#ifdef EXT3_DELETE_THREAD
@@ -420,9 +442,26 @@ long latency while truncating very large files.
  /* 
   * ext3_get_inode_loc returns with an extra refcount against the
   * inode's underlying buffer_head on success. 
---- linux-2.4.18-18.8.0-l15/include/linux/ext3_fs.h~ext3-delete_thread-2.4.18  Tue Jun  3 17:26:20 2003
-+++ linux-2.4.18-18.8.0-l15-adilger/include/linux/ext3_fs.h    Wed Jul  2 23:19:09 2003
-@@ -190,6 +190,7 @@ struct ext3_group_desc
+Index: linux-2.4.18-chaos/fs/buffer.c
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/buffer.c        2003-07-28 17:52:03.000000000 +0400
++++ linux-2.4.18-chaos/fs/buffer.c     2004-01-13 16:34:43.000000000 +0300
+@@ -352,9 +352,9 @@
+       lock_super(sb);
+       if (sb->s_dirt && sb->s_op && sb->s_op->write_super)
+               sb->s_op->write_super(sb);
++      unlock_super(sb);
+       if (sb->s_op && sb->s_op->sync_fs)
+               sb->s_op->sync_fs(sb);
+-      unlock_super(sb);
+       unlock_kernel();
+       return sync_buffers(dev, 1);
+Index: linux-2.4.18-chaos/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.18-chaos.orig/include/linux/ext3_fs.h    2004-01-13 15:39:03.000000000 +0300
++++ linux-2.4.18-chaos/include/linux/ext3_fs.h 2004-01-13 16:26:01.000000000 +0300
+@@ -190,6 +190,7 @@
   */
  #define EXT3_STATE_JDATA              0x00000001 /* journaled data exists */
  #define EXT3_STATE_NEW                        0x00000002 /* inode is newly created */
@@ -430,7 +469,7 @@ long latency while truncating very large files.
  
  /*
   * ioctl commands
-@@ -317,6 +318,7 @@ struct ext3_inode {
+@@ -317,6 +318,7 @@
  #define EXT3_MOUNT_UPDATE_JOURNAL     0x1000  /* Update the journal format */
  #define EXT3_MOUNT_NO_UID32           0x2000  /* Disable 32-bit UIDs */
  #define EXT3_MOUNT_INDEX              0x4000  /* Enable directory index */
@@ -438,7 +477,7 @@ long latency while truncating very large files.
  
  /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
  #ifndef _LINUX_EXT2_FS_H
-@@ -651,6 +653,9 @@ extern void ext3_discard_prealloc (struc
+@@ -651,6 +653,9 @@
  extern void ext3_dirty_inode(struct inode *);
  extern int ext3_change_inode_journal_flag(struct inode *, int);
  extern void ext3_truncate (struct inode *);
@@ -448,8 +487,10 @@ long latency while truncating very large files.
  
  /* ioctl.c */
  extern int ext3_ioctl (struct inode *, struct file *, unsigned int,
---- linux-2.4.18-18.8.0-l15/include/linux/ext3_fs_sb.h~ext3-delete_thread-2.4.18       Tue Jun  3 17:26:21 2003
-+++ linux-2.4.18-18.8.0-l15-adilger/include/linux/ext3_fs_sb.h Wed Jul  2 23:19:09 2003
+Index: linux-2.4.18-chaos/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.18-chaos.orig/include/linux/ext3_fs_sb.h 2004-01-13 15:39:03.000000000 +0300
++++ linux-2.4.18-chaos/include/linux/ext3_fs_sb.h      2004-01-13 16:26:01.000000000 +0300
 @@ -29,6 +29,8 @@
  
  #define EXT3_MAX_GROUP_LOADED 32
@@ -459,7 +500,7 @@ long latency while truncating very large files.
  /*
   * third extended-fs super-block data in memory
   */
-@@ -74,6 +76,14 @@ struct ext3_sb_info {
+@@ -74,6 +76,14 @@
        struct timer_list turn_ro_timer;        /* For turning read-only (crash simulation) */
        wait_queue_head_t ro_wait_queue;        /* For people waiting for the fs to go read-only */
  #endif
@@ -474,5 +515,3 @@ long latency while truncating very large files.
  };
  
  #endif        /* _LINUX_EXT3_FS_SB */
-
-_
diff --git a/lustre/kernel_patches/patches/ext3-delete_thread-2.4.20-hp.patch b/lustre/kernel_patches/patches/ext3-delete_thread-2.4.20-hp.patch
new file mode 100644 (file)
index 0000000..f91b8ff
--- /dev/null
@@ -0,0 +1,510 @@
+ fs/ext3/file.c             |    4 
+ fs/ext3/inode.c            |  116 ++++++++++++++++++++++
+ fs/ext3/super.c            |  230 +++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/ext3_fs.h    |    5 
+ include/linux/ext3_fs_sb.h |   10 +
+ 5 files changed, 365 insertions(+)
+
+Index: linux-2.4.20-hp4-pnnl13/fs/ext3/super.c
+===================================================================
+--- linux-2.4.20-hp4-pnnl13.orig/fs/ext3/super.c       2004-01-12 19:22:32.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13/fs/ext3/super.c    2004-01-13 17:04:38.000000000 +0300
+@@ -400,6 +400,221 @@
+       }
+ }
++#ifdef EXT3_DELETE_THREAD
++/*
++ * Delete inodes in a loop until there are no more to be deleted.
++ * Normally, we run in the background doing the deletes and sleeping again,
++ * and clients just add new inodes to be deleted onto the end of the list.
++ * If someone is concerned about free space (e.g. block allocation or similar)
++ * then they can sleep on s_delete_waiter_queue and be woken up when space
++ * has been freed.
++ */
++int ext3_delete_thread(void *data)
++{
++      struct super_block *sb = data;
++      struct ext3_sb_info *sbi = EXT3_SB(sb);
++      struct task_struct *tsk = current;
++
++      /* Almost like daemonize, but not quite */
++      exit_mm(current);
++      tsk->session = 1;
++      tsk->pgrp = 1;
++      tsk->tty = NULL;
++      exit_files(current);
++      reparent_to_init();
++
++      sprintf(tsk->comm, "kdelext3-%s", kdevname(sb->s_dev));
++      sigfillset(&tsk->blocked);
++
++      /*tsk->flags |= PF_KERNTHREAD;*/
++
++      INIT_LIST_HEAD(&sbi->s_delete_list);
++      wake_up(&sbi->s_delete_waiter_queue);
++      ext3_debug("delete thread on %s started\n", kdevname(sb->s_dev));
++
++      /* main loop */
++      for (;;) {
++              wait_event_interruptible(sbi->s_delete_thread_queue,
++                                       !list_empty(&sbi->s_delete_list) ||
++                                       !test_opt(sb, ASYNCDEL));
++              ext3_debug("%s woken up: %lu inodes, %lu blocks\n",
++                         tsk->comm,sbi->s_delete_inodes,sbi->s_delete_blocks);
++
++              spin_lock(&sbi->s_delete_lock);
++              if (list_empty(&sbi->s_delete_list)) {
++                      clear_opt(sbi->s_mount_opt, ASYNCDEL);
++                      memset(&sbi->s_delete_list, 0,
++                             sizeof(sbi->s_delete_list));
++                      spin_unlock(&sbi->s_delete_lock);
++                      ext3_debug("delete thread on %s exiting\n",
++                                 kdevname(sb->s_dev));
++                      wake_up(&sbi->s_delete_waiter_queue);
++                      break;
++              }
++
++              while (!list_empty(&sbi->s_delete_list)) {
++                      struct inode *inode=list_entry(sbi->s_delete_list.next,
++                                                     struct inode, i_dentry);
++                      unsigned long blocks = inode->i_blocks >>
++                                                      (inode->i_blkbits - 9);
++
++                      list_del_init(&inode->i_dentry);
++                      spin_unlock(&sbi->s_delete_lock);
++                      ext3_debug("%s delete ino %lu blk %lu\n",
++                                 tsk->comm, inode->i_ino, blocks);
++
++                      iput(inode);
++
++                      spin_lock(&sbi->s_delete_lock);
++                      sbi->s_delete_blocks -= blocks;
++                      sbi->s_delete_inodes--;
++              }
++              if (sbi->s_delete_blocks != 0 || sbi->s_delete_inodes != 0) {
++                      ext3_warning(sb, __FUNCTION__,
++                                   "%lu blocks, %lu inodes on list?\n",
++                                   sbi->s_delete_blocks,sbi->s_delete_inodes);
++                      sbi->s_delete_blocks = 0;
++                      sbi->s_delete_inodes = 0;
++              }
++              spin_unlock(&sbi->s_delete_lock);
++              wake_up(&sbi->s_delete_waiter_queue);
++      }
++
++      return 0;
++}
++
++static void ext3_start_delete_thread(struct super_block *sb)
++{
++      struct ext3_sb_info *sbi = EXT3_SB(sb);
++      int rc;
++
++      spin_lock_init(&sbi->s_delete_lock);
++      init_waitqueue_head(&sbi->s_delete_thread_queue);
++      init_waitqueue_head(&sbi->s_delete_waiter_queue);
++
++      if (!test_opt(sb, ASYNCDEL))
++              return;
++
++      rc = kernel_thread(ext3_delete_thread, sb, CLONE_VM | CLONE_FILES);
++      if (rc < 0)
++              printk(KERN_ERR "EXT3-fs: cannot start delete thread: rc %d\n",
++                     rc);
++      else
++              wait_event(sbi->s_delete_waiter_queue, sbi->s_delete_list.next);
++}
++
++static void ext3_stop_delete_thread(struct ext3_sb_info *sbi)
++{
++      if (sbi->s_delete_list.next == 0)       /* thread never started */
++              return;
++
++      clear_opt(sbi->s_mount_opt, ASYNCDEL);
++      wake_up(&sbi->s_delete_thread_queue);
++      wait_event(sbi->s_delete_waiter_queue,
++                      sbi->s_delete_list.next == 0 && sbi->s_delete_inodes == 0);
++}
++
++/* Instead of playing games with the inode flags, destruction, etc we just
++ * create a new inode locally and put it on a list for the truncate thread.
++ * We need large parts of the inode struct in order to complete the
++ * truncate and unlink, so we may as well just have a real inode to do it.
++ *
++ * If we have any problem deferring the delete, just delete it right away.
++ * If we defer it, we also mark how many blocks it would free, so that we
++ * can keep the statfs data correct, and we know if we should sleep on the
++ * delete thread when we run out of space.
++ */
++static void ext3_delete_inode_thread(struct inode *old_inode)
++{
++      struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb);
++      struct ext3_inode_info *nei, *oei = EXT3_I(old_inode);
++      struct inode *new_inode;
++      unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9);
++
++      if (is_bad_inode(old_inode)) {
++              clear_inode(old_inode);
++              return;
++      }
++
++      if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next)
++              goto out_delete;
++
++      /* We may want to delete the inode immediately and not defer it */
++      if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS)
++              goto out_delete;
++
++      /* We can't use the delete thread as-is during real orphan recovery,
++       * as we add to the orphan list here, causing ext3_orphan_cleanup()
++       * to loop endlessly.  It would be nice to do so, but needs work.
++       */
++      if (oei->i_state & EXT3_STATE_DELETE ||
++          sbi->s_mount_state & EXT3_ORPHAN_FS) {
++              ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
++                         old_inode->i_ino, blocks);
++              goto out_delete;
++      }
++
++      /* We can iget this inode again here, because our caller has unhashed
++       * old_inode, so new_inode will be in a different inode struct.
++       *
++       * We need to ensure that the i_orphan pointers in the other inodes
++       * point at the new inode copy instead of the old one so the orphan
++       * list doesn't get corrupted when the old orphan inode is freed.
++       */
++      down(&sbi->s_orphan_lock);
++
++      sbi->s_mount_state |= EXT3_ORPHAN_FS;
++      new_inode = iget(old_inode->i_sb, old_inode->i_ino);
++      sbi->s_mount_state &= ~EXT3_ORPHAN_FS;
++      if (is_bad_inode(new_inode)) {
++              printk(KERN_WARNING "read bad inode %lu\n", old_inode->i_ino);
++              iput(new_inode);
++              new_inode = NULL;
++      }
++      if (!new_inode) {
++              up(&sbi->s_orphan_lock);
++              ext3_debug("delete inode %lu directly (bad read)\n",
++                         old_inode->i_ino);
++              goto out_delete;
++      }
++      J_ASSERT(new_inode != old_inode);
++
++      J_ASSERT(!list_empty(&oei->i_orphan));
++
++      nei = EXT3_I(new_inode);
++      /* Ugh.  We need to insert new_inode into the same spot on the list
++       * as old_inode was, to ensure the in-memory orphan list is still
++       * in the same order as the on-disk orphan list (badness otherwise).
++       */
++      nei->i_orphan = oei->i_orphan;
++      nei->i_orphan.next->prev = &nei->i_orphan;
++      nei->i_orphan.prev->next = &nei->i_orphan;
++      nei->i_state |= EXT3_STATE_DELETE;
++      up(&sbi->s_orphan_lock);
++
++      clear_inode(old_inode);
++
++      spin_lock(&sbi->s_delete_lock);
++      J_ASSERT(list_empty(&new_inode->i_dentry));
++      list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list);
++      sbi->s_delete_blocks += blocks;
++      sbi->s_delete_inodes++;
++      spin_unlock(&sbi->s_delete_lock);
++
++      ext3_debug("delete inode %lu (%lu blocks) by thread\n",
++                 new_inode->i_ino, blocks);
++
++      wake_up(&sbi->s_delete_thread_queue);
++      return;
++
++out_delete:
++      ext3_delete_inode(old_inode);
++}
++#else
++#define ext3_start_delete_thread(sbi) do {} while(0)
++#define ext3_stop_delete_thread(sbi) do {} while(0)
++#endif /* EXT3_DELETE_THREAD */
++
+ void ext3_put_super (struct super_block * sb)
+ {
+       struct ext3_sb_info *sbi = EXT3_SB(sb);
+@@ -407,6 +622,7 @@
+       kdev_t j_dev = sbi->s_journal->j_dev;
+       int i;
++      J_ASSERT(sbi->s_delete_inodes == 0);
+       ext3_xattr_put_super(sb);
+       journal_destroy(sbi->s_journal);
+       if (!(sb->s_flags & MS_RDONLY)) {
+@@ -455,7 +671,11 @@
+       write_inode:    ext3_write_inode,       /* BKL not held.  Don't need */
+       dirty_inode:    ext3_dirty_inode,       /* BKL not held.  We take it */
+       put_inode:      ext3_put_inode,         /* BKL not held.  Don't need */
+-      delete_inode:   ext3_delete_inode,      /* BKL not held.  We take it */
++#ifdef EXT3_DELETE_THREAD
++      delete_inode:   ext3_delete_inode_thread,/* BKL not held. We take it */
++#else
++      delete_inode:   ext3_delete_inode,      /* BKL not held.  We take it */
++#endif
+       put_super:      ext3_put_super,         /* BKL held */
+       write_super:    ext3_write_super,       /* BKL held */
+       sync_fs:        ext3_sync_fs,
+@@ -524,6 +744,13 @@
+                       clear_opt (*mount_options, XATTR_USER);
+               else
+ #endif
++#ifdef EXT3_DELETE_THREAD
++              if (!strcmp(this_char, "asyncdel"))
++                      set_opt(*mount_options, ASYNCDEL);
++              else if (!strcmp(this_char, "noasyncdel"))
++                      clear_opt(*mount_options, ASYNCDEL);
++              else
++#endif
+               if (!strcmp (this_char, "bsddf"))
+                       clear_opt (*mount_options, MINIX_DF);
+               else if (!strcmp (this_char, "nouid32")) {
+@@ -1223,6 +1450,7 @@
+       }
+       ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
++      ext3_start_delete_thread(sb);
+       /*
+        * akpm: core read_super() calls in here with the superblock locked.
+        * That deadlocks, because orphan cleanup needs to lock the superblock
+@@ -1614,7 +1842,12 @@
+ static int ext3_sync_fs(struct super_block *sb)
+ {
+       tid_t target;
+-      
++
++      if (atomic_read(&sb->s_active) == 0) {
++              /* fs is being umounted: time to stop delete thread */
++              ext3_stop_delete_thread(EXT3_SB(sb));
++      }
++
+       sb->s_dirt = 0;
+       target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
+       log_wait_commit(EXT3_SB(sb)->s_journal, target);
+@@ -1678,6 +1911,9 @@
+       if (!parse_options(data, &tmp, sbi, &tmp, 1))
+               return -EINVAL;
++      if (!test_opt(sb, ASYNCDEL) || (*flags & MS_RDONLY))
++              ext3_stop_delete_thread(sbi);
++
+       if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
+               ext3_abort(sb, __FUNCTION__, "Abort forced by user");
+Index: linux-2.4.20-hp4-pnnl13/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.20-hp4-pnnl13.orig/fs/ext3/inode.c       2004-01-12 19:22:32.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13/fs/ext3/inode.c    2004-01-13 17:01:40.000000000 +0300
+@@ -2500,6 +2500,118 @@
+       return err;
+ }
++#ifdef EXT3_DELETE_THREAD
++/* Move blocks from to-be-truncated inode over to a new inode, and delete
++ * that one from the delete thread instead.  This avoids a lot of latency
++ * when truncating large files.
++ *
++ * If we have any problem deferring the truncate, just truncate it right away.
++ * If we defer it, we also mark how many blocks it would free, so that we
++ * can keep the statfs data correct, and we know if we should sleep on the
++ * delete thread when we run out of space.
++ */
++void ext3_truncate_thread(struct inode *old_inode)
++{
++      struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb);
++      struct ext3_inode_info *nei, *oei = EXT3_I(old_inode);
++      struct inode *new_inode;
++      handle_t *handle;
++      unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9);
++
++      if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next)
++              goto out_truncate;
++
++      /* XXX This is a temporary limitation for code simplicity.
++       *     We could truncate to arbitrary sizes at some later time.
++       */
++      if (old_inode->i_size != 0)
++              goto out_truncate;
++
++      /* We may want to truncate the inode immediately and not defer it */
++      if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS ||
++          old_inode->i_size > oei->i_disksize)
++              goto out_truncate;
++
++      /* We can't use the delete thread as-is during real orphan recovery,
++       * as we add to the orphan list here, causing ext3_orphan_cleanup()
++       * to loop endlessly.  It would be nice to do so, but needs work.
++       */
++      if (oei->i_state & EXT3_STATE_DELETE ||
++          sbi->s_mount_state & EXT3_ORPHAN_FS) {
++              ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
++                         old_inode->i_ino, blocks);
++              goto out_truncate;
++      }
++
++      ext3_discard_prealloc(old_inode);
++
++      /* old_inode   = 1
++       * new_inode   = sb + GDT + ibitmap
++       * orphan list = 1 inode/superblock for add, 2 inodes for del
++       * quota files = 2 * EXT3_SINGLEDATA_TRANS_BLOCKS
++       */
++      handle = ext3_journal_start(old_inode, 7);
++      if (IS_ERR(handle))
++              goto out_truncate;
++
++      new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode);
++      if (IS_ERR(new_inode)) {
++              ext3_debug("truncate inode %lu directly (no new inodes)\n",
++                         old_inode->i_ino);
++              goto out_journal;
++      }
++
++      nei = EXT3_I(new_inode);
++
++      down_write(&oei->truncate_sem);
++      new_inode->i_size = old_inode->i_size;
++      new_inode->i_blocks = old_inode->i_blocks;
++      new_inode->i_uid = old_inode->i_uid;
++      new_inode->i_gid = old_inode->i_gid;
++      new_inode->i_nlink = 0;
++
++      /* FIXME when we do arbitrary truncates */
++      old_inode->i_blocks = oei->i_file_acl ? old_inode->i_blksize / 512 : 0;
++      old_inode->i_mtime = old_inode->i_ctime = CURRENT_TIME;
++
++      memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data));
++      memset(oei->i_data, 0, sizeof(oei->i_data));
++
++      nei->i_disksize = oei->i_disksize;
++      nei->i_state |= EXT3_STATE_DELETE;
++      up_write(&oei->truncate_sem);
++
++      if (ext3_orphan_add(handle, new_inode) < 0)
++              goto out_journal;
++
++      if (ext3_orphan_del(handle, old_inode) < 0) {
++              ext3_orphan_del(handle, new_inode);
++              iput(new_inode);
++              goto out_journal;
++      }
++
++      ext3_journal_stop(handle, old_inode);
++
++      spin_lock(&sbi->s_delete_lock);
++      J_ASSERT(list_empty(&new_inode->i_dentry));
++      list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list);
++      sbi->s_delete_blocks += blocks;
++      sbi->s_delete_inodes++;
++      spin_unlock(&sbi->s_delete_lock);
++
++      ext3_debug("delete inode %lu (%lu blocks) by thread\n",
++                 new_inode->i_ino, blocks);
++
++      wake_up(&sbi->s_delete_thread_queue);
++      return;
++
++out_journal:
++      ext3_journal_stop(handle, old_inode);
++out_truncate:
++      ext3_truncate(old_inode);
++}
++#endif /* EXT3_DELETE_THREAD */
++
+ /* 
+  * On success, We end up with an outstanding reference count against
+  * iloc->bh.  This _must_ be cleaned up later. 
+Index: linux-2.4.20-hp4-pnnl13/fs/ext3/file.c
+===================================================================
+--- linux-2.4.20-hp4-pnnl13.orig/fs/ext3/file.c        2004-01-12 19:22:32.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13/fs/ext3/file.c     2004-01-13 17:01:40.000000000 +0300
+@@ -125,7 +125,11 @@
+ };
+ struct inode_operations ext3_file_inode_operations = {
++#ifdef EXT3_DELETE_THREAD
++      truncate:       ext3_truncate_thread,   /* BKL held */
++#else
+       truncate:       ext3_truncate,          /* BKL held */
++#endif
+       setattr:        ext3_setattr,           /* BKL held */
+       setxattr:       ext3_setxattr,          /* BKL held */
+       getxattr:       ext3_getxattr,          /* BKL held */
+Index: linux-2.4.20-hp4-pnnl13/fs/buffer.c
+===================================================================
+--- linux-2.4.20-hp4-pnnl13.orig/fs/buffer.c   2003-09-13 15:19:26.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13/fs/buffer.c        2004-01-13 17:01:40.000000000 +0300
+@@ -376,6 +376,8 @@
+       if (sb->s_op && sb->s_op->sync_fs)
+               sb->s_op->sync_fs(sb);
+       unlock_super(sb);
++      if (sb->s_op && sb->s_op->sync_fs)
++              sb->s_op->sync_fs(sb);
+       unlock_kernel();
+       return sync_buffers(dev, 1);
+Index: linux-2.4.20-hp4-pnnl13/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.20-hp4-pnnl13.orig/include/linux/ext3_fs.h       2004-01-12 19:22:32.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13/include/linux/ext3_fs.h    2004-01-13 17:01:40.000000000 +0300
+@@ -193,6 +193,7 @@
+  */
+ #define EXT3_STATE_JDATA              0x00000001 /* journaled data exists */
+ #define EXT3_STATE_NEW                        0x00000002 /* inode is newly created */
++#define EXT3_STATE_DELETE             0x00000010 /* deferred delete inode */
+ /*
+  * ioctl commands
+@@ -320,6 +321,7 @@
+ #define EXT3_MOUNT_UPDATE_JOURNAL     0x1000  /* Update the journal format */
+ #define EXT3_MOUNT_NO_UID32           0x2000  /* Disable 32-bit UIDs */
+ #define EXT3_MOUNT_XATTR_USER         0x4000  /* Extended user attributes */
++#define EXT3_MOUNT_ASYNCDEL           0x20000 /* Delayed deletion */
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+@@ -694,6 +696,9 @@
+ extern void ext3_dirty_inode(struct inode *);
+ extern int ext3_change_inode_journal_flag(struct inode *, int);
+ extern void ext3_truncate (struct inode *);
++#ifdef EXT3_DELETE_THREAD
++extern void ext3_truncate_thread(struct inode *inode);
++#endif
+ /* ioctl.c */
+ extern int ext3_ioctl (struct inode *, struct file *, unsigned int,
+Index: linux-2.4.20-hp4-pnnl13/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.20-hp4-pnnl13.orig/include/linux/ext3_fs_sb.h    2004-01-12 19:22:32.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13/include/linux/ext3_fs_sb.h 2004-01-13 17:01:40.000000000 +0300
+@@ -29,6 +29,8 @@
+ #define EXT3_MAX_GROUP_LOADED 8
++#define EXT3_DELETE_THREAD
++
+ /*
+  * third extended-fs super-block data in memory
+  */
+@@ -76,6 +78,14 @@
+       struct timer_list turn_ro_timer;        /* For turning read-only (crash simulation) */
+       wait_queue_head_t ro_wait_queue;        /* For people waiting for the fs to go read-only */
+ #endif
++#ifdef EXT3_DELETE_THREAD
++      spinlock_t s_delete_lock;
++      struct list_head s_delete_list;
++      unsigned long s_delete_blocks;
++      unsigned long s_delete_inodes;
++      wait_queue_head_t s_delete_thread_queue;
++      wait_queue_head_t s_delete_waiter_queue;
++#endif
+ };
+ #endif        /* _LINUX_EXT3_FS_SB */
index a8816ec..ca05893 100644 (file)
@@ -5,9 +5,20 @@
  include/linux/ext3_fs_sb.h |   10 +
  5 files changed, 365 insertions(+)
 
---- linux/fs/ext3/super.c~ext3-delete_thread-2.4.20    Thu Jul 10 14:11:32 2003
-+++ linux-mmonroe/fs/ext3/super.c      Thu Jul 10 14:11:33 2003
-@@ -400,6 +400,220 @@ static void dump_orphan_list(struct supe
+Index: linux-2.4.20/fs/ext3/super.c
+===================================================================
+--- linux-2.4.20.orig/fs/ext3/super.c  2004-01-12 20:13:37.000000000 +0300
++++ linux-2.4.20/fs/ext3/super.c       2004-01-13 16:59:54.000000000 +0300
+@@ -48,6 +48,8 @@
+ static void ext3_clear_journal_err(struct super_block * sb,
+                                  struct ext3_super_block * es);
++static int ext3_sync_fs(struct super_block * sb);
++
+ #ifdef CONFIG_JBD_DEBUG
+ int journal_no_write[2];
+@@ -398,6 +400,221 @@
        }
  }
  
 +
 +      clear_opt(sbi->s_mount_opt, ASYNCDEL);
 +      wake_up(&sbi->s_delete_thread_queue);
-+      wait_event(sbi->s_delete_waiter_queue, list_empty(&sbi->s_delete_list));
++      wait_event(sbi->s_delete_waiter_queue,
++                      sbi->s_delete_list.next == 0 && sbi->s_delete_inodes == 0);
 +}
 +
 +/* Instead of playing games with the inode flags, destruction, etc we just
  void ext3_put_super (struct super_block * sb)
  {
        struct ext3_sb_info *sbi = EXT3_SB(sb);
-@@ -407,6 +621,7 @@ void ext3_put_super (struct super_block 
+@@ -405,6 +622,7 @@
        kdev_t j_dev = sbi->s_journal->j_dev;
        int i;
  
-+      ext3_stop_delete_thread(sbi);
++      J_ASSERT(sbi->s_delete_inodes == 0);
        ext3_xattr_put_super(sb);
        journal_destroy(sbi->s_journal);
        if (!(sb->s_flags & MS_RDONLY)) {
-@@ -455,7 +670,11 @@ static struct super_operations ext3_sops
+@@ -453,9 +671,14 @@
        write_inode:    ext3_write_inode,       /* BKL not held.  Don't need */
        dirty_inode:    ext3_dirty_inode,       /* BKL not held.  We take it */
        put_inode:      ext3_put_inode,         /* BKL not held.  Don't need */
 +#endif
        put_super:      ext3_put_super,         /* BKL held */
        write_super:    ext3_write_super,       /* BKL held */
-       sync_fs:        ext3_sync_fs,
-@@ -524,6 +743,13 @@ static int parse_options (char * options
++      sync_fs:        ext3_sync_fs,
+       write_super_lockfs: ext3_write_super_lockfs, /* BKL not held. Take it */
+       unlockfs:       ext3_unlockfs,          /* BKL not held.  We take it */
+       statfs:         ext3_statfs,            /* BKL held */
+@@ -521,6 +744,13 @@
                        clear_opt (*mount_options, XATTR_USER);
                else
  #endif
                if (!strcmp (this_char, "bsddf"))
                        clear_opt (*mount_options, MINIX_DF);
                else if (!strcmp (this_char, "nouid32")) {
-@@ -1223,6 +1449,7 @@ struct super_block * ext3_read_super (st
+@@ -1220,6 +1450,7 @@
        }
  
        ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
        /*
         * akpm: core read_super() calls in here with the superblock locked.
         * That deadlocks, because orphan cleanup needs to lock the superblock
-@@ -1678,6 +1905,9 @@ int ext3_remount (struct super_block * s
+@@ -1625,6 +1856,21 @@
+       }
+ }
++static int ext3_sync_fs(struct super_block *sb)
++{
++      tid_t target;
++
++      if (atomic_read(&sb->s_active) == 0) {
++              /* fs is being umounted: time to stop delete thread */
++              ext3_stop_delete_thread(EXT3_SB(sb));
++      }
++
++      sb->s_dirt = 0;
++      target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
++      log_wait_commit(EXT3_SB(sb)->s_journal, target);
++      return 0;
++}
++
+ /*
+  * LVM calls this function before a (read-only) snapshot is created.  This
+  * gives us a chance to flush the journal completely and mark the fs clean.
+@@ -1682,6 +1928,9 @@
        if (!parse_options(data, &tmp, sbi, &tmp, 1))
                return -EINVAL;
  
        if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
                ext3_abort(sb, __FUNCTION__, "Abort forced by user");
  
---- linux/fs/ext3/inode.c~ext3-delete_thread-2.4.20    Thu Jul 10 14:11:29 2003
-+++ linux-mmonroe/fs/ext3/inode.c      Thu Jul 10 14:11:33 2003
-@@ -2013,6 +2013,118 @@ out_stop:
-       ext3_journal_stop(handle, inode);
+Index: linux-2.4.20/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.20.orig/fs/ext3/inode.c  2004-01-12 20:13:37.000000000 +0300
++++ linux-2.4.20/fs/ext3/inode.c       2004-01-13 16:55:45.000000000 +0300
+@@ -2552,6 +2552,118 @@
+       return err;
  }
  
 +#ifdef EXT3_DELETE_THREAD
 +#endif /* EXT3_DELETE_THREAD */
 +
  /* 
-  * ext3_get_inode_loc returns with an extra refcount against the
-  * inode's underlying buffer_head on success. 
---- linux/fs/ext3/file.c~ext3-delete_thread-2.4.20     Thu Jul 10 14:11:21 2003
-+++ linux-mmonroe/fs/ext3/file.c       Thu Jul 10 14:12:17 2003
-@@ -125,7 +125,11 @@ struct file_operations ext3_file_operati
+  * On success, We end up with an outstanding reference count against
+  * iloc->bh.  This _must_ be cleaned up later. 
+Index: linux-2.4.20/fs/ext3/file.c
+===================================================================
+--- linux-2.4.20.orig/fs/ext3/file.c   2004-01-12 20:13:36.000000000 +0300
++++ linux-2.4.20/fs/ext3/file.c        2004-01-13 16:55:45.000000000 +0300
+@@ -125,7 +125,11 @@
  };
  
  struct inode_operations ext3_file_inode_operations = {
        setattr:        ext3_setattr,           /* BKL held */
        setxattr:       ext3_setxattr,          /* BKL held */
        getxattr:       ext3_getxattr,          /* BKL held */
---- linux/include/linux/ext3_fs.h~ext3-delete_thread-2.4.20    Thu Jul 10 14:11:26 2003
-+++ linux-mmonroe/include/linux/ext3_fs.h      Thu Jul 10 14:11:33 2003
-@@ -193,6 +193,7 @@ struct ext3_group_desc
+Index: linux-2.4.20/fs/buffer.c
+===================================================================
+--- linux-2.4.20.orig/fs/buffer.c      2003-05-16 05:29:12.000000000 +0400
++++ linux-2.4.20/fs/buffer.c   2004-01-13 16:55:45.000000000 +0300
+@@ -328,6 +328,8 @@
+       if (sb->s_dirt && sb->s_op && sb->s_op->write_super)
+               sb->s_op->write_super(sb);
+       unlock_super(sb);
++      if (sb->s_op && sb->s_op->sync_fs)
++              sb->s_op->sync_fs(sb);
+       unlock_kernel();
+       return sync_buffers(dev, 1);
+Index: linux-2.4.20/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.20.orig/include/linux/ext3_fs.h  2004-01-12 20:13:37.000000000 +0300
++++ linux-2.4.20/include/linux/ext3_fs.h       2004-01-13 16:55:45.000000000 +0300
+@@ -193,6 +193,7 @@
   */
  #define EXT3_STATE_JDATA              0x00000001 /* journaled data exists */
  #define EXT3_STATE_NEW                        0x00000002 /* inode is newly created */
  
  /*
   * ioctl commands
-@@ -320,6 +321,7 @@ struct ext3_inode {
+@@ -320,6 +321,7 @@
  #define EXT3_MOUNT_UPDATE_JOURNAL     0x1000  /* Update the journal format */
  #define EXT3_MOUNT_NO_UID32           0x2000  /* Disable 32-bit UIDs */
  #define EXT3_MOUNT_XATTR_USER         0x4000  /* Extended user attributes */
  
  /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
  #ifndef _LINUX_EXT2_FS_H
-@@ -694,6 +696,9 @@ extern void ext3_discard_prealloc (struc
+@@ -696,6 +698,9 @@
  extern void ext3_dirty_inode(struct inode *);
  extern int ext3_change_inode_journal_flag(struct inode *, int);
  extern void ext3_truncate (struct inode *);
  
  /* ioctl.c */
  extern int ext3_ioctl (struct inode *, struct file *, unsigned int,
---- linux/include/linux/ext3_fs_sb.h~ext3-delete_thread-2.4.20 Thu Jul 10 14:11:32 2003
-+++ linux-mmonroe/include/linux/ext3_fs_sb.h   Thu Jul 10 14:11:33 2003
+Index: linux-2.4.20/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.20.orig/include/linux/ext3_fs_sb.h       2004-01-12 20:13:37.000000000 +0300
++++ linux-2.4.20/include/linux/ext3_fs_sb.h    2004-01-13 16:55:45.000000000 +0300
 @@ -29,6 +29,8 @@
  
  #define EXT3_MAX_GROUP_LOADED 8
  /*
   * third extended-fs super-block data in memory
   */
-@@ -76,6 +78,14 @@ struct ext3_sb_info {
+@@ -76,6 +78,14 @@
        struct timer_list turn_ro_timer;        /* For turning read-only (crash simulation) */
        wait_queue_head_t ro_wait_queue;        /* For people waiting for the fs to go read-only */
  #endif
  };
  
  #endif        /* _LINUX_EXT3_FS_SB */
-
-_
+Index: linux-2.4.20/include/linux/fs.h
+===================================================================
+--- linux-2.4.20.orig/include/linux/fs.h       2004-01-12 20:13:36.000000000 +0300
++++ linux-2.4.20/include/linux/fs.h    2004-01-13 16:55:45.000000000 +0300
+@@ -917,6 +917,7 @@
+       void (*delete_inode) (struct inode *);
+       void (*put_super) (struct super_block *);
+       void (*write_super) (struct super_block *);
++      int (*sync_fs) (struct super_block *);
+       void (*write_super_lockfs) (struct super_block *);
+       void (*unlockfs) (struct super_block *);
+       int (*statfs) (struct super_block *, struct statfs *);
index b73ebf5..2fc365d 100644 (file)
@@ -7,9 +7,9 @@
 
 Index: linux-2.4.21-chaos/fs/ext3/super.c
 ===================================================================
---- linux-2.4.21-chaos.orig/fs/ext3/super.c    2003-12-12 16:18:41.000000000 +0300
-+++ linux-2.4.21-chaos/fs/ext3/super.c 2003-12-12 16:18:43.000000000 +0300
-@@ -425,6 +425,220 @@
+--- linux-2.4.21-chaos.orig/fs/ext3/super.c    2004-01-12 19:20:07.000000000 +0300
++++ linux-2.4.21-chaos/fs/ext3/super.c 2004-01-13 17:25:49.000000000 +0300
+@@ -425,6 +425,221 @@
        }
  }
  
@@ -123,7 +123,8 @@ Index: linux-2.4.21-chaos/fs/ext3/super.c
 +
 +      clear_opt(sbi->s_mount_opt, ASYNCDEL);
 +      wake_up(&sbi->s_delete_thread_queue);
-+      wait_event(sbi->s_delete_waiter_queue, list_empty(&sbi->s_delete_list));
++      wait_event(sbi->s_delete_waiter_queue,
++                      sbi->s_delete_list.next == 0 && sbi->s_delete_inodes == 0);
 +}
 +
 +/* Instead of playing games with the inode flags, destruction, etc we just
@@ -230,15 +231,15 @@ Index: linux-2.4.21-chaos/fs/ext3/super.c
  void ext3_put_super (struct super_block * sb)
  {
        struct ext3_sb_info *sbi = EXT3_SB(sb);
-@@ -432,6 +646,7 @@
+@@ -432,6 +647,7 @@
        kdev_t j_dev = sbi->s_journal->j_dev;
        int i;
  
-+      ext3_stop_delete_thread(sbi);
++      J_ASSERT(sbi->s_delete_inodes == 0);
        ext3_xattr_put_super(sb);
        journal_destroy(sbi->s_journal);
        if (!(sb->s_flags & MS_RDONLY)) {
-@@ -501,7 +716,11 @@
+@@ -501,7 +717,11 @@
        write_inode:    ext3_write_inode,       /* BKL not held.  Don't need */
        dirty_inode:    ext3_dirty_inode,       /* BKL not held.  We take it */
        put_inode:      ext3_put_inode,         /* BKL not held.  Don't need */
@@ -250,7 +251,7 @@ Index: linux-2.4.21-chaos/fs/ext3/super.c
        put_super:      ext3_put_super,         /* BKL held */
        write_super:    ext3_write_super,       /* BKL held */
        sync_fs:        ext3_sync_fs,
-@@ -579,6 +798,13 @@
+@@ -579,6 +799,13 @@
                        *mount_flags &= ~MS_POSIXACL;
                else
  #endif
@@ -264,7 +265,7 @@ Index: linux-2.4.21-chaos/fs/ext3/super.c
                if (!strcmp (this_char, "bsddf"))
                        clear_opt (*mount_options, MINIX_DF);
                else if (!strcmp (this_char, "nouid32")) {
-@@ -1283,6 +1509,7 @@
+@@ -1283,6 +1510,7 @@
        }
  
        ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
@@ -272,7 +273,21 @@ Index: linux-2.4.21-chaos/fs/ext3/super.c
        /*
         * akpm: core read_super() calls in here with the superblock locked.
         * That deadlocks, because orphan cleanup needs to lock the superblock
-@@ -1746,6 +1973,9 @@
+@@ -1676,7 +1904,12 @@
+ static int ext3_sync_fs(struct super_block *sb)
+ {
+       tid_t target;
+-      
++
++      if (atomic_read(&sb->s_active) == 0) {
++              /* fs is being umounted: time to stop delete thread */
++              ext3_stop_delete_thread(EXT3_SB(sb));
++      }
++
+       sb->s_dirt = 0;
+       target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
+       log_wait_commit(EXT3_SB(sb)->s_journal, target);
+@@ -1746,6 +1979,9 @@
        if (!parse_options(data, &tmp, sbi, &mount_flags, &tmp, 1))
                return -EINVAL;
  
@@ -284,8 +299,8 @@ Index: linux-2.4.21-chaos/fs/ext3/super.c
  
 Index: linux-2.4.21-chaos/fs/ext3/inode.c
 ===================================================================
---- linux-2.4.21-chaos.orig/fs/ext3/inode.c    2003-12-12 16:18:40.000000000 +0300
-+++ linux-2.4.21-chaos/fs/ext3/inode.c 2003-12-12 16:18:43.000000000 +0300
+--- linux-2.4.21-chaos.orig/fs/ext3/inode.c    2004-01-12 19:20:06.000000000 +0300
++++ linux-2.4.21-chaos/fs/ext3/inode.c 2004-01-12 19:20:07.000000000 +0300
 @@ -2179,6 +2179,118 @@
        return;         /* AKPM: return what? */
  }
@@ -407,8 +422,8 @@ Index: linux-2.4.21-chaos/fs/ext3/inode.c
   * inode's underlying buffer_head on success. 
 Index: linux-2.4.21-chaos/fs/ext3/file.c
 ===================================================================
---- linux-2.4.21-chaos.orig/fs/ext3/file.c     2003-12-12 16:18:27.000000000 +0300
-+++ linux-2.4.21-chaos/fs/ext3/file.c  2003-12-12 16:18:43.000000000 +0300
+--- linux-2.4.21-chaos.orig/fs/ext3/file.c     2004-01-12 19:20:06.000000000 +0300
++++ linux-2.4.21-chaos/fs/ext3/file.c  2004-01-12 19:20:07.000000000 +0300
 @@ -132,7 +132,11 @@
  };
  
@@ -423,8 +438,8 @@ Index: linux-2.4.21-chaos/fs/ext3/file.c
        getxattr:       ext3_getxattr,          /* BKL held */
 Index: linux-2.4.21-chaos/include/linux/ext3_fs.h
 ===================================================================
---- linux-2.4.21-chaos.orig/include/linux/ext3_fs.h    2003-12-12 16:18:40.000000000 +0300
-+++ linux-2.4.21-chaos/include/linux/ext3_fs.h 2003-12-12 16:18:43.000000000 +0300
+--- linux-2.4.21-chaos.orig/include/linux/ext3_fs.h    2004-01-12 19:20:06.000000000 +0300
++++ linux-2.4.21-chaos/include/linux/ext3_fs.h 2004-01-12 19:20:07.000000000 +0300
 @@ -195,6 +195,7 @@
   */
  #define EXT3_STATE_JDATA              0x00000001 /* journaled data exists */
@@ -453,8 +468,8 @@ Index: linux-2.4.21-chaos/include/linux/ext3_fs.h
  extern int ext3_ioctl (struct inode *, struct file *, unsigned int,
 Index: linux-2.4.21-chaos/include/linux/ext3_fs_sb.h
 ===================================================================
---- linux-2.4.21-chaos.orig/include/linux/ext3_fs_sb.h 2003-12-12 16:18:41.000000000 +0300
-+++ linux-2.4.21-chaos/include/linux/ext3_fs_sb.h      2003-12-12 16:18:43.000000000 +0300
+--- linux-2.4.21-chaos.orig/include/linux/ext3_fs_sb.h 2004-01-12 19:20:07.000000000 +0300
++++ linux-2.4.21-chaos/include/linux/ext3_fs_sb.h      2004-01-12 20:53:51.000000000 +0300
 @@ -29,6 +29,8 @@
  
  #define EXT3_MAX_GROUP_LOADED 32
index ab8c168..6059aba 100644 (file)
@@ -5,11 +5,11 @@
  include/linux/ext3_fs_sb.h |   10 +
  5 files changed, 365 insertions(+)
 
-Index: linux-2.4.24-vanilla/fs/ext3/super.c
+Index: linux-2.4.24/fs/ext3/super.c
 ===================================================================
---- linux-2.4.24-vanilla.orig/fs/ext3/super.c  2004-01-10 17:49:10.000000000 +0300
-+++ linux-2.4.24-vanilla/fs/ext3/super.c       2004-01-11 23:13:34.000000000 +0300
-@@ -400,6 +400,127 @@
+--- linux-2.4.24.orig/fs/ext3/super.c  2004-01-12 20:36:31.000000000 +0300
++++ linux-2.4.24/fs/ext3/super.c       2004-01-13 16:27:43.000000000 +0300
+@@ -400,6 +400,128 @@
        }
  }
  
@@ -127,7 +127,8 @@ Index: linux-2.4.24-vanilla/fs/ext3/super.c
 +
 +      clear_opt(sbi->s_mount_opt, ASYNCDEL);
 +      wake_up(&sbi->s_delete_thread_queue);
-+      wait_event(sbi->s_delete_waiter_queue, sbi->s_delete_list.next == 0);
++      wait_event(sbi->s_delete_waiter_queue,
++                      sbi->s_delete_list.next == 0 && sbi->s_delete_inodes == 0);
 +}
 +#else
 +#define ext3_start_delete_thread(sbi) do {} while(0)
@@ -137,7 +138,15 @@ Index: linux-2.4.24-vanilla/fs/ext3/super.c
  void ext3_put_super (struct super_block * sb)
  {
        struct ext3_sb_info *sbi = EXT3_SB(sb);
-@@ -527,6 +648,13 @@
+@@ -407,6 +529,7 @@
+       kdev_t j_dev = sbi->s_journal->j_dev;
+       int i;
++      J_ASSERT(sbi->s_delete_inodes == 0);
+       ext3_xattr_put_super(sb);
+       journal_destroy(sbi->s_journal);
+       if (!(sb->s_flags & MS_RDONLY)) {
+@@ -527,6 +650,13 @@
                        clear_opt (*mount_options, XATTR_USER);
                else
  #endif
@@ -151,7 +160,7 @@ Index: linux-2.4.24-vanilla/fs/ext3/super.c
                if (!strcmp (this_char, "bsddf"))
                        clear_opt (*mount_options, MINIX_DF);
                else if (!strcmp (this_char, "nouid32")) {
-@@ -1227,6 +1355,7 @@
+@@ -1227,6 +1357,7 @@
        }
  
        ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
@@ -159,7 +168,7 @@ Index: linux-2.4.24-vanilla/fs/ext3/super.c
        /*
         * akpm: core read_super() calls in here with the superblock locked.
         * That deadlocks, because orphan cleanup needs to lock the superblock
-@@ -1618,7 +1747,12 @@
+@@ -1618,7 +1749,12 @@
  static int ext3_sync_fs(struct super_block *sb)
  {
        tid_t target;
@@ -173,7 +182,7 @@ Index: linux-2.4.24-vanilla/fs/ext3/super.c
        sb->s_dirt = 0;
        target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
        log_wait_commit(EXT3_SB(sb)->s_journal, target);
-@@ -1682,6 +1816,9 @@
+@@ -1682,6 +1818,9 @@
        if (!parse_options(data, &tmp, sbi, &tmp, 1))
                return -EINVAL;
  
@@ -183,10 +192,10 @@ Index: linux-2.4.24-vanilla/fs/ext3/super.c
        if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
                ext3_abort(sb, __FUNCTION__, "Abort forced by user");
  
-Index: linux-2.4.24-vanilla/fs/ext3/inode.c
+Index: linux-2.4.24/fs/ext3/inode.c
 ===================================================================
---- linux-2.4.24-vanilla.orig/fs/ext3/inode.c  2004-01-10 17:49:11.000000000 +0300
-+++ linux-2.4.24-vanilla/fs/ext3/inode.c       2004-01-11 23:12:44.000000000 +0300
+--- linux-2.4.24.orig/fs/ext3/inode.c  2004-01-12 20:36:31.000000000 +0300
++++ linux-2.4.24/fs/ext3/inode.c       2004-01-12 20:36:32.000000000 +0300
 @@ -2551,6 +2551,118 @@
        return err;
  }
@@ -306,10 +315,10 @@ Index: linux-2.4.24-vanilla/fs/ext3/inode.c
  /* 
   * On success, We end up with an outstanding reference count against
   * iloc->bh.  This _must_ be cleaned up later. 
-Index: linux-2.4.24-vanilla/fs/ext3/file.c
+Index: linux-2.4.24/fs/ext3/file.c
 ===================================================================
---- linux-2.4.24-vanilla.orig/fs/ext3/file.c   2004-01-10 17:49:10.000000000 +0300
-+++ linux-2.4.24-vanilla/fs/ext3/file.c        2004-01-11 23:08:54.000000000 +0300
+--- linux-2.4.24.orig/fs/ext3/file.c   2004-01-12 20:36:29.000000000 +0300
++++ linux-2.4.24/fs/ext3/file.c        2004-01-12 20:36:32.000000000 +0300
 @@ -126,7 +126,11 @@
  };
  
@@ -322,10 +331,10 @@ Index: linux-2.4.24-vanilla/fs/ext3/file.c
        setattr:        ext3_setattr,           /* BKL held */
        setxattr:       ext3_setxattr,          /* BKL held */
        getxattr:       ext3_getxattr,          /* BKL held */
-Index: linux-2.4.24-vanilla/fs/ext3/namei.c
+Index: linux-2.4.24/fs/ext3/namei.c
 ===================================================================
---- linux-2.4.24-vanilla.orig/fs/ext3/namei.c  2004-01-10 17:49:10.000000000 +0300
-+++ linux-2.4.24-vanilla/fs/ext3/namei.c       2004-01-11 23:08:54.000000000 +0300
+--- linux-2.4.24.orig/fs/ext3/namei.c  2004-01-12 20:36:31.000000000 +0300
++++ linux-2.4.24/fs/ext3/namei.c       2004-01-12 20:36:32.000000000 +0300
 @@ -1936,6 +1936,36 @@
        return retval;
  }
@@ -375,10 +384,10 @@ Index: linux-2.4.24-vanilla/fs/ext3/namei.c
        inode->i_ctime = dir->i_ctime;
        ext3_mark_inode_dirty(handle, inode);
        retval = 0;
-Index: linux-2.4.24-vanilla/include/linux/ext3_fs.h
+Index: linux-2.4.24/include/linux/ext3_fs.h
 ===================================================================
---- linux-2.4.24-vanilla.orig/include/linux/ext3_fs.h  2004-01-10 17:49:11.000000000 +0300
-+++ linux-2.4.24-vanilla/include/linux/ext3_fs.h       2004-01-11 23:08:54.000000000 +0300
+--- linux-2.4.24.orig/include/linux/ext3_fs.h  2004-01-12 20:36:31.000000000 +0300
++++ linux-2.4.24/include/linux/ext3_fs.h       2004-01-12 20:36:32.000000000 +0300
 @@ -193,6 +193,7 @@
   */
  #define EXT3_STATE_JDATA              0x00000001 /* journaled data exists */
@@ -405,10 +414,10 @@ Index: linux-2.4.24-vanilla/include/linux/ext3_fs.h
  extern void ext3_set_inode_flags(struct inode *);
  
  /* ioctl.c */
-Index: linux-2.4.24-vanilla/include/linux/ext3_fs_sb.h
+Index: linux-2.4.24/include/linux/ext3_fs_sb.h
 ===================================================================
---- linux-2.4.24-vanilla.orig/include/linux/ext3_fs_sb.h       2004-01-10 17:49:10.000000000 +0300
-+++ linux-2.4.24-vanilla/include/linux/ext3_fs_sb.h    2004-01-11 23:08:54.000000000 +0300
+--- linux-2.4.24.orig/include/linux/ext3_fs_sb.h       2004-01-12 20:36:31.000000000 +0300
++++ linux-2.4.24/include/linux/ext3_fs_sb.h    2004-01-12 20:36:32.000000000 +0300
 @@ -29,6 +29,8 @@
  
  #define EXT3_MAX_GROUP_LOADED 8
index 083e028..f3d7f3c 100644 (file)
@@ -7,9 +7,9 @@
 
 Index: linux-2.4.21-suse/fs/ext3/super.c
 ===================================================================
---- linux-2.4.21-suse.orig/fs/ext3/super.c     2003-10-30 02:03:04.000000000 +0300
-+++ linux-2.4.21-suse/fs/ext3/super.c  2003-10-30 02:05:38.000000000 +0300
-@@ -400,6 +400,220 @@
+--- linux-2.4.21-suse.orig/fs/ext3/super.c     2004-01-12 19:49:25.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/super.c  2004-01-13 17:39:59.000000000 +0300
+@@ -400,6 +400,221 @@
        }
  }
  
@@ -123,7 +123,8 @@ Index: linux-2.4.21-suse/fs/ext3/super.c
 +
 +      clear_opt(sbi->s_mount_opt, ASYNCDEL);
 +      wake_up(&sbi->s_delete_thread_queue);
-+      wait_event(sbi->s_delete_waiter_queue, list_empty(&sbi->s_delete_list));
++      wait_event(sbi->s_delete_waiter_queue,
++                      sbi->s_delete_list.next == 0 && sbi->s_delete_inodes == 0);
 +}
 +
 +/* Instead of playing games with the inode flags, destruction, etc we just
@@ -230,15 +231,15 @@ Index: linux-2.4.21-suse/fs/ext3/super.c
  void ext3_put_super (struct super_block * sb)
  {
        struct ext3_sb_info *sbi = EXT3_SB(sb);
-@@ -407,6 +621,7 @@
+@@ -407,6 +622,7 @@
        kdev_t j_dev = sbi->s_journal->j_dev;
        int i;
  
-+      ext3_stop_delete_thread(sbi);
++      J_ASSERT(sbi->s_delete_inodes == 0);
        ext3_xattr_put_super(sb);
        journal_destroy(sbi->s_journal);
        if (!(sb->s_flags & MS_RDONLY)) {
-@@ -455,7 +670,11 @@
+@@ -455,7 +671,11 @@
        write_inode:    ext3_write_inode,       /* BKL not held.  Don't need */
        dirty_inode:    ext3_dirty_inode,       /* BKL not held.  We take it */
        put_inode:      ext3_put_inode,         /* BKL not held.  Don't need */
@@ -250,7 +251,7 @@ Index: linux-2.4.21-suse/fs/ext3/super.c
        put_super:      ext3_put_super,         /* BKL held */
        write_super:    ext3_write_super,       /* BKL held */
        sync_fs:        ext3_sync_fs,
-@@ -524,6 +743,13 @@
+@@ -524,6 +744,13 @@
                        clear_opt (*mount_options, XATTR_USER);
                else
  #endif
@@ -264,7 +265,7 @@ Index: linux-2.4.21-suse/fs/ext3/super.c
                if (!strcmp (this_char, "bsddf"))
                        clear_opt (*mount_options, MINIX_DF);
                else if (!strcmp (this_char, "nouid32")) {
-@@ -1223,6 +1449,7 @@
+@@ -1223,6 +1450,7 @@
        }
  
        ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
@@ -272,7 +273,21 @@ Index: linux-2.4.21-suse/fs/ext3/super.c
        /*
         * akpm: core read_super() calls in here with the superblock locked.
         * That deadlocks, because orphan cleanup needs to lock the superblock
-@@ -1678,6 +1905,9 @@
+@@ -1614,7 +1842,12 @@
+ static int ext3_sync_fs(struct super_block *sb)
+ {
+       tid_t target;
+-      
++
++      if (atomic_read(&sb->s_active) == 0) {
++              /* fs is being umounted: time to stop delete thread */
++              ext3_stop_delete_thread(EXT3_SB(sb));
++      }
++
+       sb->s_dirt = 0;
+       target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
+       log_wait_commit(EXT3_SB(sb)->s_journal, target);
+@@ -1678,6 +1911,9 @@
        if (!parse_options(data, &tmp, sbi, &tmp, 1))
                return -EINVAL;
  
@@ -284,8 +299,8 @@ Index: linux-2.4.21-suse/fs/ext3/super.c
  
 Index: linux-2.4.21-suse/fs/ext3/inode.c
 ===================================================================
---- linux-2.4.21-suse.orig/fs/ext3/inode.c     2003-10-30 02:03:57.000000000 +0300
-+++ linux-2.4.21-suse/fs/ext3/inode.c  2003-10-30 02:05:38.000000000 +0300
+--- linux-2.4.21-suse.orig/fs/ext3/inode.c     2004-01-13 17:38:09.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/inode.c  2004-01-13 17:38:10.000000000 +0300
 @@ -2552,6 +2552,118 @@
        return err;
  }
@@ -407,8 +422,8 @@ Index: linux-2.4.21-suse/fs/ext3/inode.c
   * iloc->bh.  This _must_ be cleaned up later. 
 Index: linux-2.4.21-suse/fs/ext3/file.c
 ===================================================================
---- linux-2.4.21-suse.orig/fs/ext3/file.c      2003-10-30 01:40:33.000000000 +0300
-+++ linux-2.4.21-suse/fs/ext3/file.c   2003-10-30 02:05:38.000000000 +0300
+--- linux-2.4.21-suse.orig/fs/ext3/file.c      2004-01-12 19:49:25.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/file.c   2004-01-13 17:38:10.000000000 +0300
 @@ -125,7 +125,11 @@
  };
  
@@ -423,8 +438,8 @@ Index: linux-2.4.21-suse/fs/ext3/file.c
        getxattr:       ext3_getxattr,          /* BKL held */
 Index: linux-2.4.21-suse/include/linux/ext3_fs.h
 ===================================================================
---- linux-2.4.21-suse.orig/include/linux/ext3_fs.h     2003-10-30 02:03:57.000000000 +0300
-+++ linux-2.4.21-suse/include/linux/ext3_fs.h  2003-10-30 02:06:05.000000000 +0300
+--- linux-2.4.21-suse.orig/include/linux/ext3_fs.h     2004-01-13 17:38:09.000000000 +0300
++++ linux-2.4.21-suse/include/linux/ext3_fs.h  2004-01-13 17:38:10.000000000 +0300
 @@ -193,6 +193,7 @@
   */
  #define EXT3_STATE_JDATA              0x00000001 /* journaled data exists */
@@ -453,8 +468,8 @@ Index: linux-2.4.21-suse/include/linux/ext3_fs.h
  /* ioctl.c */
 Index: linux-2.4.21-suse/include/linux/ext3_fs_sb.h
 ===================================================================
---- linux-2.4.21-suse.orig/include/linux/ext3_fs_sb.h  2003-10-30 02:03:04.000000000 +0300
-+++ linux-2.4.21-suse/include/linux/ext3_fs_sb.h       2003-10-30 02:05:38.000000000 +0300
+--- linux-2.4.21-suse.orig/include/linux/ext3_fs_sb.h  2004-01-12 19:49:25.000000000 +0300
++++ linux-2.4.21-suse/include/linux/ext3_fs_sb.h       2004-01-13 17:38:10.000000000 +0300
 @@ -29,6 +29,8 @@
  
  #define EXT3_MAX_GROUP_LOADED 8
index c020054..a88b30d 100644 (file)
@@ -8,8 +8,10 @@
  include/linux/ext3_fs_sb.h |   10 
  8 files changed, 1684 insertions(+), 8 deletions(-)
 
---- /dev/null  2003-01-30 13:24:37.000000000 +0300
-+++ linux-2.4.18-chaos-alexey/fs/ext3/extents.c        2003-09-23 18:08:59.000000000 +0400
+Index: linux-2.4.18-chaos/fs/ext3/extents.c
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/extents.c  2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.18-chaos/fs/ext3/extents.c       2004-01-13 16:11:00.000000000 +0300
 @@ -0,0 +1,1614 @@
 +/*
 + *
 +                              sbi->s_ext_sum / sbi->s_ext_count,
 +                              sbi->s_ext_blocks / sbi->s_ext_extents);
 +}
-+
---- linux-2.4.18-chaos/fs/ext3/ialloc.c~ext3-extents-2.4.18-chaos      2003-09-19 22:07:14.000000000 +0400
-+++ linux-2.4.18-chaos-alexey/fs/ext3/ialloc.c 2003-09-20 00:18:43.000000000 +0400
-@@ -573,6 +573,10 @@ repeat:
+Index: linux-2.4.18-chaos/fs/ext3/ialloc.c
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/ialloc.c   2004-01-13 16:10:23.000000000 +0300
++++ linux-2.4.18-chaos/fs/ext3/ialloc.c        2004-01-13 16:11:00.000000000 +0300
+@@ -573,6 +573,10 @@
        ei->i_prealloc_count = 0;
  #endif
        ei->i_block_group = i;
  
        if (ei->i_flags & EXT3_SYNC_FL)
                inode->i_flags |= S_SYNC;
---- linux-2.4.18-chaos/fs/ext3/inode.c~ext3-extents-2.4.18-chaos       2003-09-19 22:07:14.000000000 +0400
-+++ linux-2.4.18-chaos-alexey/fs/ext3/inode.c  2003-09-22 15:40:30.000000000 +0400
-@@ -842,6 +842,15 @@ changed:
+Index: linux-2.4.18-chaos/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/inode.c    2004-01-13 16:10:23.000000000 +0300
++++ linux-2.4.18-chaos/fs/ext3/inode.c 2004-01-13 16:11:00.000000000 +0300
+@@ -842,6 +842,15 @@
        goto reread;
  }
  
  /*
   * The BKL is not held on entry here.
   */
-@@ -855,7 +864,7 @@ static int ext3_get_block(struct inode *
+@@ -855,7 +864,7 @@
                handle = ext3_journal_current_handle();
                J_ASSERT(handle != 0);
        }
                                bh_result, create, 1);
        return ret;
  }
-@@ -882,7 +891,7 @@ ext3_direct_io_get_block(struct inode *i
+@@ -882,7 +891,7 @@
                }
        }
        if (ret == 0)
                                        bh_result, create, 0);
        if (ret == 0)
                bh_result->b_size = (1 << inode->i_blkbits);
-@@ -904,7 +913,7 @@ struct buffer_head *ext3_getblk(handle_t
+@@ -904,7 +913,7 @@
        dummy.b_state = 0;
        dummy.b_blocknr = -1000;
        buffer_trace_init(&dummy.b_history);
        if (!*errp && buffer_mapped(&dummy)) {
                struct buffer_head *bh;
                bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
-@@ -1520,7 +1529,7 @@ ext3_block_truncate_page_prepare(struct 
+@@ -1520,7 +1529,7 @@
   * This required during truncate. We need to physically zero the tail end
   * of that block so it doesn't yield old data if the file is later grown.
   */
                                    struct address_space *mapping, loff_t from,
                                    struct page *page, unsigned blocksize)
  {
-@@ -1998,6 +2007,9 @@ void ext3_truncate(struct inode * inode)
+@@ -1998,6 +2007,9 @@
  
        ext3_discard_prealloc(inode);
  
        blocksize = inode->i_sb->s_blocksize;
        last_block = (inode->i_size + blocksize-1)
                                        >> EXT3_BLOCK_SIZE_BITS(inode->i_sb);
-@@ -2436,6 +2448,8 @@ void ext3_read_inode(struct inode * inod
+@@ -2436,6 +2448,8 @@
        ei->i_prealloc_count = 0;
  #endif
        ei->i_block_group = iloc.block_group;
  
        /*
         * NOTE! The in-memory inode i_data array is in little-endian order
-@@ -2556,6 +2570,7 @@ static int ext3_do_update_inode(handle_t
+@@ -2556,6 +2570,7 @@
                raw_inode->i_fsize = 0;
        }
  #endif
        raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl);
        if (!S_ISREG(inode->i_mode)) {
                raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl);
-@@ -2759,6 +2774,9 @@ int ext3_writepage_trans_blocks(struct i
+@@ -2759,6 +2774,9 @@
        int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3;
        int ret;
        
        if (ext3_should_journal_data(inode))
                ret = 3 * (bpp + indirects) + 2;
        else
-@@ -3082,7 +3100,7 @@ int ext3_prep_san_write(struct inode *in
+@@ -3082,7 +3100,7 @@
  
        /* alloc blocks one by one */
        for (i = 0; i < nblocks; i++) {
                                                &bh_tmp, 1, 1);
                if (ret)
                        break;
-@@ -3143,7 +3161,7 @@ int ext3_map_inode_page(struct inode *in
+@@ -3158,7 +3176,7 @@
                  if (blocks[i] != 0)
                          continue;
  
                  if (rc) {
                          printk(KERN_INFO "ext3_map_inode_page: error %d "
                                 "allocating block %ld\n", rc, iblock);
---- linux-2.4.18-chaos/fs/ext3/Makefile~ext3-extents-2.4.18-chaos      2003-09-19 22:07:14.000000000 +0400
-+++ linux-2.4.18-chaos-alexey/fs/ext3/Makefile 2003-09-20 00:18:43.000000000 +0400
-@@ -12,7 +12,8 @@ O_TARGET := ext3.o
+Index: linux-2.4.18-chaos/fs/ext3/Makefile
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/Makefile   2004-01-13 16:10:23.000000000 +0300
++++ linux-2.4.18-chaos/fs/ext3/Makefile        2004-01-13 16:11:00.000000000 +0300
+@@ -12,7 +12,8 @@
  export-objs :=        ext3-exports.o
  
  obj-y    := balloc.o iopen.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
  obj-m    := $(O_TARGET)
  
  include $(TOPDIR)/Rules.make
---- linux-2.4.18-chaos/fs/ext3/super.c~ext3-extents-2.4.18-chaos       2003-09-19 22:07:15.000000000 +0400
-+++ linux-2.4.18-chaos-alexey/fs/ext3/super.c  2003-09-20 00:18:43.000000000 +0400
-@@ -619,6 +619,7 @@ void ext3_put_super (struct super_block 
-       kdev_t j_dev = sbi->s_journal->j_dev;
-       int i;
+Index: linux-2.4.18-chaos/fs/ext3/super.c
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/super.c    2004-01-13 16:10:23.000000000 +0300
++++ linux-2.4.18-chaos/fs/ext3/super.c 2004-01-13 16:11:23.000000000 +0300
+@@ -622,6 +622,7 @@
+       J_ASSERT(sbi->s_delete_inodes == 0);
  
 +      ext3_ext_release(sb);
-       ext3_stop_delete_thread(sbi);
        ext3_xattr_put_super(sb);
        journal_destroy(sbi->s_journal);
-@@ -741,6 +742,12 @@ static int parse_options (char * options
+       if (!(sb->s_flags & MS_RDONLY)) {
+@@ -743,6 +744,12 @@
                else
  #endif
  
                if (!strcmp (this_char, "bsddf"))
                        clear_opt (*mount_options, MINIX_DF);
                else if (!strcmp (this_char, "nouid32")) {
-@@ -1468,6 +1475,7 @@ struct super_block * ext3_read_super (st
+@@ -1470,6 +1477,7 @@
                test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal":
                test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
                "writeback");
  
        return sb;
  
---- linux-2.4.18-chaos/include/linux/ext3_fs.h~ext3-extents-2.4.18-chaos       2003-09-19 22:07:14.000000000 +0400
-+++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs.h  2003-09-20 00:18:43.000000000 +0400
-@@ -183,6 +183,7 @@ struct ext3_group_desc
+Index: linux-2.4.18-chaos/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.18-chaos.orig/include/linux/ext3_fs.h    2004-01-13 16:10:23.000000000 +0300
++++ linux-2.4.18-chaos/include/linux/ext3_fs.h 2004-01-13 16:11:00.000000000 +0300
+@@ -183,6 +183,7 @@
  #define EXT3_IMAGIC_FL                        0x00002000 /* AFS directory */
  #define EXT3_JOURNAL_DATA_FL          0x00004000 /* file data should be journaled */
  #define EXT3_RESERVED_FL              0x80000000 /* reserved for ext3 lib */
  
  #define EXT3_FL_USER_VISIBLE          0x00005FFF /* User visible flags */
  #define EXT3_FL_USER_MODIFIABLE               0x000000FF /* User modifiable flags */
-@@ -243,7 +244,7 @@ struct ext3_inode {
+@@ -243,7 +244,7 @@
                struct {
                        __u8    l_i_frag;       /* Fragment number */
                        __u8    l_i_fsize;      /* Fragment size */
                        __u16   l_i_uid_high;   /* these 2 fields    */
                        __u16   l_i_gid_high;   /* were reserved2[0] */
                        __u32   l_i_reserved2;
-@@ -324,6 +325,8 @@ struct ext3_inode {
+@@ -324,6 +325,8 @@
  #define EXT3_MOUNT_IOPEN              0x8000  /* Allow access via iopen */
  #define EXT3_MOUNT_IOPEN_NOPRIV               0x10000 /* Make iopen world-readable */
  #define EXT3_MOUNT_ASYNCDEL           0x20000 /* Delayed deletion */
  
  /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
  #ifndef _LINUX_EXT2_FS_H
-@@ -663,6 +666,12 @@ extern void ext3_discard_prealloc (struc
+@@ -663,6 +666,12 @@
  extern void ext3_dirty_inode(struct inode *);
  extern int ext3_change_inode_journal_flag(struct inode *, int);
  extern void ext3_truncate (struct inode *);
  #ifdef EXT3_DELETE_THREAD
  extern void ext3_truncate_thread(struct inode *inode);
  #endif
-@@ -722,6 +731,13 @@ extern struct inode_operations ext3_dir_
+@@ -722,6 +731,13 @@
  /* symlink.c */
  extern struct inode_operations ext3_fast_symlink_inode_operations;
  
  
  #endif        /* __KERNEL__ */
  
---- linux-2.4.18-chaos/include/linux/ext3_fs_i.h~ext3-extents-2.4.18-chaos     2001-11-22 22:46:19.000000000 +0300
-+++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs_i.h        2003-09-20 00:18:43.000000000 +0400
-@@ -73,6 +73,10 @@ struct ext3_inode_info {
+Index: linux-2.4.18-chaos/include/linux/ext3_fs_i.h
+===================================================================
+--- linux-2.4.18-chaos.orig/include/linux/ext3_fs_i.h  2001-11-22 22:46:19.000000000 +0300
++++ linux-2.4.18-chaos/include/linux/ext3_fs_i.h       2004-01-13 16:11:00.000000000 +0300
+@@ -73,6 +73,10 @@
         * by other means, so we have truncate_sem.
         */
        struct rw_semaphore truncate_sem;
  };
  
  #endif        /* _LINUX_EXT3_FS_I */
---- linux-2.4.18-chaos/include/linux/ext3_fs_sb.h~ext3-extents-2.4.18-chaos    2003-09-19 22:07:13.000000000 +0400
-+++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs_sb.h       2003-09-20 00:18:43.000000000 +0400
-@@ -84,6 +84,16 @@ struct ext3_sb_info {
+Index: linux-2.4.18-chaos/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.18-chaos.orig/include/linux/ext3_fs_sb.h 2004-01-13 16:10:21.000000000 +0300
++++ linux-2.4.18-chaos/include/linux/ext3_fs_sb.h      2004-01-13 16:11:00.000000000 +0300
+@@ -84,6 +84,16 @@
        wait_queue_head_t s_delete_thread_queue;
        wait_queue_head_t s_delete_waiter_queue;
  #endif
  };
  
  #endif        /* _LINUX_EXT3_FS_SB */
-
-_
index ad873a9..414d60d 100644 (file)
@@ -5,9 +5,11 @@
  include/linux/ext3_fs_sb.h |   10 +
  5 files changed, 365 insertions(+)
 
---- kernel-2.4.20-6chaos_18_7/fs/ext3/super.c~ext3_delete_thread_2.4.20_chaos  2003-07-12 15:35:26.000000000 -0600
-+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/super.c    2003-07-12 15:36:19.000000000 -0600
-@@ -400,6 +400,220 @@ static void dump_orphan_list(struct supe
+Index: linux-2.4.20-rh-20.9/fs/ext3/super.c
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/fs/ext3/super.c  2004-01-12 19:27:46.000000000 +0300
++++ linux-2.4.20-rh-20.9/fs/ext3/super.c       2004-01-13 17:20:31.000000000 +0300
+@@ -400,6 +400,221 @@
        }
  }
  
 +
 +      clear_opt(sbi->s_mount_opt, ASYNCDEL);
 +      wake_up(&sbi->s_delete_thread_queue);
-+      wait_event(sbi->s_delete_waiter_queue, list_empty(&sbi->s_delete_list));
++      wait_event(sbi->s_delete_waiter_queue,
++                      sbi->s_delete_list.next == 0 && sbi->s_delete_inodes == 0);
 +}
 +
 +/* Instead of playing games with the inode flags, destruction, etc we just
  void ext3_put_super (struct super_block * sb)
  {
        struct ext3_sb_info *sbi = EXT3_SB(sb);
-@@ -407,6 +621,7 @@ void ext3_put_super (struct super_block 
+@@ -407,6 +622,7 @@
        kdev_t j_dev = sbi->s_journal->j_dev;
        int i;
  
-+      ext3_stop_delete_thread(sbi);
++      J_ASSERT(sbi->s_delete_inodes == 0);
        ext3_xattr_put_super(sb);
        journal_destroy(sbi->s_journal);
        if (!(sb->s_flags & MS_RDONLY)) {
-@@ -455,7 +670,11 @@ static struct super_operations ext3_sops
+@@ -455,7 +671,11 @@
        write_inode:    ext3_write_inode,       /* BKL not held.  Don't need */
        dirty_inode:    ext3_dirty_inode,       /* BKL not held.  We take it */
        put_inode:      ext3_put_inode,         /* BKL not held.  Don't need */
        put_super:      ext3_put_super,         /* BKL held */
        write_super:    ext3_write_super,       /* BKL held */
        sync_fs:        ext3_sync_fs,
-@@ -524,6 +743,13 @@ static int parse_options (char * options
+@@ -524,6 +744,13 @@
                        clear_opt (*mount_options, XATTR_USER);
                else
  #endif
                if (!strcmp (this_char, "bsddf"))
                        clear_opt (*mount_options, MINIX_DF);
                else if (!strcmp (this_char, "nouid32")) {
-@@ -1223,6 +1449,7 @@ struct super_block * ext3_read_super (st
+@@ -1223,6 +1450,7 @@
        }
  
        ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
        /*
         * akpm: core read_super() calls in here with the superblock locked.
         * That deadlocks, because orphan cleanup needs to lock the superblock
-@@ -1678,6 +1905,9 @@ int ext3_remount (struct super_block * s
+@@ -1614,7 +1842,12 @@
+ static int ext3_sync_fs(struct super_block *sb)
+ {
+       tid_t target;
+-      
++
++      if (atomic_read(&sb->s_active) == 0) {
++              /* fs is being umounted: time to stop delete thread */
++              ext3_stop_delete_thread(EXT3_SB(sb));
++      }
++
+       sb->s_dirt = 0;
+       target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
+       log_wait_commit(EXT3_SB(sb)->s_journal, target);
+@@ -1678,6 +1911,9 @@
        if (!parse_options(data, &tmp, sbi, &tmp, 1))
                return -EINVAL;
  
        if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
                ext3_abort(sb, __FUNCTION__, "Abort forced by user");
  
---- kernel-2.4.20-6chaos_18_7/fs/ext3/inode.c~ext3_delete_thread_2.4.20_chaos  2003-07-12 15:34:44.000000000 -0600
-+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/inode.c    2003-07-12 15:36:19.000000000 -0600
-@@ -2017,6 +2017,122 @@ out_stop:
+Index: linux-2.4.20-rh-20.9/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/fs/ext3/inode.c  2004-01-12 19:27:46.000000000 +0300
++++ linux-2.4.20-rh-20.9/fs/ext3/inode.c       2004-01-13 17:15:48.000000000 +0300
+@@ -2017,6 +2017,122 @@
        ext3_journal_stop(handle, inode);
  }
  
  /* 
   * ext3_get_inode_loc returns with an extra refcount against the
   * inode's underlying buffer_head on success. 
---- kernel-2.4.20-6chaos_18_7/fs/ext3/file.c~ext3_delete_thread_2.4.20_chaos   2003-07-12 15:34:44.000000000 -0600
-+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/file.c     2003-07-12 15:36:19.000000000 -0600
-@@ -125,7 +125,11 @@ struct file_operations ext3_file_operati
+Index: linux-2.4.20-rh-20.9/fs/ext3/file.c
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/fs/ext3/file.c   2004-01-12 19:27:46.000000000 +0300
++++ linux-2.4.20-rh-20.9/fs/ext3/file.c        2004-01-13 17:15:48.000000000 +0300
+@@ -125,7 +125,11 @@
  };
  
  struct inode_operations ext3_file_inode_operations = {
        setattr:        ext3_setattr,           /* BKL held */
        setxattr:       ext3_setxattr,          /* BKL held */
        getxattr:       ext3_getxattr,          /* BKL held */
---- kernel-2.4.20-6chaos_18_7/include/linux/ext3_fs.h~ext3_delete_thread_2.4.20_chaos  2003-07-12 15:34:44.000000000 -0600
-+++ kernel-2.4.20-6chaos_18_7-braam/include/linux/ext3_fs.h    2003-07-12 15:37:13.000000000 -0600
-@@ -193,6 +193,7 @@ struct ext3_group_desc
+Index: linux-2.4.20-rh-20.9/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/include/linux/ext3_fs.h  2004-01-12 19:27:46.000000000 +0300
++++ linux-2.4.20-rh-20.9/include/linux/ext3_fs.h       2004-01-13 17:15:48.000000000 +0300
+@@ -193,6 +193,7 @@
   */
  #define EXT3_STATE_JDATA              0x00000001 /* journaled data exists */
  #define EXT3_STATE_NEW                        0x00000002 /* inode is newly created */
  
  /*
   * ioctl commands
-@@ -320,6 +321,7 @@ struct ext3_inode {
+@@ -320,6 +321,7 @@
  #define EXT3_MOUNT_UPDATE_JOURNAL     0x1000  /* Update the journal format */
  #define EXT3_MOUNT_NO_UID32           0x2000  /* Disable 32-bit UIDs */
  #define EXT3_MOUNT_XATTR_USER         0x4000  /* Extended user attributes */
  
  /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
  #ifndef _LINUX_EXT2_FS_H
-@@ -695,6 +697,9 @@ extern void ext3_discard_prealloc (struc
+@@ -695,6 +697,9 @@
  extern void ext3_dirty_inode(struct inode *);
  extern int ext3_change_inode_journal_flag(struct inode *, int);
  extern void ext3_truncate (struct inode *);
  extern void ext3_set_inode_flags(struct inode *);
  
  /* ioctl.c */
---- kernel-2.4.20-6chaos_18_7/include/linux/ext3_fs_sb.h~ext3_delete_thread_2.4.20_chaos       2003-07-12 15:35:26.000000000 -0600
-+++ kernel-2.4.20-6chaos_18_7-braam/include/linux/ext3_fs_sb.h 2003-07-12 15:36:19.000000000 -0600
+Index: linux-2.4.20-rh-20.9/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/include/linux/ext3_fs_sb.h       2004-01-12 19:27:46.000000000 +0300
++++ linux-2.4.20-rh-20.9/include/linux/ext3_fs_sb.h    2004-01-13 17:15:48.000000000 +0300
 @@ -29,6 +29,8 @@
  
  #define EXT3_MAX_GROUP_LOADED 32
  /*
   * third extended-fs super-block data in memory
   */
-@@ -76,6 +78,14 @@ struct ext3_sb_info {
+@@ -76,6 +78,14 @@
        struct timer_list turn_ro_timer;        /* For turning read-only (crash simulation) */
        wait_queue_head_t ro_wait_queue;        /* For people waiting for the fs to go read-only */
  #endif
  };
  
  #endif        /* _LINUX_EXT3_FS_SB */
-
-_
index 5bf9d1b..ec539c5 100644 (file)
@@ -10,7 +10,7 @@ linux-2.4.18ea-0.8.26.patch
 ext3-2.4-ino_t.patch
 ext3-2.4.18-ino_sb_macro.patch
 ext3-orphan_lock.patch
-ext3-delete_thread-2.4.18.patch
+ext3-delete_thread-2.4.18.patch 
 extN-misc-fixup.patch
 extN-noread.patch
 extN-wantedi.patch
@@ -24,7 +24,7 @@ jbd-commit-tricks.patch
 ext3-o_direct-1-2.4.18-chaos.patch
 ext3-no-write-super-chaos.patch
 add_page_private.patch
-ext3-extents-2.4.18-chaos.patch
+ext3-extents-2.4.18-chaos.patch 
 ext3-extents-oflag-2.4.18-chaos.patch
 ext3-raw-lookup.patch
 nfs_export_kernel-2.4.18.patch
index e0316fe..bcaa036 100644 (file)
@@ -17,7 +17,7 @@ ext3-largefile.patch
 ext3-truncate_blocks.patch
 ext3-use-after-free.patch
 ext3-orphan_lock.patch
-ext3-delete_thread-2.4.20.patch
+ext3-delete_thread-2.4.20-hp.patch 
 ext3-noread-2.4.20.patch
 extN-wantedi.patch
 ext3-san-2.4.20.patch
index 89717c3..9fb8c0f 100644 (file)
@@ -15,7 +15,7 @@ ext-2.4-patch-4.patch
 linux-2.4.20-xattr-0.8.54-chaos.patch
 ext3-2.4.20-fixes.patch
 ext3_orphan_lock-2.4.20-rh.patch
-ext3_delete_thread_2.4.20_chaos.patch
+ext3_delete_thread_2.4.20_chaos.patch 
 ext3-noread-2.4.20.patch
 extN-wantedi.patch
 ext3-san-2.4.20.patch
index 45ec358..2b01f1f 100644 (file)
@@ -28,3 +28,4 @@ ext3-trusted_ea-2.4.20.patch
 gfp_memalloc-2.4.22.patch
 ext3-xattr-ptr-arith-fix.patch
 procfs-ndynamic-2.4.patch
+kernel_text_address-2.4.18-chaos.patch
index 5796dfb..667ebf4 100644 (file)
@@ -25,7 +25,7 @@ ext3-unmount_sync.patch
 ext3-use-after-free.patch
 ext3-orphan_lock.patch
 ext3-noread-2.4.20.patch
-ext3-delete_thread-2.4.20.patch
+ext3-delete_thread-2.4.20.patch 
 extN-wantedi.patch
 ext3-san-2.4.20.patch
 ext3-map_inode_page.patch