From fdd49ed3f58aed89e12d9863540cc6ee659b4e07 Mon Sep 17 00:00:00 2001 From: pschwan Date: Thu, 12 Jun 2003 07:28:57 +0000 Subject: [PATCH] more extN cleanup --- lustre/extN/ext3-orphan_lock.diff | 79 ---------- lustre/extN/ext3-truncate_blocks.diff | 92 ------------ lustre/extN/extN-delete_thread.diff | 274 ---------------------------------- lustre/extN/extN.patch-2.5.63 | 42 ------ 4 files changed, 487 deletions(-) delete mode 100644 lustre/extN/ext3-orphan_lock.diff delete mode 100644 lustre/extN/ext3-truncate_blocks.diff delete mode 100644 lustre/extN/extN-delete_thread.diff delete mode 100644 lustre/extN/extN.patch-2.5.63 diff --git a/lustre/extN/ext3-orphan_lock.diff b/lustre/extN/ext3-orphan_lock.diff deleted file mode 100644 index d1e5c8d..0000000 --- a/lustre/extN/ext3-orphan_lock.diff +++ /dev/null @@ -1,79 +0,0 @@ ---- linux/fs/ext3/namei.c.orig Fri Mar 14 14:11:58 2003 -+++ linux/fs/ext3/namei.c Fri Mar 14 14:39:48 2003 -@@ -1406,8 +1409,8 @@ - struct super_block *sb = inode->i_sb; - struct ext3_iloc iloc; - int err = 0, rc; -- -- lock_super(sb); -+ -+ down(&EXT3_SB(sb)->s_orphan_lock); - if (!list_empty(&EXT3_I(inode)->i_orphan)) - goto out_unlock; - -@@ -1455,7 +1458,7 @@ - jbd_debug(4, "orphan inode %ld will point to %d\n", - inode->i_ino, NEXT_ORPHAN(inode)); - out_unlock: -- unlock_super(sb); -+ up(&EXT3_SB(sb)->s_orphan_lock); - ext3_std_error(inode->i_sb, err); - return err; - } -@@ -1468,20 +1471,19 @@ - { - struct list_head *prev; - struct ext3_inode_info *ei = EXT3_I(inode); -- struct ext3_sb_info *sbi; -+ struct ext3_sb_info *sbi = EXT3_SB(inode->i_sb); - unsigned long ino_next; - struct ext3_iloc iloc; - int err = 0; - -- lock_super(inode->i_sb); -+ down(&sbi->s_orphan_lock); - if (list_empty(&ei->i_orphan)) { -- unlock_super(inode->i_sb); -+ up(&sbi->s_orphan_lock); - return 0; - } - - ino_next = NEXT_ORPHAN(inode); - prev = ei->i_orphan.prev; -- sbi = EXT3_SB(inode->i_sb); - - jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino); - -@@ -1525,10 +1527,10 @@ - if (err) - goto out_brelse; - --out_err: -+out_err: - ext3_std_error(inode->i_sb, err); - out: -- unlock_super(inode->i_sb); -+ up(&sbi->s_orphan_lock); - return err; - - out_brelse: ---- linux/fs/ext3/super.c.orig Fri Mar 14 14:11:58 2003 -+++ linux/fs/ext3/super.c Fri Mar 14 14:36:00 2003 -@@ -1134,6 +1314,7 @@ - */ - sb->s_op = &ext3_sops; - INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ -+ sema_init(&sbi->s_orphan_lock, 1); - - sb->s_root = 0; - ---- linux/include/linux/ext3_fs_sb.h.orig Tue Feb 11 16:34:33 2003 -+++ linux/include/linux/ext3_fs_sb.h Fri Mar 14 14:30:11 2003 -@@ -67,6 +69,7 @@ - struct inode * s_journal_inode; - struct journal_s * s_journal; - struct list_head s_orphan; -+ struct semaphore s_orphan_lock; - unsigned long s_commit_interval; - struct block_device *journal_bdev; - #ifdef CONFIG_JBD_DEBUG diff --git a/lustre/extN/ext3-truncate_blocks.diff b/lustre/extN/ext3-truncate_blocks.diff deleted file mode 100644 index ce3928d..0000000 --- a/lustre/extN/ext3-truncate_blocks.diff +++ /dev/null @@ -1,92 +0,0 @@ ---- ./fs/ext3/inode.c.orig Wed Mar 12 02:44:06 2003 -+++ ./fs/ext3/inode.c Wed Mar 12 11:55:20 2003 -@@ -99,7 +99,35 @@ int ext3_forget(handle_t *handle, int is - return err; - } - --/* -+/* -+ * Work out how many blocks we need to progress with the next chunk of a -+ * truncate transaction. -+ */ -+ -+static unsigned long blocks_for_truncate(struct inode *inode) -+{ -+ unsigned long needed; -+ -+ needed = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9); -+ -+ /* Give ourselves just enough room to cope with inodes in which -+ * i_blocks is corrupt: we've seen disk corruptions in the past -+ * which resulted in random data in an inode which looked enough -+ * like a regular file for ext3 to try to delete it. Things -+ * will go a bit crazy if that happens, but at least we should -+ * try not to panic the whole kernel. */ -+ if (needed < 2) -+ needed = 2; -+ -+ /* But we need to bound the transaction so we don't overflow the -+ * journal. */ -+ if (needed > EXT3_MAX_TRANS_DATA) -+ needed = EXT3_MAX_TRANS_DATA; -+ -+ return EXT3_DATA_TRANS_BLOCKS + needed; -+} -+ -+/* - * Truncate transactions can be complex and absolutely huge. So we need to - * be able to restart the transaction at a conventient checkpoint to make - * sure we don't overflow the journal. -@@ -110,19 +138,14 @@ int ext3_forget(handle_t *handle, int is - * transaction in the top-level truncate loop. --sct - */ - --static handle_t *start_transaction(struct inode *inode) -+static handle_t *start_transaction(struct inode *inode) - { -- long needed; - handle_t *result; -- -- needed = inode->i_blocks; -- if (needed > EXT3_MAX_TRANS_DATA) -- needed = EXT3_MAX_TRANS_DATA; -- -- result = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS + needed); -+ -+ result = ext3_journal_start(inode, blocks_for_truncate(inode)); - if (!IS_ERR(result)) - return result; -- -+ - ext3_std_error(inode->i_sb, PTR_ERR(result)); - return result; - } -@@ -135,14 +158,9 @@ static handle_t *start_transaction(struc - */ - static int try_to_extend_transaction(handle_t *handle, struct inode *inode) - { -- long needed; -- - if (handle->h_buffer_credits > EXT3_RESERVE_TRANS_BLOCKS) - return 0; -- needed = inode->i_blocks; -- if (needed > EXT3_MAX_TRANS_DATA) -- needed = EXT3_MAX_TRANS_DATA; -- if (!ext3_journal_extend(handle, EXT3_RESERVE_TRANS_BLOCKS + needed)) -+ if (!ext3_journal_extend(handle, blocks_for_truncate(inode))) - return 0; - return 1; - } -@@ -154,11 +172,8 @@ static int try_to_extend_transaction(han - */ - static int ext3_journal_test_restart(handle_t *handle, struct inode *inode) - { -- long needed = inode->i_blocks; -- if (needed > EXT3_MAX_TRANS_DATA) -- needed = EXT3_MAX_TRANS_DATA; - jbd_debug(2, "restarting handle %p\n", handle); -- return ext3_journal_restart(handle, EXT3_DATA_TRANS_BLOCKS + needed); -+ return ext3_journal_restart(handle, blocks_for_truncate(inode)); - } - - /* diff --git a/lustre/extN/extN-delete_thread.diff b/lustre/extN/extN-delete_thread.diff deleted file mode 100644 index 6e278c8..0000000 --- a/lustre/extN/extN-delete_thread.diff +++ /dev/null @@ -1,274 +0,0 @@ ---- linux/include/linux/extN_fs.h.orig Fri Mar 14 18:09:02 2003 -+++ linux/include/linux/extN_fs.h Fri Mar 14 18:10:20 2003 -@@ -190,6 +192,7 @@ - */ - #define EXTN_STATE_JDATA 0x00000001 /* journaled data exists */ - #define EXTN_STATE_NEW 0x00000002 /* inode is newly created */ -+#define EXTN_STATE_DELETE 0x00000010 /* deferred delete inode */ - - /* - * ioctl commands ---- linux/include/linux/extN_fs_sb.h.orig Tue Feb 11 16:34:33 2003 -+++ linux/include/linux/extN_fs_sb.h Mon Mar 10 14:42:07 2003 -@@ -29,6 +29,8 @@ - - #define EXTN_MAX_GROUP_LOADED 32 - -+#define EXTN_DELETE_THREAD -+ - /* - * third extended-fs super-block data in memory - */ -@@ -73,6 +75,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 EXTN_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_EXTN_FS_SB */ ---- linux/fs/extN/super.c.orig Wed Mar 12 14:05:30 2003 -+++ linux/fs/extN/super.c Thu Mar 13 19:05:26 2003 -@@ -396,6 +396,207 @@ - } - } - -+#ifdef EXTN_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 extN_delete_thread(void *data) -+{ -+ struct super_block *sb = data; -+ struct extN_sb_info *sbi = EXTN_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, "kdelextN-%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); -+ printk(KERN_INFO "EXTN-fs: delete thread on %s started\n", -+ kdevname(sb->s_dev)); -+ -+ /* main loop */ -+ for (;;) { -+ sleep_on(&sbi->s_delete_thread_queue); -+ printk(KERN_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)) { -+ memset(&sbi->s_delete_list, 0, -+ sizeof(sbi->s_delete_list)); -+ spin_unlock(&sbi->s_delete_lock); -+ printk(KERN_DEBUG "extN 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); -+ printk(KERN_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) -+ printk(KERN_WARNING -+ "%lu blocks and %lu left 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 extN_start_delete_thread(struct super_block *sb) -+{ -+ struct extN_sb_info *sbi = EXTN_SB(sb); -+ int rc; -+ -+ spin_lock_init(&sbi->s_delete_lock); -+ memset(&sbi->s_delete_list, 0, sizeof(sbi->s_delete_list)); -+ init_waitqueue_head(&sbi->s_delete_thread_queue); -+ init_waitqueue_head(&sbi->s_delete_waiter_queue); -+ sbi->s_delete_blocks = 0; -+ sbi->s_delete_inodes = 0; -+ rc = kernel_thread(extN_delete_thread, sb, CLONE_VM | CLONE_FILES); -+ if (rc < 0) -+ printk(KERN_ERR "EXTN-fs: cannot start delete thread: rc %d\n", -+ rc); -+ else -+ wait_event(sbi->s_delete_waiter_queue, sbi->s_delete_list.next); -+} -+ -+static void extN_stop_delete_thread(struct extN_sb_info *sbi) -+{ -+ wake_up(&sbi->s_delete_thread_queue); -+ wait_event(sbi->s_delete_waiter_queue, list_empty(&sbi->s_delete_list)); -+} -+ -+/* Instead of playing games with the inode flags, destruction, etc we just -+ * duplicate the inode data 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 copy the whole thing. -+ * -+ * 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 -+ * truncate thread when we run out of space. -+ * -+ * One shouldn't consider this duplicate an "inode", as it isn't really -+ * visible to the VFS, but rather a data struct that holds truncate data. -+ * -+ * In 2.5 this can be done much more cleanly by just registering a "drop" -+ * method in the super_operations struct. -+ */ -+static void extN_delete_inode_thread(struct inode *old_inode) -+{ -+ struct extN_sb_info *sbi = EXTN_SB(old_inode->i_sb); -+ 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; -+ } -+ -+ /* We may want to delete the inode immediately and not defer it */ -+ if (IS_SYNC(old_inode) || blocks <= EXTN_NDIR_BLOCKS || -+ !sbi->s_delete_list.next) { -+ extN_delete_inode(old_inode); -+ return; -+ } -+ -+ if (EXTN_I(old_inode)->i_state & EXTN_STATE_DELETE) { -+ extN_debug("doing deferred inode %lu delete (%lu blocks)\n", -+ old_inode->i_ino, blocks); -+ extN_delete_inode(old_inode); -+ return; -+ } -+ -+ /* 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); -+ -+ EXTN_SB(old_inode->i_sb)->s_mount_state |= EXTN_ORPHAN_FS; -+ new_inode = iget(old_inode->i_sb, old_inode->i_ino); -+ EXTN_SB(old_inode->i_sb)->s_mount_state &= ~EXTN_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); -+ extN_debug(KERN_DEBUG "delete inode %lu directly (bad read)\n", -+ old_inode->i_ino); -+ extN_delete_inode(old_inode); -+ return; -+ } -+ J_ASSERT(new_inode != old_inode); -+ -+ J_ASSERT(!list_empty(&EXTN_I(old_inode)->i_orphan)); -+ /* 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 -+ * the same as the on-disk orphan list. -+ */ -+ EXTN_I(new_inode)->i_orphan = EXTN_I(old_inode)->i_orphan; -+ EXTN_I(new_inode)->i_orphan.next->prev = &EXTN_I(new_inode)->i_orphan; -+ EXTN_I(new_inode)->i_orphan.prev->next = &EXTN_I(new_inode)->i_orphan; -+ EXTN_I(new_inode)->i_state |= EXTN_STATE_DELETE; -+ up(&sbi->s_orphan_lock); -+ -+ clear_inode(old_inode); -+ -+ printk(KERN_DEBUG "delete inode %lu (%lu blocks) by thread\n", -+ new_inode->i_ino, blocks); -+ 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); -+ -+ wake_up(&sbi->s_delete_thread_queue); -+} -+#else -+#define extN_start_delete_thread(sbi) do {} while(0) -+#define extN_stop_delete_thread(sbi) do {} while(0) -+#endif /* EXTN_DELETE_THREAD */ -+ - void extN_put_super (struct super_block * sb) - { - struct extN_sb_info *sbi = EXTN_SB(sb); -@@ -403,6 +578,7 @@ - kdev_t j_dev = sbi->s_journal->j_dev; - int i; - -+ extN_stop_delete_thread(sbi); - extN_xattr_put_super(sb); - journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { -@@ -451,7 +627,11 @@ - write_inode: extN_write_inode, /* BKL not held. Don't need */ - dirty_inode: extN_dirty_inode, /* BKL not held. We take it */ - put_inode: extN_put_inode, /* BKL not held. Don't need */ -+#ifdef EXTN_DELETE_THREAD -+ delete_inode: extN_delete_inode_thread,/* BKL not held. We take it */ -+#else - delete_inode: extN_delete_inode, /* BKL not held. We take it */ -+#endif - put_super: extN_put_super, /* BKL held */ - write_super: extN_write_super, /* BKL held */ - write_super_lockfs: extN_write_super_lockfs, /* BKL not held. Take it */ -@@ -1205,6 +1385,7 @@ - } - - extN_setup_super (sb, es, sb->s_flags & MS_RDONLY); -+ extN_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 diff --git a/lustre/extN/extN.patch-2.5.63 b/lustre/extN/extN.patch-2.5.63 deleted file mode 100644 index e1bb363..0000000 --- a/lustre/extN/extN.patch-2.5.63 +++ /dev/null @@ -1,42 +0,0 @@ ---- fs/extN/xattr.c Wed Mar 5 23:09:55 2003 -+++ fs/extN/xattr.c Tue Mar 11 17:57:24 2003 -@@ -1181,3 +1181,7 @@ - ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, - &ext3_xattr_user_handler); - } -+ -+EXPORT_SYMBOL(extN_xattr_get); -+EXPORT_SYMBOL(extN_xattr_set); -+ ---- fs/extN/inode.c Wed Mar 5 23:09:55 2003 -+++ fs/extN/inode.c Tue Mar 11 18:24:42 2003 -@@ -1019,7 +1019,7 @@ - *err = -EIO; - return NULL; - } -- -+EXPORT_SYMBOL(extN_bread); - static int walk_page_buffers( handle_t *handle, - struct buffer_head *head, - unsigned from, ---- fs/extN/super.c Wed Mar 5 23:09:55 2003 -+++ fs/extN/super.c Tue Mar 11 18:28:01 2003 -@@ -1703,6 +1703,7 @@ - unlock_kernel(); - return ret; - } -+EXPORT_SYMBOL(extN_force_commit); - - /* - * Ext3 always journals updates to the superblock itself, so we don't ---- fs/extN/xattr.h Tue Mar 11 21:37:48 2003 -+++ fs/extN/xattr.h Tue Mar 11 21:18:12 2003 -@@ -5,7 +5,7 @@ - - (C) 2001 Andreas Gruenbacher, - */ -- -+#include - #include - #include - -- 1.8.3.1