Whamcloud - gitweb
This commit was manufactured by cvs2svn to create branch
authorcvs2svn <admin@example.com>
Wed, 7 May 2003 19:12:11 +0000 (19:12 +0000)
committercvs2svn <admin@example.com>
Wed, 7 May 2003 19:12:11 +0000 (19:12 +0000)
'unlabeled-1.1.4.3.6'.

276 files changed:
lustre/extN/ext3-2.4-ino_t.diff [deleted file]
lustre/extN/ext3-2.5-noread.diff [deleted file]
lustre/extN/ext3-largefile.diff [deleted file]
lustre/extN/ext3-orphan_lock.diff [deleted file]
lustre/extN/ext3-truncate_blocks.diff [deleted file]
lustre/extN/ext3-unmount_sync.diff [deleted file]
lustre/extN/ext3-use-after-free.diff [deleted file]
lustre/extN/extN-delete_thread.diff [deleted file]
lustre/extN/extN-san.diff [deleted file]
lustre/extN/extN.patch-2.5.63 [deleted file]
lustre/extN/patch-2.4.18-chaos22 [deleted file]
lustre/include/ioctl.h [deleted file]
lustre/include/liblustre.h [deleted file]
lustre/include/linux/.cvsignore [deleted file]
lustre/include/linux/lustre_handles.h [deleted file]
lustre/kernel_patches/README [deleted file]
lustre/kernel_patches/config/config-linux-2.4.20-uml [deleted file]
lustre/kernel_patches/config/uml.spec [deleted file]
lustre/kernel_patches/patches/dev_read_only.patch [deleted file]
lustre/kernel_patches/patches/dev_read_only_2.4.20.patch [deleted file]
lustre/kernel_patches/patches/dev_read_only_hp-2.4.19.patch [deleted file]
lustre/kernel_patches/patches/export-truncate.patch [deleted file]
lustre/kernel_patches/patches/exports.patch [deleted file]
lustre/kernel_patches/patches/exports_2.4.20.patch [deleted file]
lustre/kernel_patches/patches/exports_hp-2.4.19.patch [deleted file]
lustre/kernel_patches/patches/exports_hp_2.4.20.patch [deleted file]
lustre/kernel_patches/patches/ext-2.4-patch-1-chaos.patch [deleted file]
lustre/kernel_patches/patches/ext-2.4-patch-1-hp-2.4.19.patch [deleted file]
lustre/kernel_patches/patches/ext-2.4-patch-1.patch [deleted file]
lustre/kernel_patches/patches/ext-2.4-patch-2.patch [deleted file]
lustre/kernel_patches/patches/ext-2.4-patch-3.patch [deleted file]
lustre/kernel_patches/patches/ext-2.4-patch-4.patch [deleted file]
lustre/kernel_patches/patches/ext3-2.4-ino_t.patch [deleted file]
lustre/kernel_patches/patches/ext3-2.4.18-fixes.patch [deleted file]
lustre/kernel_patches/patches/ext3-2.4.18-ino_sb_macro.patch [deleted file]
lustre/kernel_patches/patches/ext3-2.4.20-fixes.patch [deleted file]
lustre/kernel_patches/patches/ext3-2.5-noread.patch [deleted file]
lustre/kernel_patches/patches/ext3-delete_thread-2.4.20.patch [deleted file]
lustre/kernel_patches/patches/ext3-largefile.patch [deleted file]
lustre/kernel_patches/patches/ext3-noread-2.4.20.patch [deleted file]
lustre/kernel_patches/patches/ext3-orphan_lock.patch [deleted file]
lustre/kernel_patches/patches/ext3-san-2.4.20-hp.patch [deleted file]
lustre/kernel_patches/patches/ext3-truncate_blocks-chaos.patch.patch [deleted file]
lustre/kernel_patches/patches/ext3-truncate_blocks.patch [deleted file]
lustre/kernel_patches/patches/ext3-unmount_sync.patch [deleted file]
lustre/kernel_patches/patches/ext3-use-after-free-hp-2.4.19.patch [deleted file]
lustre/kernel_patches/patches/ext3-use-after-free.patch [deleted file]
lustre/kernel_patches/patches/extN-2.4.18-ino_sb_fixup.patch [deleted file]
lustre/kernel_patches/patches/extN-delete_thread.patch [deleted file]
lustre/kernel_patches/patches/extN-iget-debug.patch [deleted file]
lustre/kernel_patches/patches/extN-misc-fixup.patch [deleted file]
lustre/kernel_patches/patches/extN-noread.patch [deleted file]
lustre/kernel_patches/patches/extN-san.patch [deleted file]
lustre/kernel_patches/patches/extN-wantedi.patch [deleted file]
lustre/kernel_patches/patches/htree-ext3-2.4.18.patch [deleted file]
lustre/kernel_patches/patches/invalidate_show.patch [deleted file]
lustre/kernel_patches/patches/iod-rmap-exports-2.4.20.patch [deleted file]
lustre/kernel_patches/patches/iod-rmap-exports.patch [deleted file]
lustre/kernel_patches/patches/iod-stock-24-exports.patch [deleted file]
lustre/kernel_patches/patches/iod-stock-24-exports_hp.patch [deleted file]
lustre/kernel_patches/patches/jbd-transno-cb.patch [deleted file]
lustre/kernel_patches/patches/kmem_cache_validate.patch [deleted file]
lustre/kernel_patches/patches/kmem_cache_validate_2.4.20-rh.patch [deleted file]
lustre/kernel_patches/patches/lin-2.5.44.patch [deleted file]
lustre/kernel_patches/patches/linux-2.4.18ea-0.8.26.patch [deleted file]
lustre/kernel_patches/patches/linux-2.4.19-xattr-0.8.54-hp.patch [deleted file]
lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-chaos.patch [deleted file]
lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-hp.patch [deleted file]
lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54.patch [deleted file]
lustre/kernel_patches/patches/lustre-2.5.63.patch [deleted file]
lustre/kernel_patches/patches/lustre_version.patch [deleted file]
lustre/kernel_patches/patches/tcp-zero-copy-2.4.18.patch [deleted file]
lustre/kernel_patches/patches/uml_check_get_page.patch [deleted file]
lustre/kernel_patches/patches/uml_compile_fixes.patch [deleted file]
lustre/kernel_patches/patches/uml_no_panic.patch [deleted file]
lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch [deleted file]
lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch [deleted file]
lustre/kernel_patches/patches/vfs_intent-2.4.20.patch [deleted file]
lustre/kernel_patches/patches/vfs_intent.patch [deleted file]
lustre/kernel_patches/patches/vfs_intent_hp_2.4.19.patch [deleted file]
lustre/kernel_patches/pc/dev_read_only.pc [deleted file]
lustre/kernel_patches/pc/dev_read_only_2.4.20.pc [deleted file]
lustre/kernel_patches/pc/dev_read_only_hp-2.4.19.pc [deleted file]
lustre/kernel_patches/pc/export-truncate.pc [deleted file]
lustre/kernel_patches/pc/exports.pc [deleted file]
lustre/kernel_patches/pc/exports_2.4.20.pc [deleted file]
lustre/kernel_patches/pc/exports_hp-2.4.19.pc [deleted file]
lustre/kernel_patches/pc/exports_hp_2.4.20.pc [deleted file]
lustre/kernel_patches/pc/ext-2.4-patch-1-chaos.pc [deleted file]
lustre/kernel_patches/pc/ext-2.4-patch-1-hp-2.4.19.pc [deleted file]
lustre/kernel_patches/pc/ext-2.4-patch-1.pc [deleted file]
lustre/kernel_patches/pc/ext-2.4-patch-2.pc [deleted file]
lustre/kernel_patches/pc/ext-2.4-patch-3.pc [deleted file]
lustre/kernel_patches/pc/ext-2.4-patch-4.pc [deleted file]
lustre/kernel_patches/pc/ext3-2.4-ino_t.pc [deleted file]
lustre/kernel_patches/pc/ext3-2.4.18-fixes.pc [deleted file]
lustre/kernel_patches/pc/ext3-2.4.18-ino_sb_macro.pc [deleted file]
lustre/kernel_patches/pc/ext3-2.4.20-fixes.pc [deleted file]
lustre/kernel_patches/pc/ext3-2.5-noread.pc [deleted file]
lustre/kernel_patches/pc/ext3-delete_thread-2.4.20.pc [deleted file]
lustre/kernel_patches/pc/ext3-largefile.pc [deleted file]
lustre/kernel_patches/pc/ext3-noread-2.4.20.pc [deleted file]
lustre/kernel_patches/pc/ext3-orphan_lock.pc [deleted file]
lustre/kernel_patches/pc/ext3-san-2.4.20-hp.pc [deleted file]
lustre/kernel_patches/pc/ext3-truncate_blocks-chaos.patch.pc [deleted file]
lustre/kernel_patches/pc/ext3-truncate_blocks.pc [deleted file]
lustre/kernel_patches/pc/ext3-unmount_sync.pc [deleted file]
lustre/kernel_patches/pc/ext3-use-after-free-hp-2.4.19.pc [deleted file]
lustre/kernel_patches/pc/ext3-use-after-free.pc [deleted file]
lustre/kernel_patches/pc/extN-2.4.18-ino_sb_fixup.pc [deleted file]
lustre/kernel_patches/pc/extN-delete_thread.pc [deleted file]
lustre/kernel_patches/pc/extN-iget-debug.pc [deleted file]
lustre/kernel_patches/pc/extN-misc-fixup.pc [deleted file]
lustre/kernel_patches/pc/extN-noread.pc [deleted file]
lustre/kernel_patches/pc/extN-san.pc [deleted file]
lustre/kernel_patches/pc/extN-wantedi.pc [deleted file]
lustre/kernel_patches/pc/htree-ext3-2.4.18.pc [deleted file]
lustre/kernel_patches/pc/iod-rmap-exports-2.4.20.pc [deleted file]
lustre/kernel_patches/pc/iod-rmap-exports.pc [deleted file]
lustre/kernel_patches/pc/iod-stock-24-exports.pc [deleted file]
lustre/kernel_patches/pc/iod-stock-24-exports_hp.pc [deleted file]
lustre/kernel_patches/pc/jbd-transno-cb.pc [deleted file]
lustre/kernel_patches/pc/kmem_cache_validate.pc [deleted file]
lustre/kernel_patches/pc/kmem_cache_validate_2.4.20-rh.pc [deleted file]
lustre/kernel_patches/pc/lin-2.5.44.pc [deleted file]
lustre/kernel_patches/pc/linux-2.4.18ea-0.8.26.pc [deleted file]
lustre/kernel_patches/pc/linux-2.4.19-xattr-0.8.54-hp.pc [deleted file]
lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-chaos.pc [deleted file]
lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-hp.pc [deleted file]
lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54.pc [deleted file]
lustre/kernel_patches/pc/lustre-2.5.63.pc [deleted file]
lustre/kernel_patches/pc/lustre-2.5.pc [deleted file]
lustre/kernel_patches/pc/lustre_version.pc [deleted file]
lustre/kernel_patches/pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc [deleted file]
lustre/kernel_patches/pc/uml-patch-2.4.20-3.pc [deleted file]
lustre/kernel_patches/pc/uml-patch-2.4.20-tmp.pc [deleted file]
lustre/kernel_patches/pc/uml_check_get_page.pc [deleted file]
lustre/kernel_patches/pc/uml_compile_fixes.pc [deleted file]
lustre/kernel_patches/pc/uml_no_panic.pc [deleted file]
lustre/kernel_patches/pc/vanilla-2.4.18.pc [deleted file]
lustre/kernel_patches/pc/vanilla-2.4.19.pc [deleted file]
lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc [deleted file]
lustre/kernel_patches/pc/vfs_intent-2.4.20-rh.pc [deleted file]
lustre/kernel_patches/pc/vfs_intent-2.4.20-vanilla.pc [deleted file]
lustre/kernel_patches/pc/vfs_intent-2.4.20.pc [deleted file]
lustre/kernel_patches/pc/vfs_intent.pc [deleted file]
lustre/kernel_patches/pc/vfs_intent_hp_2.4.19.pc [deleted file]
lustre/kernel_patches/prepare_tree.sh [deleted file]
lustre/kernel_patches/scripts/added-by-patch [deleted file]
lustre/kernel_patches/scripts/apatch [deleted file]
lustre/kernel_patches/scripts/cat-series [deleted file]
lustre/kernel_patches/scripts/combine-applied [deleted file]
lustre/kernel_patches/scripts/combine-series [deleted file]
lustre/kernel_patches/scripts/cvs-take-patch [deleted file]
lustre/kernel_patches/scripts/docco.txt [deleted file]
lustre/kernel_patches/scripts/export_patch [deleted file]
lustre/kernel_patches/scripts/extract_description [deleted file]
lustre/kernel_patches/scripts/forkpatch [deleted file]
lustre/kernel_patches/scripts/fpatch [deleted file]
lustre/kernel_patches/scripts/import_patch [deleted file]
lustre/kernel_patches/scripts/inpatch [deleted file]
lustre/kernel_patches/scripts/join-patch [deleted file]
lustre/kernel_patches/scripts/linus-patch [deleted file]
lustre/kernel_patches/scripts/mpatch [deleted file]
lustre/kernel_patches/scripts/new-kernel [deleted file]
lustre/kernel_patches/scripts/p0-2-p1 [deleted file]
lustre/kernel_patches/scripts/p_diff [deleted file]
lustre/kernel_patches/scripts/patchdesc [deleted file]
lustre/kernel_patches/scripts/patchfns [deleted file]
lustre/kernel_patches/scripts/pcpatch [deleted file]
lustre/kernel_patches/scripts/poppatch [deleted file]
lustre/kernel_patches/scripts/prep-patch [deleted file]
lustre/kernel_patches/scripts/pstatus [deleted file]
lustre/kernel_patches/scripts/ptkdiff [deleted file]
lustre/kernel_patches/scripts/pushpatch [deleted file]
lustre/kernel_patches/scripts/refpatch [deleted file]
lustre/kernel_patches/scripts/removed-by-patch [deleted file]
lustre/kernel_patches/scripts/rename-patch [deleted file]
lustre/kernel_patches/scripts/rolled-up-patch [deleted file]
lustre/kernel_patches/scripts/rpatch [deleted file]
lustre/kernel_patches/scripts/split-patch [deleted file]
lustre/kernel_patches/scripts/sum-series [deleted file]
lustre/kernel_patches/scripts/tag-series [deleted file]
lustre/kernel_patches/scripts/toppatch [deleted file]
lustre/kernel_patches/scripts/touched-by-patch [deleted file]
lustre/kernel_patches/scripts/trypatch [deleted file]
lustre/kernel_patches/scripts/unitdiff.py [deleted file]
lustre/kernel_patches/scripts/unused-patches [deleted file]
lustre/kernel_patches/series/chaos [deleted file]
lustre/kernel_patches/series/chaos-2.4.20 [deleted file]
lustre/kernel_patches/series/hp-pnnl [deleted file]
lustre/kernel_patches/series/hp-pnnl-2.4.20 [deleted file]
lustre/kernel_patches/series/hp-pnnl-2.4.20.orig [deleted file]
lustre/kernel_patches/series/lin-2.5.44 [deleted file]
lustre/kernel_patches/series/rh-2.4.18-18 [deleted file]
lustre/kernel_patches/series/rh-2.4.20 [deleted file]
lustre/kernel_patches/series/rh-8.0 [deleted file]
lustre/kernel_patches/series/vanilla-2.4.18 [deleted file]
lustre/kernel_patches/series/vanilla-2.4.19 [deleted file]
lustre/kernel_patches/series/vanilla-2.4.20 [deleted file]
lustre/kernel_patches/series/vanilla-2.5 [deleted file]
lustre/kernel_patches/series/vanilla-2.5.63 [deleted file]
lustre/kernel_patches/txt/dev_read_only.txt [deleted file]
lustre/kernel_patches/txt/exports.txt [deleted file]
lustre/kernel_patches/txt/ext3-2.4.20-fixes.txt [deleted file]
lustre/kernel_patches/txt/kmem_cache_validate.txt [deleted file]
lustre/kernel_patches/txt/lin-2.5.44.txt [deleted file]
lustre/kernel_patches/txt/lustre_version.txt [deleted file]
lustre/kernel_patches/txt/uml_check_get_page.txt [deleted file]
lustre/kernel_patches/txt/uml_compile_fixes.txt [deleted file]
lustre/kernel_patches/txt/uml_no_panic.txt [deleted file]
lustre/kernel_patches/txt/vfs_intent.txt [deleted file]
lustre/kernel_patches/which_patch [deleted file]
lustre/liblustre/.cvsignore [deleted file]
lustre/liblustre/Makefile.am [deleted file]
lustre/liblustre/file.c [deleted file]
lustre/liblustre/libtest.c [deleted file]
lustre/liblustre/llite_lib.c [deleted file]
lustre/liblustre/llite_lib.h [deleted file]
lustre/liblustre/lltest.c [deleted file]
lustre/liblustre/rw.c [deleted file]
lustre/liblustre/super.c [deleted file]
lustre/llite/iod.c [deleted file]
lustre/lov/lov_pack.c [deleted file]
lustre/mds/mds_internal.h [deleted file]
lustre/mds/mds_open.c [deleted file]
lustre/obdclass/lustre_handles.c [deleted file]
lustre/obdclass/lustre_peer.c [deleted file]
lustre/ptlrpc/Makefile.am [deleted file]
lustre/ptlrpc/client.c [deleted file]
lustre/ptlrpc/events.c [deleted file]
lustre/ptlrpc/lustre_peer.c [deleted file]
lustre/ptlrpc/niobuf.c [deleted file]
lustre/ptlrpc/pinger.c [deleted file]
lustre/ptlrpc/ptlrpc_internal.h [deleted file]
lustre/ptlrpc/ptlrpc_module.c [deleted file]
lustre/ptlrpc/service.c [deleted file]
lustre/scripts/llite-group.sh [deleted file]
lustre/scripts/nodelustre [deleted file]
lustre/scripts/version_tag.pl [deleted file]
lustre/tests/acceptance-metadata-double.sh [deleted file]
lustre/tests/acceptance-metadata-single.sh [deleted file]
lustre/tests/ba-echo.sh [deleted file]
lustre/tests/ba-mount.sh [deleted file]
lustre/tests/checkstack.pl [deleted file]
lustre/tests/compile.sh [deleted file]
lustre/tests/mkdirdeep.c [deleted file]
lustre/tests/mkdirmany.c [deleted file]
lustre/tests/mlink.c [deleted file]
lustre/tests/munlink.c [deleted file]
lustre/tests/open_delay.c [deleted file]
lustre/tests/opendevunlink.c [deleted file]
lustre/tests/opendirunlink.c [deleted file]
lustre/tests/openfile.c [deleted file]
lustre/tests/recovery-cleanup.sh [deleted file]
lustre/tests/recovery-small.sh [deleted file]
lustre/tests/rename.pl [deleted file]
lustre/tests/runas.c [deleted file]
lustre/tests/runslabinfo [deleted file]
lustre/tests/runvmstat [deleted file]
lustre/tests/sanity-ldlm.sh [deleted file]
lustre/tests/statone.c [deleted file]
lustre/tests/unlinkmany.c [deleted file]
lustre/tests/writeme.c [deleted file]
lustre/utils/Lustre/.cvsignore [deleted file]
lustre/utils/Lustre/Makefile.am [deleted file]
lustre/utils/Lustre/cmdline.py [deleted file]
lustre/utils/Lustre/error.py [deleted file]
lustre/utils/Lustre/lustredb.py [deleted file]
lustre/utils/lactive [deleted file]
lustre/utils/lfind.c [deleted file]
lustre/utils/llparser.pm [deleted file]
lustre/utils/load_ldap.sh [deleted file]
lustre/utils/lstripe.c [deleted file]
lustre/utils/obdio.c [deleted file]
lustre/utils/obdstat.c [deleted file]

diff --git a/lustre/extN/ext3-2.4-ino_t.diff b/lustre/extN/ext3-2.4-ino_t.diff
deleted file mode 100644 (file)
index ce1bd88..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
---- linux/fs/ext3/ialloc.c.orig        Sat Oct 19 11:42:23 2002
-+++ linux/fs/ext3/ialloc.c     Sat Jan  4 12:14:18 2003
-@@ -64,8 +64,8 @@ static int read_inode_bitmap (struct sup
-       if (!bh) {
-               ext3_error (sb, "read_inode_bitmap",
-                           "Cannot read inode bitmap - "
--                          "block_group = %lu, inode_bitmap = %lu",
--                          block_group, (unsigned long) gdp->bg_inode_bitmap);
-+                          "block_group = %lu, inode_bitmap = %u",
-+                          block_group, gdp->bg_inode_bitmap);
-               retval = -EIO;
-       }
-       /*
-@@ -531,19 +532,19 @@ out:
- }
- /* Verify that we are loading a valid orphan from disk */
--struct inode *ext3_orphan_get (struct super_block * sb, ino_t ino)
-+struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
- {
--      ino_t max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count);
-+      unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count);
-       unsigned long block_group;
-       int bit;
-       int bitmap_nr;
-       struct buffer_head *bh;
-       struct inode *inode = NULL;
--      
-+
-       /* Error cases - e2fsck has already cleaned up for us */
-       if (ino > max_ino) {
-               ext3_warning(sb, __FUNCTION__,
--                           "bad orphan ino %ld!  e2fsck was run?\n", ino);
-+                           "bad orphan ino %lu!  e2fsck was run?\n", ino);
-               return NULL;
-       }
-@@ -552,7 +553,7 @@ struct inode *ext3_orphan_get (struct su
-       if ((bitmap_nr = load_inode_bitmap(sb, block_group)) < 0 ||
-           !(bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr])) {
-               ext3_warning(sb, __FUNCTION__,
--                           "inode bitmap error for orphan %ld\n", ino);
-+                           "inode bitmap error for orphan %lu\n", ino);
-               return NULL;
-       }
-@@ -563,7 +564,7 @@ struct inode *ext3_orphan_get (struct su
-       if (!ext3_test_bit(bit, bh->b_data) || !(inode = iget(sb, ino)) ||
-           is_bad_inode(inode) || NEXT_ORPHAN(inode) > max_ino) {
-               ext3_warning(sb, __FUNCTION__,
--                           "bad orphan inode %ld!  e2fsck was run?\n", ino);
-+                           "bad orphan inode %lu!  e2fsck was run?\n", ino);
-               printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%ld) = %d\n",
-                      bit, bh->b_blocknr, ext3_test_bit(bit, bh->b_data));
-               printk(KERN_NOTICE "inode=%p\n", inode);
-@@ -570,9 +571,9 @@ struct inode *ext3_orphan_get (struct su
-               if (inode) {
-                       printk(KERN_NOTICE "is_bad_inode(inode)=%d\n",
-                              is_bad_inode(inode));
--                      printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%d\n",
-+                      printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n",
-                              NEXT_ORPHAN(inode));
--                      printk(KERN_NOTICE "max_ino=%ld\n", max_ino);
-+                      printk(KERN_NOTICE "max_ino=%lu\n", max_ino);
-               }
-               /* Avoid freeing blocks if we got a bad deleted inode */
-               if (inode && inode->i_nlink == 0)
---- linux/fs/ext3/namei.c.orig Sat Oct 19 11:42:45 2002
-+++ linux/fs/ext3/namei.c      Sat Jan  4 12:13:27 2003
-@@ -716,10 +716,10 @@ int ext3_orphan_del(handle_t *handle, st
- {
-       struct list_head *prev;
-       struct ext3_sb_info *sbi;
--      ino_t ino_next; 
-+      unsigned long ino_next;
-       struct ext3_iloc iloc;
-       int err = 0;
--      
-+
-       lock_super(inode->i_sb);
-       if (list_empty(&inode->u.ext3_i.i_orphan)) {
-               unlock_super(inode->i_sb);
-@@ -730,7 +730,7 @@ int ext3_orphan_del(handle_t *handle, st
-       prev = inode->u.ext3_i.i_orphan.prev;
-       sbi = EXT3_SB(inode->i_sb);
--      jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino);
-+      jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
-       list_del(&inode->u.ext3_i.i_orphan);
-       INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
-@@ -741,13 +741,13 @@ int ext3_orphan_del(handle_t *handle, st
-        * list in memory. */
-       if (!handle)
-               goto out;
--      
-+
-       err = ext3_reserve_inode_write(handle, inode, &iloc);
-       if (err)
-               goto out_err;
-       if (prev == &sbi->s_orphan) {
--              jbd_debug(4, "superblock will point to %ld\n", ino_next);
-+              jbd_debug(4, "superblock will point to %lu\n", ino_next);
-               BUFFER_TRACE(sbi->s_sbh, "get_write_access");
-               err = ext3_journal_get_write_access(handle, sbi->s_sbh);
-               if (err)
-@@ -758,8 +758,8 @@ int ext3_orphan_del(handle_t *handle, st
-               struct ext3_iloc iloc2;
-               struct inode *i_prev =
-                       list_entry(prev, struct inode, u.ext3_i.i_orphan);
--              
--              jbd_debug(4, "orphan inode %ld will point to %ld\n",
-+
-+              jbd_debug(4, "orphan inode %lu will point to %lu\n",
-                         i_prev->i_ino, ino_next);
-               err = ext3_reserve_inode_write(handle, i_prev, &iloc2);
-               if (err)
-@@ -774,7 +774,7 @@ int ext3_orphan_del(handle_t *handle, st
-       if (err)
-               goto out_brelse;
--out_err:      
-+out_err: 
-       ext3_std_error(inode->i_sb, err);
- out:
-       unlock_super(inode->i_sb);
---- linux/include/linux/ext3_fs.h.orig Thu Jan  2 16:10:24 2003
-+++ linux/include/linux/ext3_fs.h      Sat Jan  4 12:25:41 2003
-@@ -622,7 +622,7 @@ extern int ext3_sync_file (struct file *
- /* ialloc.c */
- extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
- extern void ext3_free_inode (handle_t *, struct inode *);
--extern struct inode * ext3_orphan_get (struct super_block *, ino_t);
-+extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
- extern unsigned long ext3_count_free_inodes (struct super_block *);
- extern void ext3_check_inodes_bitmap (struct super_block *);
- extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
diff --git a/lustre/extN/ext3-2.5-noread.diff b/lustre/extN/ext3-2.5-noread.diff
deleted file mode 100644 (file)
index f1c611f..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-===== fs/ext3/ialloc.c 1.26 vs edited =====
---- 1.26/fs/ext3/ialloc.c      Fri Feb 14 19:24:09 2003
-+++ edited/fs/ext3/ialloc.c    Sat Mar  8 01:20:55 2003
-@@ -195,6 +195,36 @@
- }
- /*
-+ * @block_group: block group of inode
-+ * @offset: relative offset of inode within @block_group
-+ *
-+ * Check whether any of the inodes in this disk block are in use.
-+ *
-+ * Caller must be holding superblock lock (group/bitmap read lock in
-+ * future).
-+ */
-+int ext3_itable_block_used(struct super_block *sb, unsigned int block_group,
-+                         int offset)
-+{
-+      struct buffer_head *ibitmap = read_inode_bitmap(sb, block_group);
-+      int inodes_per_block;
-+      unsigned long inum, iend;
-+
-+      if (!ibitmap)
-+              return 1;
-+
-+      inodes_per_block = sb->s_blocksize / EXT3_SB(sb)->s_inode_size;
-+      inum = offset & ~(inodes_per_block - 1);
-+      iend = inum + inodes_per_block;
-+      for (; inum < iend; inum++) {
-+              if (inum != offset && ext3_test_bit(inum, ibitmap->b_data))
-+                      return 1;
-+      }
-+
-+      return 0;
-+}
-+
-+/*
-  * There are two policies for allocating an inode.  If the new inode is
-  * a directory, then a forward search is made for a block group with both
-  * free space and a low directory-to-inode ratio; if that fails, then of
-@@ -422,8 +452,9 @@
-       struct ext3_group_desc * gdp;
-       struct ext3_super_block * es;
-       struct ext3_inode_info *ei;
--      int err = 0;
-+      struct ext3_iloc iloc;
-       struct inode *ret;
-+      int err = 0;
-       /* Cannot create files in a deleted directory */
-       if (!dir || !dir->i_nlink)
-@@ -587,16 +618,23 @@
-               goto fail2;
-       }
-       err = ext3_init_acl(handle, inode, dir);
-+      if (err)
-+              goto fail3;
-+
-+      err = ext3_get_inode_loc_new(inode, &iloc, 1);
-+      if (err)
-+              goto fail3;
-+
-+      BUFFER_TRACE(iloc->bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, iloc.bh);
-       if (err) {
--              DQUOT_FREE_INODE(inode);
--              goto fail2;
--      }
--      err = ext3_mark_inode_dirty(handle, inode);
--      if (err) {
--              ext3_std_error(sb, err);
--              DQUOT_FREE_INODE(inode);
--              goto fail2;
--      }
-+              brelse(iloc.bh);
-+              iloc.bh = NULL;
-+              goto fail3;
-+      }
-+      err = ext3_mark_iloc_dirty(handle, inode, &iloc);
-+      if (err)
-+              goto fail3;
-       ext3_debug("allocating inode %lu\n", inode->i_ino);
-       goto really_out;
-@@ -610,6 +648,9 @@
-       brelse(bitmap_bh);
-       return ret;
-+fail3:
-+      ext3_std_error(sb, err);
-+      DQUOT_FREE_INODE(inode);
- fail2:
-       inode->i_flags |= S_NOQUOTA;
-       inode->i_nlink = 0;
-===== fs/ext3/inode.c 1.62 vs edited =====
---- 1.62/fs/ext3/inode.c       Fri Feb 14 19:24:09 2003
-+++ edited/fs/ext3/inode.c     Sat Mar  8 02:10:39 2003
-@@ -2144,69 +2144,118 @@
-       unlock_kernel();
- }
--/* 
-- * ext3_get_inode_loc returns with an extra refcount against the
-- * inode's underlying buffer_head on success. 
-- */
-+#define NUM_INODE_PREREAD 16
--int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
-+/*
-+ * ext3_get_inode_loc returns with an extra refcount against the inode's
-+ * underlying buffer_head on success.  If this is for a new inode allocation
-+ * (new is non-zero) then we may be able to optimize away the read if there
-+ * are no other in-use inodes in this inode table block.  If we need to do
-+ * a read, then read in a whole chunk of blocks to avoid blocking again soon
-+ * if we are doing lots of creates/updates.
-+ */
-+int ext3_get_inode_loc_new(struct inode *inode, struct ext3_iloc *iloc, int new)
- {
--      struct buffer_head *bh = 0;
-+      struct buffer_head *bh[NUM_INODE_PREREAD];
-+      struct super_block *sb = inode->i_sb;
-+      struct ext3_sb_info *sbi = EXT3_SB(sb);
-+      unsigned long ino = inode->i_ino;
-       unsigned long block;
-       unsigned long block_group;
-       unsigned long group_desc;
-       unsigned long desc;
-       unsigned long offset;
-       struct ext3_group_desc * gdp;
--              
--      if ((inode->i_ino != EXT3_ROOT_INO &&
--              inode->i_ino != EXT3_JOURNAL_INO &&
--              inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
--              inode->i_ino > le32_to_cpu(
--                      EXT3_SB(inode->i_sb)->s_es->s_inodes_count)) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "bad inode number: %lu", inode->i_ino);
-+
-+      if ((ino != EXT3_ROOT_INO && ino != EXT3_JOURNAL_INO &&
-+           ino < EXT3_FIRST_INO(sb)) ||
-+          ino > le32_to_cpu(sbi->s_es->s_inodes_count)) {
-+              ext3_error(sb, "ext3_get_inode_loc", "bad inode number: %lu",
-+                         ino);
-               goto bad_inode;
-       }
--      block_group = (inode->i_ino - 1) / EXT3_INODES_PER_GROUP(inode->i_sb);
--      if (block_group >= EXT3_SB(inode->i_sb)->s_groups_count) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "group >= groups count");
-+      block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb);
-+      if (block_group >= EXT3_SB(sb)->s_groups_count) {
-+              ext3_error(sb, "ext3_get_inode_loc", "group >= groups count");
-               goto bad_inode;
-       }
--      group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(inode->i_sb);
--      desc = block_group & (EXT3_DESC_PER_BLOCK(inode->i_sb) - 1);
--      bh = EXT3_SB(inode->i_sb)->s_group_desc[group_desc];
--      if (!bh) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "Descriptor not loaded");
-+      group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(sb);
-+      desc = block_group & (EXT3_DESC_PER_BLOCK(sb) - 1);
-+      if (!sbi->s_group_desc[group_desc]) {
-+              ext3_error(sb, "ext3_get_inode_loc", "Descriptor not loaded");
-               goto bad_inode;
-       }
--      gdp = (struct ext3_group_desc *) bh->b_data;
-+      gdp = (struct ext3_group_desc *)(sbi->s_group_desc[group_desc]->b_data);
-       /*
-        * Figure out the offset within the block group inode table
-        */
--      offset = ((inode->i_ino - 1) % EXT3_INODES_PER_GROUP(inode->i_sb)) *
--              EXT3_INODE_SIZE(inode->i_sb);
-+      offset = ((ino - 1) % EXT3_INODES_PER_GROUP(sb));
-       block = le32_to_cpu(gdp[desc].bg_inode_table) +
--              (offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb));
--      if (!(bh = sb_bread(inode->i_sb, block))) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "unable to read inode block - "
--                          "inode=%lu, block=%lu", inode->i_ino, block);
--              goto bad_inode;
-+              (offset * sbi->s_inode_size >> EXT3_BLOCK_SIZE_BITS(sb));
-+      bh[0] = sb_getblk(sb, block);
-+      if (buffer_uptodate(bh[0]))
-+              goto done;
-+
-+      /* If we don't really need to read this block, and it isn't already
-+       * in memory, then we just zero it out.  Otherwise, we keep the
-+       * current block contents (deleted inode data) for posterity.
-+       */
-+      if (new && !ext3_itable_block_used(sb, block_group, offset)) {
-+              lock_buffer(bh[0]);
-+              memset(bh[0]->b_data, 0, bh[0]->b_size);
-+              set_buffer_uptodate(bh[0]);
-+              unlock_buffer(bh[0]);
-+      } else {
-+              unsigned long block_end, itable_end;
-+              int count = 1;
-+
-+              itable_end = le32_to_cpu(gdp[desc].bg_inode_table) +
-+                      sbi->s_itb_per_group;
-+              block_end = block + NUM_INODE_PREREAD;
-+              if (block_end > itable_end)
-+                      block_end = itable_end;
-+
-+              for (; block < block_end; block++) {
-+                      bh[count] = sb_getblk(sb, block);
-+                      if (count && (buffer_uptodate(bh[count]) ||
-+                                    buffer_locked(bh[count]))) {
-+                              __brelse(bh[count]);
-+                      } else
-+                              count++;
-+              }
-+
-+              ll_rw_block(READ, count, bh);
-+
-+              /* Release all but the block we actually need (bh[0]) */
-+              while (--count > 0)
-+                      __brelse(bh[count]);
-+
-+              wait_on_buffer(bh[0]);
-+              if (!buffer_uptodate(bh[0])) {
-+                      ext3_error(sb, __FUNCTION__,
-+                                 "unable to read inode block - "
-+                                 "inode=%lu, block=%llu", ino,
-+                                 (unsigned long long)bh[0]->b_blocknr);
-+                      goto bad_inode;
-+              }
-       }
--      offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1);
-+done:
-+      offset = (offset * sbi->s_inode_size) & (EXT3_BLOCK_SIZE(sb) - 1);
--      iloc->bh = bh;
--      iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset);
-+      iloc->bh = bh[0];
-+      iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset);
-       iloc->block_group = block_group;
--      
-+
-       return 0;
--      
-+
-  bad_inode:
-       return -EIO;
-+}
-+
-+int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc)
-+{
-+      return ext3_get_inode_loc_new(inode, iloc, 0);
- }
- void ext3_read_inode(struct inode * inode)
-===== include/linux/ext3_fs.h 1.22 vs edited =====
---- 1.22/include/linux/ext3_fs.h       Tue Jan 14 00:56:29 2003
-+++ edited/include/linux/ext3_fs.h     Sat Mar  8 01:56:28 2003
-@@ -719,6 +719,8 @@
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
-+extern int ext3_itable_block_used(struct super_block *, unsigned int, int);
-+extern int ext3_get_inode_loc_new(struct inode *, struct ext3_iloc *, int);
- extern int  ext3_get_inode_loc (struct inode *, struct ext3_iloc *);
- extern void ext3_read_inode (struct inode *);
- extern void ext3_write_inode (struct inode *, int);
diff --git a/lustre/extN/ext3-largefile.diff b/lustre/extN/ext3-largefile.diff
deleted file mode 100644 (file)
index db41aab..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-Under rare conditions (filesystem corruption, really) it is possible
-for ext3_dirty_inode() to require _two_ blocks for the transaction: one
-for the inode and one to update the superblock - to set
-EXT3_FEATURE_RO_COMPAT_LARGE_FILE.  This causes the filesystem to go
-BUG.
-
-So reserve an additional block for that eventuality.
-
-
- fs/ext3/inode.c |    2 +-
- 1 files changed, 1 insertion(+), 1 deletion(-)
-
---- 25/fs/ext3/inode.c~ext3-transaction-reserved-blocks        Sat Dec 14 18:28:21 2002
-+++ 25-akpm/fs/ext3/inode.c    Sat Dec 14 18:28:21 2002
-@@ -2698,7 +2698,7 @@ void ext3_dirty_inode(struct inode *inod
-       handle_t *handle;
-       lock_kernel();
--      handle = ext3_journal_start(inode, 1);
-+      handle = ext3_journal_start(inode, 2);
-       if (IS_ERR(handle))
-               goto out;
-       if (current_handle &&
diff --git a/lustre/extN/ext3-orphan_lock.diff b/lustre/extN/ext3-orphan_lock.diff
deleted file mode 100644 (file)
index d1e5c8d..0000000
+++ /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 (file)
index ce3928d..0000000
+++ /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/ext3-unmount_sync.diff b/lustre/extN/ext3-unmount_sync.diff
deleted file mode 100644 (file)
index 1f9b796..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-From adilger@clusterfs.com Mon Dec  2 10:26:44 2002
-Date: Mon, 2 Dec 2002 10:26:44 -0700
-From: Andreas Dilger <adilger@clusterfs.com>
-To: Lustre LLNL Mailing list <lc-lustre@llnl.gov>,
-       Lustre Development Mailing List <lustre-devel@lists.sourceforge.net>
-Subject: Re: data corrupting bug in 2.4.20 ext3, data=journal
-Message-ID: <20021202102644.H1422@schatzie.adilger.int>
-Mail-Followup-To: Lustre LLNL Mailing list <lc-lustre@llnl.gov>,
-       Lustre Development Mailing List <lustre-devel@lists.sourceforge.net>
-Mime-Version: 1.0
-Content-Type: text/plain; charset=us-ascii
-Content-Disposition: inline
-User-Agent: Mutt/1.2.5.1i
-X-GPG-Key: 1024D/0D35BED6
-X-GPG-Fingerprint: 7A37 5D79 BF1B CECA D44F  8A29 A488 39F5 0D35 BED6
-Status: RO
-Content-Length: 1160
-Lines: 39
-
-Here is the new-improved fix for the ext3 discarding data at umount bug
-discovered late last week.  To be used instead of the previous ext3 fix.
-
-Sadly, this is completely unrelated to the problems Mike is having with
-ext3 under UML, since it is an unmount-time problem.
-
------ Forwarded message from "Stephen C. Tweedie" <sct@redhat.com> -----
-The attached patch seems to fix things for me.
-
-Cheers,
- Stephen
-
-
---- linux-2.4-ext3merge/fs/ext3/super.c.=K0027=.orig   2002-12-02 15:35:13.000000000 +0000
-+++ linux-2.4-ext3merge/fs/ext3/super.c        2002-12-02 15:35:14.000000000 +0000
-@@ -1640,7 +1640,12 @@
-       sb->s_dirt = 0;
-       target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
--      if (do_sync_supers) {
-+      /*
-+       * Tricky --- if we are unmounting, the write really does need
-+       * to be synchronous.  We can detect that by looking for NULL in
-+       * sb->s_root.
-+       */
-+      if (do_sync_supers || !sb->s_root) {
-               unlock_super(sb);
-               log_wait_commit(EXT3_SB(sb)->s_journal, target);
-               lock_super(sb);
-
-
------ End forwarded message -----
-
-Cheers, Andreas
---
-Andreas Dilger
-http://sourceforge.net/projects/ext2resize/
-http://www-mddsp.enel.ucalgary.ca/People/adilger/
-
-
diff --git a/lustre/extN/ext3-use-after-free.diff b/lustre/extN/ext3-use-after-free.diff
deleted file mode 100644 (file)
index 8cd673f..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-If ext3_add_nondir() fails it will do an iput() of the inode.  But we
-continue to run ext3_mark_inode_dirty() against the potentially-freed
-inode.  This oopses when slab poisoning is enabled.
-
-Fix it so that we only run ext3_mark_inode_dirty() if the inode was
-successfully instantiated.
-
-This bug was added in 2.4.20-pre9.
-
-
- fs/ext3/namei.c |   11 +++++------
- 1 files changed, 5 insertions(+), 6 deletions(-)
-
---- 24/fs/ext3/namei.c~ext3-use-after-free     Sun Dec 15 11:27:50 2002
-+++ 24-akpm/fs/ext3/namei.c    Sun Dec 15 11:27:50 2002
-@@ -429,8 +429,11 @@ static int ext3_add_nondir(handle_t *han
- {
-       int err = ext3_add_entry(handle, dentry, inode);
-       if (!err) {
--              d_instantiate(dentry, inode);
--              return 0;
-+              err = ext3_mark_inode_dirty(handle, inode);
-+              if (err == 0) {
-+                      d_instantiate(dentry, inode);
-+                      return 0;
-+              }
-       }
-       ext3_dec_count(handle, inode);
-       iput(inode);
-@@ -465,7 +468,6 @@ static int ext3_create (struct inode * d
-               inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-               err = ext3_add_nondir(handle, dentry, inode);
--              ext3_mark_inode_dirty(handle, inode);
-       }
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -490,7 +492,6 @@ static int ext3_mknod (struct inode * di
-       if (!IS_ERR(inode)) {
-               init_special_inode(inode, mode, rdev);
-               err = ext3_add_nondir(handle, dentry, inode);
--              ext3_mark_inode_dirty(handle, inode);
-       }
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -934,7 +935,6 @@ static int ext3_symlink (struct inode * 
-       }
-       inode->u.ext3_i.i_disksize = inode->i_size;
-       err = ext3_add_nondir(handle, dentry, inode);
--      ext3_mark_inode_dirty(handle, inode);
- out_stop:
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -971,7 +971,6 @@ static int ext3_link (struct dentry * ol
-       atomic_inc(&inode->i_count);
-       err = ext3_add_nondir(handle, dentry, inode);
--      ext3_mark_inode_dirty(handle, inode);
-       ext3_journal_stop(handle, dir);
-       return err;
- }
-
-_
diff --git a/lustre/extN/extN-delete_thread.diff b/lustre/extN/extN-delete_thread.diff
deleted file mode 100644 (file)
index 6e278c8..0000000
+++ /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-san.diff b/lustre/extN/extN-san.diff
deleted file mode 100644 (file)
index 4d0f277..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
---- lustre/extN/inode.orig.c   2002-12-29 18:48:56.000000000 +0800
-+++ lustre/extN/inode.c        2002-12-29 19:17:24.000000000 +0800
-@@ -2728,3 +2728,85 @@
-  * here, in extN_aops_journal_start() to ensure that the forthcoming "see if we
-  * need to extend" test in extN_prepare_write() succeeds.  
-  */
-+
-+/* for each block: 1 ind + 1 dind + 1 tind
-+ * for each block: 3 bitmap blocks
-+ * for each block: 3 group descriptor blocks
-+ * i inode block
-+ * 1 superblock
-+ * 2 * EXTN_SINGLEDATA_TRANS_BLOCKS for the quote files
-+ * ((1+1+1) * 3 * nblocks) + 1 + 1 + 2 * EXTN_SINGLEDATA_TRANS_BLOCKS
-+ *
-+ * XXX assuming:
-+ * (1) fs logic block size == page size
-+ * (2) extN in writeback mode
-+ */
-+static inline int extN_san_write_trans_blocks(int nblocks)
-+{
-+      int ret;
-+      
-+      ret = (1 + 1 + 1) * 3 * nblocks + 1 + 1;
-+
-+#ifdef CONFIG_QUOTA
-+      ret += 2 * EXTN_SINGLEDATA_TRANS_BLOCKS;
-+#endif
-+
-+      return ret;
-+}
-+
-+/* Alloc blocks for an inode, while don't create any buffer/page
-+ * for data I/O; set the inode size if file is extended.
-+ *
-+ * @inode:    target inode
-+ * @blocks:   array of logic block number
-+ * @nblocks:  how many blocks need be alloced
-+ * @newsize:  new filesize we should set
-+ *
-+ * return:    0 success, otherwise failed
-+ *            (*blocks) contains physical block number alloced
-+ *
-+ * XXX this assume the fs block size == page size
-+ */
-+int extN_prep_san_write(struct inode *inode, long *blocks,
-+                      int nblocks, loff_t newsize)
-+{
-+      handle_t *handle;
-+      struct buffer_head bh_tmp;
-+      int needed_blocks;
-+      int i, ret = 0, ret2;
-+
-+      needed_blocks = extN_san_write_trans_blocks(nblocks);
-+
-+      lock_kernel();
-+      handle = extN_journal_start(inode, needed_blocks);
-+      if (IS_ERR(handle)) {
-+              unlock_kernel();
-+              return PTR_ERR(handle);
-+      }
-+      unlock_kernel();
-+
-+      /* alloc blocks one by one */
-+      for (i = 0; i < nblocks; i++) {
-+              ret = extN_get_block_handle(handle, inode, blocks[i],
-+                                              &bh_tmp, 1);
-+              if (ret)
-+                      break;
-+
-+              blocks[i] = bh_tmp.b_blocknr;
-+      }
-+
-+      /* set inode size if needed */
-+      if (!ret && (newsize > inode->i_size)) {
-+              inode->i_size = newsize;
-+              extN_mark_inode_dirty(handle, inode);
-+      }
-+
-+      lock_kernel();
-+      ret2 = extN_journal_stop(handle, inode);
-+      unlock_kernel();
-+
-+      if (!ret)
-+              ret = ret2;
-+      return ret;
-+}
-+EXPORT_SYMBOL(extN_prep_san_write);
diff --git a/lustre/extN/extN.patch-2.5.63 b/lustre/extN/extN.patch-2.5.63
deleted file mode 100644 (file)
index e1bb363..0000000
+++ /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, <a.gruenbacher@computer.org>
- */
--
-+#include <linux/module.h>
- #include <linux/config.h>
- #include <linux/xattr.h>
-
diff --git a/lustre/extN/patch-2.4.18-chaos22 b/lustre/extN/patch-2.4.18-chaos22
deleted file mode 100644 (file)
index c40d4ea..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-diff -ru lum-2.4.18-um30/fs/ext3/balloc.c uml-2.4.18-12.5/fs/ext3/balloc.c
---- lum-2.4.18-um30/fs/ext3/balloc.c   Mon Feb 25 12:38:08 2002
-+++ uml-2.4.18-12.5/fs/ext3/balloc.c   Thu Sep 19 13:40:11 2002
-@@ -276,7 +276,8 @@
-       }
-       lock_super (sb);
-       es = sb->u.ext3_sb.s_es;
--      if (block < le32_to_cpu(es->s_first_data_block) || 
-+      if (block < le32_to_cpu(es->s_first_data_block) ||
-+          block + count < block ||
-           (block + count) > le32_to_cpu(es->s_blocks_count)) {
-               ext3_error (sb, "ext3_free_blocks",
-                           "Freeing blocks not in datazone - "
-@@ -309,17 +310,6 @@
-       if (!gdp)
-               goto error_return;
--      if (in_range (le32_to_cpu(gdp->bg_block_bitmap), block, count) ||
--          in_range (le32_to_cpu(gdp->bg_inode_bitmap), block, count) ||
--          in_range (block, le32_to_cpu(gdp->bg_inode_table),
--                    sb->u.ext3_sb.s_itb_per_group) ||
--          in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table),
--                    sb->u.ext3_sb.s_itb_per_group))
--              ext3_error (sb, "ext3_free_blocks",
--                          "Freeing blocks in system zones - "
--                          "Block = %lu, count = %lu",
--                          block, count);
--
-       /*
-        * We are about to start releasing blocks in the bitmap,
-        * so we need undo access.
-@@ -345,14 +335,24 @@
-       if (err)
-               goto error_return;
--      for (i = 0; i < count; i++) {
-+      for (i = 0; i < count; i++, block++) {
-+              if (block == le32_to_cpu(gdp->bg_block_bitmap) ||
-+                  block == le32_to_cpu(gdp->bg_inode_bitmap) ||
-+                  in_range(block, le32_to_cpu(gdp->bg_inode_table),
-+                           sb->u.ext2_sb.s_itb_per_group)) {
-+                      ext3_error(sb, __FUNCTION__,
-+                                 "Freeing block in system zone - block = %lu",
-+                                 block);
-+                      continue;
-+              }
-+
-               /*
-                * An HJ special.  This is expensive...
-                */
- #ifdef CONFIG_JBD_DEBUG
-               {
-                       struct buffer_head *debug_bh;
--                      debug_bh = sb_get_hash_table(sb, block + i);
-+                      debug_bh = sb_get_hash_table(sb, block);
-                       if (debug_bh) {
-                               BUFFER_TRACE(debug_bh, "Deleted!");
-                               if (!bh2jh(bitmap_bh)->b_committed_data)
-@@ -365,9 +365,8 @@
- #endif
-               BUFFER_TRACE(bitmap_bh, "clear bit");
-               if (!ext3_clear_bit (bit + i, bitmap_bh->b_data)) {
--                      ext3_error (sb, __FUNCTION__,
--                                    "bit already cleared for block %lu", 
--                                    block + i);
-+                      ext3_error(sb, __FUNCTION__,
-+                                 "bit already cleared for block %lu", block);
-                       BUFFER_TRACE(bitmap_bh, "bit already cleared");
-               } else {
-                       dquot_freed_blocks++;
-@@ -415,7 +417,6 @@
-       if (!err) err = ret;
-       if (overflow && !err) {
--              block += count;
-               count = overflow;
-               goto do_more;
-       }
-@@ -575,6 +577,7 @@
-       ext3_debug ("goal=%lu.\n", goal);
-+repeat:
-       /*
-        * First, test whether the goal block is free.
-        */
-@@ -684,10 +686,21 @@
-       if (tmp == le32_to_cpu(gdp->bg_block_bitmap) ||
-           tmp == le32_to_cpu(gdp->bg_inode_bitmap) ||
-           in_range (tmp, le32_to_cpu(gdp->bg_inode_table),
--                    sb->u.ext3_sb.s_itb_per_group))
--              ext3_error (sb, "ext3_new_block",
--                          "Allocating block in system zone - "
--                          "block = %u", tmp);
-+                    EXT3_SB(sb)->s_itb_per_group)) {
-+              ext3_error(sb, __FUNCTION__,
-+                         "Allocating block in system zone - block = %u", tmp);
-+
-+              /* Note: This will potentially use up one of the handle's
-+               * buffer credits.  Normally we have way too many credits,
-+               * so that is OK.  In _very_ rare cases it might not be OK.
-+               * We will trigger an assertion if we run out of credits,
-+               * and we will have to do a full fsck of the filesystem -
-+               * better than randomly corrupting filesystem metadata.
-+               */
-+              ext3_set_bit(j, bh->b_data);
-+              goto repeat;
-+      }
-+
-       /* The superblock lock should guard against anybody else beating
-        * us to this point! */
-diff -ru lum-2.4.18-um30/fs/ext3/namei.c uml-2.4.18-12.5/fs/ext3/namei.c
---- lum-2.4.18-um30/fs/ext3/namei.c    Fri Nov  9 15:25:04 2001
-+++ uml-2.4.18-12.5/fs/ext3/namei.c    Thu Sep 19 13:40:11 2002
-@@ -354,8 +355,8 @@
-                        */
-                       dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-                       dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
--                      ext3_mark_inode_dirty(handle, dir);
-                       dir->i_version = ++event;
-+                      ext3_mark_inode_dirty(handle, dir);
-                       BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
-                       ext3_journal_dirty_metadata(handle, bh);
-                       brelse(bh);
-@@ -464,8 +465,8 @@
-               inode->i_op = &ext3_file_inode_operations;
-               inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
--              ext3_mark_inode_dirty(handle, inode);
-               err = ext3_add_nondir(handle, dentry, inode);
-+              ext3_mark_inode_dirty(handle, inode);
-       }
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -489,8 +490,8 @@
-       err = PTR_ERR(inode);
-       if (!IS_ERR(inode)) {
-               init_special_inode(inode, mode, rdev);
--              ext3_mark_inode_dirty(handle, inode);
-               err = ext3_add_nondir(handle, dentry, inode);
-+              ext3_mark_inode_dirty(handle, inode);
-       }
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -933,8 +934,8 @@
-               inode->i_size = l-1;
-       }
-       inode->u.ext3_i.i_disksize = inode->i_size;
--      ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_nondir(handle, dentry, inode);
-+      ext3_mark_inode_dirty(handle, inode);
- out_stop:
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -970,8 +971,8 @@
-       ext3_inc_count(handle, inode);
-       atomic_inc(&inode->i_count);
--      ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_nondir(handle, dentry, inode);
-+      ext3_mark_inode_dirty(handle, inode);
-       ext3_journal_stop(handle, dir);
-       return err;
- }
diff --git a/lustre/include/ioctl.h b/lustre/include/ioctl.h
deleted file mode 100644 (file)
index a4ec8a5..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef _ASMI386_IOCTL_H
-#define _ASMI386_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS     8
-#define _IOC_TYPEBITS   8
-#define _IOC_SIZEBITS   14
-#define _IOC_DIRBITS    2
-
-#define _IOC_NRMASK     ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK   ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK   ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK    ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT    0
-#define _IOC_TYPESHIFT  (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT  (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT   (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE       0U
-#define _IOC_WRITE      1U
-#define _IOC_READ       2U
-
-#define _IOC(dir,type,nr,size) (((dir)  << _IOC_DIRSHIFT) | ((type) << _IOC_TYPESHIFT) | ((nr)   << _IOC_NRSHIFT) | ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)            _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)      _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)      _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)     _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)            (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)           (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)             (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)           (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN          (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT         (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT       ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK    (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT   (_IOC_SIZESHIFT)
-
-#endif /* _ASMI386_IOCTL_H */
diff --git a/lustre/include/liblustre.h b/lustre/include/liblustre.h
deleted file mode 100644 (file)
index 7804610..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-#ifndef LIBLUSTRE_H__
-#define LIBLUSTRE_H__
-
-#include <sys/mman.h>
-#include <asm/page.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/vfs.h>
-
-#include <portals/list.h>
-#include <portals/p30.h>
-
-/* definitions for liblustre */ 
-
-/* always adopt 2.5 definitions */
-#define LINUX_VERSION_CODE 1
-#define KERNEL_VERSION(a,b,c) 0 
-
-/* cheats for now */
-
-struct work_struct { 
-        void (*ws_task)(void *arg);
-        void *ws_arg;
-};
-
-static inline void prepare_work(struct work_struct *q, void (*t)(void *),
-                                void *arg) 
-{ 
-        q->ws_task = t;
-        q->ws_arg = arg;
-        return;
-}
-
-static inline void schedule_work(struct work_struct *q)
-{
-        q->ws_task(q->ws_arg);
-}
-
-
-#define strnlen(a,b) strlen(a)
-#define kmalloc(a,b) malloc(a)
-#define vmalloc malloc
-#define vfree free
-#define kfree(a) free(a)
-#define GFP_KERNEL 1
-#define GFP_HIGHUSER 1
-#define IS_ERR(a) (abs((int)(a)) < 500 ? 1 : 0)
-#define PTR_ERR(a) ((int)(a))
-
-#define capable(foo) 1
-#define CAP_SYS_ADMIN 1
-
-typedef struct {
-        void *cwd;
-
-}mm_segment_t;
-
-typedef void *read_proc_t;
-typedef void *write_proc_t;
-
-
-/* modules */
-
-struct module { 
-        int count;
-};
-
-static inline void MODULE_AUTHOR(char *name)
-{ 
-        printf("%s\n", name);
-}
-#define MODULE_DESCRIPTION(name) MODULE_AUTHOR(name)
-#define MODULE_LICENSE(name) MODULE_AUTHOR(name)
-
-#define THIS_MODULE NULL
-#define __init 
-#define __exit
-
-/* devices */
-
-static inline int misc_register(void *foo) 
-{ 
-        return 0;
-} 
-#define misc_deregister misc_register
-
-#define __MOD_INC_USE_COUNT(m)  (m->count++)
-#define __MOD_DEC_USE_COUNT(m)  (m->count--)
-#define MOD_INC_USE_COUNT  do {int a = 1; a++; } while (0)
-#define MOD_DEC_USE_COUNT  do {int a = 1; a++; } while (0)
-
-/* general stuff */
-
-#define EXPORT_SYMBOL(S)  
-
-typedef int spinlock_t;
-typedef __u64 kdev_t;
-
-#define SPIN_LOCK_UNLOCKED 0
-#define spin_lock(l) do {int a = 1; a++; } while (0)
-#define spin_unlock(l) do {int a= 1; a++; } while (0)
-#define spin_lock_init(l) do {int a= 1; a++; } while (0)
-static inline void spin_lock_irqrestore(a,b)
-{
-        return;
-} 
-static inline void spin_unlock_irqrestore(a,b)
-{
-        return;
-} 
-static inline void spin_lock_irqsave(a,b)
-{
-        return;
-} 
-
-#define barrier() do {int a= 1; a++; } while (0)
-
-/* registering symbols */
-extern void *inter_module_get(char *name);
-extern void inter_module_put(char *name);
-
-#define ERESTARTSYS ERESTART
-#define HZ 1
-
-/* random */
-
-static inline void get_random_bytes(void *ptr, int size)
-{
-        static int r;
-        int *p = (int *)ptr;
-        int *end = p + (size / sizeof(int));
-        r = rand();
-        while ( p + sizeof(int) < end ) {
-                *p = r;
-                p++;
-        }
-}
-
-/* memory */
-
-static inline int copy_from_user(void *a,void *b, int c) 
-{ 
-        memcpy(a,b,c);
-        return 0;
-}
-
-static inline int copy_to_user(void *a,void *b, int c) 
-{ 
-        memcpy(a,b,c);
-        return 0;
-}
-
-
-/* slabs */
-typedef struct { 
-         int size;
-} kmem_cache_t;
-
-static inline kmem_cache_t *kmem_cache_create(name,objsize,c,d,e,f)
-{
-        return malloc(objsize);
-};
-
-static inline int kmem_cache_destroy(kmem_cache_t *a)
-{
-        free(a);
-        return 0;
-}
-#define kmem_cache_validate(a,b) 1
-#define kmem_cache_alloc(cache, prio) malloc(cache->size)
-#define kmem_cache_free(cache, obj) OBD_FREE(obj, cache->size)
-#define PORTAL_SLAB_ALLOC(lock,cache,size) do { lock = kmem_cache_alloc(cache,prio); } while (0)
-#define PORTAL_SLAB_FREE(lock,cache,size) do { lock = kmem_cache_alloc(cache,prio); } while (0)
-
-struct page { 
-        void *addr;
-        int index;
-};
-
-#define kmap(page) (page)->addr
-#define kunmap(a) do { int foo = 1; foo++; } while (0)
-
-static inline struct page *alloc_pages(mask,foo) 
-{
-        struct page *pg = malloc(sizeof(*pg));
-
-        if (!pg) 
-                return NULL;
-#ifdef MAP_ANONYMOUS
-        pg->addr = mmap(0, PAGE_SIZE, PROT_WRITE, MAP_ANONYMOUS, 0, 0);
-#else
-        pg->addr = malloc(PAGE_SIZE);
-#endif
-
-        if (!pg->addr) {
-                free(pg); 
-                return NULL;
-        }
-        return pg;
-}
-
-static inline void __free_pages(struct page *pg, int what) 
-{
-#ifdef MAP_ANONYMOUS
-        munmap(pg->addr, PAGE_SIZE);
-#else 
-        free(pg->addr);
-#endif
-        free(pg);
-}
-
-/* arithmetic */
-#define do_div(a,b) (a)/(b)
-
-/* dentries / intents */
-struct lookup_intent { 
-        void *it_iattr;
-};
-
-struct iattr { 
-        int mode;
-};
-
-struct dentry { 
-        int d_count;
-};
-struct file { 
-        struct dentry *f_dentry;
-        void *private_data;
-} ;
-
-struct vfsmount {
-        void *pwd;
-};
-#define cpu_to_le32(x) ((__u32)(x))
-
-/* semaphores */
-struct semaphore { 
-        int count;
-};
-
-#define down(a) do {(a)->count++;} while (0)
-#define up(a) do {(a)->count--;} while (0)
-#define sema_init(a,b) do { (a)->count = b; } while (0)
-
-typedef struct  { 
-        struct list_head sleepers;
-} wait_queue_head_t;
-
-typedef struct  { 
-        struct list_head sleeping;
-        void *process;
-} wait_queue_t;
-
-struct signal { 
-        int signal;
-};
-
-struct task_struct { 
-        int state;
-        struct signal pending;
-        char comm[32];
-        int pid;
-};
-
-extern struct task_struct *current;
-
-
-
-#define set_current_state(foo) do { current->state = foo; } while (0)
-
-#define init_waitqueue_entry(q,p) do { (q)->process = p; } while (0)
-#define add_wait_queue(q,p) do {  list_add(&(q)->sleepers, &(p)->sleeping); } while (0)
-#define del_wait_queue(p) do { list_del(&(p)->sleeping); } while (0)
-#define remove_wait_queue(q,p) do { list_del(&(p)->sleeping); } while (0)
-
-#define init_waitqueue_head(l) INIT_LIST_HEAD(&(l)->sleepers)
-#define wake_up(l) do { int a; a++; } while (0)
-#define wait_event(l,m) do { int a; a++; } while (0)
-#define TASK_INTERRUPTIBLE 0
-#define TASK_UNINTERRUPTIBLE 1
-#define TASK_RUNNING 2
-
-
-#define schedule() do { int a; a++; } while (0)
-static inline int schedule_timeout(t)
-{
-        return 0;
-}
-
-#define lock_kernel() do { int a; a++; } while (0)
-#define daemonize(l) do { int a; a++; } while (0)
-#define sigfillset(l) do { int a; a++; } while (0)
-#define recalc_sigpending(l) do { int a; a++; } while (0)
-#define kernel_thread(l,m,n) 
-
-static inline int call_usermodehelper(char *prog, char **argv, char **evnp)
-{
-        return 0;
-}
-
-
-
-#define KERN_INFO 
-
-
-
-struct timer_list { 
-        struct list_head tl_list;
-};
-
-typedef struct { volatile int counter; } atomic_t;
-
-#define atomic_read(a) ((a)->counter)
-#define atomic_set(a,b) do {(a)->counter = b; } while (0)
-#define atomic_dec_and_test(a) ((--((a)->counter)) == 0)
-#define atomic_inc(a)  (((a)->counter)++)
-#define atomic_dec(a)  do { (a)->counter--; } while (0)
-#define atomic_add(b,a)  do {(a)->counter += b;} while (0)
-#define atomic_sub(b,a)  do {(a)->counter -= b;} while (0)
-
-#define LBUG() do { sleep(1000000); } while (0)
-
-#include <linux/obd_support.h>
-#include <linux/lustre_idl.h>
-#include <linux/lustre_lib.h>
-#include <linux/lustre_import.h>
-#include <linux/lustre_export.h>
-#include <linux/lustre_net.h>
-
-
-#endif
-
diff --git a/lustre/include/linux/.cvsignore b/lustre/include/linux/.cvsignore
deleted file mode 100644 (file)
index eb16cdd..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-.Xrefs
-config.log
-config.status
-configure
-Makefile
-Makefile.in
-.deps
-TAGS
-extN_fs.h
-extN_fs_i.h
-extN_fs_sb.h
-extN_jbd.h
diff --git a/lustre/include/linux/lustre_handles.h b/lustre/include/linux/lustre_handles.h
deleted file mode 100644 (file)
index 993a323..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef __LINUX_HANDLES_H_
-#define __LINUX_HANDLES_H_
-
-#ifdef __KERNEL__
-#include <asm/types.h>
-#include <asm/atomic.h>
-#include <linux/list.h>
-#endif
-
-typedef void (*portals_handle_addref_cb)(void *object);
-
-/* These handles are most easily used by having them appear at the very top of
- * whatever object that you want to make handles for.  ie:
- *
- * struct ldlm_lock {
- *         struct portals_handle handle;
- *         ...
- * };
- *
- * Now you're able to assign the results of cookie2handle directly to an
- * ldlm_lock.  If it's not at the top, you'll want to hack up a macro that
- * uses some offsetof() magic. */
-
-struct portals_handle {
-        struct list_head h_link;
-        __u64 h_cookie;
-        portals_handle_addref_cb h_addref;
-};
-
-/* handles.c */
-
-/* Add a handle to the hash table */
-void portals_handle_hash(struct portals_handle *, portals_handle_addref_cb);
-void portals_handle_unhash(struct portals_handle *);
-void *portals_handle2object(__u64 cookie);
-int portals_handle_init(void);
-void portals_handle_cleanup(void);
-
-#endif
diff --git a/lustre/kernel_patches/README b/lustre/kernel_patches/README
deleted file mode 100644 (file)
index 05a04d0..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-
-Lustre requires changes to the core kernel before it can be compiled against
-hte core kernel source tree.  We use Andrew Morton's 'patch-scripts' utilties
-to keep the complexity of managing changes across multiple kernel targets down.
-They handle the ordering metadata, application, refreshing, and removal of
-patches  for us.  Please read scripts/docco.txt for a more thorough explanation
-of what 'patch-scripts' do.
-
-We create a thin wrapper around patchscripts with our ./prepare_tree.sh.  It
-exports two environment variables.  PATCHSCRIPTS is a relative path from the
-kernel source tree to the checked-out patchscripts repository.  It is requires
-for patchscripts to operate on data outside the kernel source tree.  It also
-puts the absolute path to the scripts/ directory at the front of PATH.
-Finally, it creates a 'series' link from the kernel tree back to the proper
-series file for that kernel tree.  More on that below.
-
-prepare_tree.sh and the patch-scripts commands are the only interface we should
-use on a daily basis.  We should never have to manage the patches by hand.
-This will save us heart-ache once we're good with the tools.  I promise.
-
-Data to be aware of:
-
-patches/
-       contains all the patch files themselves.  We should have a patch per 
-       functional change.  
-
-series/
-       the text files that patch-utils use to define the ordering of patches
-       that are applied to a tree.  We have a series file for each kernel
-       tree variant that requires wildly different patches.  (architecture
-       differences, stock vs. redhat, etc) 
-
-pc/
-       control files for patch-utils.  These are per tree and should never
-       be in cvs.
-
-txt/
-       text descriptions of the patches.  Nice, but not functionally required.
-
-First, before anything happens, you need to prep a tree for use with
-patch-utils.  This means putting a series link in the file and setting the
-environment variable:
-
-       $ eval `./prepare_tree.sh -t /tmp/kernels/linux-2.4.18 -r stock-2.4`
-
-prepare-tree.sh is careful to output variable assignments to stdout and
-everything else to stderr so the eval won't go awry.  It also is clever about
-resolving the series name, so tab-completed relative paths to the series files
-can be used with -r.  (it assumes that series/ is under where prepare_tree.sh
-was executed from).  The series link that is created from the tree back into
-the cvs repository is created by force.  Don't re-run the command with a
-different role.  (this should probably be fixed)
-
-With this in place, the shell that did the eval is ready to wield patch-utils.
-
-] To apply all the patches to a given tree:
-
-       $ eval `./prepare_tree.sh -t /tmp/kernels/linux-2.4.18 -r stock-2.4`
-       $ cd /tmp/kernels/linux-2.4.18
-       $ pushpatch 100000
-               ( the huge number just serves to iterate through the patches )
-
-] To refresh the patches against a newer kernel that the series applies to.
-
-Say the series file 'rh-8.0-dev' corresponds to a CFS policy of tracking the
-most recent red hat 8.0 distro kernel.   It used to be 2.4.18-14, say, and RH
-has now released RH 2.4.18-17.8.0 and CFS has decided to move to it.  We
-want to update the patches in cvs HEAD to be against 2.4.18-17.8.0
-
-       $ eval `./prepare_tree.sh -t /tmp/linux-2.4.18-17.8.0 -r rh-8.0-dev`
-       $ cd /tmp/linux-2.4.18-17.8.0
-       $ for a in $NUM_PATCHES_HAVE ; do
-               pushpatch;
-               refpatch;
-         done
-
-] To add a new series 
-
-Simply add a new empty file to the series/ directory, choosing a descriptive
-name for the series.
-
-] To add a patch into a series
-
-Ideally a patch can be added to the end of the series.  This is most easily
-done with patch-utils import_patch.  After the patch is imported it still needs
-to be applied and refreshed with 'pushpatch' and 'refpatch'.  ___remember to
-cvs add the patch with -ko___ so that tags in the context of the diff aren't
-change by CVS, rendering the patch unusable.
-
-It is considered valuable to have a common HEAD which can be checked out to
-patch a kernel and build lustre across lots of targets.  This creates some
-friction in the desire to keep a single canonical set of patches in CVS.  We
-solve this with the patch-utils scripts by having well-named patches that are
-bound to the different series.  Say alpha and ia64 kernel trees both need a
-common lustre patch.  Ideally they'd both have our-funcionality.patch in their
-series, but perhaps the code path we want to alter is different in the trees
-and not in the architecture-dependant part of the kernel.  For this we'd want
-our-functionality-ia64.patch in the ia64 series file, and
-our-functionality-alpha.patch in the alpha.  This split becomes irritating to
-manage as shared changes want to be pushed to all the patches.  This will be a
-pain as long as the kernel's we're receiving don't share revision control
-somehow.  At least the patch utils make it relatively painless to 'pushpatch'
-the source patch, clean up rejects, test, and 'refpatch' to generate the new
-patch for that series.
diff --git a/lustre/kernel_patches/config/config-linux-2.4.20-uml b/lustre/kernel_patches/config/config-linux-2.4.20-uml
deleted file mode 100644 (file)
index 2d4a2d5..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_USERMODE=y
-# CONFIG_ISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_PCI is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
-# General Setup
-#
-# CONFIG_MODE_SKAS is not set
-CONFIG_MODE_TT=y
-CONFIG_MODE_TT=y
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_SYSCTL=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=y
-CONFIG_HOSTFS=y
-# CONFIG_HPPFS is not set
-CONFIG_MCONSOLE=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_HOST_2G_2G is not set
-# CONFIG_UML_SMP is not set
-# CONFIG_SMP is not set
-CONFIG_NEST_LEVEL=0
-CONFIG_KERNEL_HALF_GIGS=1
-# CONFIG_HIGHMEM is not set
-# CONFIG_PROC_MM is not set
-CONFIG_KERNEL_STACK_ORDER=2
-CONFIG_MODE_TT=y
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_KMOD is not set
-
-#
-# Character Devices
-#
-CONFIG_STDIO_CONSOLE=y
-CONFIG_SSL=y
-CONFIG_FD_CHAN=y
-# CONFIG_NULL_CHAN is not set
-CONFIG_PORT_CHAN=y
-CONFIG_PTY_CHAN=y
-CONFIG_TTY_CHAN=y
-CONFIG_XTERM_CHAN=y
-CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
-CONFIG_CON_CHAN="xterm"
-CONFIG_SSL_CHAN="pty"
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-# CONFIG_WATCHDOG is not set
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_UML_WATCHDOG is not set
-# CONFIG_UML_SOUND is not set
-# CONFIG_SOUND is not set
-# CONFIG_HOSTAUDIO is not set
-# CONFIG_TTY_LOG is not set
-
-#
-# Block Devices
-#
-CONFIG_BLK_DEV_UBD=y
-# CONFIG_BLK_DEV_UBD_SYNC is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_MMAPPER is not set
-CONFIG_NETDEVICES=y
-
-#
-# Network Devices
-#
-CONFIG_UML_NET=y
-CONFIG_UML_NET_ETHERTAP=y
-CONFIG_UML_NET_TUNTAP=y
-CONFIG_UML_NET_SLIP=y
-# CONFIG_UML_NET_SLIRP is not set
-CONFIG_UML_NET_DAEMON=y
-CONFIG_UML_NET_MCAST=y
-# CONFIG_UML_NET_PCAP is not set
-CONFIG_DUMMY=y
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=y
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPPOE is not set
-CONFIG_SLIP=y
-# CONFIG_SLIP_COMPRESSED is not set
-# CONFIG_SLIP_SMART is not set
-# CONFIG_SLIP_MODE_SLIP6 is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#  
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-
-#
-# File systems
-#
-CONFIG_QUOTA=y
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-CONFIG_REISERFS_FS=y
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_XATTR_SHARING is not set
-# CONFIG_EXT3_FS_XATTR_USER is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-# CONFIG_CRAMFS is not set
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XATTR_SHARING is not set
-# CONFIG_EXT2_FS_XATTR_USER is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-# CONFIG_NFS_FS is not set
-# CONFIG_NFS_V3 is not set
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-CONFIG_FS_MBCACHE=y
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Library routines
-#
-# CONFIG_ZLIB_INFLATE is not set
-# CONFIG_ZLIB_DEFLATE is not set
-
-#
-# Kernel hacking
-#
-CONFIG_DEBUG_SLAB=y
-CONFIG_DEBUGSYM=y
-CONFIG_PT_PROXY=y
-# CONFIG_GPROF is not set
-# CONFIG_GCOV is not set
diff --git a/lustre/kernel_patches/config/uml.spec b/lustre/kernel_patches/config/uml.spec
deleted file mode 100644 (file)
index b7510b9..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-# These four variables will all be replaced automatically by lbuild-uml
-# please do not add any extra whitespace
-%define tag 0305061924
-%define uml_location /usr/src/uml-b_open
-%define kernel_version 2.4.20
-%define uml_version kernel-2
-%define patch_version -8
-%define lustre_source /home/build/build/lustre-b_open
-%define lustre_version 16
-
-Summary: Lustre UML kernel package
-Name: lum
-Version: %{kernel_version}_uml_lustre%{lustre_version}
-Release: %{tag}
-License: GPL
-Group: System
-URL: http://www.lustre.org/pub/lustre/
-Source0: linux-%{kernel_version}%{patch_version}.tar.gz
-Source1: uml-config
-Patch0: one-big-patch
-BuildRoot: %{_tmppath}/%{kernel_version}-%{patch_version}-buildroot
-%define __spec_install_post /usr/lib/rpm/brp-compress || :
-
-%description
-A user mode kernel package for Lustre development.
-
-%prep
-%setup -q -n linux-%{kernel_version}%{patch_version}
-%patch0 -p1
-cp -fv /usr/src/redhat/SOURCES/uml-config .config
-ln -s ../kernel/tt/include/ptrace-tt.h arch/um/sys-i386
-#cd %{lustre_source}/kernel_patches
-#eval `./prepare_tree.sh -t $RPM_BUILD_DIR/linux -s rh-2.4.18-18` && cd $RPM_BUILD_DIR/linux && pushpatch 1000
-
-%build
-make distclean
-cp -fv /usr/src/redhat/SOURCES/uml-config .config
-make  oldconfig ARCH=um
-make  dep ARCH=um
-make  linux modules ARCH=um
-make  clean
-
-%install
-rm -rf $RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT/%{uml_location}
-#mkdir -p $RPM_BUILD_ROOT
-#mkdir -p %{uml_location}
-#mkdir -p $RPM_BUILD_ROOT/linux-%{kernel_version}-uml-lustre-%{tag}
-cd ..
-cp -Rp linux-%{kernel_version}%{patch_version} $RPM_BUILD_ROOT/%{uml_location}/linux-%{kernel_version}-uml-lustre-%{tag}
-ln -s linux-%{kernel_version}-uml-lustre-%{tag} $RPM_BUILD_ROOT/%{uml_location}/uml-%{kernel_version}
-
-#find linux-%{kernel_version}%{patch_version} -maxdepth 1 -exec cp -a {} $RPM_BUILD_ROOT/%{uml_location} \; 
-#cp -a linux-%{kernel_version}%{patch_version} $RPM_BUILD_ROOT/%{uml_location}
-
-#find $RPM_BUILD_ROOT/%{uml_location} -type f > /tmp/kernel-rpm_tmp.list
-#sed -e "s,$RPM_BUILD_ROOT,,g" /tmp/kernel-rpm_tmp.list  > /tmp/kernel-rpm.list
-#rm -rf /tmp/kernel-rpm_tmp.list
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-#%files -f /tmp/kernel-rpm.list
-%files
-%defattr(-,root,root,-)
-%{uml_location}/uml-%{kernel_version}
-%{uml_location}/linux-%{kernel_version}-uml-lustre-%{tag}/
-%doc
-
-
-%changelog
-* Thu Aug 01 2002 Phil Schwan <phil@clusterfs.com>
-- Abstract uml_location, uml_version, and kernel_version
-* Fri Jul 19 2002 Peter J. Braam <braam@clusterfs.com> 
-- Initial build.
diff --git a/lustre/kernel_patches/patches/dev_read_only.patch b/lustre/kernel_patches/patches/dev_read_only.patch
deleted file mode 100644 (file)
index 9ff075e..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
- 0 files changed
-
---- linux-2.4.18-17.8.0/drivers/block/blkpg.c~dev_read_only    2002-12-06 14:52:29.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/drivers/block/blkpg.c      2002-12-06 14:52:29.000000000 -0800
-@@ -297,3 +297,38 @@ int blk_ioctl(kdev_t dev, unsigned int c
- }
- EXPORT_SYMBOL(blk_ioctl);
-+
-+#define NUM_DEV_NO_WRITE 16
-+static int dev_no_write[NUM_DEV_NO_WRITE];
-+
-+/*
-+ * Debug code for turning block devices "read-only" (will discard writes
-+ * silently).  This is for filesystem crash/recovery testing.
-+ */
-+void dev_set_rdonly(kdev_t dev, int no_write)
-+{
-+      if (dev) {
-+              printk(KERN_WARNING "Turning device %s read-only\n",
-+                     bdevname(dev));
-+              dev_no_write[no_write] = 0xdead0000 + dev;
-+      }
-+}
-+
-+int dev_check_rdonly(kdev_t dev) {
-+      int i;
-+
-+      for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
-+              if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
-+                  dev == (dev_no_write[i] & 0xffff))
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+void dev_clear_rdonly(int no_write) {
-+      dev_no_write[no_write] = 0;
-+}
-+
-+EXPORT_SYMBOL(dev_set_rdonly);
-+EXPORT_SYMBOL(dev_check_rdonly);
-+EXPORT_SYMBOL(dev_clear_rdonly);
---- linux-2.4.18-17.8.0/drivers/block/loop.c~dev_read_only     2002-12-06 14:52:29.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/drivers/block/loop.c       2002-12-06 14:52:29.000000000 -0800
-@@ -491,6 +491,11 @@ static int loop_make_request(request_que
-       spin_unlock_irq(&lo->lo_lock);
-       if (rw == WRITE) {
-+#ifdef CONFIG_DEV_RDONLY
-+              if (dev_check_rdonly(rbh->b_rdev))
-+                      goto err;
-+#endif
-+
-               if (lo->lo_flags & LO_FLAGS_READ_ONLY)
-                       goto err;
-       } else if (rw == READA) {
---- linux-2.4.18-17.8.0/drivers/ide/ide-disk.c~dev_read_only   2002-12-06 14:52:29.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/drivers/ide/ide-disk.c     2002-12-06 14:52:29.000000000 -0800
-@@ -557,6 +557,12 @@ static ide_startstop_t lba_48_rw_disk (i
-  */
- static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
- {
-+#ifdef CONFIG_DEV_RDONLY
-+      if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
-+              ide_end_request(1, HWGROUP(drive));
-+              return ide_stopped;
-+      }
-+#endif
-       if (IDE_CONTROL_REG)
-               OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
-
-_
diff --git a/lustre/kernel_patches/patches/dev_read_only_2.4.20.patch b/lustre/kernel_patches/patches/dev_read_only_2.4.20.patch
deleted file mode 100644 (file)
index c6ebe7c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
- drivers/block/blkpg.c  |   35 +++++++++++++++++++++++++++++++++++
- drivers/block/loop.c   |    3 +++
- drivers/ide/ide-disk.c |    4 ++++
- 3 files changed, 42 insertions(+)
-
---- linux-rh-2.4.20-6/drivers/block/blkpg.c~dev_read_only_2.4.20       Mon Mar 31 23:41:44 2003
-+++ linux-rh-2.4.20-6-braam/drivers/block/blkpg.c      Mon Mar 31 23:41:44 2003
-@@ -297,3 +297,38 @@ int blk_ioctl(kdev_t dev, unsigned int c
- }
- EXPORT_SYMBOL(blk_ioctl);
-+
-+#define NUM_DEV_NO_WRITE 16
-+static int dev_no_write[NUM_DEV_NO_WRITE];
-+
-+/*
-+ * Debug code for turning block devices "read-only" (will discard writes
-+ * silently).  This is for filesystem crash/recovery testing.
-+ */
-+void dev_set_rdonly(kdev_t dev, int no_write)
-+{
-+      if (dev) {
-+              printk(KERN_WARNING "Turning device %s read-only\n",
-+                     bdevname(dev));
-+              dev_no_write[no_write] = 0xdead0000 + dev;
-+      }
-+}
-+
-+int dev_check_rdonly(kdev_t dev) {
-+      int i;
-+
-+      for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
-+              if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
-+                  dev == (dev_no_write[i] & 0xffff))
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+void dev_clear_rdonly(int no_write) {
-+      dev_no_write[no_write] = 0;
-+}
-+
-+EXPORT_SYMBOL(dev_set_rdonly);
-+EXPORT_SYMBOL(dev_check_rdonly);
-+EXPORT_SYMBOL(dev_clear_rdonly);
---- linux-rh-2.4.20-6/drivers/block/loop.c~dev_read_only_2.4.20        Mon Mar 31 23:41:44 2003
-+++ linux-rh-2.4.20-6-braam/drivers/block/loop.c       Mon Mar 31 23:41:44 2003
-@@ -491,6 +491,9 @@ static int loop_make_request(request_que
-       spin_unlock_irq(&lo->lo_lock);
-       if (rw == WRITE) {
-+              if (dev_check_rdonly(rbh->b_rdev))
-+                      goto err;
-+
-               if (lo->lo_flags & LO_FLAGS_READ_ONLY)
-                       goto err;
-       } else if (rw == READA) {
---- linux-rh-2.4.20-6/drivers/ide/ide-disk.c~dev_read_only_2.4.20      Mon Mar 31 23:41:44 2003
-+++ linux-rh-2.4.20-6-braam/drivers/ide/ide-disk.c     Mon Mar 31 23:43:28 2003
-@@ -551,6 +551,10 @@ static ide_startstop_t lba_48_rw_disk(id
-  */
- static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
- {
-+      if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
-+              ide_end_request(1, HWGROUP(drive));
-+              return ide_stopped;
-+      }
-       if (!blk_fs_request(rq)) {
-               printk(KERN_ERR "%s: bad command: %d\n", drive->name, rq->cmd);
-               idedisk_end_request(drive, 0);
-
-_
diff --git a/lustre/kernel_patches/patches/dev_read_only_hp-2.4.19.patch b/lustre/kernel_patches/patches/dev_read_only_hp-2.4.19.patch
deleted file mode 100644 (file)
index ccd3286..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
- drivers/block/blkpg.c  |   38 ++++++++++++++++++++++++++++++++++++++
- drivers/block/loop.c   |    3 +++
- drivers/ide/ide-disk.c |    4 ++++
- 3 files changed, 45 insertions(+)
-
---- linux-2.4.19-hppl/drivers/block/blkpg.c~dev_read_only_hp_chaos     2003-04-11 16:36:21.000000000 +0800
-+++ linux-2.4.19-hppl-root/drivers/block/blkpg.c       2003-04-11 16:47:55.000000000 +0800
-@@ -309,6 +309,44 @@ int blk_ioctl(kdev_t dev, unsigned int c
- }
- EXPORT_SYMBOL(blk_ioctl);
-+ 
-+   
-+ 
-+ #define NUM_DEV_NO_WRITE 16
-+ static int dev_no_write[NUM_DEV_NO_WRITE];
-+ 
-+ /*
-+  * Debug code for turning block devices "read-only" (will discard writes
-+  * silently).  This is for filesystem crash/recovery testing.
-+  */
-+ void dev_set_rdonly(kdev_t dev, int no_write)
-+ {
-+      if (dev) {
-+              printk(KERN_WARNING "Turning device %s read-only\n",
-+                     bdevname(dev));
-+              dev_no_write[no_write] = 0xdead0000 + dev;
-+      }
-+ }
-+ 
-+ int dev_check_rdonly(kdev_t dev) {
-+      int i;
-+ 
-+      for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
-+              if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
-+                  dev == (dev_no_write[i] & 0xffff))
-+                      return 1;
-+      }
-+      return 0;
-+ }
-+ 
-+ void dev_clear_rdonly(int no_write) {
-+      dev_no_write[no_write] = 0;
-+ }
-+ 
-+ EXPORT_SYMBOL(dev_set_rdonly);
-+ EXPORT_SYMBOL(dev_check_rdonly);
-+ EXPORT_SYMBOL(dev_clear_rdonly);
-+ 
- /**
-  * get_last_sector()
---- linux-2.4.19-hppl/drivers/block/loop.c~dev_read_only_hp_chaos      2002-08-03 08:39:43.000000000 +0800
-+++ linux-2.4.19-hppl-root/drivers/block/loop.c        2003-04-11 16:46:47.000000000 +0800
-@@ -474,6 +474,9 @@ static int loop_make_request(request_que
-       spin_unlock_irq(&lo->lo_lock);
-       if (rw == WRITE) {
-+              if (dev_check_rdonly(rbh->b_rdev))
-+                      goto err;
-+
-               if (lo->lo_flags & LO_FLAGS_READ_ONLY)
-                       goto err;
-       } else if (rw == READA) {
---- linux-2.4.19-hppl/drivers/ide/ide-disk.c~dev_read_only_hp_chaos    2002-08-03 08:39:44.000000000 +0800
-+++ linux-2.4.19-hppl-root/drivers/ide/ide-disk.c      2003-04-11 16:46:47.000000000 +0800
-@@ -551,6 +551,10 @@ static ide_startstop_t lba_48_rw_disk (i
-  */
- static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
- {
-+      if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
-+              ide_end_request(1, HWGROUP(drive));
-+              return ide_stopped;
-+      }
-       if (IDE_CONTROL_REG)
-               OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
-
-_
diff --git a/lustre/kernel_patches/patches/export-truncate.patch b/lustre/kernel_patches/patches/export-truncate.patch
deleted file mode 100644 (file)
index 12e6f44..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
---- linux/include/linux/mm.h.truncexport       2003-03-21 20:03:18.000000000 -0500
-+++ linux/include/linux/mm.h   2003-03-21 20:05:04.000000000 -0500
-@@ -650,6 +650,7 @@
- /* filemap.c */
- extern void remove_inode_page(struct page *);
- extern unsigned long page_unuse(struct page *);
-+extern void truncate_complete_page(struct page *);
- extern void truncate_inode_pages(struct address_space *, loff_t);
- /* generic vm_area_ops exported for stackable file systems */
---- linux/mm/filemap.c.truncexport     2003-03-21 20:01:19.000000000 -0500
-+++ linux/mm/filemap.c 2003-03-21 20:01:41.000000000 -0500
-@@ -245,7 +245,7 @@
-               do_flushpage(page, partial);
- }
--static void truncate_complete_page(struct page *page)
-+void truncate_complete_page(struct page *page)
- {
-       /*
-        * Leave it on the LRU if it gets converted into anonymous buffers
-@@ -266,6 +266,7 @@
-       remove_inode_page(page);
-       page_cache_release(page);
- }
-+EXPORT_SYMBOL_GPL(truncate_complete_page);
- static int FASTCALL(truncate_list_pages(struct list_head *, unsigned long, unsigned *));
- static int truncate_list_pages(struct list_head *head, unsigned long start, unsigned *partial)
diff --git a/lustre/kernel_patches/patches/exports.patch b/lustre/kernel_patches/patches/exports.patch
deleted file mode 100644 (file)
index cdf72f0..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
- 0 files changed
-
---- linux-2.4.18-17.8.0/fs/ext3/Makefile~exports       2002-12-06 14:52:29.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/fs/ext3/Makefile   2002-12-06 14:52:29.000000000 -0800
-@@ -9,6 +9,8 @@
- O_TARGET := ext3.o
-+export-objs :=        super.o
-+
- obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-               ioctl.o namei.o super.o symlink.o
- obj-m    := $(O_TARGET)
---- linux-2.4.18-17.8.0/fs/ext3/super.c~exports        2002-12-06 14:52:29.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/fs/ext3/super.c    2002-12-06 14:52:29.000000000 -0800
-@@ -1746,7 +1746,7 @@ static void __exit exit_ext3_fs(void)
-       unregister_filesystem(&ext3_fs_type);
- }
--EXPORT_NO_SYMBOLS;
-+EXPORT_SYMBOL(ext3_bread);
- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
- MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
---- linux-2.4.18-17.8.0/include/linux/fs.h~exports     2002-12-06 14:52:29.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/include/linux/fs.h 2002-12-06 14:52:29.000000000 -0800
-@@ -1046,6 +1046,7 @@ extern int unregister_filesystem(struct 
- extern struct vfsmount *kern_mount(struct file_system_type *);
- extern int may_umount(struct vfsmount *);
- extern long do_mount(char *, char *, char *, unsigned long, void *);
-+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
- extern void umount_tree(struct vfsmount *);
- #define kern_umount mntput
---- linux-2.4.18-17.8.0/kernel/ksyms.c~exports 2002-12-06 14:52:29.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/kernel/ksyms.c     2002-12-06 14:52:29.000000000 -0800
-@@ -306,6 +306,11 @@ EXPORT_SYMBOL_GPL(buffermem_pages);
- EXPORT_SYMBOL_GPL(nr_free_pages);
- EXPORT_SYMBOL_GPL(page_cache_size);
-+/* lustre */
-+EXPORT_SYMBOL(panic_notifier_list);
-+EXPORT_SYMBOL(pagecache_lock_cacheline);
-+EXPORT_SYMBOL(do_kern_mount);
-+
- /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
- EXPORT_SYMBOL(default_llseek);
- EXPORT_SYMBOL(dentry_open);
-
-_
diff --git a/lustre/kernel_patches/patches/exports_2.4.20.patch b/lustre/kernel_patches/patches/exports_2.4.20.patch
deleted file mode 100644 (file)
index 6332735..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
- fs/ext3/Makefile   |    2 ++
- fs/ext3/super.c    |    2 +-
- include/linux/fs.h |    1 +
- kernel/ksyms.c     |    4 ++++
- 4 files changed, 8 insertions(+), 1 deletion(-)
-
---- linux-2.4.20-hp4_pnnl1/fs/ext3/Makefile~exports_hp Tue Apr  1 20:36:07 2003
-+++ linux-2.4.20-hp4_pnnl1-braam/fs/ext3/Makefile      Tue Apr  1 20:36:07 2003
-@@ -9,6 +9,8 @@
- O_TARGET := ext3.o
-+export-objs :=        super.o
-+
- obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-               ioctl.o namei.o super.o symlink.o
- obj-m    := $(O_TARGET)
---- linux-2.4.20-hp4_pnnl1/fs/ext3/super.c~exports_hp  Tue Apr  1 20:36:07 2003
-+++ linux-2.4.20-hp4_pnnl1-braam/fs/ext3/super.c       Tue Apr  1 20:36:07 2003
-@@ -1769,7 +1769,7 @@
-       unregister_filesystem(&ext3_fs_type);
- }
--EXPORT_NO_SYMBOLS;
-+EXPORT_SYMBOL(ext3_bread);
- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
- MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
---- linux-2.4.20-hp4_pnnl1/include/linux/fs.h~exports_hp       Tue Apr  1 20:36:07 2003
-+++ linux-2.4.20-hp4_pnnl1-braam/include/linux/fs.h    Tue Apr  1 20:36:52 2003
-@@ -1020,6 +1020,7 @@
- extern struct vfsmount *kern_mount(struct file_system_type *);
- extern int may_umount(struct vfsmount *);
- extern long do_mount(char *, char *, char *, unsigned long, void *);
-+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
- #define kern_umount mntput
---- linux-2.4.20-hp4_pnnl1/kernel/ksyms.c~exports_hp   Tue Apr  1 20:36:07 2003
-+++ linux-2.4.20-hp4_pnnl1-braam/kernel/ksyms.c        Tue Apr  1 20:36:07 2003
-@@ -308,6 +308,11 @@
- EXPORT_SYMBOL(dcache_readdir);
- EXPORT_SYMBOL(dcache_dir_ops);
-+/* lustre */
-+EXPORT_SYMBOL(pagecache_lock_cacheline);
-+EXPORT_SYMBOL(panic_notifier_list);
-+EXPORT_SYMBOL(do_kern_mount);
-+
- /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
- EXPORT_SYMBOL(default_llseek);
- EXPORT_SYMBOL(dentry_open);
-
-_
diff --git a/lustre/kernel_patches/patches/exports_hp-2.4.19.patch b/lustre/kernel_patches/patches/exports_hp-2.4.19.patch
deleted file mode 100644 (file)
index 82a9323..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
- fs/ext3/Makefile   |    2 ++
- fs/ext3/super.c    |    2 +-
- include/linux/fs.h |    1 +
- kernel/ksyms.c     |    4 ++++
- 4 files changed, 8 insertions(+), 1 deletion(-)
-
---- linux-2.4.19-hppl/fs/ext3/Makefile~export_hp_2.4.19        2001-12-22 01:41:55.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext3/Makefile    2003-04-11 17:12:50.000000000 +0800
-@@ -9,6 +9,8 @@
- O_TARGET := ext3.o
-+export-objs :=        super.o inode.o
-+
- obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-               ioctl.o namei.o super.o symlink.o
- obj-m    := $(O_TARGET)
---- linux-2.4.19-hppl/fs/ext3/super.c~export_hp_2.4.19 2002-02-26 03:38:08.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext3/super.c     2003-04-11 17:12:50.000000000 +0800
-@@ -1744,7 +1744,7 @@ static void __exit exit_ext3_fs(void)
-       unregister_filesystem(&ext3_fs_type);
- }
--EXPORT_NO_SYMBOLS;
-+EXPORT_SYMBOL(ext3_bread);
- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
- MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
---- linux-2.4.19-hppl/include/linux/fs.h~export_hp_2.4.19      2003-04-11 17:02:19.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/linux/fs.h  2003-04-11 17:13:39.000000000 +0800
-@@ -1020,6 +1020,7 @@ extern int unregister_filesystem(struct 
- extern struct vfsmount *kern_mount(struct file_system_type *);
- extern int may_umount(struct vfsmount *);
- extern long do_mount(char *, char *, char *, unsigned long, void *);
-+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
- extern void umount_tree(struct vfsmount *);
- #define kern_umount mntput
---- linux-2.4.19-hppl/kernel/ksyms.c~export_hp_2.4.19  2003-04-11 17:02:20.000000000 +0800
-+++ linux-2.4.19-hppl-root/kernel/ksyms.c      2003-04-11 17:12:50.000000000 +0800
-@@ -308,6 +308,10 @@ EXPORT_SYMBOL(dcache_dir_fsync);
- EXPORT_SYMBOL(dcache_readdir);
- EXPORT_SYMBOL(dcache_dir_ops);
-+/* lustre */
-+EXPORT_SYMBOL(pagecache_lock_cacheline);
-+EXPORT_SYMBOL(do_kern_mount);
-+
- /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
- EXPORT_SYMBOL(default_llseek);
- EXPORT_SYMBOL(dentry_open);
-
-_
diff --git a/lustre/kernel_patches/patches/exports_hp_2.4.20.patch b/lustre/kernel_patches/patches/exports_hp_2.4.20.patch
deleted file mode 100644 (file)
index feaeec6..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
- fs/ext3/Makefile   |    2 ++
- fs/ext3/super.c    |    2 +-
- include/linux/fs.h |    1 +
- kernel/ksyms.c     |    4 ++++
- 4 files changed, 8 insertions(+), 1 deletion(-)
-
---- linux/fs/ext3/Makefile~exports_2.4.20      Wed Apr  9 10:07:14 2003
-+++ linux-mmonroe/fs/ext3/Makefile     Wed Apr  9 10:19:53 2003
-@@ -9,6 +9,8 @@
- O_TARGET := ext3.o
-+export-objs :=        super.o inode.o
-+
- obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-               ioctl.o namei.o super.o symlink.o
- obj-m    := $(O_TARGET)
---- linux/fs/ext3/super.c~exports_2.4.20       Wed Apr  9 10:07:14 2003
-+++ linux-mmonroe/fs/ext3/super.c      Wed Apr  9 10:19:53 2003
-@@ -1769,7 +1769,7 @@ static void __exit exit_ext3_fs(void)
-       unregister_filesystem(&ext3_fs_type);
- }
--EXPORT_NO_SYMBOLS;
-+EXPORT_SYMBOL(ext3_bread);
- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
- MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
---- linux/include/linux/fs.h~exports_2.4.20    Wed Apr  9 10:07:14 2003
-+++ linux-mmonroe/include/linux/fs.h   Wed Apr  9 10:19:53 2003
-@@ -1020,6 +1020,7 @@ extern int unregister_filesystem(struct 
- extern struct vfsmount *kern_mount(struct file_system_type *);
- extern int may_umount(struct vfsmount *);
- extern long do_mount(char *, char *, char *, unsigned long, void *);
-+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
- #define kern_umount mntput
---- linux/kernel/ksyms.c~exports_2.4.20        Wed Apr  9 10:07:14 2003
-+++ linux-mmonroe/kernel/ksyms.c       Wed Apr  9 10:19:53 2003
-@@ -308,6 +308,10 @@ EXPORT_SYMBOL(dcache_dir_fsync);
- EXPORT_SYMBOL(dcache_readdir);
- EXPORT_SYMBOL(dcache_dir_ops);
-+/* lustre */
-+EXPORT_SYMBOL(pagecache_lock_cacheline);
-+EXPORT_SYMBOL(do_kern_mount);
-+
- /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
- EXPORT_SYMBOL(default_llseek);
- EXPORT_SYMBOL(dentry_open);
-
-_
diff --git a/lustre/kernel_patches/patches/ext-2.4-patch-1-chaos.patch b/lustre/kernel_patches/patches/ext-2.4-patch-1-chaos.patch
deleted file mode 100644 (file)
index b59cea2..0000000
+++ /dev/null
@@ -1,2527 +0,0 @@
- fs/ext3/Makefile           |    2 
- fs/ext3/dir.c              |  299 +++++++++
- fs/ext3/file.c             |    3 
- fs/ext3/hash.c             |  215 ++++++
- fs/ext3/namei.c            | 1388 ++++++++++++++++++++++++++++++++++++++++-----
- fs/ext3/super.c            |    7 
- include/linux/ext3_fs.h    |   85 ++
- include/linux/ext3_fs_sb.h |    2 
- include/linux/ext3_jbd.h   |    2 
- include/linux/rbtree.h     |    2 
- lib/rbtree.c               |   42 +
- 11 files changed, 1887 insertions(+), 160 deletions(-)
-
---- linux-chaos-2.4.20-6/fs/ext3/Makefile~ext-2.4-patch-1-chaos        2003-04-09 16:10:38.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/Makefile        2003-04-09 16:18:55.000000000 -0600
-@@ -12,7 +12,7 @@ O_TARGET := ext3.o
- export-objs :=        super.o
- obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
--              ioctl.o namei.o super.o symlink.o
-+              ioctl.o namei.o super.o symlink.o hash.o
- obj-m    := $(O_TARGET)
- include $(TOPDIR)/Rules.make
---- linux-chaos-2.4.20-6/fs/ext3/dir.c~ext-2.4-patch-1-chaos   2002-05-07 15:53:46.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/dir.c   2003-04-09 16:18:55.000000000 -0600
-@@ -21,12 +21,16 @@
- #include <linux/fs.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include <linux/slab.h>
-+#include <linux/rbtree.h>
- static unsigned char ext3_filetype_table[] = {
-       DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
- };
- static int ext3_readdir(struct file *, void *, filldir_t);
-+static int ext3_dx_readdir(struct file * filp,
-+                         void * dirent, filldir_t filldir);
- struct file_operations ext3_dir_operations = {
-       read:           generic_read_dir,
-@@ -35,6 +39,17 @@ struct file_operations ext3_dir_operatio
-       fsync:          ext3_sync_file,         /* BKL held */
- };
-+
-+static unsigned char get_dtype(struct super_block *sb, int filetype)
-+{
-+      if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
-+          (filetype >= EXT3_FT_MAX))
-+              return DT_UNKNOWN;
-+
-+      return (ext3_filetype_table[filetype]);
-+}
-+                             
-+
- int ext3_check_dir_entry (const char * function, struct inode * dir,
-                         struct ext3_dir_entry_2 * de,
-                         struct buffer_head * bh,
-@@ -79,6 +94,16 @@ static int ext3_readdir(struct file * fi
-       sb = inode->i_sb;
-+      if (is_dx(inode)) {
-+              err = ext3_dx_readdir(filp, dirent, filldir);
-+              if (err != ERR_BAD_DX_DIR)
-+                      return err;
-+              /*
-+               * We don't set the inode dirty flag since it's not
-+               * critical that it get flushed back to the disk.
-+               */
-+              EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL;
-+      }
-       stored = 0;
-       bh = NULL;
-       offset = filp->f_pos & (sb->s_blocksize - 1);
-@@ -162,18 +187,12 @@ revalidate:
-                                * during the copy operation.
-                                */
-                               unsigned long version = filp->f_version;
--                              unsigned char d_type = DT_UNKNOWN;
--                              if (EXT3_HAS_INCOMPAT_FEATURE(sb,
--                                              EXT3_FEATURE_INCOMPAT_FILETYPE)
--                                              && de->file_type < EXT3_FT_MAX)
--                                      d_type =
--                                        ext3_filetype_table[de->file_type];
-                               error = filldir(dirent, de->name,
-                                               de->name_len,
-                                               filp->f_pos,
-                                               le32_to_cpu(de->inode),
--                                              d_type);
-+                                              get_dtype(sb, de->file_type));
-                               if (error)
-                                       break;
-                               if (version != filp->f_version)
-@@ -188,3 +207,269 @@ revalidate:
-       UPDATE_ATIME(inode);
-       return 0;
- }
-+
-+#ifdef CONFIG_EXT3_INDEX
-+/*
-+ * These functions convert from the major/minor hash to an f_pos
-+ * value.
-+ * 
-+ * Currently we only use major hash numer.  This is unfortunate, but
-+ * on 32-bit machines, the same VFS interface is used for lseek and
-+ * llseek, so if we use the 64 bit offset, then the 32-bit versions of
-+ * lseek/telldir/seekdir will blow out spectacularly, and from within
-+ * the ext2 low-level routine, we don't know if we're being called by
-+ * a 64-bit version of the system call or the 32-bit version of the
-+ * system call.  Worse yet, NFSv2 only allows for a 32-bit readdir
-+ * cookie.  Sigh.
-+ */
-+#define hash2pos(major, minor)        (major >> 1)
-+#define pos2maj_hash(pos)     ((pos << 1) & 0xffffffff)
-+#define pos2min_hash(pos)     (0)
-+
-+/*
-+ * This structure holds the nodes of the red-black tree used to store
-+ * the directory entry in hash order.
-+ */
-+struct fname {
-+      __u32           hash;
-+      __u32           minor_hash;
-+      rb_node_t       rb_hash; 
-+      struct fname    *next;
-+      __u32           inode;
-+      __u8            name_len;
-+      __u8            file_type;
-+      char            name[0];
-+};
-+
-+/*
-+ * This functoin implements a non-recursive way of freeing all of the
-+ * nodes in the red-black tree.
-+ */
-+static void free_rb_tree_fname(rb_root_t *root)
-+{
-+      rb_node_t       *n = root->rb_node;
-+      rb_node_t       *parent;
-+      struct fname    *fname;
-+
-+      while (n) {
-+              /* Do the node's children first */
-+              if ((n)->rb_left) {
-+                      n = n->rb_left;
-+                      continue;
-+              }
-+              if (n->rb_right) {
-+                      n = n->rb_right;
-+                      continue;
-+              }
-+              /*
-+               * The node has no children; free it, and then zero
-+               * out parent's link to it.  Finally go to the
-+               * beginning of the loop and try to free the parent
-+               * node.
-+               */
-+              parent = n->rb_parent;
-+              fname = rb_entry(n, struct fname, rb_hash);
-+              kfree(fname);
-+              if (!parent)
-+                      root->rb_node = 0;
-+              else if (parent->rb_left == n)
-+                      parent->rb_left = 0;
-+              else if (parent->rb_right == n)
-+                      parent->rb_right = 0;
-+              n = parent;
-+      }
-+      root->rb_node = 0;
-+}
-+
-+
-+struct dir_private_info *create_dir_info(loff_t pos)
-+{
-+      struct dir_private_info *p;
-+
-+      p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL);
-+      if (!p)
-+              return NULL;
-+      p->root.rb_node = 0;
-+      p->curr_node = 0;
-+      p->extra_fname = 0;
-+      p->last_pos = 0;
-+      p->curr_hash = pos2maj_hash(pos);
-+      p->curr_minor_hash = pos2min_hash(pos);
-+      p->next_hash = 0;
-+      return p;
-+}
-+
-+void ext3_htree_free_dir_info(struct dir_private_info *p)
-+{
-+      free_rb_tree_fname(&p->root);
-+      kfree(p);
-+}
-+              
-+/*
-+ * Given a directory entry, enter it into the fname rb tree.
-+ */
-+void ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
-+                           __u32 minor_hash,
-+                           struct ext3_dir_entry_2 *dirent)
-+{
-+      rb_node_t **p, *parent = NULL;
-+      struct fname * fname, *new_fn;
-+      struct dir_private_info *info;
-+      int len;
-+
-+      info = (struct dir_private_info *) dir_file->private_data;
-+      p = &info->root.rb_node;
-+
-+      /* Create and allocate the fname structure */
-+      len = sizeof(struct fname) + dirent->name_len + 1;
-+      new_fn = kmalloc(len, GFP_KERNEL);
-+      memset(new_fn, 0, len);
-+      new_fn->hash = hash;
-+      new_fn->minor_hash = minor_hash;
-+      new_fn->inode = le32_to_cpu(dirent->inode);
-+      new_fn->name_len = dirent->name_len;
-+      new_fn->file_type = dirent->file_type;
-+      memcpy(new_fn->name, dirent->name, dirent->name_len);
-+      new_fn->name[dirent->name_len] = 0;
-+      
-+      while (*p) {
-+              parent = *p;
-+              fname = rb_entry(parent, struct fname, rb_hash);
-+
-+              /*
-+               * If the hash and minor hash match up, then we put
-+               * them on a linked list.  This rarely happens...
-+               */
-+              if ((new_fn->hash == fname->hash) &&
-+                  (new_fn->minor_hash == fname->minor_hash)) {
-+                      new_fn->next = fname->next;
-+                      fname->next = new_fn;
-+                      return;
-+              }
-+                      
-+              if (new_fn->hash < fname->hash)
-+                      p = &(*p)->rb_left;
-+              else if (new_fn->hash > fname->hash)
-+                      p = &(*p)->rb_right;
-+              else if (new_fn->minor_hash < fname->minor_hash)
-+                      p = &(*p)->rb_left;
-+              else /* if (new_fn->minor_hash > fname->minor_hash) */
-+                      p = &(*p)->rb_right;
-+      }
-+
-+      rb_link_node(&new_fn->rb_hash, parent, p);
-+      rb_insert_color(&new_fn->rb_hash, &info->root);
-+}
-+
-+
-+
-+/*
-+ * This is a helper function for ext3_dx_readdir.  It calls filldir
-+ * for all entres on the fname linked list.  (Normally there is only
-+ * one entry on the linked list, unless there are 62 bit hash collisions.)
-+ */
-+static int call_filldir(struct file * filp, void * dirent,
-+                      filldir_t filldir, struct fname *fname)
-+{
-+      struct dir_private_info *info = filp->private_data;
-+      loff_t  curr_pos;
-+      struct inode *inode = filp->f_dentry->d_inode;
-+      struct super_block * sb;
-+      int error;
-+
-+      sb = inode->i_sb;
-+      
-+      if (!fname) {
-+              printk("call_filldir: called with null fname?!?\n");
-+              return 0;
-+      }
-+      curr_pos = hash2pos(fname->hash, fname->minor_hash);
-+      while (fname) {
-+              error = filldir(dirent, fname->name,
-+                              fname->name_len, curr_pos, 
-+                              fname->inode,
-+                              get_dtype(sb, fname->file_type));
-+              if (error) {
-+                      filp->f_pos = curr_pos;
-+                      info->extra_fname = fname->next;
-+                      return error;
-+              }
-+              fname = fname->next;
-+      }
-+      return 0;
-+}
-+
-+static int ext3_dx_readdir(struct file * filp,
-+                       void * dirent, filldir_t filldir)
-+{
-+      struct dir_private_info *info = filp->private_data;
-+      struct inode *inode = filp->f_dentry->d_inode;
-+      struct fname *fname;
-+      int     ret;
-+
-+      if (!info) {
-+              info = create_dir_info(filp->f_pos);
-+              if (!info)
-+                      return -ENOMEM;
-+              filp->private_data = info;
-+      }
-+
-+      /* Some one has messed with f_pos; reset the world */
-+      if (info->last_pos != filp->f_pos) {
-+              free_rb_tree_fname(&info->root);
-+              info->curr_node = 0;
-+              info->extra_fname = 0;
-+              info->curr_hash = pos2maj_hash(filp->f_pos);
-+              info->curr_minor_hash = pos2min_hash(filp->f_pos);
-+      }
-+
-+      /*
-+       * If there are any leftover names on the hash collision
-+       * chain, return them first.
-+       */
-+      if (info->extra_fname &&
-+          call_filldir(filp, dirent, filldir, info->extra_fname))
-+              goto finished;
-+
-+      if (!info->curr_node)
-+              info->curr_node = rb_get_first(&info->root);
-+
-+      while (1) {
-+              /*
-+               * Fill the rbtree if we have no more entries,
-+               * or the inode has changed since we last read in the
-+               * cached entries. 
-+               */
-+              if ((!info->curr_node) ||
-+                  (filp->f_version != inode->i_version)) {
-+                      info->curr_node = 0;
-+                      free_rb_tree_fname(&info->root);
-+                      filp->f_version = inode->i_version;
-+                      ret = ext3_htree_fill_tree(filp, info->curr_hash,
-+                                                 info->curr_minor_hash,
-+                                                 &info->next_hash);
-+                      if (ret < 0)
-+                              return ret;
-+                      if (ret == 0)
-+                              break;
-+                      info->curr_node = rb_get_first(&info->root);
-+              }
-+
-+              fname = rb_entry(info->curr_node, struct fname, rb_hash);
-+              info->curr_hash = fname->hash;
-+              info->curr_minor_hash = fname->minor_hash;
-+              if (call_filldir(filp, dirent, filldir, fname))
-+                      break;
-+
-+              info->curr_node = rb_get_next(info->curr_node);
-+              if (!info->curr_node) {
-+                      info->curr_hash = info->next_hash;
-+                      info->curr_minor_hash = 0;
-+              }
-+      }
-+finished:
-+      info->last_pos = filp->f_pos;
-+      UPDATE_ATIME(inode);
-+      return 0;
-+}
-+#endif
---- linux-chaos-2.4.20-6/fs/ext3/file.c~ext-2.4-patch-1-chaos  2003-02-14 15:59:09.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/file.c  2003-04-09 16:18:55.000000000 -0600
-@@ -35,6 +35,9 @@ static int ext3_release_file (struct ino
- {
-       if (filp->f_mode & FMODE_WRITE)
-               ext3_discard_prealloc (inode);
-+      if (is_dx(inode) && filp->private_data)
-+              ext3_htree_free_dir_info(filp->private_data);
-+
-       return 0;
- }
---- /dev/null  2003-01-30 03:24:37.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/hash.c  2003-04-09 16:18:55.000000000 -0600
-@@ -0,0 +1,215 @@
-+/*
-+ *  linux/fs/ext3/hash.c
-+ *
-+ * Copyright (C) 2002 by Theodore Ts'o
-+ *
-+ * This file is released under the GPL v2.
-+ * 
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ */
-+
-+#include <linux/fs.h>
-+#include <linux/jbd.h>
-+#include <linux/sched.h>
-+#include <linux/ext3_fs.h>
-+
-+#define DELTA 0x9E3779B9
-+
-+static void TEA_transform(__u32 buf[4], __u32 const in[])
-+{
-+      __u32   sum = 0;
-+      __u32   b0 = buf[0], b1 = buf[1];
-+      __u32   a = in[0], b = in[1], c = in[2], d = in[3];
-+      int     n = 16;
-+
-+      do {                                                    
-+              sum += DELTA;                                   
-+              b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); 
-+              b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); 
-+      } while(--n);
-+
-+      buf[0] += b0;
-+      buf[1] += b1;
-+}
-+
-+/* F, G and H are basic MD4 functions: selection, majority, parity */
-+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
-+#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
-+#define H(x, y, z) ((x) ^ (y) ^ (z))
-+
-+/*
-+ * The generic round function.  The application is so specific that
-+ * we don't bother protecting all the arguments with parens, as is generally
-+ * good macro practice, in favor of extra legibility.
-+ * Rotation is separate from addition to prevent recomputation
-+ */
-+#define ROUND(f, a, b, c, d, x, s)    \
-+      (a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
-+#define K1 0
-+#define K2 013240474631UL
-+#define K3 015666365641UL
-+
-+/*
-+ * Basic cut-down MD4 transform.  Returns only 32 bits of result.
-+ */
-+static void halfMD4Transform (__u32 buf[4], __u32 const in[])
-+{
-+      __u32   a = buf[0], b = buf[1], c = buf[2], d = buf[3];
-+
-+      /* Round 1 */
-+      ROUND(F, a, b, c, d, in[0] + K1,  3);
-+      ROUND(F, d, a, b, c, in[1] + K1,  7);
-+      ROUND(F, c, d, a, b, in[2] + K1, 11);
-+      ROUND(F, b, c, d, a, in[3] + K1, 19);
-+      ROUND(F, a, b, c, d, in[4] + K1,  3);
-+      ROUND(F, d, a, b, c, in[5] + K1,  7);
-+      ROUND(F, c, d, a, b, in[6] + K1, 11);
-+      ROUND(F, b, c, d, a, in[7] + K1, 19);
-+
-+      /* Round 2 */
-+      ROUND(G, a, b, c, d, in[1] + K2,  3);
-+      ROUND(G, d, a, b, c, in[3] + K2,  5);
-+      ROUND(G, c, d, a, b, in[5] + K2,  9);
-+      ROUND(G, b, c, d, a, in[7] + K2, 13);
-+      ROUND(G, a, b, c, d, in[0] + K2,  3);
-+      ROUND(G, d, a, b, c, in[2] + K2,  5);
-+      ROUND(G, c, d, a, b, in[4] + K2,  9);
-+      ROUND(G, b, c, d, a, in[6] + K2, 13);
-+
-+      /* Round 3 */
-+      ROUND(H, a, b, c, d, in[3] + K3,  3);
-+      ROUND(H, d, a, b, c, in[7] + K3,  9);
-+      ROUND(H, c, d, a, b, in[2] + K3, 11);
-+      ROUND(H, b, c, d, a, in[6] + K3, 15);
-+      ROUND(H, a, b, c, d, in[1] + K3,  3);
-+      ROUND(H, d, a, b, c, in[5] + K3,  9);
-+      ROUND(H, c, d, a, b, in[0] + K3, 11);
-+      ROUND(H, b, c, d, a, in[4] + K3, 15);
-+
-+      buf[0] += a;
-+      buf[1] += b;
-+      buf[2] += c;
-+      buf[3] += d;
-+}
-+
-+#undef ROUND
-+#undef F
-+#undef G
-+#undef H
-+#undef K1
-+#undef K2
-+#undef K3
-+
-+/* The old legacy hash */
-+static __u32 dx_hack_hash (const char *name, int len)
-+{
-+      __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
-+      while (len--) {
-+              __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
-+              
-+              if (hash & 0x80000000) hash -= 0x7fffffff;
-+              hash1 = hash0;
-+              hash0 = hash;
-+      }
-+      return (hash0 << 1);
-+}
-+
-+static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
-+{
-+      __u32   pad, val;
-+      int     i;
-+
-+      pad = (__u32)len | ((__u32)len << 8);
-+      pad |= pad << 16;
-+
-+      val = pad;
-+      if (len > num*4)
-+              len = num * 4;
-+      for (i=0; i < len; i++) {
-+              if ((i % 4) == 0)
-+                      val = pad;
-+              val = msg[i] + (val << 8);
-+              if ((i % 4) == 3) {
-+                      *buf++ = val;
-+                      val = pad;
-+                      num--;
-+              }
-+      }
-+      if (--num >= 0)
-+              *buf++ = val;
-+      while (--num >= 0)
-+              *buf++ = pad;
-+}
-+
-+/*
-+ * Returns the hash of a filename.  If len is 0 and name is NULL, then
-+ * this function can be used to test whether or not a hash version is
-+ * supported.
-+ * 
-+ * The seed is an 4 longword (32 bits) "secret" which can be used to
-+ * uniquify a hash.  If the seed is all zero's, then some default seed
-+ * may be used.
-+ * 
-+ * A particular hash version specifies whether or not the seed is
-+ * represented, and whether or not the returned hash is 32 bits or 64
-+ * bits.  32 bit hashes will return 0 for the minor hash.
-+ */
-+int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
-+{
-+      __u32   hash;
-+      __u32   minor_hash = 0;
-+      const char      *p;
-+      int             i;
-+      __u32           in[8], buf[4];
-+
-+      /* Initialize the default seed for the hash checksum functions */
-+      buf[0] = 0x67452301;
-+      buf[1] = 0xefcdab89;
-+      buf[2] = 0x98badcfe;
-+      buf[3] = 0x10325476;
-+
-+      /* Check to see if the seed is all zero's */
-+      if (hinfo->seed) {
-+              for (i=0; i < 4; i++) {
-+                      if (hinfo->seed[i])
-+                              break;
-+              }
-+              if (i < 4)
-+                      memcpy(buf, hinfo->seed, sizeof(buf));
-+      }
-+              
-+      switch (hinfo->hash_version) {
-+      case DX_HASH_LEGACY:
-+              hash = dx_hack_hash(name, len);
-+              break;
-+      case DX_HASH_HALF_MD4:
-+              p = name;
-+              while (len > 0) {
-+                      str2hashbuf(p, len, in, 8);
-+                      halfMD4Transform(buf, in);
-+                      len -= 32;
-+                      p += 32;
-+              }
-+              minor_hash = buf[2];
-+              hash = buf[1];
-+              break;
-+      case DX_HASH_TEA:
-+              p = name;
-+              while (len > 0) {
-+                      str2hashbuf(p, len, in, 4);
-+                      TEA_transform(buf, in);
-+                      len -= 16;
-+                      p += 16;
-+              }
-+              hash = buf[0];
-+              minor_hash = buf[1];
-+              break;
-+      default:
-+              hinfo->hash = 0;
-+              return -1;
-+      }
-+      hinfo->hash = hash & ~1;
-+      hinfo->minor_hash = minor_hash;
-+      return 0;
-+}
---- linux-chaos-2.4.20-6/fs/ext3/namei.c~ext-2.4-patch-1-chaos 2003-03-12 12:51:02.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/namei.c 2003-04-09 16:26:04.000000000 -0600
-@@ -16,6 +16,12 @@
-  *        David S. Miller (davem@caip.rutgers.edu), 1995
-  *  Directory entry file type support and forward compatibility hooks
-  *    for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
-+ *  Hash Tree Directory indexing (c)
-+ *    Daniel Phillips, 2001
-+ *  Hash Tree Directory indexing porting
-+ *    Christopher Li, 2002
-+ *  Hash Tree Directory indexing cleanup
-+ *    Theodore Ts'o, 2002
-  */
- #include <linux/fs.h>
-@@ -38,6 +44,630 @@
- #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
- #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
-+static struct buffer_head *ext3_append(handle_t *handle,
-+                                      struct inode *inode,
-+                                      u32 *block, int *err)
-+{
-+      struct buffer_head *bh;
-+
-+      *block = inode->i_size >> inode->i_sb->s_blocksize_bits;
-+
-+      if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
-+              inode->i_size += inode->i_sb->s_blocksize;
-+              EXT3_I(inode)->i_disksize = inode->i_size;
-+              ext3_journal_get_write_access(handle,bh);
-+      }
-+      return bh;
-+}
-+
-+#ifndef assert
-+#define assert(test) J_ASSERT(test)
-+#endif
-+
-+#ifndef swap
-+#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
-+#endif
-+
-+typedef struct { u32 v; } le_u32;
-+typedef struct { u16 v; } le_u16;
-+
-+#ifdef DX_DEBUG
-+#define dxtrace(command) command
-+#else
-+#define dxtrace(command) 
-+#endif
-+
-+struct fake_dirent
-+{
-+      /*le*/u32 inode;
-+      /*le*/u16 rec_len;
-+      u8 name_len;
-+      u8 file_type;
-+};
-+
-+struct dx_countlimit
-+{
-+      le_u16 limit;
-+      le_u16 count;
-+};
-+
-+struct dx_entry
-+{
-+      le_u32 hash;
-+      le_u32 block;
-+};
-+
-+/*
-+ * dx_root_info is laid out so that if it should somehow get overlaid by a
-+ * dirent the two low bits of the hash version will be zero.  Therefore, the
-+ * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
-+ */
-+
-+struct dx_root
-+{
-+      struct fake_dirent dot;
-+      char dot_name[4];
-+      struct fake_dirent dotdot;
-+      char dotdot_name[4];
-+      struct dx_root_info
-+      {
-+              le_u32 reserved_zero;
-+              u8 hash_version;
-+              u8 info_length; /* 8 */
-+              u8 indirect_levels;
-+              u8 unused_flags;
-+      }
-+      info;
-+      struct dx_entry entries[0];
-+};
-+
-+struct dx_node
-+{
-+      struct fake_dirent fake;
-+      struct dx_entry entries[0];
-+};
-+
-+
-+struct dx_frame
-+{
-+      struct buffer_head *bh;
-+      struct dx_entry *entries;
-+      struct dx_entry *at;
-+};
-+
-+struct dx_map_entry
-+{
-+      u32 hash;
-+      u32 offs;
-+};
-+
-+#ifdef CONFIG_EXT3_INDEX
-+static inline unsigned dx_get_block (struct dx_entry *entry);
-+static void dx_set_block (struct dx_entry *entry, unsigned value);
-+static inline unsigned dx_get_hash (struct dx_entry *entry);
-+static void dx_set_hash (struct dx_entry *entry, unsigned value);
-+static unsigned dx_get_count (struct dx_entry *entries);
-+static unsigned dx_get_limit (struct dx_entry *entries);
-+static void dx_set_count (struct dx_entry *entries, unsigned value);
-+static void dx_set_limit (struct dx_entry *entries, unsigned value);
-+static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
-+static unsigned dx_node_limit (struct inode *dir);
-+static struct dx_frame *dx_probe(struct dentry *dentry,
-+                               struct inode *dir,
-+                               struct dx_hash_info *hinfo,
-+                               struct dx_frame *frame,
-+                               int *err);
-+static void dx_release (struct dx_frame *frames);
-+static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
-+                      struct dx_hash_info *hinfo, struct dx_map_entry map[]);
-+static void dx_sort_map(struct dx_map_entry *map, unsigned count);
-+static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to,
-+              struct dx_map_entry *offsets, int count);
-+static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size);
-+static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
-+static int ext3_htree_next_block(struct inode *dir, __u32 hash,
-+                               struct dx_frame *frame,
-+                               struct dx_frame *frames, int *err,
-+                               __u32 *start_hash);
-+static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
-+                     struct ext3_dir_entry_2 **res_dir, int *err);
-+static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
-+                           struct inode *inode);
-+
-+/*
-+ * Future: use high four bits of block for coalesce-on-delete flags
-+ * Mask them off for now.
-+ */
-+
-+static inline unsigned dx_get_block (struct dx_entry *entry)
-+{
-+      return le32_to_cpu(entry->block.v) & 0x00ffffff;
-+}
-+
-+static inline void dx_set_block (struct dx_entry *entry, unsigned value)
-+{
-+      entry->block.v = cpu_to_le32(value);
-+}
-+
-+static inline unsigned dx_get_hash (struct dx_entry *entry)
-+{
-+      return le32_to_cpu(entry->hash.v);
-+}
-+
-+static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
-+{
-+      entry->hash.v = cpu_to_le32(value);
-+}
-+
-+static inline unsigned dx_get_count (struct dx_entry *entries)
-+{
-+      return le16_to_cpu(((struct dx_countlimit *) entries)->count.v);
-+}
-+
-+static inline unsigned dx_get_limit (struct dx_entry *entries)
-+{
-+      return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v);
-+}
-+
-+static inline void dx_set_count (struct dx_entry *entries, unsigned value)
-+{
-+      ((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value);
-+}
-+
-+static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
-+{
-+      ((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value);
-+}
-+
-+static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
-+{
-+      unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) -
-+              EXT3_DIR_REC_LEN(2) - infosize;
-+      return 0? 20: entry_space / sizeof(struct dx_entry);
-+}
-+
-+static inline unsigned dx_node_limit (struct inode *dir)
-+{
-+      unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0);
-+      return 0? 22: entry_space / sizeof(struct dx_entry);
-+}
-+
-+/*
-+ * Debug
-+ */
-+#ifdef DX_DEBUG
-+struct stats
-+{ 
-+      unsigned names;
-+      unsigned space;
-+      unsigned bcount;
-+};
-+
-+static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_entry_2 *de,
-+                               int size, int show_names)
-+{
-+      unsigned names = 0, space = 0;
-+      char *base = (char *) de;
-+      struct dx_hash_info h = *hinfo;
-+      
-+      printk("names: ");
-+      while ((char *) de < base + size)
-+      {
-+              if (de->inode)
-+              {
-+                      if (show_names)
-+                      {
-+                              int len = de->name_len;
-+                              char *name = de->name;
-+                              while (len--) printk("%c", *name++);
-+                              ext3fs_dirhash(de->name, de->name_len, &h);
-+                              printk(":%x.%u ", h.hash,
-+                                     ((char *) de - base));
-+                      }
-+                      space += EXT3_DIR_REC_LEN(de->name_len);
-+                      names++;
-+              }
-+              de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-+      }
-+      printk("(%i)\n", names);
-+      return (struct stats) { names, space, 1 };
-+}
-+
-+struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
-+                           struct dx_entry *entries, int levels)
-+{
-+      unsigned blocksize = dir->i_sb->s_blocksize;
-+      unsigned count = dx_get_count (entries), names = 0, space = 0, i;
-+      unsigned bcount = 0;
-+      struct buffer_head *bh;
-+      int err;
-+      printk("%i indexed blocks...\n", count);
-+      for (i = 0; i < count; i++, entries++)
-+      {
-+              u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0;
-+              u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
-+              struct stats stats;
-+              printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
-+              if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue;
-+              stats = levels?
-+                 dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
-+                 dx_show_leaf(hinfo, (struct ext3_dir_entry_2 *) bh->b_data, blocksize, 0);
-+              names += stats.names;
-+              space += stats.space;
-+              bcount += stats.bcount;
-+              brelse (bh);
-+      }
-+      if (bcount)
-+              printk("%snames %u, fullness %u (%u%%)\n", levels?"":"   ",
-+                      names, space/bcount,(space/bcount)*100/blocksize);
-+      return (struct stats) { names, space, bcount};
-+}
-+#endif /* DX_DEBUG */
-+
-+/*
-+ * Probe for a directory leaf block to search.
-+ *
-+ * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
-+ * error in the directory index, and the caller should fall back to
-+ * searching the directory normally.  The callers of dx_probe **MUST**
-+ * check for this error code, and make sure it never gets reflected
-+ * back to userspace.
-+ */
-+static struct dx_frame *
-+dx_probe(struct dentry *dentry, struct inode *dir,
-+       struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
-+{
-+      unsigned count, indirect;
-+      struct dx_entry *at, *entries, *p, *q, *m;
-+      struct dx_root *root;
-+      struct buffer_head *bh;
-+      struct dx_frame *frame = frame_in;
-+      u32 hash;
-+
-+      frame->bh = NULL;
-+      if (dentry)
-+              dir = dentry->d_parent->d_inode;
-+      if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
-+              goto fail;
-+      root = (struct dx_root *) bh->b_data;
-+      if (root->info.hash_version != DX_HASH_TEA &&
-+          root->info.hash_version != DX_HASH_HALF_MD4 &&
-+          root->info.hash_version != DX_HASH_LEGACY) {
-+              ext3_warning(dir->i_sb, __FUNCTION__,
-+                           "Unrecognised inode hash code %d",
-+                           root->info.hash_version);
-+              brelse(bh);
-+              *err = ERR_BAD_DX_DIR;
-+              goto fail;
-+      }
-+      hinfo->hash_version = root->info.hash_version;
-+      hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed;
-+      if (dentry)
-+              ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
-+      hash = hinfo->hash;
-+
-+      if (root->info.unused_flags & 1) {
-+              ext3_warning(dir->i_sb, __FUNCTION__,
-+                           "Unimplemented inode hash flags: %#06x",
-+                           root->info.unused_flags);
-+              brelse(bh);
-+              *err = ERR_BAD_DX_DIR;
-+              goto fail;
-+      }
-+
-+      if ((indirect = root->info.indirect_levels) > 1) {
-+              ext3_warning(dir->i_sb, __FUNCTION__,
-+                           "Unimplemented inode hash depth: %#06x",
-+                           root->info.indirect_levels);
-+              brelse(bh);
-+              *err = ERR_BAD_DX_DIR;
-+              goto fail;
-+      }
-+
-+      entries = (struct dx_entry *) (((char *)&root->info) +
-+                                     root->info.info_length);
-+      assert(dx_get_limit(entries) == dx_root_limit(dir,
-+                                                    root->info.info_length));
-+      dxtrace (printk("Look up %x", hash));
-+      while (1)
-+      {
-+              count = dx_get_count(entries);
-+              assert (count && count <= dx_get_limit(entries));
-+              p = entries + 1;
-+              q = entries + count - 1;
-+              while (p <= q)
-+              {
-+                      m = p + (q - p)/2;
-+                      dxtrace(printk("."));
-+                      if (dx_get_hash(m) > hash)
-+                              q = m - 1;
-+                      else
-+                              p = m + 1;
-+              }
-+
-+              if (0) // linear search cross check
-+              {
-+                      unsigned n = count - 1;
-+                      at = entries;
-+                      while (n--)
-+                      {
-+                              dxtrace(printk(","));
-+                              if (dx_get_hash(++at) > hash)
-+                              {
-+                                      at--;
-+                                      break;
-+                              }
-+                      }
-+                      assert (at == p - 1);
-+              }
-+
-+              at = p - 1;
-+              dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
-+              frame->bh = bh;
-+              frame->entries = entries;
-+              frame->at = at;
-+              if (!indirect--) return frame;
-+              if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
-+                      goto fail2;
-+              at = entries = ((struct dx_node *) bh->b_data)->entries;
-+              assert (dx_get_limit(entries) == dx_node_limit (dir));
-+              frame++;
-+      }
-+fail2:
-+      while (frame >= frame_in) {
-+              brelse(frame->bh);
-+              frame--;
-+      }
-+fail:
-+      return NULL;
-+}
-+
-+static void dx_release (struct dx_frame *frames)
-+{
-+      if (frames[0].bh == NULL)
-+              return;
-+
-+      if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
-+              brelse(frames[1].bh);
-+      brelse(frames[0].bh);
-+}
-+
-+/*
-+ * This function increments the frame pointer to search the next leaf
-+ * block, and reads in the necessary intervening nodes if the search
-+ * should be necessary.  Whether or not the search is necessary is
-+ * controlled by the hash parameter.  If the hash value is even, then
-+ * the search is only continued if the next block starts with that
-+ * hash value.  This is used if we are searching for a specific file.
-+ *
-+ * If the hash value is HASH_NB_ALWAYS, then always go to the next block.
-+ *
-+ * This function returns 1 if the caller should continue to search,
-+ * or 0 if it should not.  If there is an error reading one of the
-+ * index blocks, it will return -1.
-+ *
-+ * If start_hash is non-null, it will be filled in with the starting
-+ * hash of the next page.
-+ */
-+static int ext3_htree_next_block(struct inode *dir, __u32 hash,
-+                               struct dx_frame *frame,
-+                               struct dx_frame *frames, int *err,
-+                               __u32 *start_hash)
-+{
-+      struct dx_frame *p;
-+      struct buffer_head *bh;
-+      int num_frames = 0;
-+      __u32 bhash;
-+
-+      *err = ENOENT;
-+      p = frame;
-+      /*
-+       * Find the next leaf page by incrementing the frame pointer.
-+       * If we run out of entries in the interior node, loop around and
-+       * increment pointer in the parent node.  When we break out of
-+       * this loop, num_frames indicates the number of interior
-+       * nodes need to be read.
-+       */
-+      while (1) {
-+              if (++(p->at) < p->entries + dx_get_count(p->entries))
-+                      break;
-+              if (p == frames)
-+                      return 0;
-+              num_frames++;
-+              p--;
-+      }
-+
-+      /*
-+       * If the hash is 1, then continue only if the next page has a
-+       * continuation hash of any value.  This is used for readdir
-+       * handling.  Otherwise, check to see if the hash matches the
-+       * desired contiuation hash.  If it doesn't, return since
-+       * there's no point to read in the successive index pages.
-+       */
-+      bhash = dx_get_hash(p->at);
-+      if (start_hash)
-+              *start_hash = bhash;
-+      if ((hash & 1) == 0) {
-+              if ((bhash & ~1) != hash)
-+                      return 0;
-+      }
-+      /*
-+       * If the hash is HASH_NB_ALWAYS, we always go to the next
-+       * block so no check is necessary
-+       */
-+      while (num_frames--) {
-+              if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
-+                                    0, err)))
-+                      return -1; /* Failure */
-+              p++;
-+              brelse (p->bh);
-+              p->bh = bh;
-+              p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
-+      }
-+      return 1;
-+}
-+
-+
-+/*
-+ * p is at least 6 bytes before the end of page
-+ */
-+static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p)
-+{
-+      return (struct ext3_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len));
-+}
-+
-+/*
-+ * This function fills a red-black tree with information from a
-+ * directory.  We start scanning the directory in hash order, starting
-+ * at start_hash and start_minor_hash.
-+ *
-+ * This function returns the number of entries inserted into the tree,
-+ * or a negative error code.
-+ */
-+int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
-+                       __u32 start_minor_hash, __u32 *next_hash)
-+{
-+      struct dx_hash_info hinfo;
-+      struct buffer_head *bh;
-+      struct ext3_dir_entry_2 *de, *top;
-+      static struct dx_frame frames[2], *frame;
-+      struct inode *dir;
-+      int block, err;
-+      int count = 0;
-+      int ret;
-+      __u32 hashval;
-+      
-+      dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
-+                     start_minor_hash));
-+      dir = dir_file->f_dentry->d_inode;
-+      hinfo.hash = start_hash;
-+      hinfo.minor_hash = 0;
-+      frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
-+      if (!frame)
-+              return err;
-+
-+      while (1) {
-+              block = dx_get_block(frame->at);
-+              dxtrace(printk("Reading block %d\n", block));
-+              if (!(bh = ext3_bread (NULL, dir, block, 0, &err)))
-+                      goto errout;
-+      
-+              de = (struct ext3_dir_entry_2 *) bh->b_data;
-+              top = (struct ext3_dir_entry_2 *) ((char *) de + dir->i_sb->s_blocksize -
-+                                     EXT3_DIR_REC_LEN(0));
-+              for (; de < top; de = ext3_next_entry(de)) {
-+                      ext3fs_dirhash(de->name, de->name_len, &hinfo);
-+                      if ((hinfo.hash < start_hash) ||
-+                          ((hinfo.hash == start_hash) &&
-+                           (hinfo.minor_hash < start_minor_hash)))
-+                              continue;
-+                      ext3_htree_store_dirent(dir_file, hinfo.hash,
-+                                              hinfo.minor_hash, de);
-+                      count++;
-+              }
-+              brelse (bh);
-+              hashval = ~1;
-+              ret = ext3_htree_next_block(dir, HASH_NB_ALWAYS, 
-+                                          frame, frames, &err, &hashval);
-+              if (next_hash)
-+                      *next_hash = hashval;
-+              if (ret == -1)
-+                      goto errout;
-+              /*
-+               * Stop if:  (a) there are no more entries, or
-+               * (b) we have inserted at least one entry and the
-+               * next hash value is not a continuation
-+               */
-+              if ((ret == 0) ||
-+                  (count && ((hashval & 1) == 0)))
-+                      break;
-+      }
-+      dx_release(frames);
-+      dxtrace(printk("Fill tree: returned %d entries\n", count));
-+      return count;
-+errout:
-+      dx_release(frames);
-+      return (err);
-+}
-+
-+
-+/*
-+ * Directory block splitting, compacting
-+ */
-+
-+static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
-+                      struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
-+{
-+      int count = 0;
-+      char *base = (char *) de;
-+      struct dx_hash_info h = *hinfo;
-+      
-+      while ((char *) de < base + size)
-+      {
-+              if (de->name_len && de->inode) {
-+                      ext3fs_dirhash(de->name, de->name_len, &h);
-+                      map_tail--;
-+                      map_tail->hash = h.hash;
-+                      map_tail->offs = (u32) ((char *) de - base);
-+                      count++;
-+              }
-+              /* XXX: do we need to check rec_len == 0 case? -Chris */
-+              de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-+      }
-+      return count;
-+}
-+
-+static void dx_sort_map (struct dx_map_entry *map, unsigned count)
-+{
-+        struct dx_map_entry *p, *q, *top = map + count - 1;
-+        int more;
-+        /* Combsort until bubble sort doesn't suck */
-+        while (count > 2)
-+      {
-+                count = count*10/13;
-+                if (count - 9 < 2) /* 9, 10 -> 11 */
-+                        count = 11;
-+                for (p = top, q = p - count; q >= map; p--, q--)
-+                        if (p->hash < q->hash)
-+                                swap(*p, *q);
-+        }
-+        /* Garden variety bubble sort */
-+        do {
-+                more = 0;
-+                q = top;
-+                while (q-- > map)
-+              {
-+                        if (q[1].hash >= q[0].hash)
-+                              continue;
-+                        swap(*(q+1), *q);
-+                        more = 1;
-+              }
-+      } while(more);
-+}
-+
-+static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
-+{
-+      struct dx_entry *entries = frame->entries;
-+      struct dx_entry *old = frame->at, *new = old + 1;
-+      int count = dx_get_count(entries);
-+
-+      assert(count < dx_get_limit(entries));
-+      assert(old < entries + count);
-+      memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
-+      dx_set_hash(new, hash);
-+      dx_set_block(new, block);
-+      dx_set_count(entries, count + 1);
-+}
-+#endif
-+
-+
-+static void ext3_update_dx_flag(struct inode *inode)
-+{
-+      if (!EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
-+                                   EXT3_FEATURE_COMPAT_DIR_INDEX))
-+              EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL;
-+}
-+
- /*
-  * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure.
-  *
-@@ -94,6 +724,7 @@ static int inline search_dirblock(struct
-       return 0;
- }
-+
- /*
-  *    ext3_find_entry()
-  *
-@@ -105,6 +736,8 @@ static int inline search_dirblock(struct
-  * The returned buffer_head has ->b_count elevated.  The caller is expected
-  * to brelse() it when appropriate.
-  */
-+
-+      
- static struct buffer_head * ext3_find_entry (struct dentry *dentry,
-                                       struct ext3_dir_entry_2 ** res_dir)
- {
-@@ -119,12 +752,32 @@ static struct buffer_head * ext3_find_en
-       int num = 0;
-       int nblocks, i, err;
-       struct inode *dir = dentry->d_parent->d_inode;
-+      int namelen;
-+      const u8 *name;
-+      unsigned blocksize;
-       *res_dir = NULL;
-       sb = dir->i_sb;
--
-+      blocksize = sb->s_blocksize;
-+      namelen = dentry->d_name.len;
-+      name = dentry->d_name.name;
-+      if (namelen > EXT3_NAME_LEN)
-+              return NULL;
-+#ifdef CONFIG_EXT3_INDEX
-+      if (is_dx(dir)) {
-+              bh = ext3_dx_find_entry(dentry, res_dir, &err);
-+              /*
-+               * On success, or if the error was file not found,
-+               * return.  Otherwise, fall back to doing a search the
-+               * old fashioned way.
-+               */
-+              if (bh || (err != ERR_BAD_DX_DIR))
-+                      return bh;
-+              dxtrace(printk("ext3_find_entry: dx failed, falling back\n"));
-+      }
-+#endif
-       nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
--      start = dir->u.ext3_i.i_dir_start_lookup;
-+      start = EXT3_I(dir)->i_dir_start_lookup;
-       if (start >= nblocks)
-               start = 0;
-       block = start;
-@@ -166,7 +819,7 @@ restart:
-               i = search_dirblock(bh, dir, dentry,
-                           block << EXT3_BLOCK_SIZE_BITS(sb), res_dir);
-               if (i == 1) {
--                      dir->u.ext3_i.i_dir_start_lookup = block;
-+                      EXT3_I(dir)->i_dir_start_lookup = block;
-                       ret = bh;
-                       goto cleanup_and_exit;
-               } else {
-@@ -197,6 +850,66 @@ cleanup_and_exit:
-       return ret;
- }
-+#ifdef CONFIG_EXT3_INDEX
-+static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
-+                     struct ext3_dir_entry_2 **res_dir, int *err)
-+{
-+      struct super_block * sb;
-+      struct dx_hash_info     hinfo;
-+      u32 hash;
-+      struct dx_frame frames[2], *frame;
-+      struct ext3_dir_entry_2 *de, *top;
-+      struct buffer_head *bh;
-+      unsigned long block;
-+      int retval;
-+      int namelen = dentry->d_name.len;
-+      const u8 *name = dentry->d_name.name;
-+      struct inode *dir = dentry->d_parent->d_inode;
-+      
-+      sb = dir->i_sb;
-+      if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
-+              return NULL;
-+      hash = hinfo.hash;
-+      do {
-+              block = dx_get_block(frame->at);
-+              if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
-+                      goto errout;
-+              de = (struct ext3_dir_entry_2 *) bh->b_data;
-+              top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize -
-+                                     EXT3_DIR_REC_LEN(0));
-+              for (; de < top; de = ext3_next_entry(de))
-+              if (ext3_match (namelen, name, de)) {
-+                      if (!ext3_check_dir_entry("ext3_find_entry",
-+                                                dir, de, bh,
-+                                (block<<EXT3_BLOCK_SIZE_BITS(sb))
-+                                        +((char *)de - bh->b_data))) {
-+                              brelse (bh);
-+                              goto errout;
-+                      }
-+                      *res_dir = de;
-+                      dx_release (frames);
-+                      return bh;
-+              }
-+              brelse (bh);
-+              /* Check to see if we should continue to search */
-+              retval = ext3_htree_next_block(dir, hash, frame,
-+                                             frames, err, 0);
-+              if (retval == -1) {
-+                      ext3_warning(sb, __FUNCTION__,
-+                           "error reading index page in directory #%lu",
-+                           dir->i_ino);
-+                      goto errout;
-+              }
-+      } while (retval == 1);
-+      
-+      *err = -ENOENT;
-+errout:
-+      dxtrace(printk("%s not found\n", name));
-+      dx_release (frames);
-+      return NULL;
-+}
-+#endif
-+
- static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
- {
-       struct inode * inode;
-@@ -213,8 +926,9 @@ static struct dentry *ext3_lookup(struct
-               brelse (bh);
-               inode = iget(dir->i_sb, ino);
--              if (!inode)
-+              if (!inode) {
-                       return ERR_PTR(-EACCES);
-+              }
-       }
-       d_add(dentry, inode);
-       return NULL;
-@@ -238,6 +952,300 @@ static inline void ext3_set_de_type(stru
-               de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
- }
-+#ifdef CONFIG_EXT3_INDEX
-+static struct ext3_dir_entry_2 *
-+dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
-+{
-+      unsigned rec_len = 0;
-+
-+      while (count--) {
-+              struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs);
-+              rec_len = EXT3_DIR_REC_LEN(de->name_len);
-+              memcpy (to, de, rec_len);
-+              ((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
-+              de->inode = 0;
-+              map++;
-+              to += rec_len;
-+      }
-+      return (struct ext3_dir_entry_2 *) (to - rec_len);
-+}
-+
-+static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
-+{
-+      struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base;
-+      unsigned rec_len = 0;
-+
-+      prev = to = de;
-+      while ((char*)de < base + size) {
-+              next = (struct ext3_dir_entry_2 *) ((char *) de +
-+                                                  le16_to_cpu(de->rec_len));
-+              if (de->inode && de->name_len) {
-+                      rec_len = EXT3_DIR_REC_LEN(de->name_len);
-+                      if (de > to)
-+                              memmove(to, de, rec_len);
-+                      to->rec_len = rec_len;
-+                      prev = to;
-+                      to = (struct ext3_dir_entry_2 *) (((char *) to) + rec_len);
-+              }
-+              de = next;
-+      }
-+      return prev;
-+}
-+
-+static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
-+                      struct buffer_head **bh,struct dx_frame *frame,
-+                      struct dx_hash_info *hinfo, int *error)
-+{
-+      unsigned blocksize = dir->i_sb->s_blocksize;
-+      unsigned count, continued;
-+      struct buffer_head *bh2;
-+      u32 newblock;
-+      u32 hash2;
-+      struct dx_map_entry *map;
-+      char *data1 = (*bh)->b_data, *data2;
-+      unsigned split;
-+      struct ext3_dir_entry_2 *de = NULL, *de2;
-+      int     err;
-+
-+      bh2 = ext3_append (handle, dir, &newblock, error);
-+      if (!(bh2)) {
-+              brelse(*bh);
-+              *bh = NULL;
-+              goto errout;
-+      }
-+
-+      BUFFER_TRACE(*bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, *bh);
-+      if (err) {
-+      journal_error:
-+              brelse(*bh);
-+              brelse(bh2);
-+              *bh = NULL;
-+              ext3_std_error(dir->i_sb, err);
-+              goto errout;
-+      }
-+      BUFFER_TRACE(frame->bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, frame->bh);
-+      if (err)
-+              goto journal_error;
-+
-+      data2 = bh2->b_data;
-+
-+      /* create map in the end of data2 block */
-+      map = (struct dx_map_entry *) (data2 + blocksize);
-+      count = dx_make_map ((struct ext3_dir_entry_2 *) data1,
-+                           blocksize, hinfo, map);
-+      map -= count;
-+      split = count/2; // need to adjust to actual middle
-+      dx_sort_map (map, count);
-+      hash2 = map[split].hash;
-+      continued = hash2 == map[split - 1].hash;
-+      dxtrace(printk("Split block %i at %x, %i/%i\n",
-+              dx_get_block(frame->at), hash2, split, count-split));
-+
-+      /* Fancy dance to stay within two buffers */
-+      de2 = dx_move_dirents(data1, data2, map + split, count - split);
-+      de = dx_pack_dirents(data1,blocksize);
-+      de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
-+      de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
-+      dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1));
-+      dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1));
-+
-+      /* Which block gets the new entry? */
-+      if (hinfo->hash >= hash2)
-+      {
-+              swap(*bh, bh2);
-+              de = de2;
-+      }
-+      dx_insert_block (frame, hash2 + continued, newblock);
-+      err = ext3_journal_dirty_metadata (handle, bh2);
-+      if (err)
-+              goto journal_error;
-+      err = ext3_journal_dirty_metadata (handle, frame->bh);
-+      if (err)
-+              goto journal_error;
-+      brelse (bh2);
-+      dxtrace(dx_show_index ("frame", frame->entries));
-+errout:
-+      return de;
-+}
-+#endif
-+
-+
-+/*
-+ * Add a new entry into a directory (leaf) block.  If de is non-NULL,
-+ * it points to a directory entry which is guaranteed to be large
-+ * enough for new directory entry.  If de is NULL, then
-+ * add_dirent_to_buf will attempt search the directory block for
-+ * space.  It will return -ENOSPC if no space is available, and -EIO
-+ * and -EEXIST if directory entry already exists.
-+ * 
-+ * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
-+ * all other cases bh is released.
-+ */
-+static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
-+                           struct inode *inode, struct ext3_dir_entry_2 *de,
-+                           struct buffer_head * bh)
-+{
-+      struct inode    *dir = dentry->d_parent->d_inode;
-+      const char      *name = dentry->d_name.name;
-+      int             namelen = dentry->d_name.len;
-+      unsigned long   offset = 0;
-+      unsigned short  reclen;
-+      int             nlen, rlen, err;
-+      char            *top;
-+      
-+      reclen = EXT3_DIR_REC_LEN(namelen);
-+      if (!de) {
-+              de = (struct ext3_dir_entry_2 *)bh->b_data;
-+              top = bh->b_data + dir->i_sb->s_blocksize - reclen;
-+              while ((char *) de <= top) {
-+                      if (!ext3_check_dir_entry("ext3_add_entry", dir, de,
-+                                                bh, offset)) {
-+                              brelse (bh);
-+                              return -EIO;
-+                      }
-+                      if (ext3_match (namelen, name, de)) {
-+                              brelse (bh);
-+                              return -EEXIST;
-+                      }
-+                      nlen = EXT3_DIR_REC_LEN(de->name_len);
-+                      rlen = le16_to_cpu(de->rec_len);
-+                      if ((de->inode? rlen - nlen: rlen) >= reclen)
-+                              break;
-+                      de = (struct ext3_dir_entry_2 *)((char *)de + rlen);
-+                      offset += rlen;
-+              }
-+              if ((char *) de > top)
-+                      return -ENOSPC;
-+      }
-+      BUFFER_TRACE(bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, bh);
-+      if (err) {
-+              ext3_std_error(dir->i_sb, err);
-+              brelse(bh);
-+              return err;
-+      }
-+      
-+      /* By now the buffer is marked for journaling */
-+      nlen = EXT3_DIR_REC_LEN(de->name_len);
-+      rlen = le16_to_cpu(de->rec_len);
-+      if (de->inode) {
-+              struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen);
-+              de1->rec_len = cpu_to_le16(rlen - nlen);
-+              de->rec_len = cpu_to_le16(nlen);
-+              de = de1;
-+      }
-+      de->file_type = EXT3_FT_UNKNOWN;
-+      if (inode) {
-+              de->inode = cpu_to_le32(inode->i_ino);
-+              ext3_set_de_type(dir->i_sb, de, inode->i_mode);
-+      } else
-+              de->inode = 0;
-+      de->name_len = namelen;
-+      memcpy (de->name, name, namelen);
-+      /*
-+       * XXX shouldn't update any times until successful
-+       * completion of syscall, but too many callers depend
-+       * on this.
-+       *
-+       * XXX similarly, too many callers depend on
-+       * ext3_new_inode() setting the times, but error
-+       * recovery deletes the inode, so the worst that can
-+       * happen is that the times are slightly out of date
-+       * and/or different from the directory change time.
-+       */
-+      dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-+      ext3_update_dx_flag(dir);
-+      dir->i_version = ++event;
-+      ext3_mark_inode_dirty(handle, dir);
-+      BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
-+      err = ext3_journal_dirty_metadata(handle, bh);
-+      if (err)
-+              ext3_std_error(dir->i_sb, err);
-+      brelse(bh);
-+      return 0;
-+}
-+
-+#ifdef CONFIG_EXT3_INDEX
-+/*
-+ * This converts a one block unindexed directory to a 3 block indexed
-+ * directory, and adds the dentry to the indexed directory.
-+ */
-+static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
-+                          struct inode *inode, struct buffer_head *bh)
-+{
-+      struct inode    *dir = dentry->d_parent->d_inode;
-+      const char      *name = dentry->d_name.name;
-+      int             namelen = dentry->d_name.len;
-+      struct buffer_head *bh2;
-+      struct dx_root  *root;
-+      struct dx_frame frames[2], *frame;
-+      struct dx_entry *entries;
-+      struct ext3_dir_entry_2 *de, *de2;
-+      char            *data1, *top;
-+      unsigned        len;
-+      int             retval;
-+      unsigned        blocksize;
-+      struct dx_hash_info hinfo;
-+      u32             block;
-+              
-+      blocksize =  dir->i_sb->s_blocksize;
-+      dxtrace(printk("Creating index\n"));
-+      retval = ext3_journal_get_write_access(handle, bh);
-+      if (retval) {
-+              ext3_std_error(dir->i_sb, retval);
-+              brelse(bh);
-+              return retval;
-+      }
-+      root = (struct dx_root *) bh->b_data;
-+              
-+      EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
-+      bh2 = ext3_append (handle, dir, &block, &retval);
-+      if (!(bh2)) {
-+              brelse(bh);
-+              return retval;
-+      }
-+      data1 = bh2->b_data;
-+
-+      /* The 0th block becomes the root, move the dirents out */
-+      de = (struct ext3_dir_entry_2 *) &root->info;
-+      len = ((char *) root) + blocksize - (char *) de;
-+      memcpy (data1, de, len);
-+      de = (struct ext3_dir_entry_2 *) data1;
-+      top = data1 + len;
-+      while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top)
-+              de = de2;
-+      de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
-+      /* Initialize the root; the dot dirents already exist */
-+      de = (struct ext3_dir_entry_2 *) (&root->dotdot);
-+      de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2));
-+      memset (&root->info, 0, sizeof(root->info));
-+      root->info.info_length = sizeof(root->info);
-+      root->info.hash_version = dir->i_sb->u.ext3_sb.s_def_hash_version;
-+      entries = root->entries;
-+      dx_set_block (entries, 1);
-+      dx_set_count (entries, 1);
-+      dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
-+
-+      /* Initialize as for dx_probe */
-+      hinfo.hash_version = root->info.hash_version;
-+      hinfo.seed = dir->i_sb->u.ext3_sb.s_hash_seed;
-+      ext3fs_dirhash(name, namelen, &hinfo);
-+      frame = frames;
-+      frame->entries = entries;
-+      frame->at = entries;
-+      frame->bh = bh;
-+      bh = bh2;
-+      de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
-+      dx_release (frames);
-+      if (!(de))
-+              return retval;
-+
-+      return add_dirent_to_buf(handle, dentry, inode, de, bh);
-+}
-+#endif
-+
- /*
-  *    ext3_add_entry()
-  *
-@@ -248,127 +1256,198 @@ static inline void ext3_set_de_type(stru
-  * may not sleep between calling this and putting something into
-  * the entry, as someone else might have used it while you slept.
-  */
--
--/*
-- * AKPM: the journalling code here looks wrong on the error paths
-- */
- static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
-       struct inode *inode)
- {
-       struct inode *dir = dentry->d_parent->d_inode;
--      const char *name = dentry->d_name.name;
--      int namelen = dentry->d_name.len;
-       unsigned long offset;
--      unsigned short rec_len;
-       struct buffer_head * bh;
--      struct ext3_dir_entry_2 * de, * de1;
-+      struct ext3_dir_entry_2 *de;
-       struct super_block * sb;
-       int     retval;
-+#ifdef CONFIG_EXT3_INDEX
-+      int     dx_fallback=0;
-+#endif
-+      unsigned blocksize;
-+      unsigned nlen, rlen;
-+      u32 block, blocks;
-       sb = dir->i_sb;
--
--      if (!namelen)
-+      blocksize = sb->s_blocksize;
-+      if (!dentry->d_name.len)
-               return -EINVAL;
--      bh = ext3_bread (handle, dir, 0, 0, &retval);
-+#ifdef CONFIG_EXT3_INDEX
-+      if (is_dx(dir)) {
-+              retval = ext3_dx_add_entry(handle, dentry, inode);
-+              if (!retval || (retval != ERR_BAD_DX_DIR))
-+                      return retval;
-+              EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL;
-+              dx_fallback++;
-+              ext3_mark_inode_dirty(handle, dir);
-+      }
-+#endif
-+      blocks = dir->i_size >> sb->s_blocksize_bits;
-+      for (block = 0, offset = 0; block < blocks; block++) {
-+              bh = ext3_bread(handle, dir, block, 0, &retval);
-+              if(!bh)
-+                      return retval;
-+              retval = add_dirent_to_buf(handle, dentry, inode, 0, bh);
-+              if (retval != -ENOSPC)
-+                      return retval;
-+
-+#ifdef CONFIG_EXT3_INDEX
-+              if (blocks == 1 && !dx_fallback &&
-+                  EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
-+                      return make_indexed_dir(handle, dentry, inode, bh);
-+#endif
-+              brelse(bh);
-+      }
-+      bh = ext3_append(handle, dir, &block, &retval);
-       if (!bh)
-               return retval;
--      rec_len = EXT3_DIR_REC_LEN(namelen);
--      offset = 0;
-       de = (struct ext3_dir_entry_2 *) bh->b_data;
--      while (1) {
--              if ((char *)de >= sb->s_blocksize + bh->b_data) {
--                      brelse (bh);
--                      bh = NULL;
--                      bh = ext3_bread (handle, dir,
--                              offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval);
--                      if (!bh)
--                              return retval;
--                      if (dir->i_size <= offset) {
--                              if (dir->i_size == 0) {
--                                      brelse(bh);
--                                      return -ENOENT;
--                              }
-+      de->inode = 0;
-+      de->rec_len = cpu_to_le16(rlen = blocksize);
-+      nlen = 0;
-+      return add_dirent_to_buf(handle, dentry, inode, de, bh);
-+}
--                              ext3_debug ("creating next block\n");
-+#ifdef CONFIG_EXT3_INDEX
-+/*
-+ * Returns 0 for success, or a negative error value
-+ */
-+static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
-+                           struct inode *inode)
-+{
-+      struct dx_frame frames[2], *frame;
-+      struct dx_entry *entries, *at;
-+      struct dx_hash_info hinfo;
-+      struct buffer_head * bh;
-+      struct inode *dir = dentry->d_parent->d_inode;
-+      struct super_block * sb = dir->i_sb;
-+      struct ext3_dir_entry_2 *de;
-+      int err;
--                              BUFFER_TRACE(bh, "get_write_access");
--                              ext3_journal_get_write_access(handle, bh);
--                              de = (struct ext3_dir_entry_2 *) bh->b_data;
--                              de->inode = 0;
--                              de->rec_len = le16_to_cpu(sb->s_blocksize);
--                              dir->u.ext3_i.i_disksize =
--                                      dir->i_size = offset + sb->s_blocksize;
--                              dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
--                              ext3_mark_inode_dirty(handle, dir);
--                      } else {
-+      frame = dx_probe(dentry, 0, &hinfo, frames, &err);
-+      if (!frame)
-+              return err;
-+      entries = frame->entries;
-+      at = frame->at;
--                              ext3_debug ("skipping to next block\n");
-+      if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
-+              goto cleanup;
--                              de = (struct ext3_dir_entry_2 *) bh->b_data;
--                      }
--              }
--              if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh,
--                                         offset)) {
--                      brelse (bh);
--                      return -ENOENT;
--              }
--              if (ext3_match (namelen, name, de)) {
--                              brelse (bh);
--                              return -EEXIST;
-+      BUFFER_TRACE(bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, bh);
-+      if (err)
-+              goto journal_error;
-+
-+      err = add_dirent_to_buf(handle, dentry, inode, 0, bh);
-+      if (err != -ENOSPC) {
-+              bh = 0;
-+              goto cleanup;
-+      }
-+
-+      /* Block full, should compress but for now just split */
-+      dxtrace(printk("using %u of %u node entries\n",
-+                     dx_get_count(entries), dx_get_limit(entries)));
-+      /* Need to split index? */
-+      if (dx_get_count(entries) == dx_get_limit(entries)) {
-+              u32 newblock;
-+              unsigned icount = dx_get_count(entries);
-+              int levels = frame - frames;
-+              struct dx_entry *entries2;
-+              struct dx_node *node2;
-+              struct buffer_head *bh2;
-+
-+              if (levels && (dx_get_count(frames->entries) ==
-+                             dx_get_limit(frames->entries))) {
-+                      ext3_warning(sb, __FUNCTION__,
-+                                   "Directory index full!\n");
-+                      err = -ENOSPC;
-+                      goto cleanup;
-               }
--              if ((le32_to_cpu(de->inode) == 0 &&
--                              le16_to_cpu(de->rec_len) >= rec_len) ||
--                  (le16_to_cpu(de->rec_len) >=
--                              EXT3_DIR_REC_LEN(de->name_len) + rec_len)) {
--                      BUFFER_TRACE(bh, "get_write_access");
--                      ext3_journal_get_write_access(handle, bh);
--                      /* By now the buffer is marked for journaling */
--                      offset += le16_to_cpu(de->rec_len);
--                      if (le32_to_cpu(de->inode)) {
--                              de1 = (struct ext3_dir_entry_2 *) ((char *) de +
--                                      EXT3_DIR_REC_LEN(de->name_len));
--                              de1->rec_len =
--                                      cpu_to_le16(le16_to_cpu(de->rec_len) -
--                                      EXT3_DIR_REC_LEN(de->name_len));
--                              de->rec_len = cpu_to_le16(
--                                              EXT3_DIR_REC_LEN(de->name_len));
--                              de = de1;
-+              bh2 = ext3_append (handle, dir, &newblock, &err);
-+              if (!(bh2))
-+                      goto cleanup;
-+              node2 = (struct dx_node *)(bh2->b_data);
-+              entries2 = node2->entries;
-+              node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
-+              node2->fake.inode = 0;
-+              BUFFER_TRACE(frame->bh, "get_write_access");
-+              err = ext3_journal_get_write_access(handle, frame->bh);
-+              if (err)
-+                      goto journal_error;
-+              if (levels) {
-+                      unsigned icount1 = icount/2, icount2 = icount - icount1;
-+                      unsigned hash2 = dx_get_hash(entries + icount1);
-+                      dxtrace(printk("Split index %i/%i\n", icount1, icount2));
-+                              
-+                      BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
-+                      err = ext3_journal_get_write_access(handle,
-+                                                           frames[0].bh);
-+                      if (err)
-+                              goto journal_error;
-+                              
-+                      memcpy ((char *) entries2, (char *) (entries + icount1),
-+                              icount2 * sizeof(struct dx_entry));
-+                      dx_set_count (entries, icount1);
-+                      dx_set_count (entries2, icount2);
-+                      dx_set_limit (entries2, dx_node_limit(dir));
-+
-+                      /* Which index block gets the new entry? */
-+                      if (at - entries >= icount1) {
-+                              frame->at = at = at - entries - icount1 + entries2;
-+                              frame->entries = entries = entries2;
-+                              swap(frame->bh, bh2);
-                       }
--                      de->file_type = EXT3_FT_UNKNOWN;
--                      if (inode) {
--                              de->inode = cpu_to_le32(inode->i_ino);
--                              ext3_set_de_type(dir->i_sb, de, inode->i_mode);
--                      } else
--                              de->inode = 0;
--                      de->name_len = namelen;
--                      memcpy (de->name, name, namelen);
--                      /*
--                       * XXX shouldn't update any times until successful
--                       * completion of syscall, but too many callers depend
--                       * on this.
--                       *
--                       * XXX similarly, too many callers depend on
--                       * ext3_new_inode() setting the times, but error
--                       * recovery deletes the inode, so the worst that can
--                       * happen is that the times are slightly out of date
--                       * and/or different from the directory change time.
--                       */
--                      dir->i_mtime = dir->i_ctime = CURRENT_TIME;
--                      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
--                      dir->i_version = ++event;
--                      ext3_mark_inode_dirty(handle, dir);
--                      BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
--                      ext3_journal_dirty_metadata(handle, bh);
--                      brelse(bh);
--                      return 0;
-+                      dx_insert_block (frames + 0, hash2, newblock);
-+                      dxtrace(dx_show_index ("node", frames[1].entries));
-+                      dxtrace(dx_show_index ("node",
-+                             ((struct dx_node *) bh2->b_data)->entries));
-+                      err = ext3_journal_dirty_metadata(handle, bh2);
-+                      if (err)
-+                              goto journal_error;
-+                      brelse (bh2);
-+              } else {
-+                      dxtrace(printk("Creating second level index...\n"));
-+                      memcpy((char *) entries2, (char *) entries,
-+                             icount * sizeof(struct dx_entry));
-+                      dx_set_limit(entries2, dx_node_limit(dir));
-+
-+                      /* Set up root */
-+                      dx_set_count(entries, 1);
-+                      dx_set_block(entries + 0, newblock);
-+                      ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
-+
-+                      /* Add new access path frame */
-+                      frame = frames + 1;
-+                      frame->at = at = at - entries + entries2;
-+                      frame->entries = entries = entries2;
-+                      frame->bh = bh2;
-+                      err = ext3_journal_get_write_access(handle,
-+                                                           frame->bh);
-+                      if (err)
-+                              goto journal_error;
-               }
--              offset += le16_to_cpu(de->rec_len);
--              de = (struct ext3_dir_entry_2 *)
--                      ((char *) de + le16_to_cpu(de->rec_len));
-+              ext3_journal_dirty_metadata(handle, frames[0].bh);
-       }
--      brelse (bh);
--      return -ENOSPC;
-+      de = do_split(handle, dir, &bh, frame, &hinfo, &err);
-+      if (!de)
-+              goto cleanup;
-+      err = add_dirent_to_buf(handle, dentry, inode, de, bh);
-+      bh = 0;
-+      goto cleanup;
-+      
-+journal_error:
-+      ext3_std_error(dir->i_sb, err);
-+cleanup:
-+      if (bh)
-+              brelse(bh);
-+      dx_release(frames);
-+      return err;
- }
-+#endif
- /*
-  * ext3_delete_entry deletes a directory entry by merging it with the
-@@ -455,9 +1534,11 @@ static int ext3_create (struct inode * d
-       struct inode * inode;
-       int err;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -481,9 +1562,11 @@ static int ext3_mknod (struct inode * di
-       struct inode *inode;
-       int err;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -509,9 +1592,11 @@ static int ext3_mkdir(struct inode * dir
-       if (dir->i_nlink >= EXT3_LINK_MAX)
-               return -EMLINK;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -523,7 +1608,7 @@ static int ext3_mkdir(struct inode * dir
-       inode->i_op = &ext3_dir_inode_operations;
-       inode->i_fop = &ext3_dir_operations;
--      inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize;
-+      inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
-       inode->i_blocks = 0;    
-       dir_block = ext3_bread (handle, inode, 0, 1, &err);
-       if (!dir_block) {
-@@ -556,21 +1641,19 @@ static int ext3_mkdir(struct inode * dir
-               inode->i_mode |= S_ISGID;
-       ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_entry (handle, dentry, inode);
--      if (err)
--              goto out_no_entry;
-+      if (err) {
-+              inode->i_nlink = 0;
-+              ext3_mark_inode_dirty(handle, inode);
-+              iput (inode);
-+              goto out_stop;
-+      }
-       dir->i_nlink++;
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
-       d_instantiate(dentry, inode);
- out_stop:
-       ext3_journal_stop(handle, dir);
-       return err;
--
--out_no_entry:
--      inode->i_nlink = 0;
--      ext3_mark_inode_dirty(handle, inode);
--      iput (inode);
--      goto out_stop;
- }
- /*
-@@ -657,7 +1740,7 @@ int ext3_orphan_add(handle_t *handle, st
-       int err = 0, rc;
-       
-       lock_super(sb);
--      if (!list_empty(&inode->u.ext3_i.i_orphan))
-+      if (!list_empty(&EXT3_I(inode)->i_orphan))
-               goto out_unlock;
-       /* Orphan handling is only valid for files with data blocks
-@@ -698,7 +1781,7 @@ int ext3_orphan_add(handle_t *handle, st
-        * This is safe: on error we're going to ignore the orphan list
-        * anyway on the next recovery. */
-       if (!err)
--              list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan);
-+              list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
-       jbd_debug(4, "superblock will point to %ld\n", inode->i_ino);
-       jbd_debug(4, "orphan inode %ld will point to %d\n",
-@@ -716,25 +1799,26 @@ out_unlock:
- int ext3_orphan_del(handle_t *handle, struct inode *inode)
- {
-       struct list_head *prev;
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-       struct ext3_sb_info *sbi;
-       unsigned long ino_next;
-       struct ext3_iloc iloc;
-       int err = 0;
-       lock_super(inode->i_sb);
--      if (list_empty(&inode->u.ext3_i.i_orphan)) {
-+      if (list_empty(&ei->i_orphan)) {
-               unlock_super(inode->i_sb);
-               return 0;
-       }
-       ino_next = NEXT_ORPHAN(inode);
--      prev = inode->u.ext3_i.i_orphan.prev;
-+      prev = ei->i_orphan.prev;
-       sbi = EXT3_SB(inode->i_sb);
-       jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
--      list_del(&inode->u.ext3_i.i_orphan);
--      INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
-+      list_del(&ei->i_orphan);
-+      INIT_LIST_HEAD(&ei->i_orphan);
-       /* If we're on an error path, we may not have a valid
-        * transaction handle with which to update the orphan list on
-@@ -795,8 +1879,9 @@ static int ext3_rmdir (struct inode * di
-       handle_t *handle;
-       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
--      if (IS_ERR(handle))
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       retval = -ENOENT;
-       bh = ext3_find_entry (dentry, &de);
-@@ -834,7 +1919,7 @@ static int ext3_rmdir (struct inode * di
-       dir->i_nlink--;
-       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       ext3_mark_inode_dirty(handle, inode);
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
- end_rmdir:
-@@ -852,8 +1937,9 @@ static int ext3_unlink(struct inode * di
-       handle_t *handle;
-       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
--      if (IS_ERR(handle))
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -880,7 +1966,7 @@ static int ext3_unlink(struct inode * di
-       if (retval)
-               goto end_unlink;
-       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
-       inode->i_nlink--;
-       if (!inode->i_nlink)
-@@ -906,9 +1992,11 @@ static int ext3_symlink (struct inode * 
-       if (l > dir->i_sb->s_blocksize)
-               return -ENAMETOOLONG;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -918,7 +2006,7 @@ static int ext3_symlink (struct inode * 
-       if (IS_ERR(inode))
-               goto out_stop;
--      if (l > sizeof (inode->u.ext3_i.i_data)) {
-+      if (l > sizeof (EXT3_I(inode)->i_data)) {
-               inode->i_op = &page_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-               /*
-@@ -927,24 +2015,23 @@ static int ext3_symlink (struct inode * 
-                * i_size in generic_commit_write().
-                */
-               err = block_symlink(inode, symname, l);
--              if (err)
--                      goto out_no_entry;
-+              if (err) {
-+                      ext3_dec_count(handle, inode);
-+                      ext3_mark_inode_dirty(handle, inode);
-+                      iput (inode);
-+                      goto out_stop;
-+              }
-       } else {
-               inode->i_op = &ext3_fast_symlink_inode_operations;
--              memcpy((char*)&inode->u.ext3_i.i_data,symname,l);
-+              memcpy((char*)&EXT3_I(inode)->i_data,symname,l);
-               inode->i_size = l-1;
-       }
--      inode->u.ext3_i.i_disksize = inode->i_size;
-+      EXT3_I(inode)->i_disksize = inode->i_size;
-       err = ext3_add_nondir(handle, dentry, inode);
-+      ext3_mark_inode_dirty(handle, inode);
- out_stop:
-       ext3_journal_stop(handle, dir);
-       return err;
--
--out_no_entry:
--      ext3_dec_count(handle, inode);
--      ext3_mark_inode_dirty(handle, inode);
--      iput (inode);
--      goto out_stop;
- }
- static int ext3_link (struct dentry * old_dentry,
-@@ -957,12 +2044,15 @@ static int ext3_link (struct dentry * ol
-       if (S_ISDIR(inode->i_mode))
-               return -EPERM;
--      if (inode->i_nlink >= EXT3_LINK_MAX)
-+      if (inode->i_nlink >= EXT3_LINK_MAX) {
-               return -EMLINK;
-+      }
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -995,9 +2085,11 @@ static int ext3_rename (struct inode * o
-       old_bh = new_bh = dir_bh = NULL;
--      handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(old_dir) || IS_SYNC(new_dir))
-               handle->h_sync = 1;
-@@ -1077,7 +2169,7 @@ static int ext3_rename (struct inode * o
-               new_inode->i_ctime = CURRENT_TIME;
-       }
-       old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
--      old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(old_dir);
-       if (dir_bh) {
-               BUFFER_TRACE(dir_bh, "get_write_access");
-               ext3_journal_get_write_access(handle, dir_bh);
-@@ -1089,7 +2181,7 @@ static int ext3_rename (struct inode * o
-                       new_inode->i_nlink--;
-               } else {
-                       new_dir->i_nlink++;
--                      new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+                      ext3_update_dx_flag(new_dir);
-                       ext3_mark_inode_dirty(handle, new_dir);
-               }
-       }
---- linux-chaos-2.4.20-6/fs/ext3/super.c~ext-2.4-patch-1-chaos 2003-04-09 16:10:38.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/super.c 2003-04-09 16:18:55.000000000 -0600
-@@ -710,6 +710,7 @@ static int ext3_setup_super(struct super
-       es->s_mtime = cpu_to_le32(CURRENT_TIME);
-       ext3_update_dynamic_rev(sb);
-       EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
-+
-       ext3_commit_super (sb, es, 1);
-       if (test_opt (sb, DEBUG))
-               printk (KERN_INFO
-@@ -720,6 +721,7 @@ static int ext3_setup_super(struct super
-                       EXT3_BLOCKS_PER_GROUP(sb),
-                       EXT3_INODES_PER_GROUP(sb),
-                       sbi->s_mount_opt);
-+
-       printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ",
-                               bdevname(sb->s_dev));
-       if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
-@@ -893,6 +895,7 @@ static loff_t ext3_max_size(int bits)
-       return res;
- }
-+
- struct super_block * ext3_read_super (struct super_block * sb, void * data,
-                                     int silent)
- {
-@@ -1069,6 +1072,9 @@ struct super_block * ext3_read_super (st
-       sbi->s_mount_state = le16_to_cpu(es->s_state);
-       sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
-       sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
-+      for (i=0; i < 4; i++)
-+              sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
-+      sbi->s_def_hash_version = es->s_def_hash_version;
-       if (sbi->s_blocks_per_group > blocksize * 8) {
-               printk (KERN_ERR
-@@ -1770,6 +1776,7 @@ static void __exit exit_ext3_fs(void)
-       unregister_filesystem(&ext3_fs_type);
- }
-+EXPORT_SYMBOL(ext3_force_commit);
- EXPORT_SYMBOL(ext3_bread);
- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
---- linux-chaos-2.4.20-6/include/linux/ext3_fs.h~ext-2.4-patch-1-chaos 2003-03-12 12:51:27.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/include/linux/ext3_fs.h 2003-04-09 16:18:55.000000000 -0600
-@@ -40,6 +40,11 @@
- #define EXT3FS_VERSION                "2.4-0.9.19"
- /*
-+ * Always enable hashed directories
-+ */
-+#define CONFIG_EXT3_INDEX
-+
-+/*
-  * Debug code
-  */
- #ifdef EXT3FS_DEBUG
-@@ -437,8 +442,11 @@ struct ext3_super_block {
- /*E0*/        __u32   s_journal_inum;         /* inode number of journal file */
-       __u32   s_journal_dev;          /* device number of journal file */
-       __u32   s_last_orphan;          /* start of list of inodes to delete */
--
--/*EC*/        __u32   s_reserved[197];        /* Padding to the end of the block */
-+      __u32   s_hash_seed[4];         /* HTREE hash seed */
-+      __u8    s_def_hash_version;     /* Default hash version to use */
-+      __u8    s_reserved_char_pad;
-+      __u16   s_reserved_word_pad;
-+      __u32   s_reserved[192];        /* Padding to the end of the block */
- };
- #ifdef __KERNEL__
-@@ -575,9 +583,46 @@ struct ext3_dir_entry_2 {
- #define EXT3_DIR_ROUND                        (EXT3_DIR_PAD - 1)
- #define EXT3_DIR_REC_LEN(name_len)    (((name_len) + 8 + EXT3_DIR_ROUND) & \
-                                        ~EXT3_DIR_ROUND)
-+/*
-+ * Hash Tree Directory indexing
-+ * (c) Daniel Phillips, 2001
-+ */
-+
-+#ifdef CONFIG_EXT3_INDEX
-+  #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
-+                                            EXT3_FEATURE_COMPAT_DIR_INDEX) && \
-+                    (EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
-+#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
-+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
-+#else
-+  #define is_dx(dir) 0
-+#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
-+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
-+#endif
-+
-+/* Legal values for the dx_root hash_version field: */
-+
-+#define DX_HASH_LEGACY                0
-+#define DX_HASH_HALF_MD4      1
-+#define DX_HASH_TEA           2
-+
-+/* hash info structure used by the directory hash */
-+struct dx_hash_info
-+{
-+      u32             hash;
-+      u32             minor_hash;
-+      int             hash_version;
-+      u32             *seed;
-+};
- #ifdef __KERNEL__
- /*
-+ * Control parameters used by ext3_htree_next_block
-+ */
-+#define HASH_NB_ALWAYS                1
-+
-+
-+/*
-  * Describe an inode's exact location on disk and in memory
-  */
- struct ext3_iloc
-@@ -587,6 +632,27 @@ struct ext3_iloc
-       unsigned long block_group;
- };
-+
-+/*
-+ * This structure is stuffed into the struct file's private_data field
-+ * for directories.  It is where we put information so that we can do
-+ * readdir operations in hash tree order.
-+ */
-+struct dir_private_info {
-+      rb_root_t       root;
-+      rb_node_t       *curr_node;
-+      struct fname    *extra_fname;
-+      loff_t          last_pos;
-+      __u32           curr_hash;
-+      __u32           curr_minor_hash;
-+      __u32           next_hash;
-+};
-+
-+/*
-+ * Special error return code only used by dx_probe() and its callers.
-+ */
-+#define ERR_BAD_DX_DIR        -75000
-+
- /*
-  * Function prototypes
-  */
-@@ -614,11 +680,20 @@ extern struct ext3_group_desc * ext3_get
- /* dir.c */
- extern int ext3_check_dir_entry(const char *, struct inode *,
--                              struct ext3_dir_entry_2 *, struct buffer_head *,
--                              unsigned long);
-+                              struct ext3_dir_entry_2 *,
-+                              struct buffer_head *, unsigned long);
-+extern void ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
-+                                  __u32 minor_hash,
-+                                  struct ext3_dir_entry_2 *dirent);
-+extern void ext3_htree_free_dir_info(struct dir_private_info *p);
-+
- /* fsync.c */
- extern int ext3_sync_file (struct file *, struct dentry *, int);
-+/* hash.c */
-+extern int ext3fs_dirhash(const char *name, int len, struct
-+                        dx_hash_info *hinfo);
-+
- /* ialloc.c */
- extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
- extern void ext3_free_inode (handle_t *, struct inode *);
-@@ -650,6 +725,8 @@ extern int ext3_ioctl (struct inode *, s
- /* namei.c */
- extern int ext3_orphan_add(handle_t *, struct inode *);
- extern int ext3_orphan_del(handle_t *, struct inode *);
-+extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
-+                              __u32 start_minor_hash, __u32 *next_hash);
- /* super.c */
- extern void ext3_error (struct super_block *, const char *, const char *, ...)
---- linux-chaos-2.4.20-6/include/linux/ext3_fs_sb.h~ext-2.4-patch-1-chaos      2003-03-12 12:51:27.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/include/linux/ext3_fs_sb.h      2003-04-09 16:18:55.000000000 -0600
-@@ -62,6 +62,8 @@ struct ext3_sb_info {
-       int s_inode_size;
-       int s_first_ino;
-       u32 s_next_generation;
-+      u32 s_hash_seed[4];
-+      int s_def_hash_version;
-       /* Journaling */
-       struct inode * s_journal_inode;
---- linux-chaos-2.4.20-6/include/linux/ext3_jbd.h~ext-2.4-patch-1-chaos        2003-03-12 12:51:27.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/include/linux/ext3_jbd.h        2003-04-09 16:18:55.000000000 -0600
-@@ -63,6 +63,8 @@ extern int ext3_writepage_trans_blocks(s
- #define EXT3_RESERVE_TRANS_BLOCKS     12U
-+#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8
-+
- int
- ext3_mark_iloc_dirty(handle_t *handle, 
-                    struct inode *inode,
---- linux-chaos-2.4.20-6/include/linux/rbtree.h~ext-2.4-patch-1-chaos  2002-05-07 15:53:47.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/include/linux/rbtree.h  2003-04-09 16:18:55.000000000 -0600
-@@ -120,6 +120,8 @@ rb_root_t;
- extern void rb_insert_color(rb_node_t *, rb_root_t *);
- extern void rb_erase(rb_node_t *, rb_root_t *);
-+extern rb_node_t *rb_get_first(rb_root_t *root);
-+extern rb_node_t *rb_get_next(rb_node_t *n);
- static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
- {
---- linux-chaos-2.4.20-6/lib/rbtree.c~ext-2.4-patch-1-chaos    2002-09-25 11:14:03.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/lib/rbtree.c    2003-04-09 16:18:55.000000000 -0600
-@@ -17,6 +17,8 @@
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-   linux/lib/rbtree.c
-+
-+  rb_get_first and rb_get_next written by Theodore Ts'o, 9/8/2002
- */
- #include <linux/rbtree.h>
-@@ -294,3 +296,43 @@ void rb_erase(rb_node_t * node, rb_root_
-               __rb_erase_color(child, parent, root);
- }
- EXPORT_SYMBOL(rb_erase);
-+
-+/*
-+ * This function returns the first node (in sort order) of the tree.
-+ */
-+rb_node_t *rb_get_first(rb_root_t *root)
-+{
-+      rb_node_t       *n;
-+
-+      n = root->rb_node;
-+      if (!n)
-+              return 0;
-+      while (n->rb_left)
-+              n = n->rb_left;
-+      return n;
-+}
-+EXPORT_SYMBOL(rb_get_first);
-+
-+/*
-+ * Given a node, this function will return the next node in the tree.
-+ */
-+rb_node_t *rb_get_next(rb_node_t *n)
-+{
-+      rb_node_t       *parent;
-+
-+      if (n->rb_right) {
-+              n = n->rb_right;
-+              while (n->rb_left)
-+                      n = n->rb_left;
-+              return n;
-+      } else {
-+              while ((parent = n->rb_parent)) {
-+                      if (n == parent->rb_left)
-+                              return parent;
-+                      n = parent;
-+              }
-+              return 0;
-+      }
-+}
-+EXPORT_SYMBOL(rb_get_next);
-+
-
-_
diff --git a/lustre/kernel_patches/patches/ext-2.4-patch-1-hp-2.4.19.patch b/lustre/kernel_patches/patches/ext-2.4-patch-1-hp-2.4.19.patch
deleted file mode 100644 (file)
index ef06041..0000000
+++ /dev/null
@@ -1,2682 +0,0 @@
- fs/ext3/Makefile           |    8 
- fs/ext3/dir.c              |  299 +++++++++
- fs/ext3/file.c             |    8 
- fs/ext3/hash.c             |  215 ++++++
- fs/ext3/namei.c            | 1442 +++++++++++++++++++++++++++++++++++++++------
- fs/ext3/super.c            |   40 +
- include/linux/ext3_fs.h    |   85 ++
- include/linux/ext3_fs_sb.h |    2 
- include/linux/ext3_jbd.h   |   10 
- include/linux/rbtree.h     |    2 
- lib/rbtree.c               |   42 +
- 11 files changed, 1964 insertions(+), 189 deletions(-)
-
---- linux-2.4.19-hp3_pnnl1/fs/ext3/Makefile~ext-2.4-patch-1-chaos      2003-04-11 13:55:54.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/ext3/Makefile       2003-04-11 13:56:05.000000000 +0800
-@@ -1,5 +1,5 @@
- #
--# Makefile for the linux ext2-filesystem routines.
-+# Makefile for the linux ext3-filesystem routines.
- #
- # Note! Dependencies are done automagically by 'make dep', which also
- # removes any old dependencies. DON'T put your own dependencies here
-@@ -12,7 +12,11 @@ O_TARGET := ext3.o
- export-objs :=        super.o inode.o
- obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
--              ioctl.o namei.o super.o symlink.o
-+              ioctl.o namei.o super.o symlink.o hash.o
- obj-m    := $(O_TARGET)
-+export-objs += xattr.o
-+obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o
-+obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o
-+
- include $(TOPDIR)/Rules.make
---- linux-2.4.19-hp3_pnnl1/fs/ext3/dir.c~ext-2.4-patch-1-chaos 2001-11-10 06:25:04.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/ext3/dir.c  2003-04-11 13:55:58.000000000 +0800
-@@ -21,12 +21,16 @@
- #include <linux/fs.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include <linux/slab.h>
-+#include <linux/rbtree.h>
- static unsigned char ext3_filetype_table[] = {
-       DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
- };
- static int ext3_readdir(struct file *, void *, filldir_t);
-+static int ext3_dx_readdir(struct file * filp,
-+                         void * dirent, filldir_t filldir);
- struct file_operations ext3_dir_operations = {
-       read:           generic_read_dir,
-@@ -35,6 +39,17 @@ struct file_operations ext3_dir_operatio
-       fsync:          ext3_sync_file,         /* BKL held */
- };
-+
-+static unsigned char get_dtype(struct super_block *sb, int filetype)
-+{
-+      if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
-+          (filetype >= EXT3_FT_MAX))
-+              return DT_UNKNOWN;
-+
-+      return (ext3_filetype_table[filetype]);
-+}
-+                             
-+
- int ext3_check_dir_entry (const char * function, struct inode * dir,
-                         struct ext3_dir_entry_2 * de,
-                         struct buffer_head * bh,
-@@ -79,6 +94,16 @@ static int ext3_readdir(struct file * fi
-       sb = inode->i_sb;
-+      if (is_dx(inode)) {
-+              err = ext3_dx_readdir(filp, dirent, filldir);
-+              if (err != ERR_BAD_DX_DIR)
-+                      return err;
-+              /*
-+               * We don't set the inode dirty flag since it's not
-+               * critical that it get flushed back to the disk.
-+               */
-+              EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL;
-+      }
-       stored = 0;
-       bh = NULL;
-       offset = filp->f_pos & (sb->s_blocksize - 1);
-@@ -162,18 +187,12 @@ revalidate:
-                                * during the copy operation.
-                                */
-                               unsigned long version = filp->f_version;
--                              unsigned char d_type = DT_UNKNOWN;
--                              if (EXT3_HAS_INCOMPAT_FEATURE(sb,
--                                              EXT3_FEATURE_INCOMPAT_FILETYPE)
--                                              && de->file_type < EXT3_FT_MAX)
--                                      d_type =
--                                        ext3_filetype_table[de->file_type];
-                               error = filldir(dirent, de->name,
-                                               de->name_len,
-                                               filp->f_pos,
-                                               le32_to_cpu(de->inode),
--                                              d_type);
-+                                              get_dtype(sb, de->file_type));
-                               if (error)
-                                       break;
-                               if (version != filp->f_version)
-@@ -188,3 +207,269 @@ revalidate:
-       UPDATE_ATIME(inode);
-       return 0;
- }
-+
-+#ifdef CONFIG_EXT3_INDEX
-+/*
-+ * These functions convert from the major/minor hash to an f_pos
-+ * value.
-+ * 
-+ * Currently we only use major hash numer.  This is unfortunate, but
-+ * on 32-bit machines, the same VFS interface is used for lseek and
-+ * llseek, so if we use the 64 bit offset, then the 32-bit versions of
-+ * lseek/telldir/seekdir will blow out spectacularly, and from within
-+ * the ext2 low-level routine, we don't know if we're being called by
-+ * a 64-bit version of the system call or the 32-bit version of the
-+ * system call.  Worse yet, NFSv2 only allows for a 32-bit readdir
-+ * cookie.  Sigh.
-+ */
-+#define hash2pos(major, minor)        (major >> 1)
-+#define pos2maj_hash(pos)     ((pos << 1) & 0xffffffff)
-+#define pos2min_hash(pos)     (0)
-+
-+/*
-+ * This structure holds the nodes of the red-black tree used to store
-+ * the directory entry in hash order.
-+ */
-+struct fname {
-+      __u32           hash;
-+      __u32           minor_hash;
-+      rb_node_t       rb_hash; 
-+      struct fname    *next;
-+      __u32           inode;
-+      __u8            name_len;
-+      __u8            file_type;
-+      char            name[0];
-+};
-+
-+/*
-+ * This functoin implements a non-recursive way of freeing all of the
-+ * nodes in the red-black tree.
-+ */
-+static void free_rb_tree_fname(rb_root_t *root)
-+{
-+      rb_node_t       *n = root->rb_node;
-+      rb_node_t       *parent;
-+      struct fname    *fname;
-+
-+      while (n) {
-+              /* Do the node's children first */
-+              if ((n)->rb_left) {
-+                      n = n->rb_left;
-+                      continue;
-+              }
-+              if (n->rb_right) {
-+                      n = n->rb_right;
-+                      continue;
-+              }
-+              /*
-+               * The node has no children; free it, and then zero
-+               * out parent's link to it.  Finally go to the
-+               * beginning of the loop and try to free the parent
-+               * node.
-+               */
-+              parent = n->rb_parent;
-+              fname = rb_entry(n, struct fname, rb_hash);
-+              kfree(fname);
-+              if (!parent)
-+                      root->rb_node = 0;
-+              else if (parent->rb_left == n)
-+                      parent->rb_left = 0;
-+              else if (parent->rb_right == n)
-+                      parent->rb_right = 0;
-+              n = parent;
-+      }
-+      root->rb_node = 0;
-+}
-+
-+
-+struct dir_private_info *create_dir_info(loff_t pos)
-+{
-+      struct dir_private_info *p;
-+
-+      p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL);
-+      if (!p)
-+              return NULL;
-+      p->root.rb_node = 0;
-+      p->curr_node = 0;
-+      p->extra_fname = 0;
-+      p->last_pos = 0;
-+      p->curr_hash = pos2maj_hash(pos);
-+      p->curr_minor_hash = pos2min_hash(pos);
-+      p->next_hash = 0;
-+      return p;
-+}
-+
-+void ext3_htree_free_dir_info(struct dir_private_info *p)
-+{
-+      free_rb_tree_fname(&p->root);
-+      kfree(p);
-+}
-+              
-+/*
-+ * Given a directory entry, enter it into the fname rb tree.
-+ */
-+void ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
-+                           __u32 minor_hash,
-+                           struct ext3_dir_entry_2 *dirent)
-+{
-+      rb_node_t **p, *parent = NULL;
-+      struct fname * fname, *new_fn;
-+      struct dir_private_info *info;
-+      int len;
-+
-+      info = (struct dir_private_info *) dir_file->private_data;
-+      p = &info->root.rb_node;
-+
-+      /* Create and allocate the fname structure */
-+      len = sizeof(struct fname) + dirent->name_len + 1;
-+      new_fn = kmalloc(len, GFP_KERNEL);
-+      memset(new_fn, 0, len);
-+      new_fn->hash = hash;
-+      new_fn->minor_hash = minor_hash;
-+      new_fn->inode = le32_to_cpu(dirent->inode);
-+      new_fn->name_len = dirent->name_len;
-+      new_fn->file_type = dirent->file_type;
-+      memcpy(new_fn->name, dirent->name, dirent->name_len);
-+      new_fn->name[dirent->name_len] = 0;
-+      
-+      while (*p) {
-+              parent = *p;
-+              fname = rb_entry(parent, struct fname, rb_hash);
-+
-+              /*
-+               * If the hash and minor hash match up, then we put
-+               * them on a linked list.  This rarely happens...
-+               */
-+              if ((new_fn->hash == fname->hash) &&
-+                  (new_fn->minor_hash == fname->minor_hash)) {
-+                      new_fn->next = fname->next;
-+                      fname->next = new_fn;
-+                      return;
-+              }
-+                      
-+              if (new_fn->hash < fname->hash)
-+                      p = &(*p)->rb_left;
-+              else if (new_fn->hash > fname->hash)
-+                      p = &(*p)->rb_right;
-+              else if (new_fn->minor_hash < fname->minor_hash)
-+                      p = &(*p)->rb_left;
-+              else /* if (new_fn->minor_hash > fname->minor_hash) */
-+                      p = &(*p)->rb_right;
-+      }
-+
-+      rb_link_node(&new_fn->rb_hash, parent, p);
-+      rb_insert_color(&new_fn->rb_hash, &info->root);
-+}
-+
-+
-+
-+/*
-+ * This is a helper function for ext3_dx_readdir.  It calls filldir
-+ * for all entres on the fname linked list.  (Normally there is only
-+ * one entry on the linked list, unless there are 62 bit hash collisions.)
-+ */
-+static int call_filldir(struct file * filp, void * dirent,
-+                      filldir_t filldir, struct fname *fname)
-+{
-+      struct dir_private_info *info = filp->private_data;
-+      loff_t  curr_pos;
-+      struct inode *inode = filp->f_dentry->d_inode;
-+      struct super_block * sb;
-+      int error;
-+
-+      sb = inode->i_sb;
-+      
-+      if (!fname) {
-+              printk("call_filldir: called with null fname?!?\n");
-+              return 0;
-+      }
-+      curr_pos = hash2pos(fname->hash, fname->minor_hash);
-+      while (fname) {
-+              error = filldir(dirent, fname->name,
-+                              fname->name_len, curr_pos, 
-+                              fname->inode,
-+                              get_dtype(sb, fname->file_type));
-+              if (error) {
-+                      filp->f_pos = curr_pos;
-+                      info->extra_fname = fname->next;
-+                      return error;
-+              }
-+              fname = fname->next;
-+      }
-+      return 0;
-+}
-+
-+static int ext3_dx_readdir(struct file * filp,
-+                       void * dirent, filldir_t filldir)
-+{
-+      struct dir_private_info *info = filp->private_data;
-+      struct inode *inode = filp->f_dentry->d_inode;
-+      struct fname *fname;
-+      int     ret;
-+
-+      if (!info) {
-+              info = create_dir_info(filp->f_pos);
-+              if (!info)
-+                      return -ENOMEM;
-+              filp->private_data = info;
-+      }
-+
-+      /* Some one has messed with f_pos; reset the world */
-+      if (info->last_pos != filp->f_pos) {
-+              free_rb_tree_fname(&info->root);
-+              info->curr_node = 0;
-+              info->extra_fname = 0;
-+              info->curr_hash = pos2maj_hash(filp->f_pos);
-+              info->curr_minor_hash = pos2min_hash(filp->f_pos);
-+      }
-+
-+      /*
-+       * If there are any leftover names on the hash collision
-+       * chain, return them first.
-+       */
-+      if (info->extra_fname &&
-+          call_filldir(filp, dirent, filldir, info->extra_fname))
-+              goto finished;
-+
-+      if (!info->curr_node)
-+              info->curr_node = rb_get_first(&info->root);
-+
-+      while (1) {
-+              /*
-+               * Fill the rbtree if we have no more entries,
-+               * or the inode has changed since we last read in the
-+               * cached entries. 
-+               */
-+              if ((!info->curr_node) ||
-+                  (filp->f_version != inode->i_version)) {
-+                      info->curr_node = 0;
-+                      free_rb_tree_fname(&info->root);
-+                      filp->f_version = inode->i_version;
-+                      ret = ext3_htree_fill_tree(filp, info->curr_hash,
-+                                                 info->curr_minor_hash,
-+                                                 &info->next_hash);
-+                      if (ret < 0)
-+                              return ret;
-+                      if (ret == 0)
-+                              break;
-+                      info->curr_node = rb_get_first(&info->root);
-+              }
-+
-+              fname = rb_entry(info->curr_node, struct fname, rb_hash);
-+              info->curr_hash = fname->hash;
-+              info->curr_minor_hash = fname->minor_hash;
-+              if (call_filldir(filp, dirent, filldir, fname))
-+                      break;
-+
-+              info->curr_node = rb_get_next(info->curr_node);
-+              if (!info->curr_node) {
-+                      info->curr_hash = info->next_hash;
-+                      info->curr_minor_hash = 0;
-+              }
-+      }
-+finished:
-+      info->last_pos = filp->f_pos;
-+      UPDATE_ATIME(inode);
-+      return 0;
-+}
-+#endif
---- linux-2.4.19-hp3_pnnl1/fs/ext3/file.c~ext-2.4-patch-1-chaos        2001-11-16 05:37:55.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/ext3/file.c 2003-04-11 13:56:05.000000000 +0800
-@@ -23,6 +23,7 @@
- #include <linux/locks.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/ext3_jbd.h>
- #include <linux/smp_lock.h>
-@@ -35,6 +36,9 @@ static int ext3_release_file (struct ino
- {
-       if (filp->f_mode & FMODE_WRITE)
-               ext3_discard_prealloc (inode);
-+      if (is_dx(inode) && filp->private_data)
-+              ext3_htree_free_dir_info(filp->private_data);
-+
-       return 0;
- }
-@@ -90,5 +94,9 @@ struct file_operations ext3_file_operati
- struct inode_operations ext3_file_inode_operations = {
-       truncate:       ext3_truncate,          /* BKL held */
-       setattr:        ext3_setattr,           /* BKL held */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
---- /dev/null  2003-01-30 18:24:37.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/ext3/hash.c 2003-04-11 13:55:58.000000000 +0800
-@@ -0,0 +1,215 @@
-+/*
-+ *  linux/fs/ext3/hash.c
-+ *
-+ * Copyright (C) 2002 by Theodore Ts'o
-+ *
-+ * This file is released under the GPL v2.
-+ * 
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ */
-+
-+#include <linux/fs.h>
-+#include <linux/jbd.h>
-+#include <linux/sched.h>
-+#include <linux/ext3_fs.h>
-+
-+#define DELTA 0x9E3779B9
-+
-+static void TEA_transform(__u32 buf[4], __u32 const in[])
-+{
-+      __u32   sum = 0;
-+      __u32   b0 = buf[0], b1 = buf[1];
-+      __u32   a = in[0], b = in[1], c = in[2], d = in[3];
-+      int     n = 16;
-+
-+      do {                                                    
-+              sum += DELTA;                                   
-+              b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); 
-+              b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); 
-+      } while(--n);
-+
-+      buf[0] += b0;
-+      buf[1] += b1;
-+}
-+
-+/* F, G and H are basic MD4 functions: selection, majority, parity */
-+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
-+#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
-+#define H(x, y, z) ((x) ^ (y) ^ (z))
-+
-+/*
-+ * The generic round function.  The application is so specific that
-+ * we don't bother protecting all the arguments with parens, as is generally
-+ * good macro practice, in favor of extra legibility.
-+ * Rotation is separate from addition to prevent recomputation
-+ */
-+#define ROUND(f, a, b, c, d, x, s)    \
-+      (a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
-+#define K1 0
-+#define K2 013240474631UL
-+#define K3 015666365641UL
-+
-+/*
-+ * Basic cut-down MD4 transform.  Returns only 32 bits of result.
-+ */
-+static void halfMD4Transform (__u32 buf[4], __u32 const in[])
-+{
-+      __u32   a = buf[0], b = buf[1], c = buf[2], d = buf[3];
-+
-+      /* Round 1 */
-+      ROUND(F, a, b, c, d, in[0] + K1,  3);
-+      ROUND(F, d, a, b, c, in[1] + K1,  7);
-+      ROUND(F, c, d, a, b, in[2] + K1, 11);
-+      ROUND(F, b, c, d, a, in[3] + K1, 19);
-+      ROUND(F, a, b, c, d, in[4] + K1,  3);
-+      ROUND(F, d, a, b, c, in[5] + K1,  7);
-+      ROUND(F, c, d, a, b, in[6] + K1, 11);
-+      ROUND(F, b, c, d, a, in[7] + K1, 19);
-+
-+      /* Round 2 */
-+      ROUND(G, a, b, c, d, in[1] + K2,  3);
-+      ROUND(G, d, a, b, c, in[3] + K2,  5);
-+      ROUND(G, c, d, a, b, in[5] + K2,  9);
-+      ROUND(G, b, c, d, a, in[7] + K2, 13);
-+      ROUND(G, a, b, c, d, in[0] + K2,  3);
-+      ROUND(G, d, a, b, c, in[2] + K2,  5);
-+      ROUND(G, c, d, a, b, in[4] + K2,  9);
-+      ROUND(G, b, c, d, a, in[6] + K2, 13);
-+
-+      /* Round 3 */
-+      ROUND(H, a, b, c, d, in[3] + K3,  3);
-+      ROUND(H, d, a, b, c, in[7] + K3,  9);
-+      ROUND(H, c, d, a, b, in[2] + K3, 11);
-+      ROUND(H, b, c, d, a, in[6] + K3, 15);
-+      ROUND(H, a, b, c, d, in[1] + K3,  3);
-+      ROUND(H, d, a, b, c, in[5] + K3,  9);
-+      ROUND(H, c, d, a, b, in[0] + K3, 11);
-+      ROUND(H, b, c, d, a, in[4] + K3, 15);
-+
-+      buf[0] += a;
-+      buf[1] += b;
-+      buf[2] += c;
-+      buf[3] += d;
-+}
-+
-+#undef ROUND
-+#undef F
-+#undef G
-+#undef H
-+#undef K1
-+#undef K2
-+#undef K3
-+
-+/* The old legacy hash */
-+static __u32 dx_hack_hash (const char *name, int len)
-+{
-+      __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
-+      while (len--) {
-+              __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
-+              
-+              if (hash & 0x80000000) hash -= 0x7fffffff;
-+              hash1 = hash0;
-+              hash0 = hash;
-+      }
-+      return (hash0 << 1);
-+}
-+
-+static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
-+{
-+      __u32   pad, val;
-+      int     i;
-+
-+      pad = (__u32)len | ((__u32)len << 8);
-+      pad |= pad << 16;
-+
-+      val = pad;
-+      if (len > num*4)
-+              len = num * 4;
-+      for (i=0; i < len; i++) {
-+              if ((i % 4) == 0)
-+                      val = pad;
-+              val = msg[i] + (val << 8);
-+              if ((i % 4) == 3) {
-+                      *buf++ = val;
-+                      val = pad;
-+                      num--;
-+              }
-+      }
-+      if (--num >= 0)
-+              *buf++ = val;
-+      while (--num >= 0)
-+              *buf++ = pad;
-+}
-+
-+/*
-+ * Returns the hash of a filename.  If len is 0 and name is NULL, then
-+ * this function can be used to test whether or not a hash version is
-+ * supported.
-+ * 
-+ * The seed is an 4 longword (32 bits) "secret" which can be used to
-+ * uniquify a hash.  If the seed is all zero's, then some default seed
-+ * may be used.
-+ * 
-+ * A particular hash version specifies whether or not the seed is
-+ * represented, and whether or not the returned hash is 32 bits or 64
-+ * bits.  32 bit hashes will return 0 for the minor hash.
-+ */
-+int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
-+{
-+      __u32   hash;
-+      __u32   minor_hash = 0;
-+      const char      *p;
-+      int             i;
-+      __u32           in[8], buf[4];
-+
-+      /* Initialize the default seed for the hash checksum functions */
-+      buf[0] = 0x67452301;
-+      buf[1] = 0xefcdab89;
-+      buf[2] = 0x98badcfe;
-+      buf[3] = 0x10325476;
-+
-+      /* Check to see if the seed is all zero's */
-+      if (hinfo->seed) {
-+              for (i=0; i < 4; i++) {
-+                      if (hinfo->seed[i])
-+                              break;
-+              }
-+              if (i < 4)
-+                      memcpy(buf, hinfo->seed, sizeof(buf));
-+      }
-+              
-+      switch (hinfo->hash_version) {
-+      case DX_HASH_LEGACY:
-+              hash = dx_hack_hash(name, len);
-+              break;
-+      case DX_HASH_HALF_MD4:
-+              p = name;
-+              while (len > 0) {
-+                      str2hashbuf(p, len, in, 8);
-+                      halfMD4Transform(buf, in);
-+                      len -= 32;
-+                      p += 32;
-+              }
-+              minor_hash = buf[2];
-+              hash = buf[1];
-+              break;
-+      case DX_HASH_TEA:
-+              p = name;
-+              while (len > 0) {
-+                      str2hashbuf(p, len, in, 4);
-+                      TEA_transform(buf, in);
-+                      len -= 16;
-+                      p += 16;
-+              }
-+              hash = buf[0];
-+              minor_hash = buf[1];
-+              break;
-+      default:
-+              hinfo->hash = 0;
-+              return -1;
-+      }
-+      hinfo->hash = hash & ~1;
-+      hinfo->minor_hash = minor_hash;
-+      return 0;
-+}
---- linux-2.4.19-hp3_pnnl1/fs/ext3/namei.c~ext-2.4-patch-1-chaos       2001-11-10 06:25:04.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/ext3/namei.c        2003-04-11 13:55:58.000000000 +0800
-@@ -16,6 +16,12 @@
-  *        David S. Miller (davem@caip.rutgers.edu), 1995
-  *  Directory entry file type support and forward compatibility hooks
-  *    for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
-+ *  Hash Tree Directory indexing (c)
-+ *    Daniel Phillips, 2001
-+ *  Hash Tree Directory indexing porting
-+ *    Christopher Li, 2002
-+ *  Hash Tree Directory indexing cleanup
-+ *    Theodore Ts'o, 2002
-  */
- #include <linux/fs.h>
-@@ -38,6 +44,630 @@
- #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
- #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
-+static struct buffer_head *ext3_append(handle_t *handle,
-+                                      struct inode *inode,
-+                                      u32 *block, int *err)
-+{
-+      struct buffer_head *bh;
-+
-+      *block = inode->i_size >> inode->i_sb->s_blocksize_bits;
-+
-+      if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
-+              inode->i_size += inode->i_sb->s_blocksize;
-+              EXT3_I(inode)->i_disksize = inode->i_size;
-+              ext3_journal_get_write_access(handle,bh);
-+      }
-+      return bh;
-+}
-+
-+#ifndef assert
-+#define assert(test) J_ASSERT(test)
-+#endif
-+
-+#ifndef swap
-+#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
-+#endif
-+
-+typedef struct { u32 v; } le_u32;
-+typedef struct { u16 v; } le_u16;
-+
-+#ifdef DX_DEBUG
-+#define dxtrace(command) command
-+#else
-+#define dxtrace(command) 
-+#endif
-+
-+struct fake_dirent
-+{
-+      /*le*/u32 inode;
-+      /*le*/u16 rec_len;
-+      u8 name_len;
-+      u8 file_type;
-+};
-+
-+struct dx_countlimit
-+{
-+      le_u16 limit;
-+      le_u16 count;
-+};
-+
-+struct dx_entry
-+{
-+      le_u32 hash;
-+      le_u32 block;
-+};
-+
-+/*
-+ * dx_root_info is laid out so that if it should somehow get overlaid by a
-+ * dirent the two low bits of the hash version will be zero.  Therefore, the
-+ * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
-+ */
-+
-+struct dx_root
-+{
-+      struct fake_dirent dot;
-+      char dot_name[4];
-+      struct fake_dirent dotdot;
-+      char dotdot_name[4];
-+      struct dx_root_info
-+      {
-+              le_u32 reserved_zero;
-+              u8 hash_version;
-+              u8 info_length; /* 8 */
-+              u8 indirect_levels;
-+              u8 unused_flags;
-+      }
-+      info;
-+      struct dx_entry entries[0];
-+};
-+
-+struct dx_node
-+{
-+      struct fake_dirent fake;
-+      struct dx_entry entries[0];
-+};
-+
-+
-+struct dx_frame
-+{
-+      struct buffer_head *bh;
-+      struct dx_entry *entries;
-+      struct dx_entry *at;
-+};
-+
-+struct dx_map_entry
-+{
-+      u32 hash;
-+      u32 offs;
-+};
-+
-+#ifdef CONFIG_EXT3_INDEX
-+static inline unsigned dx_get_block (struct dx_entry *entry);
-+static void dx_set_block (struct dx_entry *entry, unsigned value);
-+static inline unsigned dx_get_hash (struct dx_entry *entry);
-+static void dx_set_hash (struct dx_entry *entry, unsigned value);
-+static unsigned dx_get_count (struct dx_entry *entries);
-+static unsigned dx_get_limit (struct dx_entry *entries);
-+static void dx_set_count (struct dx_entry *entries, unsigned value);
-+static void dx_set_limit (struct dx_entry *entries, unsigned value);
-+static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
-+static unsigned dx_node_limit (struct inode *dir);
-+static struct dx_frame *dx_probe(struct dentry *dentry,
-+                               struct inode *dir,
-+                               struct dx_hash_info *hinfo,
-+                               struct dx_frame *frame,
-+                               int *err);
-+static void dx_release (struct dx_frame *frames);
-+static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
-+                      struct dx_hash_info *hinfo, struct dx_map_entry map[]);
-+static void dx_sort_map(struct dx_map_entry *map, unsigned count);
-+static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to,
-+              struct dx_map_entry *offsets, int count);
-+static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size);
-+static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
-+static int ext3_htree_next_block(struct inode *dir, __u32 hash,
-+                               struct dx_frame *frame,
-+                               struct dx_frame *frames, int *err,
-+                               __u32 *start_hash);
-+static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
-+                     struct ext3_dir_entry_2 **res_dir, int *err);
-+static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
-+                           struct inode *inode);
-+
-+/*
-+ * Future: use high four bits of block for coalesce-on-delete flags
-+ * Mask them off for now.
-+ */
-+
-+static inline unsigned dx_get_block (struct dx_entry *entry)
-+{
-+      return le32_to_cpu(entry->block.v) & 0x00ffffff;
-+}
-+
-+static inline void dx_set_block (struct dx_entry *entry, unsigned value)
-+{
-+      entry->block.v = cpu_to_le32(value);
-+}
-+
-+static inline unsigned dx_get_hash (struct dx_entry *entry)
-+{
-+      return le32_to_cpu(entry->hash.v);
-+}
-+
-+static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
-+{
-+      entry->hash.v = cpu_to_le32(value);
-+}
-+
-+static inline unsigned dx_get_count (struct dx_entry *entries)
-+{
-+      return le16_to_cpu(((struct dx_countlimit *) entries)->count.v);
-+}
-+
-+static inline unsigned dx_get_limit (struct dx_entry *entries)
-+{
-+      return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v);
-+}
-+
-+static inline void dx_set_count (struct dx_entry *entries, unsigned value)
-+{
-+      ((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value);
-+}
-+
-+static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
-+{
-+      ((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value);
-+}
-+
-+static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
-+{
-+      unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) -
-+              EXT3_DIR_REC_LEN(2) - infosize;
-+      return 0? 20: entry_space / sizeof(struct dx_entry);
-+}
-+
-+static inline unsigned dx_node_limit (struct inode *dir)
-+{
-+      unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0);
-+      return 0? 22: entry_space / sizeof(struct dx_entry);
-+}
-+
-+/*
-+ * Debug
-+ */
-+#ifdef DX_DEBUG
-+struct stats
-+{ 
-+      unsigned names;
-+      unsigned space;
-+      unsigned bcount;
-+};
-+
-+static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_entry_2 *de,
-+                               int size, int show_names)
-+{
-+      unsigned names = 0, space = 0;
-+      char *base = (char *) de;
-+      struct dx_hash_info h = *hinfo;
-+      
-+      printk("names: ");
-+      while ((char *) de < base + size)
-+      {
-+              if (de->inode)
-+              {
-+                      if (show_names)
-+                      {
-+                              int len = de->name_len;
-+                              char *name = de->name;
-+                              while (len--) printk("%c", *name++);
-+                              ext3fs_dirhash(de->name, de->name_len, &h);
-+                              printk(":%x.%u ", h.hash,
-+                                     ((char *) de - base));
-+                      }
-+                      space += EXT3_DIR_REC_LEN(de->name_len);
-+                      names++;
-+              }
-+              de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-+      }
-+      printk("(%i)\n", names);
-+      return (struct stats) { names, space, 1 };
-+}
-+
-+struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
-+                           struct dx_entry *entries, int levels)
-+{
-+      unsigned blocksize = dir->i_sb->s_blocksize;
-+      unsigned count = dx_get_count (entries), names = 0, space = 0, i;
-+      unsigned bcount = 0;
-+      struct buffer_head *bh;
-+      int err;
-+      printk("%i indexed blocks...\n", count);
-+      for (i = 0; i < count; i++, entries++)
-+      {
-+              u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0;
-+              u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
-+              struct stats stats;
-+              printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
-+              if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue;
-+              stats = levels?
-+                 dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
-+                 dx_show_leaf(hinfo, (struct ext3_dir_entry_2 *) bh->b_data, blocksize, 0);
-+              names += stats.names;
-+              space += stats.space;
-+              bcount += stats.bcount;
-+              brelse (bh);
-+      }
-+      if (bcount)
-+              printk("%snames %u, fullness %u (%u%%)\n", levels?"":"   ",
-+                      names, space/bcount,(space/bcount)*100/blocksize);
-+      return (struct stats) { names, space, bcount};
-+}
-+#endif /* DX_DEBUG */
-+
-+/*
-+ * Probe for a directory leaf block to search.
-+ *
-+ * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
-+ * error in the directory index, and the caller should fall back to
-+ * searching the directory normally.  The callers of dx_probe **MUST**
-+ * check for this error code, and make sure it never gets reflected
-+ * back to userspace.
-+ */
-+static struct dx_frame *
-+dx_probe(struct dentry *dentry, struct inode *dir,
-+       struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
-+{
-+      unsigned count, indirect;
-+      struct dx_entry *at, *entries, *p, *q, *m;
-+      struct dx_root *root;
-+      struct buffer_head *bh;
-+      struct dx_frame *frame = frame_in;
-+      u32 hash;
-+
-+      frame->bh = NULL;
-+      if (dentry)
-+              dir = dentry->d_parent->d_inode;
-+      if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
-+              goto fail;
-+      root = (struct dx_root *) bh->b_data;
-+      if (root->info.hash_version != DX_HASH_TEA &&
-+          root->info.hash_version != DX_HASH_HALF_MD4 &&
-+          root->info.hash_version != DX_HASH_LEGACY) {
-+              ext3_warning(dir->i_sb, __FUNCTION__,
-+                           "Unrecognised inode hash code %d",
-+                           root->info.hash_version);
-+              brelse(bh);
-+              *err = ERR_BAD_DX_DIR;
-+              goto fail;
-+      }
-+      hinfo->hash_version = root->info.hash_version;
-+      hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed;
-+      if (dentry)
-+              ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
-+      hash = hinfo->hash;
-+
-+      if (root->info.unused_flags & 1) {
-+              ext3_warning(dir->i_sb, __FUNCTION__,
-+                           "Unimplemented inode hash flags: %#06x",
-+                           root->info.unused_flags);
-+              brelse(bh);
-+              *err = ERR_BAD_DX_DIR;
-+              goto fail;
-+      }
-+
-+      if ((indirect = root->info.indirect_levels) > 1) {
-+              ext3_warning(dir->i_sb, __FUNCTION__,
-+                           "Unimplemented inode hash depth: %#06x",
-+                           root->info.indirect_levels);
-+              brelse(bh);
-+              *err = ERR_BAD_DX_DIR;
-+              goto fail;
-+      }
-+
-+      entries = (struct dx_entry *) (((char *)&root->info) +
-+                                     root->info.info_length);
-+      assert(dx_get_limit(entries) == dx_root_limit(dir,
-+                                                    root->info.info_length));
-+      dxtrace (printk("Look up %x", hash));
-+      while (1)
-+      {
-+              count = dx_get_count(entries);
-+              assert (count && count <= dx_get_limit(entries));
-+              p = entries + 1;
-+              q = entries + count - 1;
-+              while (p <= q)
-+              {
-+                      m = p + (q - p)/2;
-+                      dxtrace(printk("."));
-+                      if (dx_get_hash(m) > hash)
-+                              q = m - 1;
-+                      else
-+                              p = m + 1;
-+              }
-+
-+              if (0) // linear search cross check
-+              {
-+                      unsigned n = count - 1;
-+                      at = entries;
-+                      while (n--)
-+                      {
-+                              dxtrace(printk(","));
-+                              if (dx_get_hash(++at) > hash)
-+                              {
-+                                      at--;
-+                                      break;
-+                              }
-+                      }
-+                      assert (at == p - 1);
-+              }
-+
-+              at = p - 1;
-+              dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
-+              frame->bh = bh;
-+              frame->entries = entries;
-+              frame->at = at;
-+              if (!indirect--) return frame;
-+              if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
-+                      goto fail2;
-+              at = entries = ((struct dx_node *) bh->b_data)->entries;
-+              assert (dx_get_limit(entries) == dx_node_limit (dir));
-+              frame++;
-+      }
-+fail2:
-+      while (frame >= frame_in) {
-+              brelse(frame->bh);
-+              frame--;
-+      }
-+fail:
-+      return NULL;
-+}
-+
-+static void dx_release (struct dx_frame *frames)
-+{
-+      if (frames[0].bh == NULL)
-+              return;
-+
-+      if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
-+              brelse(frames[1].bh);
-+      brelse(frames[0].bh);
-+}
-+
-+/*
-+ * This function increments the frame pointer to search the next leaf
-+ * block, and reads in the necessary intervening nodes if the search
-+ * should be necessary.  Whether or not the search is necessary is
-+ * controlled by the hash parameter.  If the hash value is even, then
-+ * the search is only continued if the next block starts with that
-+ * hash value.  This is used if we are searching for a specific file.
-+ *
-+ * If the hash value is HASH_NB_ALWAYS, then always go to the next block.
-+ *
-+ * This function returns 1 if the caller should continue to search,
-+ * or 0 if it should not.  If there is an error reading one of the
-+ * index blocks, it will return -1.
-+ *
-+ * If start_hash is non-null, it will be filled in with the starting
-+ * hash of the next page.
-+ */
-+static int ext3_htree_next_block(struct inode *dir, __u32 hash,
-+                               struct dx_frame *frame,
-+                               struct dx_frame *frames, int *err,
-+                               __u32 *start_hash)
-+{
-+      struct dx_frame *p;
-+      struct buffer_head *bh;
-+      int num_frames = 0;
-+      __u32 bhash;
-+
-+      *err = ENOENT;
-+      p = frame;
-+      /*
-+       * Find the next leaf page by incrementing the frame pointer.
-+       * If we run out of entries in the interior node, loop around and
-+       * increment pointer in the parent node.  When we break out of
-+       * this loop, num_frames indicates the number of interior
-+       * nodes need to be read.
-+       */
-+      while (1) {
-+              if (++(p->at) < p->entries + dx_get_count(p->entries))
-+                      break;
-+              if (p == frames)
-+                      return 0;
-+              num_frames++;
-+              p--;
-+      }
-+
-+      /*
-+       * If the hash is 1, then continue only if the next page has a
-+       * continuation hash of any value.  This is used for readdir
-+       * handling.  Otherwise, check to see if the hash matches the
-+       * desired contiuation hash.  If it doesn't, return since
-+       * there's no point to read in the successive index pages.
-+       */
-+      bhash = dx_get_hash(p->at);
-+      if (start_hash)
-+              *start_hash = bhash;
-+      if ((hash & 1) == 0) {
-+              if ((bhash & ~1) != hash)
-+                      return 0;
-+      }
-+      /*
-+       * If the hash is HASH_NB_ALWAYS, we always go to the next
-+       * block so no check is necessary
-+       */
-+      while (num_frames--) {
-+              if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
-+                                    0, err)))
-+                      return -1; /* Failure */
-+              p++;
-+              brelse (p->bh);
-+              p->bh = bh;
-+              p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
-+      }
-+      return 1;
-+}
-+
-+
-+/*
-+ * p is at least 6 bytes before the end of page
-+ */
-+static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p)
-+{
-+      return (struct ext3_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len));
-+}
-+
-+/*
-+ * This function fills a red-black tree with information from a
-+ * directory.  We start scanning the directory in hash order, starting
-+ * at start_hash and start_minor_hash.
-+ *
-+ * This function returns the number of entries inserted into the tree,
-+ * or a negative error code.
-+ */
-+int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
-+                       __u32 start_minor_hash, __u32 *next_hash)
-+{
-+      struct dx_hash_info hinfo;
-+      struct buffer_head *bh;
-+      struct ext3_dir_entry_2 *de, *top;
-+      static struct dx_frame frames[2], *frame;
-+      struct inode *dir;
-+      int block, err;
-+      int count = 0;
-+      int ret;
-+      __u32 hashval;
-+      
-+      dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
-+                     start_minor_hash));
-+      dir = dir_file->f_dentry->d_inode;
-+      hinfo.hash = start_hash;
-+      hinfo.minor_hash = 0;
-+      frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
-+      if (!frame)
-+              return err;
-+
-+      while (1) {
-+              block = dx_get_block(frame->at);
-+              dxtrace(printk("Reading block %d\n", block));
-+              if (!(bh = ext3_bread (NULL, dir, block, 0, &err)))
-+                      goto errout;
-+      
-+              de = (struct ext3_dir_entry_2 *) bh->b_data;
-+              top = (struct ext3_dir_entry_2 *) ((char *) de + dir->i_sb->s_blocksize -
-+                                     EXT3_DIR_REC_LEN(0));
-+              for (; de < top; de = ext3_next_entry(de)) {
-+                      ext3fs_dirhash(de->name, de->name_len, &hinfo);
-+                      if ((hinfo.hash < start_hash) ||
-+                          ((hinfo.hash == start_hash) &&
-+                           (hinfo.minor_hash < start_minor_hash)))
-+                              continue;
-+                      ext3_htree_store_dirent(dir_file, hinfo.hash,
-+                                              hinfo.minor_hash, de);
-+                      count++;
-+              }
-+              brelse (bh);
-+              hashval = ~1;
-+              ret = ext3_htree_next_block(dir, HASH_NB_ALWAYS, 
-+                                          frame, frames, &err, &hashval);
-+              if (next_hash)
-+                      *next_hash = hashval;
-+              if (ret == -1)
-+                      goto errout;
-+              /*
-+               * Stop if:  (a) there are no more entries, or
-+               * (b) we have inserted at least one entry and the
-+               * next hash value is not a continuation
-+               */
-+              if ((ret == 0) ||
-+                  (count && ((hashval & 1) == 0)))
-+                      break;
-+      }
-+      dx_release(frames);
-+      dxtrace(printk("Fill tree: returned %d entries\n", count));
-+      return count;
-+errout:
-+      dx_release(frames);
-+      return (err);
-+}
-+
-+
-+/*
-+ * Directory block splitting, compacting
-+ */
-+
-+static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
-+                      struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
-+{
-+      int count = 0;
-+      char *base = (char *) de;
-+      struct dx_hash_info h = *hinfo;
-+      
-+      while ((char *) de < base + size)
-+      {
-+              if (de->name_len && de->inode) {
-+                      ext3fs_dirhash(de->name, de->name_len, &h);
-+                      map_tail--;
-+                      map_tail->hash = h.hash;
-+                      map_tail->offs = (u32) ((char *) de - base);
-+                      count++;
-+              }
-+              /* XXX: do we need to check rec_len == 0 case? -Chris */
-+              de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-+      }
-+      return count;
-+}
-+
-+static void dx_sort_map (struct dx_map_entry *map, unsigned count)
-+{
-+        struct dx_map_entry *p, *q, *top = map + count - 1;
-+        int more;
-+        /* Combsort until bubble sort doesn't suck */
-+        while (count > 2)
-+      {
-+                count = count*10/13;
-+                if (count - 9 < 2) /* 9, 10 -> 11 */
-+                        count = 11;
-+                for (p = top, q = p - count; q >= map; p--, q--)
-+                        if (p->hash < q->hash)
-+                                swap(*p, *q);
-+        }
-+        /* Garden variety bubble sort */
-+        do {
-+                more = 0;
-+                q = top;
-+                while (q-- > map)
-+              {
-+                        if (q[1].hash >= q[0].hash)
-+                              continue;
-+                        swap(*(q+1), *q);
-+                        more = 1;
-+              }
-+      } while(more);
-+}
-+
-+static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
-+{
-+      struct dx_entry *entries = frame->entries;
-+      struct dx_entry *old = frame->at, *new = old + 1;
-+      int count = dx_get_count(entries);
-+
-+      assert(count < dx_get_limit(entries));
-+      assert(old < entries + count);
-+      memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
-+      dx_set_hash(new, hash);
-+      dx_set_block(new, block);
-+      dx_set_count(entries, count + 1);
-+}
-+#endif
-+
-+
-+static void ext3_update_dx_flag(struct inode *inode)
-+{
-+      if (!EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
-+                                   EXT3_FEATURE_COMPAT_DIR_INDEX))
-+              EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL;
-+}
-+
- /*
-  * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure.
-  *
-@@ -94,6 +724,7 @@ static int inline search_dirblock(struct
-       return 0;
- }
-+
- /*
-  *    ext3_find_entry()
-  *
-@@ -105,6 +736,8 @@ static int inline search_dirblock(struct
-  * The returned buffer_head has ->b_count elevated.  The caller is expected
-  * to brelse() it when appropriate.
-  */
-+
-+      
- static struct buffer_head * ext3_find_entry (struct dentry *dentry,
-                                       struct ext3_dir_entry_2 ** res_dir)
- {
-@@ -119,12 +752,32 @@ static struct buffer_head * ext3_find_en
-       int num = 0;
-       int nblocks, i, err;
-       struct inode *dir = dentry->d_parent->d_inode;
-+      int namelen;
-+      const u8 *name;
-+      unsigned blocksize;
-       *res_dir = NULL;
-       sb = dir->i_sb;
--
-+      blocksize = sb->s_blocksize;
-+      namelen = dentry->d_name.len;
-+      name = dentry->d_name.name;
-+      if (namelen > EXT3_NAME_LEN)
-+              return NULL;
-+#ifdef CONFIG_EXT3_INDEX
-+      if (is_dx(dir)) {
-+              bh = ext3_dx_find_entry(dentry, res_dir, &err);
-+              /*
-+               * On success, or if the error was file not found,
-+               * return.  Otherwise, fall back to doing a search the
-+               * old fashioned way.
-+               */
-+              if (bh || (err != ERR_BAD_DX_DIR))
-+                      return bh;
-+              dxtrace(printk("ext3_find_entry: dx failed, falling back\n"));
-+      }
-+#endif
-       nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
--      start = dir->u.ext3_i.i_dir_start_lookup;
-+      start = EXT3_I(dir)->i_dir_start_lookup;
-       if (start >= nblocks)
-               start = 0;
-       block = start;
-@@ -165,7 +818,7 @@ restart:
-               i = search_dirblock(bh, dir, dentry,
-                           block << EXT3_BLOCK_SIZE_BITS(sb), res_dir);
-               if (i == 1) {
--                      dir->u.ext3_i.i_dir_start_lookup = block;
-+                      EXT3_I(dir)->i_dir_start_lookup = block;
-                       ret = bh;
-                       goto cleanup_and_exit;
-               } else {
-@@ -196,6 +849,66 @@ cleanup_and_exit:
-       return ret;
- }
-+#ifdef CONFIG_EXT3_INDEX
-+static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
-+                     struct ext3_dir_entry_2 **res_dir, int *err)
-+{
-+      struct super_block * sb;
-+      struct dx_hash_info     hinfo;
-+      u32 hash;
-+      struct dx_frame frames[2], *frame;
-+      struct ext3_dir_entry_2 *de, *top;
-+      struct buffer_head *bh;
-+      unsigned long block;
-+      int retval;
-+      int namelen = dentry->d_name.len;
-+      const u8 *name = dentry->d_name.name;
-+      struct inode *dir = dentry->d_parent->d_inode;
-+      
-+      sb = dir->i_sb;
-+      if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
-+              return NULL;
-+      hash = hinfo.hash;
-+      do {
-+              block = dx_get_block(frame->at);
-+              if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
-+                      goto errout;
-+              de = (struct ext3_dir_entry_2 *) bh->b_data;
-+              top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize -
-+                                     EXT3_DIR_REC_LEN(0));
-+              for (; de < top; de = ext3_next_entry(de))
-+              if (ext3_match (namelen, name, de)) {
-+                      if (!ext3_check_dir_entry("ext3_find_entry",
-+                                                dir, de, bh,
-+                                (block<<EXT3_BLOCK_SIZE_BITS(sb))
-+                                        +((char *)de - bh->b_data))) {
-+                              brelse (bh);
-+                              goto errout;
-+                      }
-+                      *res_dir = de;
-+                      dx_release (frames);
-+                      return bh;
-+              }
-+              brelse (bh);
-+              /* Check to see if we should continue to search */
-+              retval = ext3_htree_next_block(dir, hash, frame,
-+                                             frames, err, 0);
-+              if (retval == -1) {
-+                      ext3_warning(sb, __FUNCTION__,
-+                           "error reading index page in directory #%lu",
-+                           dir->i_ino);
-+                      goto errout;
-+              }
-+      } while (retval == 1);
-+      
-+      *err = -ENOENT;
-+errout:
-+      dxtrace(printk("%s not found\n", name));
-+      dx_release (frames);
-+      return NULL;
-+}
-+#endif
-+
- static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
- {
-       struct inode * inode;
-@@ -212,8 +925,9 @@ static struct dentry *ext3_lookup(struct
-               brelse (bh);
-               inode = iget(dir->i_sb, ino);
--              if (!inode)
-+              if (!inode) {
-                       return ERR_PTR(-EACCES);
-+              }
-       }
-       d_add(dentry, inode);
-       return NULL;
-@@ -237,6 +951,300 @@ static inline void ext3_set_de_type(stru
-               de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
- }
-+#ifdef CONFIG_EXT3_INDEX
-+static struct ext3_dir_entry_2 *
-+dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
-+{
-+      unsigned rec_len = 0;
-+
-+      while (count--) {
-+              struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs);
-+              rec_len = EXT3_DIR_REC_LEN(de->name_len);
-+              memcpy (to, de, rec_len);
-+              ((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
-+              de->inode = 0;
-+              map++;
-+              to += rec_len;
-+      }
-+      return (struct ext3_dir_entry_2 *) (to - rec_len);
-+}
-+
-+static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
-+{
-+      struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base;
-+      unsigned rec_len = 0;
-+
-+      prev = to = de;
-+      while ((char*)de < base + size) {
-+              next = (struct ext3_dir_entry_2 *) ((char *) de +
-+                                                  le16_to_cpu(de->rec_len));
-+              if (de->inode && de->name_len) {
-+                      rec_len = EXT3_DIR_REC_LEN(de->name_len);
-+                      if (de > to)
-+                              memmove(to, de, rec_len);
-+                      to->rec_len = rec_len;
-+                      prev = to;
-+                      to = (struct ext3_dir_entry_2 *) (((char *) to) + rec_len);
-+              }
-+              de = next;
-+      }
-+      return prev;
-+}
-+
-+static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
-+                      struct buffer_head **bh,struct dx_frame *frame,
-+                      struct dx_hash_info *hinfo, int *error)
-+{
-+      unsigned blocksize = dir->i_sb->s_blocksize;
-+      unsigned count, continued;
-+      struct buffer_head *bh2;
-+      u32 newblock;
-+      u32 hash2;
-+      struct dx_map_entry *map;
-+      char *data1 = (*bh)->b_data, *data2;
-+      unsigned split;
-+      struct ext3_dir_entry_2 *de = NULL, *de2;
-+      int     err;
-+
-+      bh2 = ext3_append (handle, dir, &newblock, error);
-+      if (!(bh2)) {
-+              brelse(*bh);
-+              *bh = NULL;
-+              goto errout;
-+      }
-+
-+      BUFFER_TRACE(*bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, *bh);
-+      if (err) {
-+      journal_error:
-+              brelse(*bh);
-+              brelse(bh2);
-+              *bh = NULL;
-+              ext3_std_error(dir->i_sb, err);
-+              goto errout;
-+      }
-+      BUFFER_TRACE(frame->bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, frame->bh);
-+      if (err)
-+              goto journal_error;
-+
-+      data2 = bh2->b_data;
-+
-+      /* create map in the end of data2 block */
-+      map = (struct dx_map_entry *) (data2 + blocksize);
-+      count = dx_make_map ((struct ext3_dir_entry_2 *) data1,
-+                           blocksize, hinfo, map);
-+      map -= count;
-+      split = count/2; // need to adjust to actual middle
-+      dx_sort_map (map, count);
-+      hash2 = map[split].hash;
-+      continued = hash2 == map[split - 1].hash;
-+      dxtrace(printk("Split block %i at %x, %i/%i\n",
-+              dx_get_block(frame->at), hash2, split, count-split));
-+
-+      /* Fancy dance to stay within two buffers */
-+      de2 = dx_move_dirents(data1, data2, map + split, count - split);
-+      de = dx_pack_dirents(data1,blocksize);
-+      de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
-+      de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
-+      dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1));
-+      dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1));
-+
-+      /* Which block gets the new entry? */
-+      if (hinfo->hash >= hash2)
-+      {
-+              swap(*bh, bh2);
-+              de = de2;
-+      }
-+      dx_insert_block (frame, hash2 + continued, newblock);
-+      err = ext3_journal_dirty_metadata (handle, bh2);
-+      if (err)
-+              goto journal_error;
-+      err = ext3_journal_dirty_metadata (handle, frame->bh);
-+      if (err)
-+              goto journal_error;
-+      brelse (bh2);
-+      dxtrace(dx_show_index ("frame", frame->entries));
-+errout:
-+      return de;
-+}
-+#endif
-+
-+
-+/*
-+ * Add a new entry into a directory (leaf) block.  If de is non-NULL,
-+ * it points to a directory entry which is guaranteed to be large
-+ * enough for new directory entry.  If de is NULL, then
-+ * add_dirent_to_buf will attempt search the directory block for
-+ * space.  It will return -ENOSPC if no space is available, and -EIO
-+ * and -EEXIST if directory entry already exists.
-+ * 
-+ * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
-+ * all other cases bh is released.
-+ */
-+static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
-+                           struct inode *inode, struct ext3_dir_entry_2 *de,
-+                           struct buffer_head * bh)
-+{
-+      struct inode    *dir = dentry->d_parent->d_inode;
-+      const char      *name = dentry->d_name.name;
-+      int             namelen = dentry->d_name.len;
-+      unsigned long   offset = 0;
-+      unsigned short  reclen;
-+      int             nlen, rlen, err;
-+      char            *top;
-+      
-+      reclen = EXT3_DIR_REC_LEN(namelen);
-+      if (!de) {
-+              de = (struct ext3_dir_entry_2 *)bh->b_data;
-+              top = bh->b_data + dir->i_sb->s_blocksize - reclen;
-+              while ((char *) de <= top) {
-+                      if (!ext3_check_dir_entry("ext3_add_entry", dir, de,
-+                                                bh, offset)) {
-+                              brelse (bh);
-+                              return -EIO;
-+                      }
-+                      if (ext3_match (namelen, name, de)) {
-+                              brelse (bh);
-+                              return -EEXIST;
-+                      }
-+                      nlen = EXT3_DIR_REC_LEN(de->name_len);
-+                      rlen = le16_to_cpu(de->rec_len);
-+                      if ((de->inode? rlen - nlen: rlen) >= reclen)
-+                              break;
-+                      de = (struct ext3_dir_entry_2 *)((char *)de + rlen);
-+                      offset += rlen;
-+              }
-+              if ((char *) de > top)
-+                      return -ENOSPC;
-+      }
-+      BUFFER_TRACE(bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, bh);
-+      if (err) {
-+              ext3_std_error(dir->i_sb, err);
-+              brelse(bh);
-+              return err;
-+      }
-+      
-+      /* By now the buffer is marked for journaling */
-+      nlen = EXT3_DIR_REC_LEN(de->name_len);
-+      rlen = le16_to_cpu(de->rec_len);
-+      if (de->inode) {
-+              struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen);
-+              de1->rec_len = cpu_to_le16(rlen - nlen);
-+              de->rec_len = cpu_to_le16(nlen);
-+              de = de1;
-+      }
-+      de->file_type = EXT3_FT_UNKNOWN;
-+      if (inode) {
-+              de->inode = cpu_to_le32(inode->i_ino);
-+              ext3_set_de_type(dir->i_sb, de, inode->i_mode);
-+      } else
-+              de->inode = 0;
-+      de->name_len = namelen;
-+      memcpy (de->name, name, namelen);
-+      /*
-+       * XXX shouldn't update any times until successful
-+       * completion of syscall, but too many callers depend
-+       * on this.
-+       *
-+       * XXX similarly, too many callers depend on
-+       * ext3_new_inode() setting the times, but error
-+       * recovery deletes the inode, so the worst that can
-+       * happen is that the times are slightly out of date
-+       * and/or different from the directory change time.
-+       */
-+      dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-+      ext3_update_dx_flag(dir);
-+      dir->i_version = ++event;
-+      ext3_mark_inode_dirty(handle, dir);
-+      BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
-+      err = ext3_journal_dirty_metadata(handle, bh);
-+      if (err)
-+              ext3_std_error(dir->i_sb, err);
-+      brelse(bh);
-+      return 0;
-+}
-+
-+#ifdef CONFIG_EXT3_INDEX
-+/*
-+ * This converts a one block unindexed directory to a 3 block indexed
-+ * directory, and adds the dentry to the indexed directory.
-+ */
-+static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
-+                          struct inode *inode, struct buffer_head *bh)
-+{
-+      struct inode    *dir = dentry->d_parent->d_inode;
-+      const char      *name = dentry->d_name.name;
-+      int             namelen = dentry->d_name.len;
-+      struct buffer_head *bh2;
-+      struct dx_root  *root;
-+      struct dx_frame frames[2], *frame;
-+      struct dx_entry *entries;
-+      struct ext3_dir_entry_2 *de, *de2;
-+      char            *data1, *top;
-+      unsigned        len;
-+      int             retval;
-+      unsigned        blocksize;
-+      struct dx_hash_info hinfo;
-+      u32             block;
-+              
-+      blocksize =  dir->i_sb->s_blocksize;
-+      dxtrace(printk("Creating index\n"));
-+      retval = ext3_journal_get_write_access(handle, bh);
-+      if (retval) {
-+              ext3_std_error(dir->i_sb, retval);
-+              brelse(bh);
-+              return retval;
-+      }
-+      root = (struct dx_root *) bh->b_data;
-+              
-+      EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
-+      bh2 = ext3_append (handle, dir, &block, &retval);
-+      if (!(bh2)) {
-+              brelse(bh);
-+              return retval;
-+      }
-+      data1 = bh2->b_data;
-+
-+      /* The 0th block becomes the root, move the dirents out */
-+      de = (struct ext3_dir_entry_2 *) &root->info;
-+      len = ((char *) root) + blocksize - (char *) de;
-+      memcpy (data1, de, len);
-+      de = (struct ext3_dir_entry_2 *) data1;
-+      top = data1 + len;
-+      while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top)
-+              de = de2;
-+      de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
-+      /* Initialize the root; the dot dirents already exist */
-+      de = (struct ext3_dir_entry_2 *) (&root->dotdot);
-+      de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2));
-+      memset (&root->info, 0, sizeof(root->info));
-+      root->info.info_length = sizeof(root->info);
-+      root->info.hash_version = dir->i_sb->u.ext3_sb.s_def_hash_version;
-+      entries = root->entries;
-+      dx_set_block (entries, 1);
-+      dx_set_count (entries, 1);
-+      dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
-+
-+      /* Initialize as for dx_probe */
-+      hinfo.hash_version = root->info.hash_version;
-+      hinfo.seed = dir->i_sb->u.ext3_sb.s_hash_seed;
-+      ext3fs_dirhash(name, namelen, &hinfo);
-+      frame = frames;
-+      frame->entries = entries;
-+      frame->at = entries;
-+      frame->bh = bh;
-+      bh = bh2;
-+      de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
-+      dx_release (frames);
-+      if (!(de))
-+              return retval;
-+
-+      return add_dirent_to_buf(handle, dentry, inode, de, bh);
-+}
-+#endif
-+
- /*
-  *    ext3_add_entry()
-  *
-@@ -248,126 +1256,199 @@ static inline void ext3_set_de_type(stru
-  * the entry, as someone else might have used it while you slept.
-  */
--/*
-- * AKPM: the journalling code here looks wrong on the error paths
-- */
- static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
-       struct inode *inode)
- {
--      struct inode *dir = dentry->d_parent->d_inode;
--      const char *name = dentry->d_name.name;
--      int namelen = dentry->d_name.len;
--      unsigned long offset;
--      unsigned short rec_len;
--      struct buffer_head * bh;
--      struct ext3_dir_entry_2 * de, * de1;
--      struct super_block * sb;
--      int     retval;
--
-+      struct inode *dir = dentry->d_parent->d_inode;
-+      unsigned long offset;
-+      struct buffer_head * bh;
-+      struct ext3_dir_entry_2 *de;
-+      struct super_block * sb;
-+      int     retval;
-+#ifdef CONFIG_EXT3_INDEX
-+      int     dx_fallback=0;
-+#endif
-+      unsigned blocksize;
-+      unsigned nlen, rlen;
-+      u32 block, blocks;
-+ 
-       sb = dir->i_sb;
--
--      if (!namelen)
--              return -EINVAL;
--      bh = ext3_bread (handle, dir, 0, 0, &retval);
--      if (!bh)
--              return retval;
--      rec_len = EXT3_DIR_REC_LEN(namelen);
--      offset = 0;
--      de = (struct ext3_dir_entry_2 *) bh->b_data;
--      while (1) {
--              if ((char *)de >= sb->s_blocksize + bh->b_data) {
--                      brelse (bh);
--                      bh = NULL;
--                      bh = ext3_bread (handle, dir,
--                              offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval);
--                      if (!bh)
--                              return retval;
--                      if (dir->i_size <= offset) {
--                              if (dir->i_size == 0) {
--                                      brelse(bh);
--                                      return -ENOENT;
--                              }
--
--                              ext3_debug ("creating next block\n");
--
--                              BUFFER_TRACE(bh, "get_write_access");
--                              ext3_journal_get_write_access(handle, bh);
--                              de = (struct ext3_dir_entry_2 *) bh->b_data;
--                              de->inode = 0;
--                              de->rec_len = le16_to_cpu(sb->s_blocksize);
--                              dir->u.ext3_i.i_disksize =
--                                      dir->i_size = offset + sb->s_blocksize;
--                              dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
--                              ext3_mark_inode_dirty(handle, dir);
--                      } else {
--
--                              ext3_debug ("skipping to next block\n");
--
--                              de = (struct ext3_dir_entry_2 *) bh->b_data;
--                      }
--              }
--              if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh,
--                                         offset)) {
--                      brelse (bh);
--                      return -ENOENT;
--              }
--              if (ext3_match (namelen, name, de)) {
--                              brelse (bh);
--                              return -EEXIST;
--              }
--              if ((le32_to_cpu(de->inode) == 0 &&
--                              le16_to_cpu(de->rec_len) >= rec_len) ||
--                  (le16_to_cpu(de->rec_len) >=
--                              EXT3_DIR_REC_LEN(de->name_len) + rec_len)) {
--                      BUFFER_TRACE(bh, "get_write_access");
--                      ext3_journal_get_write_access(handle, bh);
--                      /* By now the buffer is marked for journaling */
--                      offset += le16_to_cpu(de->rec_len);
--                      if (le32_to_cpu(de->inode)) {
--                              de1 = (struct ext3_dir_entry_2 *) ((char *) de +
--                                      EXT3_DIR_REC_LEN(de->name_len));
--                              de1->rec_len =
--                                      cpu_to_le16(le16_to_cpu(de->rec_len) -
--                                      EXT3_DIR_REC_LEN(de->name_len));
--                              de->rec_len = cpu_to_le16(
--                                              EXT3_DIR_REC_LEN(de->name_len));
--                              de = de1;
--                      }
--                      de->file_type = EXT3_FT_UNKNOWN;
--                      if (inode) {
--                              de->inode = cpu_to_le32(inode->i_ino);
--                              ext3_set_de_type(dir->i_sb, de, inode->i_mode);
--                      } else
--                              de->inode = 0;
--                      de->name_len = namelen;
--                      memcpy (de->name, name, namelen);
--                      /*
--                       * XXX shouldn't update any times until successful
--                       * completion of syscall, but too many callers depend
--                       * on this.
--                       *
--                       * XXX similarly, too many callers depend on
--                       * ext3_new_inode() setting the times, but error
--                       * recovery deletes the inode, so the worst that can
--                       * happen is that the times are slightly out of date
--                       * and/or different from the directory change time.
--                       */
--                      dir->i_mtime = dir->i_ctime = CURRENT_TIME;
--                      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
--                      ext3_mark_inode_dirty(handle, dir);
--                      dir->i_version = ++event;
--                      BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
--                      ext3_journal_dirty_metadata(handle, bh);
--                      brelse(bh);
--                      return 0;
--              }
--              offset += le16_to_cpu(de->rec_len);
--              de = (struct ext3_dir_entry_2 *)
--                      ((char *) de + le16_to_cpu(de->rec_len));
--      }
--      brelse (bh);
--      return -ENOSPC;
-+      sb = dir->i_sb;
-+      blocksize = sb->s_blocksize;
-+      if (!dentry->d_name.len)
-+              return -EINVAL;
-+ #ifdef CONFIG_EXT3_INDEX
-+      if (is_dx(dir)) {
-+              retval = ext3_dx_add_entry(handle, dentry, inode);
-+              if (!retval || (retval != ERR_BAD_DX_DIR))
-+                      return retval;
-+              EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL;
-+              dx_fallback++;
-+              ext3_mark_inode_dirty(handle, dir);
-+      }
-+ #endif
-+      blocks = dir->i_size >> sb->s_blocksize_bits;
-+      for (block = 0, offset = 0; block < blocks; block++) {
-+              bh = ext3_bread(handle, dir, block, 0, &retval);
-+              if(!bh)
-+                      return retval;
-+              retval = add_dirent_to_buf(handle, dentry, inode, 0, bh);
-+              if (retval != -ENOSPC)
-+                      return retval;
-+ 
-+ #ifdef CONFIG_EXT3_INDEX
-+              if (blocks == 1 && !dx_fallback &&
-+                  EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
-+                      return make_indexed_dir(handle, dentry, inode, bh);
-+ #endif
-+              brelse(bh);
-+      }
-+      bh = ext3_append(handle, dir, &block, &retval);
-+      if (!bh)
-+              return retval;
-+      de = (struct ext3_dir_entry_2 *) bh->b_data;
-+      de->inode = 0;
-+      de->rec_len = cpu_to_le16(rlen = blocksize);
-+      nlen = 0;
-+      return add_dirent_to_buf(handle, dentry, inode, de, bh);
-+}
-+  
-+ #ifdef CONFIG_EXT3_INDEX
-+ /*
-+  * Returns 0 for success, or a negative error value
-+  */
-+static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
-+                           struct inode *inode)
-+{
-+      struct dx_frame frames[2], *frame;
-+      struct dx_entry *entries, *at;
-+      struct dx_hash_info hinfo;
-+      struct buffer_head * bh;
-+      struct inode *dir = dentry->d_parent->d_inode;
-+      struct super_block * sb = dir->i_sb;
-+      struct ext3_dir_entry_2 *de;
-+      int err;
-+  
-+      frame = dx_probe(dentry, 0, &hinfo, frames, &err);
-+      if (!frame)
-+              return err;
-+      entries = frame->entries;
-+      at = frame->at;
-+  
-+      if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
-+              goto cleanup;
-+  
-+      BUFFER_TRACE(bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, bh);
-+      if (err)
-+              goto journal_error;
-+ 
-+      err = add_dirent_to_buf(handle, dentry, inode, 0, bh);
-+      if (err != -ENOSPC) {
-+              bh = 0;
-+              goto cleanup;
-+      }
-+ 
-+      /* Block full, should compress but for now just split */
-+      dxtrace(printk("using %u of %u node entries\n",
-+                     dx_get_count(entries), dx_get_limit(entries)));
-+      /* Need to split index? */
-+      if (dx_get_count(entries) == dx_get_limit(entries)) {
-+              u32 newblock;
-+              unsigned icount = dx_get_count(entries);
-+              int levels = frame - frames;
-+              struct dx_entry *entries2;
-+              struct dx_node *node2;
-+              struct buffer_head *bh2;
-+ 
-+              if (levels && (dx_get_count(frames->entries) ==
-+                             dx_get_limit(frames->entries))) {
-+                      ext3_warning(sb, __FUNCTION__,
-+                                   "Directory index full!\n");
-+                      err = -ENOSPC;
-+                      goto cleanup;
-+              }
-+              bh2 = ext3_append (handle, dir, &newblock, &err);
-+              if (!(bh2))
-+                      goto cleanup;
-+              node2 = (struct dx_node *)(bh2->b_data);
-+              entries2 = node2->entries;
-+              node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
-+              node2->fake.inode = 0;
-+              BUFFER_TRACE(frame->bh, "get_write_access");
-+              err = ext3_journal_get_write_access(handle, frame->bh);
-+              if (err)
-+                      goto journal_error;
-+              if (levels) {
-+                      unsigned icount1 = icount/2, icount2 = icount - icount1;
-+                      unsigned hash2 = dx_get_hash(entries + icount1);
-+                      dxtrace(printk("Split index %i/%i\n", icount1, icount2));
-+                              
-+                      BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
-+                      err = ext3_journal_get_write_access(handle,
-+                                                           frames[0].bh);
-+                      if (err)
-+                              goto journal_error;
-+                              
-+                      memcpy ((char *) entries2, (char *) (entries + icount1),
-+                              icount2 * sizeof(struct dx_entry));
-+                      dx_set_count (entries, icount1);
-+                      dx_set_count (entries2, icount2);
-+                      dx_set_limit (entries2, dx_node_limit(dir));
-+ 
-+                      /* Which index block gets the new entry? */
-+                      if (at - entries >= icount1) {
-+                              frame->at = at = at - entries - icount1 + entries2;
-+                              frame->entries = entries = entries2;
-+                              swap(frame->bh, bh2);
-+                      }
-+                      dx_insert_block (frames + 0, hash2, newblock);
-+                      dxtrace(dx_show_index ("node", frames[1].entries));
-+                      dxtrace(dx_show_index ("node",
-+                             ((struct dx_node *) bh2->b_data)->entries));
-+                      err = ext3_journal_dirty_metadata(handle, bh2);
-+                      if (err)
-+                              goto journal_error;
-+                      brelse (bh2);
-+              } else {
-+                      dxtrace(printk("Creating second level index...\n"));
-+                      memcpy((char *) entries2, (char *) entries,
-+                             icount * sizeof(struct dx_entry));
-+                      dx_set_limit(entries2, dx_node_limit(dir));
-+ 
-+                      /* Set up root */
-+                      dx_set_count(entries, 1);
-+                      dx_set_block(entries + 0, newblock);
-+                      ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
-+ 
-+                      /* Add new access path frame */
-+                      frame = frames + 1;
-+                      frame->at = at = at - entries + entries2;
-+                      frame->entries = entries = entries2;
-+                      frame->bh = bh2;
-+                      err = ext3_journal_get_write_access(handle,
-+                                                           frame->bh);
-+                      if (err)
-+                              goto journal_error;
-+              }
-+              ext3_journal_dirty_metadata(handle, frames[0].bh);
-+      }
-+      de = do_split(handle, dir, &bh, frame, &hinfo, &err);
-+      if (!de)
-+              goto cleanup;
-+      err = add_dirent_to_buf(handle, dentry, inode, de, bh);
-+      bh = 0;
-+      goto cleanup;
-+      
-+ journal_error:
-+      ext3_std_error(dir->i_sb, err);
-+ cleanup:
-+      if (bh)
-+              brelse(bh);
-+      dx_release(frames);
-+      return err;
- }
-+#endif
- /*
-  * ext3_delete_entry deletes a directory entry by merging it with the
-@@ -451,9 +1532,11 @@ static int ext3_create (struct inode * d
-       struct inode * inode;
-       int err;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -478,9 +1561,11 @@ static int ext3_mknod (struct inode * di
-       struct inode *inode;
-       int err;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -507,9 +1592,11 @@ static int ext3_mkdir(struct inode * dir
-       if (dir->i_nlink >= EXT3_LINK_MAX)
-               return -EMLINK;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -521,7 +1608,7 @@ static int ext3_mkdir(struct inode * dir
-       inode->i_op = &ext3_dir_inode_operations;
-       inode->i_fop = &ext3_dir_operations;
--      inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize;
-+      inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
-       inode->i_blocks = 0;    
-       dir_block = ext3_bread (handle, inode, 0, 1, &err);
-       if (!dir_block) {
-@@ -554,21 +1641,19 @@ static int ext3_mkdir(struct inode * dir
-               inode->i_mode |= S_ISGID;
-       ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_entry (handle, dentry, inode);
--      if (err)
--              goto out_no_entry;
-+      if (err) {
-+              inode->i_nlink = 0;
-+              ext3_mark_inode_dirty(handle, inode);
-+              iput (inode);
-+              goto out_stop;
-+      }
-       dir->i_nlink++;
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
-       d_instantiate(dentry, inode);
- out_stop:
-       ext3_journal_stop(handle, dir);
-       return err;
--
--out_no_entry:
--      inode->i_nlink = 0;
--      ext3_mark_inode_dirty(handle, inode);
--      iput (inode);
--      goto out_stop;
- }
- /*
-@@ -655,7 +1740,7 @@ int ext3_orphan_add(handle_t *handle, st
-       int err = 0, rc;
-       
-       lock_super(sb);
--      if (!list_empty(&inode->u.ext3_i.i_orphan))
-+      if (!list_empty(&EXT3_I(inode)->i_orphan))
-               goto out_unlock;
-       /* Orphan handling is only valid for files with data blocks
-@@ -696,7 +1781,7 @@ int ext3_orphan_add(handle_t *handle, st
-        * This is safe: on error we're going to ignore the orphan list
-        * anyway on the next recovery. */
-       if (!err)
--              list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan);
-+              list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
-       jbd_debug(4, "superblock will point to %ld\n", inode->i_ino);
-       jbd_debug(4, "orphan inode %ld will point to %d\n",
-@@ -714,25 +1799,26 @@ out_unlock:
- int ext3_orphan_del(handle_t *handle, struct inode *inode)
- {
-       struct list_head *prev;
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-       struct ext3_sb_info *sbi;
-       ino_t ino_next; 
-       struct ext3_iloc iloc;
-       int err = 0;
-       
-       lock_super(inode->i_sb);
--      if (list_empty(&inode->u.ext3_i.i_orphan)) {
-+      if (list_empty(&ei->i_orphan)) {
-               unlock_super(inode->i_sb);
-               return 0;
-       }
-       ino_next = NEXT_ORPHAN(inode);
--      prev = inode->u.ext3_i.i_orphan.prev;
-+      prev = ei->i_orphan.prev;
-       sbi = EXT3_SB(inode->i_sb);
-       jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino);
--      list_del(&inode->u.ext3_i.i_orphan);
--      INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
-+      list_del(&ei->i_orphan);
-+      INIT_LIST_HEAD(&ei->i_orphan);
-       /* If we're on an error path, we may not have a valid
-        * transaction handle with which to update the orphan list on
-@@ -793,8 +1879,9 @@ static int ext3_rmdir (struct inode * di
-       handle_t *handle;
-       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
--      if (IS_ERR(handle))
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       retval = -ENOENT;
-       bh = ext3_find_entry (dentry, &de);
-@@ -832,7 +1919,7 @@ static int ext3_rmdir (struct inode * di
-       ext3_mark_inode_dirty(handle, inode);
-       dir->i_nlink--;
-       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
- end_rmdir:
-@@ -850,8 +1937,9 @@ static int ext3_unlink(struct inode * di
-       handle_t *handle;
-       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
--      if (IS_ERR(handle))
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -878,7 +1966,7 @@ static int ext3_unlink(struct inode * di
-       if (retval)
-               goto end_unlink;
-       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
-       inode->i_nlink--;
-       if (!inode->i_nlink)
-@@ -904,9 +1992,11 @@ static int ext3_symlink (struct inode * 
-       if (l > dir->i_sb->s_blocksize)
-               return -ENAMETOOLONG;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -916,7 +2006,7 @@ static int ext3_symlink (struct inode * 
-       if (IS_ERR(inode))
-               goto out_stop;
--      if (l > sizeof (inode->u.ext3_i.i_data)) {
-+      if (l > sizeof (EXT3_I(inode)->i_data)) {
-               inode->i_op = &page_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-               /*
-@@ -925,27 +2015,26 @@ static int ext3_symlink (struct inode * 
-                * i_size in generic_commit_write().
-                */
-               err = block_symlink(inode, symname, l);
--              if (err)
--                      goto out_no_entry;
--      } else {
--              inode->i_op = &ext3_fast_symlink_inode_operations;
--              memcpy((char*)&inode->u.ext3_i.i_data,symname,l);
--              inode->i_size = l-1;
--      }
--      inode->u.ext3_i.i_disksize = inode->i_size;
--      ext3_mark_inode_dirty(handle, inode);
--      err = ext3_add_nondir(handle, dentry, inode);
--out_stop:
--      ext3_journal_stop(handle, dir);
--      return err;
--
--out_no_entry:
--      ext3_dec_count(handle, inode);
--      ext3_mark_inode_dirty(handle, inode);
--      iput (inode);
--      goto out_stop;
-+              if (err) {
-+                      ext3_dec_count(handle, inode);
-+                      ext3_mark_inode_dirty(handle, inode);
-+                      iput (inode);
-+                      goto out_stop;
-+              }
-+      } else {
-+              inode->i_op = &ext3_fast_symlink_inode_operations;
-+              memcpy((char*)&EXT3_I(inode)->i_data,symname,l);
-+              inode->i_size = l-1;
-+      }
-+      EXT3_I(inode)->i_disksize = inode->i_size;
-+      err = ext3_add_nondir(handle, dentry, inode);
-+      ext3_mark_inode_dirty(handle, inode);
-+  out_stop:
-+      ext3_journal_stop(handle, dir);
-+      return err;
- }
-+
- static int ext3_link (struct dentry * old_dentry,
-               struct inode * dir, struct dentry *dentry)
- {
-@@ -956,12 +2045,15 @@ static int ext3_link (struct dentry * ol
-       if (S_ISDIR(inode->i_mode))
-               return -EPERM;
--      if (inode->i_nlink >= EXT3_LINK_MAX)
-+      if (inode->i_nlink >= EXT3_LINK_MAX) {
-               return -EMLINK;
-+      }
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -995,9 +2087,11 @@ static int ext3_rename (struct inode * o
-       old_bh = new_bh = dir_bh = NULL;
--      handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(old_dir) || IS_SYNC(new_dir))
-               handle->h_sync = 1;
-@@ -1077,7 +2171,7 @@ static int ext3_rename (struct inode * o
-               new_inode->i_ctime = CURRENT_TIME;
-       }
-       old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
--      old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(old_dir);
-       if (dir_bh) {
-               BUFFER_TRACE(dir_bh, "get_write_access");
-               ext3_journal_get_write_access(handle, dir_bh);
-@@ -1089,7 +2183,7 @@ static int ext3_rename (struct inode * o
-                       new_inode->i_nlink--;
-               } else {
-                       new_dir->i_nlink++;
--                      new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+                      ext3_update_dx_flag(new_dir);
-                       ext3_mark_inode_dirty(handle, new_dir);
-               }
-       }
---- linux-2.4.19-hp3_pnnl1/fs/ext3/super.c~ext-2.4-patch-1-chaos       2003-04-11 13:55:54.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/ext3/super.c        2003-04-11 13:56:05.000000000 +0800
-@@ -24,6 +24,7 @@
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/locks.h>
-@@ -404,6 +405,7 @@ void ext3_put_super (struct super_block 
-       kdev_t j_dev = sbi->s_journal->j_dev;
-       int i;
-+      ext3_xattr_put_super(sb);
-       journal_destroy(sbi->s_journal);
-       if (!(sb->s_flags & MS_RDONLY)) {
-               EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
-@@ -499,6 +501,7 @@ static int parse_options (char * options
-                         int is_remount)
- {
-       unsigned long *mount_options = &sbi->s_mount_opt;
-+      
-       uid_t *resuid = &sbi->s_resuid;
-       gid_t *resgid = &sbi->s_resgid;
-       char * this_char;
-@@ -511,6 +514,13 @@ static int parse_options (char * options
-            this_char = strtok (NULL, ",")) {
-               if ((value = strchr (this_char, '=')) != NULL)
-                       *value++ = 0;
-+#ifdef CONFIG_EXT3_FS_XATTR_USER
-+              if (!strcmp (this_char, "user_xattr"))
-+                      set_opt (*mount_options, XATTR_USER);
-+              else if (!strcmp (this_char, "nouser_xattr"))
-+                      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")) {
-@@ -702,6 +712,7 @@ static int ext3_setup_super(struct super
-       es->s_mtime = cpu_to_le32(CURRENT_TIME);
-       ext3_update_dynamic_rev(sb);
-       EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
-+
-       ext3_commit_super (sb, es, 1);
-       if (test_opt (sb, DEBUG))
-               printk (KERN_INFO
-@@ -712,6 +723,7 @@ static int ext3_setup_super(struct super
-                       EXT3_BLOCKS_PER_GROUP(sb),
-                       EXT3_INODES_PER_GROUP(sb),
-                       sbi->s_mount_opt);
-+
-       printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ",
-                               bdevname(sb->s_dev));
-       if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
-@@ -886,6 +898,7 @@ static loff_t ext3_max_size(int bits)
-       return res;
- }
-+
- struct super_block * ext3_read_super (struct super_block * sb, void * data,
-                                     int silent)
- {
-@@ -921,6 +934,12 @@ struct super_block * ext3_read_super (st
-       sbi->s_mount_opt = 0;
-       sbi->s_resuid = EXT3_DEF_RESUID;
-       sbi->s_resgid = EXT3_DEF_RESGID;
-+
-+      /* Default extended attribute flags */
-+#ifdef CONFIG_EXT3_FS_XATTR_USER
-+      /* set_opt(sbi->s_mount_opt, XATTR_USER); */
-+#endif
-+
-       if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) {
-               sb->s_dev = 0;
-               goto out_fail;
-@@ -1062,6 +1081,9 @@ struct super_block * ext3_read_super (st
-       sbi->s_mount_state = le16_to_cpu(es->s_state);
-       sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
-       sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
-+      for (i=0; i < 4; i++)
-+              sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
-+      sbi->s_def_hash_version = es->s_def_hash_version;
-       if (sbi->s_blocks_per_group > blocksize * 8) {
-               printk (KERN_ERR
-@@ -1736,14 +1758,30 @@ static DECLARE_FSTYPE_DEV(ext3_fs_type, 
- static int __init init_ext3_fs(void)
- {
--        return register_filesystem(&ext3_fs_type);
-+      int error = init_ext3_xattr();
-+      if (error)
-+              return error;
-+      error = init_ext3_xattr_user();
-+      if (error)
-+              goto fail;
-+      error = register_filesystem(&ext3_fs_type);
-+      if (!error)
-+              return 0;
-+      
-+      exit_ext3_xattr_user();
-+fail:
-+      exit_ext3_xattr();
-+      return error;
- }
- static void __exit exit_ext3_fs(void)
- {
-       unregister_filesystem(&ext3_fs_type);
-+      exit_ext3_xattr_user();
-+      exit_ext3_xattr();
- }
-+EXPORT_SYMBOL(ext3_force_commit);
- EXPORT_SYMBOL(ext3_bread);
- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
---- linux-2.4.19-hp3_pnnl1/include/linux/ext3_fs.h~ext-2.4-patch-1-chaos       2002-02-26 03:38:13.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/include/linux/ext3_fs.h        2003-04-11 13:55:58.000000000 +0800
-@@ -40,6 +40,11 @@
- #define EXT3FS_VERSION                "2.4-0.9.17"
- /*
-+ * Always enable hashed directories
-+ */
-+#define CONFIG_EXT3_INDEX
-+
-+/*
-  * Debug code
-  */
- #ifdef EXT3FS_DEBUG
-@@ -437,8 +442,11 @@ struct ext3_super_block {
- /*E0*/        __u32   s_journal_inum;         /* inode number of journal file */
-       __u32   s_journal_dev;          /* device number of journal file */
-       __u32   s_last_orphan;          /* start of list of inodes to delete */
--
--/*EC*/        __u32   s_reserved[197];        /* Padding to the end of the block */
-+      __u32   s_hash_seed[4];         /* HTREE hash seed */
-+      __u8    s_def_hash_version;     /* Default hash version to use */
-+      __u8    s_reserved_char_pad;
-+      __u16   s_reserved_word_pad;
-+      __u32   s_reserved[192];        /* Padding to the end of the block */
- };
- #ifdef __KERNEL__
-@@ -575,9 +583,46 @@ struct ext3_dir_entry_2 {
- #define EXT3_DIR_ROUND                        (EXT3_DIR_PAD - 1)
- #define EXT3_DIR_REC_LEN(name_len)    (((name_len) + 8 + EXT3_DIR_ROUND) & \
-                                        ~EXT3_DIR_ROUND)
-+/*
-+ * Hash Tree Directory indexing
-+ * (c) Daniel Phillips, 2001
-+ */
-+
-+#ifdef CONFIG_EXT3_INDEX
-+  #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
-+                                            EXT3_FEATURE_COMPAT_DIR_INDEX) && \
-+                    (EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
-+#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
-+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
-+#else
-+  #define is_dx(dir) 0
-+#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
-+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
-+#endif
-+
-+/* Legal values for the dx_root hash_version field: */
-+
-+#define DX_HASH_LEGACY                0
-+#define DX_HASH_HALF_MD4      1
-+#define DX_HASH_TEA           2
-+
-+/* hash info structure used by the directory hash */
-+struct dx_hash_info
-+{
-+      u32             hash;
-+      u32             minor_hash;
-+      int             hash_version;
-+      u32             *seed;
-+};
- #ifdef __KERNEL__
- /*
-+ * Control parameters used by ext3_htree_next_block
-+ */
-+#define HASH_NB_ALWAYS                1
-+
-+
-+/*
-  * Describe an inode's exact location on disk and in memory
-  */
- struct ext3_iloc
-@@ -587,6 +632,27 @@ struct ext3_iloc
-       unsigned long block_group;
- };
-+
-+/*
-+ * This structure is stuffed into the struct file's private_data field
-+ * for directories.  It is where we put information so that we can do
-+ * readdir operations in hash tree order.
-+ */
-+struct dir_private_info {
-+      rb_root_t       root;
-+      rb_node_t       *curr_node;
-+      struct fname    *extra_fname;
-+      loff_t          last_pos;
-+      __u32           curr_hash;
-+      __u32           curr_minor_hash;
-+      __u32           next_hash;
-+};
-+
-+/*
-+ * Special error return code only used by dx_probe() and its callers.
-+ */
-+#define ERR_BAD_DX_DIR        -75000
-+
- /*
-  * Function prototypes
-  */
-@@ -614,11 +680,20 @@ extern struct ext3_group_desc * ext3_get
- /* dir.c */
- extern int ext3_check_dir_entry(const char *, struct inode *,
--                              struct ext3_dir_entry_2 *, struct buffer_head *,
--                              unsigned long);
-+                              struct ext3_dir_entry_2 *,
-+                              struct buffer_head *, unsigned long);
-+extern void ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
-+                                  __u32 minor_hash,
-+                                  struct ext3_dir_entry_2 *dirent);
-+extern void ext3_htree_free_dir_info(struct dir_private_info *p);
-+
- /* fsync.c */
- extern int ext3_sync_file (struct file *, struct dentry *, int);
-+/* hash.c */
-+extern int ext3fs_dirhash(const char *name, int len, struct
-+                        dx_hash_info *hinfo);
-+
- /* ialloc.c */
- extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
- extern void ext3_free_inode (handle_t *, struct inode *);
-@@ -650,6 +725,8 @@ extern int ext3_ioctl (struct inode *, s
- /* namei.c */
- extern int ext3_orphan_add(handle_t *, struct inode *);
- extern int ext3_orphan_del(handle_t *, struct inode *);
-+extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
-+                              __u32 start_minor_hash, __u32 *next_hash);
- /* super.c */
- extern void ext3_error (struct super_block *, const char *, const char *, ...)
---- linux-2.4.19-hp3_pnnl1/include/linux/ext3_fs_sb.h~ext-2.4-patch-1-chaos    2002-02-26 03:38:13.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/include/linux/ext3_fs_sb.h     2003-04-11 13:55:58.000000000 +0800
-@@ -62,6 +62,8 @@ struct ext3_sb_info {
-       int s_inode_size;
-       int s_first_ino;
-       u32 s_next_generation;
-+      u32 s_hash_seed[4];
-+      int s_def_hash_version;
-       /* Journaling */
-       struct inode * s_journal_inode;
---- linux-2.4.19-hp3_pnnl1/include/linux/ext3_jbd.h~ext-2.4-patch-1-chaos      2001-12-22 01:42:03.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/include/linux/ext3_jbd.h       2003-04-11 13:56:05.000000000 +0800
-@@ -30,13 +30,19 @@
- #define EXT3_SINGLEDATA_TRANS_BLOCKS  8
-+/* Extended attributes may touch two data buffers, two bitmap buffers,
-+ * and two group and summaries. */
-+
-+#define EXT3_XATTR_TRANS_BLOCKS               8
-+
- /* Define the minimum size for a transaction which modifies data.  This
-  * needs to take into account the fact that we may end up modifying two
-  * quota files too (one for the group, one for the user quota).  The
-  * superblock only gets updated once, of course, so don't bother
-  * counting that again for the quota updates. */
--#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
-+#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
-+                                       EXT3_XATTR_TRANS_BLOCKS - 2)
- extern int ext3_writepage_trans_blocks(struct inode *inode);
-@@ -63,6 +69,8 @@ extern int ext3_writepage_trans_blocks(s
- #define EXT3_RESERVE_TRANS_BLOCKS     12
-+#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8
-+
- int
- ext3_mark_iloc_dirty(handle_t *handle, 
-                    struct inode *inode,
---- linux-2.4.19-hp3_pnnl1/include/linux/rbtree.h~ext-2.4-patch-1-chaos        2001-11-23 03:46:18.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/include/linux/rbtree.h 2003-04-11 13:55:58.000000000 +0800
-@@ -120,6 +120,8 @@ rb_root_t;
- extern void rb_insert_color(rb_node_t *, rb_root_t *);
- extern void rb_erase(rb_node_t *, rb_root_t *);
-+extern rb_node_t *rb_get_first(rb_root_t *root);
-+extern rb_node_t *rb_get_next(rb_node_t *n);
- static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
- {
---- linux-2.4.19-hp3_pnnl1/lib/rbtree.c~ext-2.4-patch-1-chaos  2002-08-03 08:39:46.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/lib/rbtree.c   2003-04-11 13:55:58.000000000 +0800
-@@ -17,6 +17,8 @@
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-   linux/lib/rbtree.c
-+
-+  rb_get_first and rb_get_next written by Theodore Ts'o, 9/8/2002
- */
- #include <linux/rbtree.h>
-@@ -294,3 +296,43 @@ void rb_erase(rb_node_t * node, rb_root_
-               __rb_erase_color(child, parent, root);
- }
- EXPORT_SYMBOL(rb_erase);
-+
-+/*
-+ * This function returns the first node (in sort order) of the tree.
-+ */
-+rb_node_t *rb_get_first(rb_root_t *root)
-+{
-+      rb_node_t       *n;
-+
-+      n = root->rb_node;
-+      if (!n)
-+              return 0;
-+      while (n->rb_left)
-+              n = n->rb_left;
-+      return n;
-+}
-+EXPORT_SYMBOL(rb_get_first);
-+
-+/*
-+ * Given a node, this function will return the next node in the tree.
-+ */
-+rb_node_t *rb_get_next(rb_node_t *n)
-+{
-+      rb_node_t       *parent;
-+
-+      if (n->rb_right) {
-+              n = n->rb_right;
-+              while (n->rb_left)
-+                      n = n->rb_left;
-+              return n;
-+      } else {
-+              while ((parent = n->rb_parent)) {
-+                      if (n == parent->rb_left)
-+                              return parent;
-+                      n = parent;
-+              }
-+              return 0;
-+      }
-+}
-+EXPORT_SYMBOL(rb_get_next);
-+
-
-_
diff --git a/lustre/kernel_patches/patches/ext-2.4-patch-1.patch b/lustre/kernel_patches/patches/ext-2.4-patch-1.patch
deleted file mode 100644 (file)
index 09caec1..0000000
+++ /dev/null
@@ -1,2527 +0,0 @@
- fs/ext3/Makefile           |    2 
- fs/ext3/dir.c              |  299 +++++++++
- fs/ext3/file.c             |    3 
- fs/ext3/hash.c             |  215 ++++++
- fs/ext3/namei.c            | 1387 ++++++++++++++++++++++++++++++++++++++++-----
- fs/ext3/super.c            |    7 
- include/linux/ext3_fs.h    |   85 ++
- include/linux/ext3_fs_sb.h |    2 
- include/linux/ext3_jbd.h   |    2 
- include/linux/rbtree.h     |    2 
- lib/rbtree.c               |   42 +
- 11 files changed, 1886 insertions(+), 160 deletions(-)
-
---- linux-2.4.20/fs/ext3/Makefile~ext-2.4-patch-1      Sat Apr  5 03:56:31 2003
-+++ linux-2.4.20-braam/fs/ext3/Makefile        Sat Apr  5 03:57:05 2003
-@@ -12,7 +12,7 @@ O_TARGET := ext3.o
- export-objs :=        super.o inode.o
- obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
--              ioctl.o namei.o super.o symlink.o
-+              ioctl.o namei.o super.o symlink.o hash.o
- obj-m    := $(O_TARGET)
- include $(TOPDIR)/Rules.make
---- linux-2.4.20/fs/ext3/dir.c~ext-2.4-patch-1 Sat Apr  5 03:56:31 2003
-+++ linux-2.4.20-braam/fs/ext3/dir.c   Sat Apr  5 03:56:31 2003
-@@ -21,12 +21,16 @@
- #include <linux/fs.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include <linux/slab.h>
-+#include <linux/rbtree.h>
- static unsigned char ext3_filetype_table[] = {
-       DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
- };
- static int ext3_readdir(struct file *, void *, filldir_t);
-+static int ext3_dx_readdir(struct file * filp,
-+                         void * dirent, filldir_t filldir);
- struct file_operations ext3_dir_operations = {
-       read:           generic_read_dir,
-@@ -35,6 +39,17 @@ struct file_operations ext3_dir_operatio
-       fsync:          ext3_sync_file,         /* BKL held */
- };
-+
-+static unsigned char get_dtype(struct super_block *sb, int filetype)
-+{
-+      if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
-+          (filetype >= EXT3_FT_MAX))
-+              return DT_UNKNOWN;
-+
-+      return (ext3_filetype_table[filetype]);
-+}
-+                             
-+
- int ext3_check_dir_entry (const char * function, struct inode * dir,
-                         struct ext3_dir_entry_2 * de,
-                         struct buffer_head * bh,
-@@ -79,6 +94,16 @@ static int ext3_readdir(struct file * fi
-       sb = inode->i_sb;
-+      if (is_dx(inode)) {
-+              err = ext3_dx_readdir(filp, dirent, filldir);
-+              if (err != ERR_BAD_DX_DIR)
-+                      return err;
-+              /*
-+               * We don't set the inode dirty flag since it's not
-+               * critical that it get flushed back to the disk.
-+               */
-+              EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL;
-+      }
-       stored = 0;
-       bh = NULL;
-       offset = filp->f_pos & (sb->s_blocksize - 1);
-@@ -162,18 +187,12 @@ revalidate:
-                                * during the copy operation.
-                                */
-                               unsigned long version = filp->f_version;
--                              unsigned char d_type = DT_UNKNOWN;
--                              if (EXT3_HAS_INCOMPAT_FEATURE(sb,
--                                              EXT3_FEATURE_INCOMPAT_FILETYPE)
--                                              && de->file_type < EXT3_FT_MAX)
--                                      d_type =
--                                        ext3_filetype_table[de->file_type];
-                               error = filldir(dirent, de->name,
-                                               de->name_len,
-                                               filp->f_pos,
-                                               le32_to_cpu(de->inode),
--                                              d_type);
-+                                              get_dtype(sb, de->file_type));
-                               if (error)
-                                       break;
-                               if (version != filp->f_version)
-@@ -188,3 +207,269 @@ revalidate:
-       UPDATE_ATIME(inode);
-       return 0;
- }
-+
-+#ifdef CONFIG_EXT3_INDEX
-+/*
-+ * These functions convert from the major/minor hash to an f_pos
-+ * value.
-+ * 
-+ * Currently we only use major hash numer.  This is unfortunate, but
-+ * on 32-bit machines, the same VFS interface is used for lseek and
-+ * llseek, so if we use the 64 bit offset, then the 32-bit versions of
-+ * lseek/telldir/seekdir will blow out spectacularly, and from within
-+ * the ext2 low-level routine, we don't know if we're being called by
-+ * a 64-bit version of the system call or the 32-bit version of the
-+ * system call.  Worse yet, NFSv2 only allows for a 32-bit readdir
-+ * cookie.  Sigh.
-+ */
-+#define hash2pos(major, minor)        (major >> 1)
-+#define pos2maj_hash(pos)     ((pos << 1) & 0xffffffff)
-+#define pos2min_hash(pos)     (0)
-+
-+/*
-+ * This structure holds the nodes of the red-black tree used to store
-+ * the directory entry in hash order.
-+ */
-+struct fname {
-+      __u32           hash;
-+      __u32           minor_hash;
-+      rb_node_t       rb_hash; 
-+      struct fname    *next;
-+      __u32           inode;
-+      __u8            name_len;
-+      __u8            file_type;
-+      char            name[0];
-+};
-+
-+/*
-+ * This functoin implements a non-recursive way of freeing all of the
-+ * nodes in the red-black tree.
-+ */
-+static void free_rb_tree_fname(rb_root_t *root)
-+{
-+      rb_node_t       *n = root->rb_node;
-+      rb_node_t       *parent;
-+      struct fname    *fname;
-+
-+      while (n) {
-+              /* Do the node's children first */
-+              if ((n)->rb_left) {
-+                      n = n->rb_left;
-+                      continue;
-+              }
-+              if (n->rb_right) {
-+                      n = n->rb_right;
-+                      continue;
-+              }
-+              /*
-+               * The node has no children; free it, and then zero
-+               * out parent's link to it.  Finally go to the
-+               * beginning of the loop and try to free the parent
-+               * node.
-+               */
-+              parent = n->rb_parent;
-+              fname = rb_entry(n, struct fname, rb_hash);
-+              kfree(fname);
-+              if (!parent)
-+                      root->rb_node = 0;
-+              else if (parent->rb_left == n)
-+                      parent->rb_left = 0;
-+              else if (parent->rb_right == n)
-+                      parent->rb_right = 0;
-+              n = parent;
-+      }
-+      root->rb_node = 0;
-+}
-+
-+
-+struct dir_private_info *create_dir_info(loff_t pos)
-+{
-+      struct dir_private_info *p;
-+
-+      p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL);
-+      if (!p)
-+              return NULL;
-+      p->root.rb_node = 0;
-+      p->curr_node = 0;
-+      p->extra_fname = 0;
-+      p->last_pos = 0;
-+      p->curr_hash = pos2maj_hash(pos);
-+      p->curr_minor_hash = pos2min_hash(pos);
-+      p->next_hash = 0;
-+      return p;
-+}
-+
-+void ext3_htree_free_dir_info(struct dir_private_info *p)
-+{
-+      free_rb_tree_fname(&p->root);
-+      kfree(p);
-+}
-+              
-+/*
-+ * Given a directory entry, enter it into the fname rb tree.
-+ */
-+void ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
-+                           __u32 minor_hash,
-+                           struct ext3_dir_entry_2 *dirent)
-+{
-+      rb_node_t **p, *parent = NULL;
-+      struct fname * fname, *new_fn;
-+      struct dir_private_info *info;
-+      int len;
-+
-+      info = (struct dir_private_info *) dir_file->private_data;
-+      p = &info->root.rb_node;
-+
-+      /* Create and allocate the fname structure */
-+      len = sizeof(struct fname) + dirent->name_len + 1;
-+      new_fn = kmalloc(len, GFP_KERNEL);
-+      memset(new_fn, 0, len);
-+      new_fn->hash = hash;
-+      new_fn->minor_hash = minor_hash;
-+      new_fn->inode = le32_to_cpu(dirent->inode);
-+      new_fn->name_len = dirent->name_len;
-+      new_fn->file_type = dirent->file_type;
-+      memcpy(new_fn->name, dirent->name, dirent->name_len);
-+      new_fn->name[dirent->name_len] = 0;
-+      
-+      while (*p) {
-+              parent = *p;
-+              fname = rb_entry(parent, struct fname, rb_hash);
-+
-+              /*
-+               * If the hash and minor hash match up, then we put
-+               * them on a linked list.  This rarely happens...
-+               */
-+              if ((new_fn->hash == fname->hash) &&
-+                  (new_fn->minor_hash == fname->minor_hash)) {
-+                      new_fn->next = fname->next;
-+                      fname->next = new_fn;
-+                      return;
-+              }
-+                      
-+              if (new_fn->hash < fname->hash)
-+                      p = &(*p)->rb_left;
-+              else if (new_fn->hash > fname->hash)
-+                      p = &(*p)->rb_right;
-+              else if (new_fn->minor_hash < fname->minor_hash)
-+                      p = &(*p)->rb_left;
-+              else /* if (new_fn->minor_hash > fname->minor_hash) */
-+                      p = &(*p)->rb_right;
-+      }
-+
-+      rb_link_node(&new_fn->rb_hash, parent, p);
-+      rb_insert_color(&new_fn->rb_hash, &info->root);
-+}
-+
-+
-+
-+/*
-+ * This is a helper function for ext3_dx_readdir.  It calls filldir
-+ * for all entres on the fname linked list.  (Normally there is only
-+ * one entry on the linked list, unless there are 62 bit hash collisions.)
-+ */
-+static int call_filldir(struct file * filp, void * dirent,
-+                      filldir_t filldir, struct fname *fname)
-+{
-+      struct dir_private_info *info = filp->private_data;
-+      loff_t  curr_pos;
-+      struct inode *inode = filp->f_dentry->d_inode;
-+      struct super_block * sb;
-+      int error;
-+
-+      sb = inode->i_sb;
-+      
-+      if (!fname) {
-+              printk("call_filldir: called with null fname?!?\n");
-+              return 0;
-+      }
-+      curr_pos = hash2pos(fname->hash, fname->minor_hash);
-+      while (fname) {
-+              error = filldir(dirent, fname->name,
-+                              fname->name_len, curr_pos, 
-+                              fname->inode,
-+                              get_dtype(sb, fname->file_type));
-+              if (error) {
-+                      filp->f_pos = curr_pos;
-+                      info->extra_fname = fname->next;
-+                      return error;
-+              }
-+              fname = fname->next;
-+      }
-+      return 0;
-+}
-+
-+static int ext3_dx_readdir(struct file * filp,
-+                       void * dirent, filldir_t filldir)
-+{
-+      struct dir_private_info *info = filp->private_data;
-+      struct inode *inode = filp->f_dentry->d_inode;
-+      struct fname *fname;
-+      int     ret;
-+
-+      if (!info) {
-+              info = create_dir_info(filp->f_pos);
-+              if (!info)
-+                      return -ENOMEM;
-+              filp->private_data = info;
-+      }
-+
-+      /* Some one has messed with f_pos; reset the world */
-+      if (info->last_pos != filp->f_pos) {
-+              free_rb_tree_fname(&info->root);
-+              info->curr_node = 0;
-+              info->extra_fname = 0;
-+              info->curr_hash = pos2maj_hash(filp->f_pos);
-+              info->curr_minor_hash = pos2min_hash(filp->f_pos);
-+      }
-+
-+      /*
-+       * If there are any leftover names on the hash collision
-+       * chain, return them first.
-+       */
-+      if (info->extra_fname &&
-+          call_filldir(filp, dirent, filldir, info->extra_fname))
-+              goto finished;
-+
-+      if (!info->curr_node)
-+              info->curr_node = rb_get_first(&info->root);
-+
-+      while (1) {
-+              /*
-+               * Fill the rbtree if we have no more entries,
-+               * or the inode has changed since we last read in the
-+               * cached entries. 
-+               */
-+              if ((!info->curr_node) ||
-+                  (filp->f_version != inode->i_version)) {
-+                      info->curr_node = 0;
-+                      free_rb_tree_fname(&info->root);
-+                      filp->f_version = inode->i_version;
-+                      ret = ext3_htree_fill_tree(filp, info->curr_hash,
-+                                                 info->curr_minor_hash,
-+                                                 &info->next_hash);
-+                      if (ret < 0)
-+                              return ret;
-+                      if (ret == 0)
-+                              break;
-+                      info->curr_node = rb_get_first(&info->root);
-+              }
-+
-+              fname = rb_entry(info->curr_node, struct fname, rb_hash);
-+              info->curr_hash = fname->hash;
-+              info->curr_minor_hash = fname->minor_hash;
-+              if (call_filldir(filp, dirent, filldir, fname))
-+                      break;
-+
-+              info->curr_node = rb_get_next(info->curr_node);
-+              if (!info->curr_node) {
-+                      info->curr_hash = info->next_hash;
-+                      info->curr_minor_hash = 0;
-+              }
-+      }
-+finished:
-+      info->last_pos = filp->f_pos;
-+      UPDATE_ATIME(inode);
-+      return 0;
-+}
-+#endif
---- linux-2.4.20/fs/ext3/file.c~ext-2.4-patch-1        Sat Apr  5 03:56:31 2003
-+++ linux-2.4.20-braam/fs/ext3/file.c  Sat Apr  5 03:56:31 2003
-@@ -35,6 +35,9 @@ static int ext3_release_file (struct ino
- {
-       if (filp->f_mode & FMODE_WRITE)
-               ext3_discard_prealloc (inode);
-+      if (is_dx(inode) && filp->private_data)
-+              ext3_htree_free_dir_info(filp->private_data);
-+
-       return 0;
- }
---- /dev/null  Fri Aug 30 17:31:37 2002
-+++ linux-2.4.20-braam/fs/ext3/hash.c  Sat Apr  5 03:56:31 2003
-@@ -0,0 +1,215 @@
-+/*
-+ *  linux/fs/ext3/hash.c
-+ *
-+ * Copyright (C) 2002 by Theodore Ts'o
-+ *
-+ * This file is released under the GPL v2.
-+ * 
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ */
-+
-+#include <linux/fs.h>
-+#include <linux/jbd.h>
-+#include <linux/sched.h>
-+#include <linux/ext3_fs.h>
-+
-+#define DELTA 0x9E3779B9
-+
-+static void TEA_transform(__u32 buf[4], __u32 const in[])
-+{
-+      __u32   sum = 0;
-+      __u32   b0 = buf[0], b1 = buf[1];
-+      __u32   a = in[0], b = in[1], c = in[2], d = in[3];
-+      int     n = 16;
-+
-+      do {                                                    
-+              sum += DELTA;                                   
-+              b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); 
-+              b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); 
-+      } while(--n);
-+
-+      buf[0] += b0;
-+      buf[1] += b1;
-+}
-+
-+/* F, G and H are basic MD4 functions: selection, majority, parity */
-+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
-+#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
-+#define H(x, y, z) ((x) ^ (y) ^ (z))
-+
-+/*
-+ * The generic round function.  The application is so specific that
-+ * we don't bother protecting all the arguments with parens, as is generally
-+ * good macro practice, in favor of extra legibility.
-+ * Rotation is separate from addition to prevent recomputation
-+ */
-+#define ROUND(f, a, b, c, d, x, s)    \
-+      (a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
-+#define K1 0
-+#define K2 013240474631UL
-+#define K3 015666365641UL
-+
-+/*
-+ * Basic cut-down MD4 transform.  Returns only 32 bits of result.
-+ */
-+static void halfMD4Transform (__u32 buf[4], __u32 const in[])
-+{
-+      __u32   a = buf[0], b = buf[1], c = buf[2], d = buf[3];
-+
-+      /* Round 1 */
-+      ROUND(F, a, b, c, d, in[0] + K1,  3);
-+      ROUND(F, d, a, b, c, in[1] + K1,  7);
-+      ROUND(F, c, d, a, b, in[2] + K1, 11);
-+      ROUND(F, b, c, d, a, in[3] + K1, 19);
-+      ROUND(F, a, b, c, d, in[4] + K1,  3);
-+      ROUND(F, d, a, b, c, in[5] + K1,  7);
-+      ROUND(F, c, d, a, b, in[6] + K1, 11);
-+      ROUND(F, b, c, d, a, in[7] + K1, 19);
-+
-+      /* Round 2 */
-+      ROUND(G, a, b, c, d, in[1] + K2,  3);
-+      ROUND(G, d, a, b, c, in[3] + K2,  5);
-+      ROUND(G, c, d, a, b, in[5] + K2,  9);
-+      ROUND(G, b, c, d, a, in[7] + K2, 13);
-+      ROUND(G, a, b, c, d, in[0] + K2,  3);
-+      ROUND(G, d, a, b, c, in[2] + K2,  5);
-+      ROUND(G, c, d, a, b, in[4] + K2,  9);
-+      ROUND(G, b, c, d, a, in[6] + K2, 13);
-+
-+      /* Round 3 */
-+      ROUND(H, a, b, c, d, in[3] + K3,  3);
-+      ROUND(H, d, a, b, c, in[7] + K3,  9);
-+      ROUND(H, c, d, a, b, in[2] + K3, 11);
-+      ROUND(H, b, c, d, a, in[6] + K3, 15);
-+      ROUND(H, a, b, c, d, in[1] + K3,  3);
-+      ROUND(H, d, a, b, c, in[5] + K3,  9);
-+      ROUND(H, c, d, a, b, in[0] + K3, 11);
-+      ROUND(H, b, c, d, a, in[4] + K3, 15);
-+
-+      buf[0] += a;
-+      buf[1] += b;
-+      buf[2] += c;
-+      buf[3] += d;
-+}
-+
-+#undef ROUND
-+#undef F
-+#undef G
-+#undef H
-+#undef K1
-+#undef K2
-+#undef K3
-+
-+/* The old legacy hash */
-+static __u32 dx_hack_hash (const char *name, int len)
-+{
-+      __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
-+      while (len--) {
-+              __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
-+              
-+              if (hash & 0x80000000) hash -= 0x7fffffff;
-+              hash1 = hash0;
-+              hash0 = hash;
-+      }
-+      return (hash0 << 1);
-+}
-+
-+static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
-+{
-+      __u32   pad, val;
-+      int     i;
-+
-+      pad = (__u32)len | ((__u32)len << 8);
-+      pad |= pad << 16;
-+
-+      val = pad;
-+      if (len > num*4)
-+              len = num * 4;
-+      for (i=0; i < len; i++) {
-+              if ((i % 4) == 0)
-+                      val = pad;
-+              val = msg[i] + (val << 8);
-+              if ((i % 4) == 3) {
-+                      *buf++ = val;
-+                      val = pad;
-+                      num--;
-+              }
-+      }
-+      if (--num >= 0)
-+              *buf++ = val;
-+      while (--num >= 0)
-+              *buf++ = pad;
-+}
-+
-+/*
-+ * Returns the hash of a filename.  If len is 0 and name is NULL, then
-+ * this function can be used to test whether or not a hash version is
-+ * supported.
-+ * 
-+ * The seed is an 4 longword (32 bits) "secret" which can be used to
-+ * uniquify a hash.  If the seed is all zero's, then some default seed
-+ * may be used.
-+ * 
-+ * A particular hash version specifies whether or not the seed is
-+ * represented, and whether or not the returned hash is 32 bits or 64
-+ * bits.  32 bit hashes will return 0 for the minor hash.
-+ */
-+int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
-+{
-+      __u32   hash;
-+      __u32   minor_hash = 0;
-+      const char      *p;
-+      int             i;
-+      __u32           in[8], buf[4];
-+
-+      /* Initialize the default seed for the hash checksum functions */
-+      buf[0] = 0x67452301;
-+      buf[1] = 0xefcdab89;
-+      buf[2] = 0x98badcfe;
-+      buf[3] = 0x10325476;
-+
-+      /* Check to see if the seed is all zero's */
-+      if (hinfo->seed) {
-+              for (i=0; i < 4; i++) {
-+                      if (hinfo->seed[i])
-+                              break;
-+              }
-+              if (i < 4)
-+                      memcpy(buf, hinfo->seed, sizeof(buf));
-+      }
-+              
-+      switch (hinfo->hash_version) {
-+      case DX_HASH_LEGACY:
-+              hash = dx_hack_hash(name, len);
-+              break;
-+      case DX_HASH_HALF_MD4:
-+              p = name;
-+              while (len > 0) {
-+                      str2hashbuf(p, len, in, 8);
-+                      halfMD4Transform(buf, in);
-+                      len -= 32;
-+                      p += 32;
-+              }
-+              minor_hash = buf[2];
-+              hash = buf[1];
-+              break;
-+      case DX_HASH_TEA:
-+              p = name;
-+              while (len > 0) {
-+                      str2hashbuf(p, len, in, 4);
-+                      TEA_transform(buf, in);
-+                      len -= 16;
-+                      p += 16;
-+              }
-+              hash = buf[0];
-+              minor_hash = buf[1];
-+              break;
-+      default:
-+              hinfo->hash = 0;
-+              return -1;
-+      }
-+      hinfo->hash = hash & ~1;
-+      hinfo->minor_hash = minor_hash;
-+      return 0;
-+}
---- linux-2.4.20/fs/ext3/namei.c~ext-2.4-patch-1       Sat Apr  5 03:56:31 2003
-+++ linux-2.4.20-braam/fs/ext3/namei.c Sat Apr  5 03:56:31 2003
-@@ -16,6 +16,12 @@
-  *        David S. Miller (davem@caip.rutgers.edu), 1995
-  *  Directory entry file type support and forward compatibility hooks
-  *    for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
-+ *  Hash Tree Directory indexing (c)
-+ *    Daniel Phillips, 2001
-+ *  Hash Tree Directory indexing porting
-+ *    Christopher Li, 2002
-+ *  Hash Tree Directory indexing cleanup
-+ *    Theodore Ts'o, 2002
-  */
- #include <linux/fs.h>
-@@ -38,6 +44,630 @@
- #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
- #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
-+static struct buffer_head *ext3_append(handle_t *handle,
-+                                      struct inode *inode,
-+                                      u32 *block, int *err)
-+{
-+      struct buffer_head *bh;
-+
-+      *block = inode->i_size >> inode->i_sb->s_blocksize_bits;
-+
-+      if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
-+              inode->i_size += inode->i_sb->s_blocksize;
-+              EXT3_I(inode)->i_disksize = inode->i_size;
-+              ext3_journal_get_write_access(handle,bh);
-+      }
-+      return bh;
-+}
-+
-+#ifndef assert
-+#define assert(test) J_ASSERT(test)
-+#endif
-+
-+#ifndef swap
-+#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
-+#endif
-+
-+typedef struct { u32 v; } le_u32;
-+typedef struct { u16 v; } le_u16;
-+
-+#ifdef DX_DEBUG
-+#define dxtrace(command) command
-+#else
-+#define dxtrace(command) 
-+#endif
-+
-+struct fake_dirent
-+{
-+      /*le*/u32 inode;
-+      /*le*/u16 rec_len;
-+      u8 name_len;
-+      u8 file_type;
-+};
-+
-+struct dx_countlimit
-+{
-+      le_u16 limit;
-+      le_u16 count;
-+};
-+
-+struct dx_entry
-+{
-+      le_u32 hash;
-+      le_u32 block;
-+};
-+
-+/*
-+ * dx_root_info is laid out so that if it should somehow get overlaid by a
-+ * dirent the two low bits of the hash version will be zero.  Therefore, the
-+ * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
-+ */
-+
-+struct dx_root
-+{
-+      struct fake_dirent dot;
-+      char dot_name[4];
-+      struct fake_dirent dotdot;
-+      char dotdot_name[4];
-+      struct dx_root_info
-+      {
-+              le_u32 reserved_zero;
-+              u8 hash_version;
-+              u8 info_length; /* 8 */
-+              u8 indirect_levels;
-+              u8 unused_flags;
-+      }
-+      info;
-+      struct dx_entry entries[0];
-+};
-+
-+struct dx_node
-+{
-+      struct fake_dirent fake;
-+      struct dx_entry entries[0];
-+};
-+
-+
-+struct dx_frame
-+{
-+      struct buffer_head *bh;
-+      struct dx_entry *entries;
-+      struct dx_entry *at;
-+};
-+
-+struct dx_map_entry
-+{
-+      u32 hash;
-+      u32 offs;
-+};
-+
-+#ifdef CONFIG_EXT3_INDEX
-+static inline unsigned dx_get_block (struct dx_entry *entry);
-+static void dx_set_block (struct dx_entry *entry, unsigned value);
-+static inline unsigned dx_get_hash (struct dx_entry *entry);
-+static void dx_set_hash (struct dx_entry *entry, unsigned value);
-+static unsigned dx_get_count (struct dx_entry *entries);
-+static unsigned dx_get_limit (struct dx_entry *entries);
-+static void dx_set_count (struct dx_entry *entries, unsigned value);
-+static void dx_set_limit (struct dx_entry *entries, unsigned value);
-+static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
-+static unsigned dx_node_limit (struct inode *dir);
-+static struct dx_frame *dx_probe(struct dentry *dentry,
-+                               struct inode *dir,
-+                               struct dx_hash_info *hinfo,
-+                               struct dx_frame *frame,
-+                               int *err);
-+static void dx_release (struct dx_frame *frames);
-+static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
-+                      struct dx_hash_info *hinfo, struct dx_map_entry map[]);
-+static void dx_sort_map(struct dx_map_entry *map, unsigned count);
-+static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to,
-+              struct dx_map_entry *offsets, int count);
-+static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size);
-+static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
-+static int ext3_htree_next_block(struct inode *dir, __u32 hash,
-+                               struct dx_frame *frame,
-+                               struct dx_frame *frames, int *err,
-+                               __u32 *start_hash);
-+static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
-+                     struct ext3_dir_entry_2 **res_dir, int *err);
-+static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
-+                           struct inode *inode);
-+
-+/*
-+ * Future: use high four bits of block for coalesce-on-delete flags
-+ * Mask them off for now.
-+ */
-+
-+static inline unsigned dx_get_block (struct dx_entry *entry)
-+{
-+      return le32_to_cpu(entry->block.v) & 0x00ffffff;
-+}
-+
-+static inline void dx_set_block (struct dx_entry *entry, unsigned value)
-+{
-+      entry->block.v = cpu_to_le32(value);
-+}
-+
-+static inline unsigned dx_get_hash (struct dx_entry *entry)
-+{
-+      return le32_to_cpu(entry->hash.v);
-+}
-+
-+static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
-+{
-+      entry->hash.v = cpu_to_le32(value);
-+}
-+
-+static inline unsigned dx_get_count (struct dx_entry *entries)
-+{
-+      return le16_to_cpu(((struct dx_countlimit *) entries)->count.v);
-+}
-+
-+static inline unsigned dx_get_limit (struct dx_entry *entries)
-+{
-+      return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v);
-+}
-+
-+static inline void dx_set_count (struct dx_entry *entries, unsigned value)
-+{
-+      ((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value);
-+}
-+
-+static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
-+{
-+      ((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value);
-+}
-+
-+static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
-+{
-+      unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) -
-+              EXT3_DIR_REC_LEN(2) - infosize;
-+      return 0? 20: entry_space / sizeof(struct dx_entry);
-+}
-+
-+static inline unsigned dx_node_limit (struct inode *dir)
-+{
-+      unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0);
-+      return 0? 22: entry_space / sizeof(struct dx_entry);
-+}
-+
-+/*
-+ * Debug
-+ */
-+#ifdef DX_DEBUG
-+struct stats
-+{ 
-+      unsigned names;
-+      unsigned space;
-+      unsigned bcount;
-+};
-+
-+static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_entry_2 *de,
-+                               int size, int show_names)
-+{
-+      unsigned names = 0, space = 0;
-+      char *base = (char *) de;
-+      struct dx_hash_info h = *hinfo;
-+      
-+      printk("names: ");
-+      while ((char *) de < base + size)
-+      {
-+              if (de->inode)
-+              {
-+                      if (show_names)
-+                      {
-+                              int len = de->name_len;
-+                              char *name = de->name;
-+                              while (len--) printk("%c", *name++);
-+                              ext3fs_dirhash(de->name, de->name_len, &h);
-+                              printk(":%x.%u ", h.hash,
-+                                     ((char *) de - base));
-+                      }
-+                      space += EXT3_DIR_REC_LEN(de->name_len);
-+                      names++;
-+              }
-+              de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-+      }
-+      printk("(%i)\n", names);
-+      return (struct stats) { names, space, 1 };
-+}
-+
-+struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
-+                           struct dx_entry *entries, int levels)
-+{
-+      unsigned blocksize = dir->i_sb->s_blocksize;
-+      unsigned count = dx_get_count (entries), names = 0, space = 0, i;
-+      unsigned bcount = 0;
-+      struct buffer_head *bh;
-+      int err;
-+      printk("%i indexed blocks...\n", count);
-+      for (i = 0; i < count; i++, entries++)
-+      {
-+              u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0;
-+              u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
-+              struct stats stats;
-+              printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
-+              if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue;
-+              stats = levels?
-+                 dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
-+                 dx_show_leaf(hinfo, (struct ext3_dir_entry_2 *) bh->b_data, blocksize, 0);
-+              names += stats.names;
-+              space += stats.space;
-+              bcount += stats.bcount;
-+              brelse (bh);
-+      }
-+      if (bcount)
-+              printk("%snames %u, fullness %u (%u%%)\n", levels?"":"   ",
-+                      names, space/bcount,(space/bcount)*100/blocksize);
-+      return (struct stats) { names, space, bcount};
-+}
-+#endif /* DX_DEBUG */
-+
-+/*
-+ * Probe for a directory leaf block to search.
-+ *
-+ * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
-+ * error in the directory index, and the caller should fall back to
-+ * searching the directory normally.  The callers of dx_probe **MUST**
-+ * check for this error code, and make sure it never gets reflected
-+ * back to userspace.
-+ */
-+static struct dx_frame *
-+dx_probe(struct dentry *dentry, struct inode *dir,
-+       struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
-+{
-+      unsigned count, indirect;
-+      struct dx_entry *at, *entries, *p, *q, *m;
-+      struct dx_root *root;
-+      struct buffer_head *bh;
-+      struct dx_frame *frame = frame_in;
-+      u32 hash;
-+
-+      frame->bh = NULL;
-+      if (dentry)
-+              dir = dentry->d_parent->d_inode;
-+      if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
-+              goto fail;
-+      root = (struct dx_root *) bh->b_data;
-+      if (root->info.hash_version != DX_HASH_TEA &&
-+          root->info.hash_version != DX_HASH_HALF_MD4 &&
-+          root->info.hash_version != DX_HASH_LEGACY) {
-+              ext3_warning(dir->i_sb, __FUNCTION__,
-+                           "Unrecognised inode hash code %d",
-+                           root->info.hash_version);
-+              brelse(bh);
-+              *err = ERR_BAD_DX_DIR;
-+              goto fail;
-+      }
-+      hinfo->hash_version = root->info.hash_version;
-+      hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed;
-+      if (dentry)
-+              ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
-+      hash = hinfo->hash;
-+
-+      if (root->info.unused_flags & 1) {
-+              ext3_warning(dir->i_sb, __FUNCTION__,
-+                           "Unimplemented inode hash flags: %#06x",
-+                           root->info.unused_flags);
-+              brelse(bh);
-+              *err = ERR_BAD_DX_DIR;
-+              goto fail;
-+      }
-+
-+      if ((indirect = root->info.indirect_levels) > 1) {
-+              ext3_warning(dir->i_sb, __FUNCTION__,
-+                           "Unimplemented inode hash depth: %#06x",
-+                           root->info.indirect_levels);
-+              brelse(bh);
-+              *err = ERR_BAD_DX_DIR;
-+              goto fail;
-+      }
-+
-+      entries = (struct dx_entry *) (((char *)&root->info) +
-+                                     root->info.info_length);
-+      assert(dx_get_limit(entries) == dx_root_limit(dir,
-+                                                    root->info.info_length));
-+      dxtrace (printk("Look up %x", hash));
-+      while (1)
-+      {
-+              count = dx_get_count(entries);
-+              assert (count && count <= dx_get_limit(entries));
-+              p = entries + 1;
-+              q = entries + count - 1;
-+              while (p <= q)
-+              {
-+                      m = p + (q - p)/2;
-+                      dxtrace(printk("."));
-+                      if (dx_get_hash(m) > hash)
-+                              q = m - 1;
-+                      else
-+                              p = m + 1;
-+              }
-+
-+              if (0) // linear search cross check
-+              {
-+                      unsigned n = count - 1;
-+                      at = entries;
-+                      while (n--)
-+                      {
-+                              dxtrace(printk(","));
-+                              if (dx_get_hash(++at) > hash)
-+                              {
-+                                      at--;
-+                                      break;
-+                              }
-+                      }
-+                      assert (at == p - 1);
-+              }
-+
-+              at = p - 1;
-+              dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
-+              frame->bh = bh;
-+              frame->entries = entries;
-+              frame->at = at;
-+              if (!indirect--) return frame;
-+              if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
-+                      goto fail2;
-+              at = entries = ((struct dx_node *) bh->b_data)->entries;
-+              assert (dx_get_limit(entries) == dx_node_limit (dir));
-+              frame++;
-+      }
-+fail2:
-+      while (frame >= frame_in) {
-+              brelse(frame->bh);
-+              frame--;
-+      }
-+fail:
-+      return NULL;
-+}
-+
-+static void dx_release (struct dx_frame *frames)
-+{
-+      if (frames[0].bh == NULL)
-+              return;
-+
-+      if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
-+              brelse(frames[1].bh);
-+      brelse(frames[0].bh);
-+}
-+
-+/*
-+ * This function increments the frame pointer to search the next leaf
-+ * block, and reads in the necessary intervening nodes if the search
-+ * should be necessary.  Whether or not the search is necessary is
-+ * controlled by the hash parameter.  If the hash value is even, then
-+ * the search is only continued if the next block starts with that
-+ * hash value.  This is used if we are searching for a specific file.
-+ *
-+ * If the hash value is HASH_NB_ALWAYS, then always go to the next block.
-+ *
-+ * This function returns 1 if the caller should continue to search,
-+ * or 0 if it should not.  If there is an error reading one of the
-+ * index blocks, it will return -1.
-+ *
-+ * If start_hash is non-null, it will be filled in with the starting
-+ * hash of the next page.
-+ */
-+static int ext3_htree_next_block(struct inode *dir, __u32 hash,
-+                               struct dx_frame *frame,
-+                               struct dx_frame *frames, int *err,
-+                               __u32 *start_hash)
-+{
-+      struct dx_frame *p;
-+      struct buffer_head *bh;
-+      int num_frames = 0;
-+      __u32 bhash;
-+
-+      *err = ENOENT;
-+      p = frame;
-+      /*
-+       * Find the next leaf page by incrementing the frame pointer.
-+       * If we run out of entries in the interior node, loop around and
-+       * increment pointer in the parent node.  When we break out of
-+       * this loop, num_frames indicates the number of interior
-+       * nodes need to be read.
-+       */
-+      while (1) {
-+              if (++(p->at) < p->entries + dx_get_count(p->entries))
-+                      break;
-+              if (p == frames)
-+                      return 0;
-+              num_frames++;
-+              p--;
-+      }
-+
-+      /*
-+       * If the hash is 1, then continue only if the next page has a
-+       * continuation hash of any value.  This is used for readdir
-+       * handling.  Otherwise, check to see if the hash matches the
-+       * desired contiuation hash.  If it doesn't, return since
-+       * there's no point to read in the successive index pages.
-+       */
-+      bhash = dx_get_hash(p->at);
-+      if (start_hash)
-+              *start_hash = bhash;
-+      if ((hash & 1) == 0) {
-+              if ((bhash & ~1) != hash)
-+                      return 0;
-+      }
-+      /*
-+       * If the hash is HASH_NB_ALWAYS, we always go to the next
-+       * block so no check is necessary
-+       */
-+      while (num_frames--) {
-+              if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
-+                                    0, err)))
-+                      return -1; /* Failure */
-+              p++;
-+              brelse (p->bh);
-+              p->bh = bh;
-+              p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
-+      }
-+      return 1;
-+}
-+
-+
-+/*
-+ * p is at least 6 bytes before the end of page
-+ */
-+static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p)
-+{
-+      return (struct ext3_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len));
-+}
-+
-+/*
-+ * This function fills a red-black tree with information from a
-+ * directory.  We start scanning the directory in hash order, starting
-+ * at start_hash and start_minor_hash.
-+ *
-+ * This function returns the number of entries inserted into the tree,
-+ * or a negative error code.
-+ */
-+int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
-+                       __u32 start_minor_hash, __u32 *next_hash)
-+{
-+      struct dx_hash_info hinfo;
-+      struct buffer_head *bh;
-+      struct ext3_dir_entry_2 *de, *top;
-+      static struct dx_frame frames[2], *frame;
-+      struct inode *dir;
-+      int block, err;
-+      int count = 0;
-+      int ret;
-+      __u32 hashval;
-+      
-+      dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
-+                     start_minor_hash));
-+      dir = dir_file->f_dentry->d_inode;
-+      hinfo.hash = start_hash;
-+      hinfo.minor_hash = 0;
-+      frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
-+      if (!frame)
-+              return err;
-+
-+      while (1) {
-+              block = dx_get_block(frame->at);
-+              dxtrace(printk("Reading block %d\n", block));
-+              if (!(bh = ext3_bread (NULL, dir, block, 0, &err)))
-+                      goto errout;
-+      
-+              de = (struct ext3_dir_entry_2 *) bh->b_data;
-+              top = (struct ext3_dir_entry_2 *) ((char *) de + dir->i_sb->s_blocksize -
-+                                     EXT3_DIR_REC_LEN(0));
-+              for (; de < top; de = ext3_next_entry(de)) {
-+                      ext3fs_dirhash(de->name, de->name_len, &hinfo);
-+                      if ((hinfo.hash < start_hash) ||
-+                          ((hinfo.hash == start_hash) &&
-+                           (hinfo.minor_hash < start_minor_hash)))
-+                              continue;
-+                      ext3_htree_store_dirent(dir_file, hinfo.hash,
-+                                              hinfo.minor_hash, de);
-+                      count++;
-+              }
-+              brelse (bh);
-+              hashval = ~1;
-+              ret = ext3_htree_next_block(dir, HASH_NB_ALWAYS, 
-+                                          frame, frames, &err, &hashval);
-+              if (next_hash)
-+                      *next_hash = hashval;
-+              if (ret == -1)
-+                      goto errout;
-+              /*
-+               * Stop if:  (a) there are no more entries, or
-+               * (b) we have inserted at least one entry and the
-+               * next hash value is not a continuation
-+               */
-+              if ((ret == 0) ||
-+                  (count && ((hashval & 1) == 0)))
-+                      break;
-+      }
-+      dx_release(frames);
-+      dxtrace(printk("Fill tree: returned %d entries\n", count));
-+      return count;
-+errout:
-+      dx_release(frames);
-+      return (err);
-+}
-+
-+
-+/*
-+ * Directory block splitting, compacting
-+ */
-+
-+static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
-+                      struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
-+{
-+      int count = 0;
-+      char *base = (char *) de;
-+      struct dx_hash_info h = *hinfo;
-+      
-+      while ((char *) de < base + size)
-+      {
-+              if (de->name_len && de->inode) {
-+                      ext3fs_dirhash(de->name, de->name_len, &h);
-+                      map_tail--;
-+                      map_tail->hash = h.hash;
-+                      map_tail->offs = (u32) ((char *) de - base);
-+                      count++;
-+              }
-+              /* XXX: do we need to check rec_len == 0 case? -Chris */
-+              de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-+      }
-+      return count;
-+}
-+
-+static void dx_sort_map (struct dx_map_entry *map, unsigned count)
-+{
-+        struct dx_map_entry *p, *q, *top = map + count - 1;
-+        int more;
-+        /* Combsort until bubble sort doesn't suck */
-+        while (count > 2)
-+      {
-+                count = count*10/13;
-+                if (count - 9 < 2) /* 9, 10 -> 11 */
-+                        count = 11;
-+                for (p = top, q = p - count; q >= map; p--, q--)
-+                        if (p->hash < q->hash)
-+                                swap(*p, *q);
-+        }
-+        /* Garden variety bubble sort */
-+        do {
-+                more = 0;
-+                q = top;
-+                while (q-- > map)
-+              {
-+                        if (q[1].hash >= q[0].hash)
-+                              continue;
-+                        swap(*(q+1), *q);
-+                        more = 1;
-+              }
-+      } while(more);
-+}
-+
-+static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
-+{
-+      struct dx_entry *entries = frame->entries;
-+      struct dx_entry *old = frame->at, *new = old + 1;
-+      int count = dx_get_count(entries);
-+
-+      assert(count < dx_get_limit(entries));
-+      assert(old < entries + count);
-+      memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
-+      dx_set_hash(new, hash);
-+      dx_set_block(new, block);
-+      dx_set_count(entries, count + 1);
-+}
-+#endif
-+
-+
-+static void ext3_update_dx_flag(struct inode *inode)
-+{
-+      if (!EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
-+                                   EXT3_FEATURE_COMPAT_DIR_INDEX))
-+              EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL;
-+}
-+
- /*
-  * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure.
-  *
-@@ -94,6 +724,7 @@ static int inline search_dirblock(struct
-       return 0;
- }
-+
- /*
-  *    ext3_find_entry()
-  *
-@@ -105,6 +736,8 @@ static int inline search_dirblock(struct
-  * The returned buffer_head has ->b_count elevated.  The caller is expected
-  * to brelse() it when appropriate.
-  */
-+
-+      
- static struct buffer_head * ext3_find_entry (struct dentry *dentry,
-                                       struct ext3_dir_entry_2 ** res_dir)
- {
-@@ -119,12 +752,32 @@ static struct buffer_head * ext3_find_en
-       int num = 0;
-       int nblocks, i, err;
-       struct inode *dir = dentry->d_parent->d_inode;
-+      int namelen;
-+      const u8 *name;
-+      unsigned blocksize;
-       *res_dir = NULL;
-       sb = dir->i_sb;
--
-+      blocksize = sb->s_blocksize;
-+      namelen = dentry->d_name.len;
-+      name = dentry->d_name.name;
-+      if (namelen > EXT3_NAME_LEN)
-+              return NULL;
-+#ifdef CONFIG_EXT3_INDEX
-+      if (is_dx(dir)) {
-+              bh = ext3_dx_find_entry(dentry, res_dir, &err);
-+              /*
-+               * On success, or if the error was file not found,
-+               * return.  Otherwise, fall back to doing a search the
-+               * old fashioned way.
-+               */
-+              if (bh || (err != ERR_BAD_DX_DIR))
-+                      return bh;
-+              dxtrace(printk("ext3_find_entry: dx failed, falling back\n"));
-+      }
-+#endif
-       nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
--      start = dir->u.ext3_i.i_dir_start_lookup;
-+      start = EXT3_I(dir)->i_dir_start_lookup;
-       if (start >= nblocks)
-               start = 0;
-       block = start;
-@@ -165,7 +818,7 @@ restart:
-               i = search_dirblock(bh, dir, dentry,
-                           block << EXT3_BLOCK_SIZE_BITS(sb), res_dir);
-               if (i == 1) {
--                      dir->u.ext3_i.i_dir_start_lookup = block;
-+                      EXT3_I(dir)->i_dir_start_lookup = block;
-                       ret = bh;
-                       goto cleanup_and_exit;
-               } else {
-@@ -196,6 +849,66 @@ cleanup_and_exit:
-       return ret;
- }
-+#ifdef CONFIG_EXT3_INDEX
-+static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
-+                     struct ext3_dir_entry_2 **res_dir, int *err)
-+{
-+      struct super_block * sb;
-+      struct dx_hash_info     hinfo;
-+      u32 hash;
-+      struct dx_frame frames[2], *frame;
-+      struct ext3_dir_entry_2 *de, *top;
-+      struct buffer_head *bh;
-+      unsigned long block;
-+      int retval;
-+      int namelen = dentry->d_name.len;
-+      const u8 *name = dentry->d_name.name;
-+      struct inode *dir = dentry->d_parent->d_inode;
-+      
-+      sb = dir->i_sb;
-+      if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
-+              return NULL;
-+      hash = hinfo.hash;
-+      do {
-+              block = dx_get_block(frame->at);
-+              if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
-+                      goto errout;
-+              de = (struct ext3_dir_entry_2 *) bh->b_data;
-+              top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize -
-+                                     EXT3_DIR_REC_LEN(0));
-+              for (; de < top; de = ext3_next_entry(de))
-+              if (ext3_match (namelen, name, de)) {
-+                      if (!ext3_check_dir_entry("ext3_find_entry",
-+                                                dir, de, bh,
-+                                (block<<EXT3_BLOCK_SIZE_BITS(sb))
-+                                        +((char *)de - bh->b_data))) {
-+                              brelse (bh);
-+                              goto errout;
-+                      }
-+                      *res_dir = de;
-+                      dx_release (frames);
-+                      return bh;
-+              }
-+              brelse (bh);
-+              /* Check to see if we should continue to search */
-+              retval = ext3_htree_next_block(dir, hash, frame,
-+                                             frames, err, 0);
-+              if (retval == -1) {
-+                      ext3_warning(sb, __FUNCTION__,
-+                           "error reading index page in directory #%lu",
-+                           dir->i_ino);
-+                      goto errout;
-+              }
-+      } while (retval == 1);
-+      
-+      *err = -ENOENT;
-+errout:
-+      dxtrace(printk("%s not found\n", name));
-+      dx_release (frames);
-+      return NULL;
-+}
-+#endif
-+
- static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
- {
-       struct inode * inode;
-@@ -212,8 +925,9 @@ static struct dentry *ext3_lookup(struct
-               brelse (bh);
-               inode = iget(dir->i_sb, ino);
--              if (!inode)
-+              if (!inode) {
-                       return ERR_PTR(-EACCES);
-+              }
-       }
-       d_add(dentry, inode);
-       return NULL;
-@@ -237,6 +951,300 @@ static inline void ext3_set_de_type(stru
-               de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
- }
-+#ifdef CONFIG_EXT3_INDEX
-+static struct ext3_dir_entry_2 *
-+dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
-+{
-+      unsigned rec_len = 0;
-+
-+      while (count--) {
-+              struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs);
-+              rec_len = EXT3_DIR_REC_LEN(de->name_len);
-+              memcpy (to, de, rec_len);
-+              ((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
-+              de->inode = 0;
-+              map++;
-+              to += rec_len;
-+      }
-+      return (struct ext3_dir_entry_2 *) (to - rec_len);
-+}
-+
-+static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
-+{
-+      struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base;
-+      unsigned rec_len = 0;
-+
-+      prev = to = de;
-+      while ((char*)de < base + size) {
-+              next = (struct ext3_dir_entry_2 *) ((char *) de +
-+                                                  le16_to_cpu(de->rec_len));
-+              if (de->inode && de->name_len) {
-+                      rec_len = EXT3_DIR_REC_LEN(de->name_len);
-+                      if (de > to)
-+                              memmove(to, de, rec_len);
-+                      to->rec_len = rec_len;
-+                      prev = to;
-+                      to = (struct ext3_dir_entry_2 *) (((char *) to) + rec_len);
-+              }
-+              de = next;
-+      }
-+      return prev;
-+}
-+
-+static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
-+                      struct buffer_head **bh,struct dx_frame *frame,
-+                      struct dx_hash_info *hinfo, int *error)
-+{
-+      unsigned blocksize = dir->i_sb->s_blocksize;
-+      unsigned count, continued;
-+      struct buffer_head *bh2;
-+      u32 newblock;
-+      u32 hash2;
-+      struct dx_map_entry *map;
-+      char *data1 = (*bh)->b_data, *data2;
-+      unsigned split;
-+      struct ext3_dir_entry_2 *de = NULL, *de2;
-+      int     err;
-+
-+      bh2 = ext3_append (handle, dir, &newblock, error);
-+      if (!(bh2)) {
-+              brelse(*bh);
-+              *bh = NULL;
-+              goto errout;
-+      }
-+
-+      BUFFER_TRACE(*bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, *bh);
-+      if (err) {
-+      journal_error:
-+              brelse(*bh);
-+              brelse(bh2);
-+              *bh = NULL;
-+              ext3_std_error(dir->i_sb, err);
-+              goto errout;
-+      }
-+      BUFFER_TRACE(frame->bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, frame->bh);
-+      if (err)
-+              goto journal_error;
-+
-+      data2 = bh2->b_data;
-+
-+      /* create map in the end of data2 block */
-+      map = (struct dx_map_entry *) (data2 + blocksize);
-+      count = dx_make_map ((struct ext3_dir_entry_2 *) data1,
-+                           blocksize, hinfo, map);
-+      map -= count;
-+      split = count/2; // need to adjust to actual middle
-+      dx_sort_map (map, count);
-+      hash2 = map[split].hash;
-+      continued = hash2 == map[split - 1].hash;
-+      dxtrace(printk("Split block %i at %x, %i/%i\n",
-+              dx_get_block(frame->at), hash2, split, count-split));
-+
-+      /* Fancy dance to stay within two buffers */
-+      de2 = dx_move_dirents(data1, data2, map + split, count - split);
-+      de = dx_pack_dirents(data1,blocksize);
-+      de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
-+      de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
-+      dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1));
-+      dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1));
-+
-+      /* Which block gets the new entry? */
-+      if (hinfo->hash >= hash2)
-+      {
-+              swap(*bh, bh2);
-+              de = de2;
-+      }
-+      dx_insert_block (frame, hash2 + continued, newblock);
-+      err = ext3_journal_dirty_metadata (handle, bh2);
-+      if (err)
-+              goto journal_error;
-+      err = ext3_journal_dirty_metadata (handle, frame->bh);
-+      if (err)
-+              goto journal_error;
-+      brelse (bh2);
-+      dxtrace(dx_show_index ("frame", frame->entries));
-+errout:
-+      return de;
-+}
-+#endif
-+
-+
-+/*
-+ * Add a new entry into a directory (leaf) block.  If de is non-NULL,
-+ * it points to a directory entry which is guaranteed to be large
-+ * enough for new directory entry.  If de is NULL, then
-+ * add_dirent_to_buf will attempt search the directory block for
-+ * space.  It will return -ENOSPC if no space is available, and -EIO
-+ * and -EEXIST if directory entry already exists.
-+ * 
-+ * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
-+ * all other cases bh is released.
-+ */
-+static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
-+                           struct inode *inode, struct ext3_dir_entry_2 *de,
-+                           struct buffer_head * bh)
-+{
-+      struct inode    *dir = dentry->d_parent->d_inode;
-+      const char      *name = dentry->d_name.name;
-+      int             namelen = dentry->d_name.len;
-+      unsigned long   offset = 0;
-+      unsigned short  reclen;
-+      int             nlen, rlen, err;
-+      char            *top;
-+      
-+      reclen = EXT3_DIR_REC_LEN(namelen);
-+      if (!de) {
-+              de = (struct ext3_dir_entry_2 *)bh->b_data;
-+              top = bh->b_data + dir->i_sb->s_blocksize - reclen;
-+              while ((char *) de <= top) {
-+                      if (!ext3_check_dir_entry("ext3_add_entry", dir, de,
-+                                                bh, offset)) {
-+                              brelse (bh);
-+                              return -EIO;
-+                      }
-+                      if (ext3_match (namelen, name, de)) {
-+                              brelse (bh);
-+                              return -EEXIST;
-+                      }
-+                      nlen = EXT3_DIR_REC_LEN(de->name_len);
-+                      rlen = le16_to_cpu(de->rec_len);
-+                      if ((de->inode? rlen - nlen: rlen) >= reclen)
-+                              break;
-+                      de = (struct ext3_dir_entry_2 *)((char *)de + rlen);
-+                      offset += rlen;
-+              }
-+              if ((char *) de > top)
-+                      return -ENOSPC;
-+      }
-+      BUFFER_TRACE(bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, bh);
-+      if (err) {
-+              ext3_std_error(dir->i_sb, err);
-+              brelse(bh);
-+              return err;
-+      }
-+      
-+      /* By now the buffer is marked for journaling */
-+      nlen = EXT3_DIR_REC_LEN(de->name_len);
-+      rlen = le16_to_cpu(de->rec_len);
-+      if (de->inode) {
-+              struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen);
-+              de1->rec_len = cpu_to_le16(rlen - nlen);
-+              de->rec_len = cpu_to_le16(nlen);
-+              de = de1;
-+      }
-+      de->file_type = EXT3_FT_UNKNOWN;
-+      if (inode) {
-+              de->inode = cpu_to_le32(inode->i_ino);
-+              ext3_set_de_type(dir->i_sb, de, inode->i_mode);
-+      } else
-+              de->inode = 0;
-+      de->name_len = namelen;
-+      memcpy (de->name, name, namelen);
-+      /*
-+       * XXX shouldn't update any times until successful
-+       * completion of syscall, but too many callers depend
-+       * on this.
-+       *
-+       * XXX similarly, too many callers depend on
-+       * ext3_new_inode() setting the times, but error
-+       * recovery deletes the inode, so the worst that can
-+       * happen is that the times are slightly out of date
-+       * and/or different from the directory change time.
-+       */
-+      dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-+      ext3_update_dx_flag(dir);
-+      dir->i_version = ++event;
-+      ext3_mark_inode_dirty(handle, dir);
-+      BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
-+      err = ext3_journal_dirty_metadata(handle, bh);
-+      if (err)
-+              ext3_std_error(dir->i_sb, err);
-+      brelse(bh);
-+      return 0;
-+}
-+
-+#ifdef CONFIG_EXT3_INDEX
-+/*
-+ * This converts a one block unindexed directory to a 3 block indexed
-+ * directory, and adds the dentry to the indexed directory.
-+ */
-+static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
-+                          struct inode *inode, struct buffer_head *bh)
-+{
-+      struct inode    *dir = dentry->d_parent->d_inode;
-+      const char      *name = dentry->d_name.name;
-+      int             namelen = dentry->d_name.len;
-+      struct buffer_head *bh2;
-+      struct dx_root  *root;
-+      struct dx_frame frames[2], *frame;
-+      struct dx_entry *entries;
-+      struct ext3_dir_entry_2 *de, *de2;
-+      char            *data1, *top;
-+      unsigned        len;
-+      int             retval;
-+      unsigned        blocksize;
-+      struct dx_hash_info hinfo;
-+      u32             block;
-+              
-+      blocksize =  dir->i_sb->s_blocksize;
-+      dxtrace(printk("Creating index\n"));
-+      retval = ext3_journal_get_write_access(handle, bh);
-+      if (retval) {
-+              ext3_std_error(dir->i_sb, retval);
-+              brelse(bh);
-+              return retval;
-+      }
-+      root = (struct dx_root *) bh->b_data;
-+              
-+      EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
-+      bh2 = ext3_append (handle, dir, &block, &retval);
-+      if (!(bh2)) {
-+              brelse(bh);
-+              return retval;
-+      }
-+      data1 = bh2->b_data;
-+
-+      /* The 0th block becomes the root, move the dirents out */
-+      de = (struct ext3_dir_entry_2 *) &root->info;
-+      len = ((char *) root) + blocksize - (char *) de;
-+      memcpy (data1, de, len);
-+      de = (struct ext3_dir_entry_2 *) data1;
-+      top = data1 + len;
-+      while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top)
-+              de = de2;
-+      de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
-+      /* Initialize the root; the dot dirents already exist */
-+      de = (struct ext3_dir_entry_2 *) (&root->dotdot);
-+      de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2));
-+      memset (&root->info, 0, sizeof(root->info));
-+      root->info.info_length = sizeof(root->info);
-+      root->info.hash_version = dir->i_sb->u.ext3_sb.s_def_hash_version;
-+      entries = root->entries;
-+      dx_set_block (entries, 1);
-+      dx_set_count (entries, 1);
-+      dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
-+
-+      /* Initialize as for dx_probe */
-+      hinfo.hash_version = root->info.hash_version;
-+      hinfo.seed = dir->i_sb->u.ext3_sb.s_hash_seed;
-+      ext3fs_dirhash(name, namelen, &hinfo);
-+      frame = frames;
-+      frame->entries = entries;
-+      frame->at = entries;
-+      frame->bh = bh;
-+      bh = bh2;
-+      de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
-+      dx_release (frames);
-+      if (!(de))
-+              return retval;
-+
-+      return add_dirent_to_buf(handle, dentry, inode, de, bh);
-+}
-+#endif
-+
- /*
-  *    ext3_add_entry()
-  *
-@@ -247,127 +1255,198 @@ static inline void ext3_set_de_type(stru
-  * may not sleep between calling this and putting something into
-  * the entry, as someone else might have used it while you slept.
-  */
--
--/*
-- * AKPM: the journalling code here looks wrong on the error paths
-- */
- static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
-       struct inode *inode)
- {
-       struct inode *dir = dentry->d_parent->d_inode;
--      const char *name = dentry->d_name.name;
--      int namelen = dentry->d_name.len;
-       unsigned long offset;
--      unsigned short rec_len;
-       struct buffer_head * bh;
--      struct ext3_dir_entry_2 * de, * de1;
-+      struct ext3_dir_entry_2 *de;
-       struct super_block * sb;
-       int     retval;
-+#ifdef CONFIG_EXT3_INDEX
-+      int     dx_fallback=0;
-+#endif
-+      unsigned blocksize;
-+      unsigned nlen, rlen;
-+      u32 block, blocks;
-       sb = dir->i_sb;
--
--      if (!namelen)
-+      blocksize = sb->s_blocksize;
-+      if (!dentry->d_name.len)
-               return -EINVAL;
--      bh = ext3_bread (handle, dir, 0, 0, &retval);
-+#ifdef CONFIG_EXT3_INDEX
-+      if (is_dx(dir)) {
-+              retval = ext3_dx_add_entry(handle, dentry, inode);
-+              if (!retval || (retval != ERR_BAD_DX_DIR))
-+                      return retval;
-+              EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL;
-+              dx_fallback++;
-+              ext3_mark_inode_dirty(handle, dir);
-+      }
-+#endif
-+      blocks = dir->i_size >> sb->s_blocksize_bits;
-+      for (block = 0, offset = 0; block < blocks; block++) {
-+              bh = ext3_bread(handle, dir, block, 0, &retval);
-+              if(!bh)
-+                      return retval;
-+              retval = add_dirent_to_buf(handle, dentry, inode, 0, bh);
-+              if (retval != -ENOSPC)
-+                      return retval;
-+
-+#ifdef CONFIG_EXT3_INDEX
-+              if (blocks == 1 && !dx_fallback &&
-+                  EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
-+                      return make_indexed_dir(handle, dentry, inode, bh);
-+#endif
-+              brelse(bh);
-+      }
-+      bh = ext3_append(handle, dir, &block, &retval);
-       if (!bh)
-               return retval;
--      rec_len = EXT3_DIR_REC_LEN(namelen);
--      offset = 0;
-       de = (struct ext3_dir_entry_2 *) bh->b_data;
--      while (1) {
--              if ((char *)de >= sb->s_blocksize + bh->b_data) {
--                      brelse (bh);
--                      bh = NULL;
--                      bh = ext3_bread (handle, dir,
--                              offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval);
--                      if (!bh)
--                              return retval;
--                      if (dir->i_size <= offset) {
--                              if (dir->i_size == 0) {
--                                      brelse(bh);
--                                      return -ENOENT;
--                              }
-+      de->inode = 0;
-+      de->rec_len = cpu_to_le16(rlen = blocksize);
-+      nlen = 0;
-+      return add_dirent_to_buf(handle, dentry, inode, de, bh);
-+}
--                              ext3_debug ("creating next block\n");
-+#ifdef CONFIG_EXT3_INDEX
-+/*
-+ * Returns 0 for success, or a negative error value
-+ */
-+static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
-+                           struct inode *inode)
-+{
-+      struct dx_frame frames[2], *frame;
-+      struct dx_entry *entries, *at;
-+      struct dx_hash_info hinfo;
-+      struct buffer_head * bh;
-+      struct inode *dir = dentry->d_parent->d_inode;
-+      struct super_block * sb = dir->i_sb;
-+      struct ext3_dir_entry_2 *de;
-+      int err;
--                              BUFFER_TRACE(bh, "get_write_access");
--                              ext3_journal_get_write_access(handle, bh);
--                              de = (struct ext3_dir_entry_2 *) bh->b_data;
--                              de->inode = 0;
--                              de->rec_len = le16_to_cpu(sb->s_blocksize);
--                              dir->u.ext3_i.i_disksize =
--                                      dir->i_size = offset + sb->s_blocksize;
--                              dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
--                              ext3_mark_inode_dirty(handle, dir);
--                      } else {
-+      frame = dx_probe(dentry, 0, &hinfo, frames, &err);
-+      if (!frame)
-+              return err;
-+      entries = frame->entries;
-+      at = frame->at;
--                              ext3_debug ("skipping to next block\n");
-+      if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
-+              goto cleanup;
--                              de = (struct ext3_dir_entry_2 *) bh->b_data;
--                      }
--              }
--              if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh,
--                                         offset)) {
--                      brelse (bh);
--                      return -ENOENT;
--              }
--              if (ext3_match (namelen, name, de)) {
--                              brelse (bh);
--                              return -EEXIST;
-+      BUFFER_TRACE(bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, bh);
-+      if (err)
-+              goto journal_error;
-+
-+      err = add_dirent_to_buf(handle, dentry, inode, 0, bh);
-+      if (err != -ENOSPC) {
-+              bh = 0;
-+              goto cleanup;
-+      }
-+
-+      /* Block full, should compress but for now just split */
-+      dxtrace(printk("using %u of %u node entries\n",
-+                     dx_get_count(entries), dx_get_limit(entries)));
-+      /* Need to split index? */
-+      if (dx_get_count(entries) == dx_get_limit(entries)) {
-+              u32 newblock;
-+              unsigned icount = dx_get_count(entries);
-+              int levels = frame - frames;
-+              struct dx_entry *entries2;
-+              struct dx_node *node2;
-+              struct buffer_head *bh2;
-+
-+              if (levels && (dx_get_count(frames->entries) ==
-+                             dx_get_limit(frames->entries))) {
-+                      ext3_warning(sb, __FUNCTION__,
-+                                   "Directory index full!\n");
-+                      err = -ENOSPC;
-+                      goto cleanup;
-               }
--              if ((le32_to_cpu(de->inode) == 0 &&
--                              le16_to_cpu(de->rec_len) >= rec_len) ||
--                  (le16_to_cpu(de->rec_len) >=
--                              EXT3_DIR_REC_LEN(de->name_len) + rec_len)) {
--                      BUFFER_TRACE(bh, "get_write_access");
--                      ext3_journal_get_write_access(handle, bh);
--                      /* By now the buffer is marked for journaling */
--                      offset += le16_to_cpu(de->rec_len);
--                      if (le32_to_cpu(de->inode)) {
--                              de1 = (struct ext3_dir_entry_2 *) ((char *) de +
--                                      EXT3_DIR_REC_LEN(de->name_len));
--                              de1->rec_len =
--                                      cpu_to_le16(le16_to_cpu(de->rec_len) -
--                                      EXT3_DIR_REC_LEN(de->name_len));
--                              de->rec_len = cpu_to_le16(
--                                              EXT3_DIR_REC_LEN(de->name_len));
--                              de = de1;
-+              bh2 = ext3_append (handle, dir, &newblock, &err);
-+              if (!(bh2))
-+                      goto cleanup;
-+              node2 = (struct dx_node *)(bh2->b_data);
-+              entries2 = node2->entries;
-+              node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
-+              node2->fake.inode = 0;
-+              BUFFER_TRACE(frame->bh, "get_write_access");
-+              err = ext3_journal_get_write_access(handle, frame->bh);
-+              if (err)
-+                      goto journal_error;
-+              if (levels) {
-+                      unsigned icount1 = icount/2, icount2 = icount - icount1;
-+                      unsigned hash2 = dx_get_hash(entries + icount1);
-+                      dxtrace(printk("Split index %i/%i\n", icount1, icount2));
-+                              
-+                      BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
-+                      err = ext3_journal_get_write_access(handle,
-+                                                           frames[0].bh);
-+                      if (err)
-+                              goto journal_error;
-+                              
-+                      memcpy ((char *) entries2, (char *) (entries + icount1),
-+                              icount2 * sizeof(struct dx_entry));
-+                      dx_set_count (entries, icount1);
-+                      dx_set_count (entries2, icount2);
-+                      dx_set_limit (entries2, dx_node_limit(dir));
-+
-+                      /* Which index block gets the new entry? */
-+                      if (at - entries >= icount1) {
-+                              frame->at = at = at - entries - icount1 + entries2;
-+                              frame->entries = entries = entries2;
-+                              swap(frame->bh, bh2);
-                       }
--                      de->file_type = EXT3_FT_UNKNOWN;
--                      if (inode) {
--                              de->inode = cpu_to_le32(inode->i_ino);
--                              ext3_set_de_type(dir->i_sb, de, inode->i_mode);
--                      } else
--                              de->inode = 0;
--                      de->name_len = namelen;
--                      memcpy (de->name, name, namelen);
--                      /*
--                       * XXX shouldn't update any times until successful
--                       * completion of syscall, but too many callers depend
--                       * on this.
--                       *
--                       * XXX similarly, too many callers depend on
--                       * ext3_new_inode() setting the times, but error
--                       * recovery deletes the inode, so the worst that can
--                       * happen is that the times are slightly out of date
--                       * and/or different from the directory change time.
--                       */
--                      dir->i_mtime = dir->i_ctime = CURRENT_TIME;
--                      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
--                      dir->i_version = ++event;
--                      ext3_mark_inode_dirty(handle, dir);
--                      BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
--                      ext3_journal_dirty_metadata(handle, bh);
--                      brelse(bh);
--                      return 0;
-+                      dx_insert_block (frames + 0, hash2, newblock);
-+                      dxtrace(dx_show_index ("node", frames[1].entries));
-+                      dxtrace(dx_show_index ("node",
-+                             ((struct dx_node *) bh2->b_data)->entries));
-+                      err = ext3_journal_dirty_metadata(handle, bh2);
-+                      if (err)
-+                              goto journal_error;
-+                      brelse (bh2);
-+              } else {
-+                      dxtrace(printk("Creating second level index...\n"));
-+                      memcpy((char *) entries2, (char *) entries,
-+                             icount * sizeof(struct dx_entry));
-+                      dx_set_limit(entries2, dx_node_limit(dir));
-+
-+                      /* Set up root */
-+                      dx_set_count(entries, 1);
-+                      dx_set_block(entries + 0, newblock);
-+                      ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
-+
-+                      /* Add new access path frame */
-+                      frame = frames + 1;
-+                      frame->at = at = at - entries + entries2;
-+                      frame->entries = entries = entries2;
-+                      frame->bh = bh2;
-+                      err = ext3_journal_get_write_access(handle,
-+                                                           frame->bh);
-+                      if (err)
-+                              goto journal_error;
-               }
--              offset += le16_to_cpu(de->rec_len);
--              de = (struct ext3_dir_entry_2 *)
--                      ((char *) de + le16_to_cpu(de->rec_len));
-+              ext3_journal_dirty_metadata(handle, frames[0].bh);
-       }
--      brelse (bh);
--      return -ENOSPC;
-+      de = do_split(handle, dir, &bh, frame, &hinfo, &err);
-+      if (!de)
-+              goto cleanup;
-+      err = add_dirent_to_buf(handle, dentry, inode, de, bh);
-+      bh = 0;
-+      goto cleanup;
-+      
-+journal_error:
-+      ext3_std_error(dir->i_sb, err);
-+cleanup:
-+      if (bh)
-+              brelse(bh);
-+      dx_release(frames);
-+      return err;
- }
-+#endif
- /*
-  * ext3_delete_entry deletes a directory entry by merging it with the
-@@ -451,9 +1530,11 @@ static int ext3_create (struct inode * d
-       struct inode * inode;
-       int err;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -478,9 +1559,11 @@ static int ext3_mknod (struct inode * di
-       struct inode *inode;
-       int err;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -507,9 +1590,11 @@ static int ext3_mkdir(struct inode * dir
-       if (dir->i_nlink >= EXT3_LINK_MAX)
-               return -EMLINK;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -521,7 +1606,7 @@ static int ext3_mkdir(struct inode * dir
-       inode->i_op = &ext3_dir_inode_operations;
-       inode->i_fop = &ext3_dir_operations;
--      inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize;
-+      inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
-       inode->i_blocks = 0;    
-       dir_block = ext3_bread (handle, inode, 0, 1, &err);
-       if (!dir_block) {
-@@ -554,21 +1639,19 @@ static int ext3_mkdir(struct inode * dir
-               inode->i_mode |= S_ISGID;
-       ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_entry (handle, dentry, inode);
--      if (err)
--              goto out_no_entry;
-+      if (err) {
-+              inode->i_nlink = 0;
-+              ext3_mark_inode_dirty(handle, inode);
-+              iput (inode);
-+              goto out_stop;
-+      }
-       dir->i_nlink++;
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
-       d_instantiate(dentry, inode);
- out_stop:
-       ext3_journal_stop(handle, dir);
-       return err;
--
--out_no_entry:
--      inode->i_nlink = 0;
--      ext3_mark_inode_dirty(handle, inode);
--      iput (inode);
--      goto out_stop;
- }
- /*
-@@ -655,7 +1738,7 @@ int ext3_orphan_add(handle_t *handle, st
-       int err = 0, rc;
-       
-       lock_super(sb);
--      if (!list_empty(&inode->u.ext3_i.i_orphan))
-+      if (!list_empty(&EXT3_I(inode)->i_orphan))
-               goto out_unlock;
-       /* Orphan handling is only valid for files with data blocks
-@@ -696,7 +1779,7 @@ int ext3_orphan_add(handle_t *handle, st
-        * This is safe: on error we're going to ignore the orphan list
-        * anyway on the next recovery. */
-       if (!err)
--              list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan);
-+              list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
-       jbd_debug(4, "superblock will point to %ld\n", inode->i_ino);
-       jbd_debug(4, "orphan inode %ld will point to %d\n",
-@@ -714,25 +1797,26 @@ out_unlock:
- int ext3_orphan_del(handle_t *handle, struct inode *inode)
- {
-       struct list_head *prev;
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-       struct ext3_sb_info *sbi;
-       ino_t ino_next; 
-       struct ext3_iloc iloc;
-       int err = 0;
-       
-       lock_super(inode->i_sb);
--      if (list_empty(&inode->u.ext3_i.i_orphan)) {
-+      if (list_empty(&ei->i_orphan)) {
-               unlock_super(inode->i_sb);
-               return 0;
-       }
-       ino_next = NEXT_ORPHAN(inode);
--      prev = inode->u.ext3_i.i_orphan.prev;
-+      prev = ei->i_orphan.prev;
-       sbi = EXT3_SB(inode->i_sb);
-       jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino);
--      list_del(&inode->u.ext3_i.i_orphan);
--      INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
-+      list_del(&ei->i_orphan);
-+      INIT_LIST_HEAD(&ei->i_orphan);
-       /* If we're on an error path, we may not have a valid
-        * transaction handle with which to update the orphan list on
-@@ -793,8 +1877,9 @@ static int ext3_rmdir (struct inode * di
-       handle_t *handle;
-       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
--      if (IS_ERR(handle))
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       retval = -ENOENT;
-       bh = ext3_find_entry (dentry, &de);
-@@ -832,7 +1917,7 @@ static int ext3_rmdir (struct inode * di
-       dir->i_nlink--;
-       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       ext3_mark_inode_dirty(handle, inode);
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
- end_rmdir:
-@@ -850,8 +1935,9 @@ static int ext3_unlink(struct inode * di
-       handle_t *handle;
-       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
--      if (IS_ERR(handle))
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -878,7 +1964,7 @@ static int ext3_unlink(struct inode * di
-       if (retval)
-               goto end_unlink;
-       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
-       inode->i_nlink--;
-       if (!inode->i_nlink)
-@@ -904,9 +1990,11 @@ static int ext3_symlink (struct inode * 
-       if (l > dir->i_sb->s_blocksize)
-               return -ENAMETOOLONG;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -916,7 +2004,7 @@ static int ext3_symlink (struct inode * 
-       if (IS_ERR(inode))
-               goto out_stop;
--      if (l > sizeof (inode->u.ext3_i.i_data)) {
-+      if (l > sizeof (EXT3_I(inode)->i_data)) {
-               inode->i_op = &page_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-               /*
-@@ -925,25 +2013,23 @@ static int ext3_symlink (struct inode * 
-                * i_size in generic_commit_write().
-                */
-               err = block_symlink(inode, symname, l);
--              if (err)
--                      goto out_no_entry;
-+              if (err) {
-+                      ext3_dec_count(handle, inode);
-+                      ext3_mark_inode_dirty(handle, inode);
-+                      iput (inode);
-+                      goto out_stop;
-+              }
-       } else {
-               inode->i_op = &ext3_fast_symlink_inode_operations;
--              memcpy((char*)&inode->u.ext3_i.i_data,symname,l);
-+              memcpy((char*)&EXT3_I(inode)->i_data,symname,l);
-               inode->i_size = l-1;
-       }
--      inode->u.ext3_i.i_disksize = inode->i_size;
-+      EXT3_I(inode)->i_disksize = inode->i_size;
-       err = ext3_add_nondir(handle, dentry, inode);
-       ext3_mark_inode_dirty(handle, inode);
- out_stop:
-       ext3_journal_stop(handle, dir);
-       return err;
--
--out_no_entry:
--      ext3_dec_count(handle, inode);
--      ext3_mark_inode_dirty(handle, inode);
--      iput (inode);
--      goto out_stop;
- }
- static int ext3_link (struct dentry * old_dentry,
-@@ -956,12 +2042,15 @@ static int ext3_link (struct dentry * ol
-       if (S_ISDIR(inode->i_mode))
-               return -EPERM;
--      if (inode->i_nlink >= EXT3_LINK_MAX)
-+      if (inode->i_nlink >= EXT3_LINK_MAX) {
-               return -EMLINK;
-+      }
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
-@@ -995,9 +2084,11 @@ static int ext3_rename (struct inode * o
-       old_bh = new_bh = dir_bh = NULL;
--      handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2);
--      if (IS_ERR(handle))
-+      handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
-+      if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-+      }
-       if (IS_SYNC(old_dir) || IS_SYNC(new_dir))
-               handle->h_sync = 1;
-@@ -1077,7 +2168,7 @@ static int ext3_rename (struct inode * o
-               new_inode->i_ctime = CURRENT_TIME;
-       }
-       old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
--      old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(old_dir);
-       if (dir_bh) {
-               BUFFER_TRACE(dir_bh, "get_write_access");
-               ext3_journal_get_write_access(handle, dir_bh);
-@@ -1089,7 +2180,7 @@ static int ext3_rename (struct inode * o
-                       new_inode->i_nlink--;
-               } else {
-                       new_dir->i_nlink++;
--                      new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+                      ext3_update_dx_flag(new_dir);
-                       ext3_mark_inode_dirty(handle, new_dir);
-               }
-       }
---- linux-2.4.20/fs/ext3/super.c~ext-2.4-patch-1       Sat Apr  5 03:56:31 2003
-+++ linux-2.4.20-braam/fs/ext3/super.c Sat Apr  5 03:56:31 2003
-@@ -707,6 +707,7 @@ static int ext3_setup_super(struct super
-       es->s_mtime = cpu_to_le32(CURRENT_TIME);
-       ext3_update_dynamic_rev(sb);
-       EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
-+
-       ext3_commit_super (sb, es, 1);
-       if (test_opt (sb, DEBUG))
-               printk (KERN_INFO
-@@ -717,6 +718,7 @@ static int ext3_setup_super(struct super
-                       EXT3_BLOCKS_PER_GROUP(sb),
-                       EXT3_INODES_PER_GROUP(sb),
-                       sbi->s_mount_opt);
-+
-       printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ",
-                               bdevname(sb->s_dev));
-       if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
-@@ -890,6 +892,7 @@ static loff_t ext3_max_size(int bits)
-       return res;
- }
-+
- struct super_block * ext3_read_super (struct super_block * sb, void * data,
-                                     int silent)
- {
-@@ -1066,6 +1069,9 @@ struct super_block * ext3_read_super (st
-       sbi->s_mount_state = le16_to_cpu(es->s_state);
-       sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
-       sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
-+      for (i=0; i < 4; i++)
-+              sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
-+      sbi->s_def_hash_version = es->s_def_hash_version;
-       if (sbi->s_blocks_per_group > blocksize * 8) {
-               printk (KERN_ERR
-@@ -1769,6 +1775,7 @@ static void __exit exit_ext3_fs(void)
-       unregister_filesystem(&ext3_fs_type);
- }
-+EXPORT_SYMBOL(ext3_force_commit);
- EXPORT_SYMBOL(ext3_bread);
- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
---- linux-2.4.20/include/linux/ext3_fs.h~ext-2.4-patch-1       Sat Apr  5 03:56:31 2003
-+++ linux-2.4.20-braam/include/linux/ext3_fs.h Sat Apr  5 03:56:31 2003
-@@ -40,6 +40,11 @@
- #define EXT3FS_VERSION                "2.4-0.9.19"
- /*
-+ * Always enable hashed directories
-+ */
-+#define CONFIG_EXT3_INDEX
-+
-+/*
-  * Debug code
-  */
- #ifdef EXT3FS_DEBUG
-@@ -437,8 +442,11 @@ struct ext3_super_block {
- /*E0*/        __u32   s_journal_inum;         /* inode number of journal file */
-       __u32   s_journal_dev;          /* device number of journal file */
-       __u32   s_last_orphan;          /* start of list of inodes to delete */
--
--/*EC*/        __u32   s_reserved[197];        /* Padding to the end of the block */
-+      __u32   s_hash_seed[4];         /* HTREE hash seed */
-+      __u8    s_def_hash_version;     /* Default hash version to use */
-+      __u8    s_reserved_char_pad;
-+      __u16   s_reserved_word_pad;
-+      __u32   s_reserved[192];        /* Padding to the end of the block */
- };
- #ifdef __KERNEL__
-@@ -575,9 +583,46 @@ struct ext3_dir_entry_2 {
- #define EXT3_DIR_ROUND                        (EXT3_DIR_PAD - 1)
- #define EXT3_DIR_REC_LEN(name_len)    (((name_len) + 8 + EXT3_DIR_ROUND) & \
-                                        ~EXT3_DIR_ROUND)
-+/*
-+ * Hash Tree Directory indexing
-+ * (c) Daniel Phillips, 2001
-+ */
-+
-+#ifdef CONFIG_EXT3_INDEX
-+  #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
-+                                            EXT3_FEATURE_COMPAT_DIR_INDEX) && \
-+                    (EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
-+#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
-+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
-+#else
-+  #define is_dx(dir) 0
-+#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
-+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
-+#endif
-+
-+/* Legal values for the dx_root hash_version field: */
-+
-+#define DX_HASH_LEGACY                0
-+#define DX_HASH_HALF_MD4      1
-+#define DX_HASH_TEA           2
-+
-+/* hash info structure used by the directory hash */
-+struct dx_hash_info
-+{
-+      u32             hash;
-+      u32             minor_hash;
-+      int             hash_version;
-+      u32             *seed;
-+};
- #ifdef __KERNEL__
- /*
-+ * Control parameters used by ext3_htree_next_block
-+ */
-+#define HASH_NB_ALWAYS                1
-+
-+
-+/*
-  * Describe an inode's exact location on disk and in memory
-  */
- struct ext3_iloc
-@@ -587,6 +632,27 @@ struct ext3_iloc
-       unsigned long block_group;
- };
-+
-+/*
-+ * This structure is stuffed into the struct file's private_data field
-+ * for directories.  It is where we put information so that we can do
-+ * readdir operations in hash tree order.
-+ */
-+struct dir_private_info {
-+      rb_root_t       root;
-+      rb_node_t       *curr_node;
-+      struct fname    *extra_fname;
-+      loff_t          last_pos;
-+      __u32           curr_hash;
-+      __u32           curr_minor_hash;
-+      __u32           next_hash;
-+};
-+
-+/*
-+ * Special error return code only used by dx_probe() and its callers.
-+ */
-+#define ERR_BAD_DX_DIR        -75000
-+
- /*
-  * Function prototypes
-  */
-@@ -614,11 +680,20 @@ extern struct ext3_group_desc * ext3_get
- /* dir.c */
- extern int ext3_check_dir_entry(const char *, struct inode *,
--                              struct ext3_dir_entry_2 *, struct buffer_head *,
--                              unsigned long);
-+                              struct ext3_dir_entry_2 *,
-+                              struct buffer_head *, unsigned long);
-+extern void ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
-+                                  __u32 minor_hash,
-+                                  struct ext3_dir_entry_2 *dirent);
-+extern void ext3_htree_free_dir_info(struct dir_private_info *p);
-+
- /* fsync.c */
- extern int ext3_sync_file (struct file *, struct dentry *, int);
-+/* hash.c */
-+extern int ext3fs_dirhash(const char *name, int len, struct
-+                        dx_hash_info *hinfo);
-+
- /* ialloc.c */
- extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
- extern void ext3_free_inode (handle_t *, struct inode *);
-@@ -650,6 +725,8 @@ extern int ext3_ioctl (struct inode *, s
- /* namei.c */
- extern int ext3_orphan_add(handle_t *, struct inode *);
- extern int ext3_orphan_del(handle_t *, struct inode *);
-+extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
-+                              __u32 start_minor_hash, __u32 *next_hash);
- /* super.c */
- extern void ext3_error (struct super_block *, const char *, const char *, ...)
---- linux-2.4.20/include/linux/ext3_fs_sb.h~ext-2.4-patch-1    Sat Apr  5 03:56:31 2003
-+++ linux-2.4.20-braam/include/linux/ext3_fs_sb.h      Sat Apr  5 03:56:31 2003
-@@ -62,6 +62,8 @@ struct ext3_sb_info {
-       int s_inode_size;
-       int s_first_ino;
-       u32 s_next_generation;
-+      u32 s_hash_seed[4];
-+      int s_def_hash_version;
-       /* Journaling */
-       struct inode * s_journal_inode;
---- linux-2.4.20/include/linux/ext3_jbd.h~ext-2.4-patch-1      Sat Apr  5 03:56:31 2003
-+++ linux-2.4.20-braam/include/linux/ext3_jbd.h        Sat Apr  5 03:56:31 2003
-@@ -63,6 +63,8 @@ extern int ext3_writepage_trans_blocks(s
- #define EXT3_RESERVE_TRANS_BLOCKS     12
-+#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8
-+
- int
- ext3_mark_iloc_dirty(handle_t *handle, 
-                    struct inode *inode,
---- linux-2.4.20/include/linux/rbtree.h~ext-2.4-patch-1        Sat Apr  5 03:56:31 2003
-+++ linux-2.4.20-braam/include/linux/rbtree.h  Sat Apr  5 03:56:31 2003
-@@ -120,6 +120,8 @@ rb_root_t;
- extern void rb_insert_color(rb_node_t *, rb_root_t *);
- extern void rb_erase(rb_node_t *, rb_root_t *);
-+extern rb_node_t *rb_get_first(rb_root_t *root);
-+extern rb_node_t *rb_get_next(rb_node_t *n);
- static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
- {
---- linux-2.4.20/lib/rbtree.c~ext-2.4-patch-1  Sat Apr  5 03:56:31 2003
-+++ linux-2.4.20-braam/lib/rbtree.c    Sat Apr  5 03:56:31 2003
-@@ -17,6 +17,8 @@
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-   linux/lib/rbtree.c
-+
-+  rb_get_first and rb_get_next written by Theodore Ts'o, 9/8/2002
- */
- #include <linux/rbtree.h>
-@@ -294,3 +296,43 @@ void rb_erase(rb_node_t * node, rb_root_
-               __rb_erase_color(child, parent, root);
- }
- EXPORT_SYMBOL(rb_erase);
-+
-+/*
-+ * This function returns the first node (in sort order) of the tree.
-+ */
-+rb_node_t *rb_get_first(rb_root_t *root)
-+{
-+      rb_node_t       *n;
-+
-+      n = root->rb_node;
-+      if (!n)
-+              return 0;
-+      while (n->rb_left)
-+              n = n->rb_left;
-+      return n;
-+}
-+EXPORT_SYMBOL(rb_get_first);
-+
-+/*
-+ * Given a node, this function will return the next node in the tree.
-+ */
-+rb_node_t *rb_get_next(rb_node_t *n)
-+{
-+      rb_node_t       *parent;
-+
-+      if (n->rb_right) {
-+              n = n->rb_right;
-+              while (n->rb_left)
-+                      n = n->rb_left;
-+              return n;
-+      } else {
-+              while ((parent = n->rb_parent)) {
-+                      if (n == parent->rb_left)
-+                              return parent;
-+                      n = parent;
-+              }
-+              return 0;
-+      }
-+}
-+EXPORT_SYMBOL(rb_get_next);
-+
-
-_
diff --git a/lustre/kernel_patches/patches/ext-2.4-patch-2.patch b/lustre/kernel_patches/patches/ext-2.4-patch-2.patch
deleted file mode 100644 (file)
index 689d33b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# This is a BitKeeper generated patch for the following project:
-# Project Name: Linux kernel tree
-#
-# namei.c |    9 +++++++++
-# 1 files changed, 9 insertions(+)
-#
-# The following is the BitKeeper ChangeSet Log
-# --------------------------------------------
-# 02/11/07     tytso@snap.thunk.org    1.777
-# Add '.' and '..' entries to be returned by readdir of htree directories
-# 
-# This patch from Chris Li adds '.' and '..' to the rbtree so that they 
-# are properly returned by readdir.
-# --------------------------------------------
-#
-diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
---- a/fs/ext3/namei.c  Thu Nov  7 10:57:30 2002
-+++ b/fs/ext3/namei.c  Thu Nov  7 10:57:30 2002
-@@ -546,6 +546,15 @@
-       if (!frame)
-               return err;
-+      /* Add '.' and '..' from the htree header */
-+      if (!start_hash && !start_minor_hash) {
-+              de = (struct ext3_dir_entry_2 *) frames[0].bh->b_data;
-+              ext3_htree_store_dirent(dir_file, 0, 0, de);
-+              de = ext3_next_entry(de);
-+              ext3_htree_store_dirent(dir_file, 0, 0, de);
-+              count += 2;
-+      }
-+
-       while (1) {
-               block = dx_get_block(frame->at);
-               dxtrace(printk("Reading block %d\n", block));
diff --git a/lustre/kernel_patches/patches/ext-2.4-patch-3.patch b/lustre/kernel_patches/patches/ext-2.4-patch-3.patch
deleted file mode 100644 (file)
index 2600b02..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-# This is a BitKeeper generated patch for the following project:
-# Project Name: Linux kernel tree
-#
-# fs/ext3/dir.c           |    7 +++++--
-# fs/ext3/namei.c         |   11 +++++++----
-# include/linux/ext3_fs.h |    2 +-
-# 3 files changed, 13 insertions(+), 7 deletions(-)
-#
-# The following is the BitKeeper ChangeSet Log
-# --------------------------------------------
-# 02/11/07     tytso@snap.thunk.org    1.778
-# Check for failed kmalloc() in ext3_htree_store_dirent()
-# 
-# This patch checks for a failed kmalloc() in ext3_htree_store_dirent(),
-# and passes the error up to its caller, ext3_htree_fill_tree().
-# --------------------------------------------
-#
-diff -Nru a/fs/ext3/dir.c b/fs/ext3/dir.c
---- a/fs/ext3/dir.c    Thu Nov  7 10:57:34 2002
-+++ b/fs/ext3/dir.c    Thu Nov  7 10:57:34 2002
-@@ -308,7 +308,7 @@
- /*
-  * Given a directory entry, enter it into the fname rb tree.
-  */
--void ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
-+int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
-                            __u32 minor_hash,
-                            struct ext3_dir_entry_2 *dirent)
- {
-@@ -323,6 +323,8 @@
-       /* Create and allocate the fname structure */
-       len = sizeof(struct fname) + dirent->name_len + 1;
-       new_fn = kmalloc(len, GFP_KERNEL);
-+      if (!new_fn)
-+              return -ENOMEM;
-       memset(new_fn, 0, len);
-       new_fn->hash = hash;
-       new_fn->minor_hash = minor_hash;
-@@ -344,7 +346,7 @@
-                   (new_fn->minor_hash == fname->minor_hash)) {
-                       new_fn->next = fname->next;
-                       fname->next = new_fn;
--                      return;
-+                      return 0;
-               }
-                       
-               if (new_fn->hash < fname->hash)
-@@ -359,6 +361,7 @@
-       rb_link_node(&new_fn->rb_hash, parent, p);
-       rb_insert_color(&new_fn->rb_hash, &info->root);
-+      return 0;
- }
-diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
---- a/fs/ext3/namei.c  Thu Nov  7 10:57:34 2002
-+++ b/fs/ext3/namei.c  Thu Nov  7 10:57:34 2002
-@@ -549,9 +549,11 @@
-       /* Add '.' and '..' from the htree header */
-       if (!start_hash && !start_minor_hash) {
-               de = (struct ext3_dir_entry_2 *) frames[0].bh->b_data;
--              ext3_htree_store_dirent(dir_file, 0, 0, de);
-+              if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
-+                      goto errout;
-               de = ext3_next_entry(de);
--              ext3_htree_store_dirent(dir_file, 0, 0, de);
-+              if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
-+                      goto errout;
-               count += 2;
-       }
-@@ -570,8 +572,9 @@
-                           ((hinfo.hash == start_hash) &&
-                            (hinfo.minor_hash < start_minor_hash)))
-                               continue;
--                      ext3_htree_store_dirent(dir_file, hinfo.hash,
--                                              hinfo.minor_hash, de);
-+                      if ((err = ext3_htree_store_dirent(dir_file,
-+                                 hinfo.hash, hinfo.minor_hash, de)) != 0)
-+                              goto errout;
-                       count++;
-               }
-               brelse (bh);
-diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
---- a/include/linux/ext3_fs.h  Thu Nov  7 10:57:34 2002
-+++ b/include/linux/ext3_fs.h  Thu Nov  7 10:57:34 2002
-@@ -682,7 +682,7 @@
- extern int ext3_check_dir_entry(const char *, struct inode *,
-                               struct ext3_dir_entry_2 *,
-                               struct buffer_head *, unsigned long);
--extern void ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
-+extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
-                                   __u32 minor_hash,
-                                   struct ext3_dir_entry_2 *dirent);
- extern void ext3_htree_free_dir_info(struct dir_private_info *p);
diff --git a/lustre/kernel_patches/patches/ext-2.4-patch-4.patch b/lustre/kernel_patches/patches/ext-2.4-patch-4.patch
deleted file mode 100644 (file)
index 67f5afa..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-# This is a BitKeeper generated patch for the following project:
-# Project Name: Linux kernel tree
-#
-# namei.c |   21 ++++++++++++++++++++-
-# 1 files changed, 20 insertions(+), 1 deletion(-)
-#
-# The following is the BitKeeper ChangeSet Log
-# --------------------------------------------
-# 02/11/07     tytso@snap.thunk.org    1.779
-# Fix ext3 htree rename bug.
-# 
-# This fixes an ext3 htree bug pointed out by Christopher Li; if 
-# adding the new name to the directory causes a split, this can cause
-# the directory entry containing the old name to move to another 
-# block, and then the removal of the old name will fail.
-# --------------------------------------------
-#
-diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
---- a/fs/ext3/namei.c  Thu Nov  7 10:57:49 2002
-+++ b/fs/ext3/namei.c  Thu Nov  7 10:57:49 2002
-@@ -2173,7 +2173,26 @@
-       /*
-        * ok, that's it
-        */
--      ext3_delete_entry(handle, old_dir, old_de, old_bh);
-+      retval = ext3_delete_entry(handle, old_dir, old_de, old_bh);
-+      if (retval == -ENOENT) {
-+              /*
-+               * old_de could have moved out from under us.
-+               */
-+              struct buffer_head *old_bh2;
-+              struct ext3_dir_entry_2 *old_de2;
-+              
-+              old_bh2 = ext3_find_entry(old_dentry, &old_de2);
-+              if (old_bh2) {
-+                      retval = ext3_delete_entry(handle, old_dir,
-+                                                 old_de2, old_bh2);
-+                      brelse(old_bh2);
-+              }
-+      }
-+      if (retval) {
-+              ext3_warning(old_dir->i_sb, "ext3_rename",
-+                              "Deleting old file (%lu), %d, error=%d",
-+                              old_dir->i_ino, old_dir->i_nlink, retval);
-+      }
-       if (new_inode) {
-               new_inode->i_nlink--;
diff --git a/lustre/kernel_patches/patches/ext3-2.4-ino_t.patch b/lustre/kernel_patches/patches/ext3-2.4-ino_t.patch
deleted file mode 100644 (file)
index 1786d0f..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
- fs/ext3/ialloc.c        |   20 ++++++++++----------
- fs/ext3/namei.c         |   16 ++++++++--------
- include/linux/ext3_fs.h |    2 +-
- 3 files changed, 19 insertions(+), 19 deletions(-)
-
---- linux-2.4.20/fs/ext3/ialloc.c~ext3-2.4-ino_t       2003-04-08 23:35:24.000000000 -0600
-+++ linux-2.4.20-braam/fs/ext3/ialloc.c        2003-04-08 23:35:24.000000000 -0600
-@@ -65,8 +65,8 @@ static int read_inode_bitmap (struct sup
-       if (!bh) {
-               ext3_error (sb, "read_inode_bitmap",
-                           "Cannot read inode bitmap - "
--                          "block_group = %lu, inode_bitmap = %lu",
--                          block_group, (unsigned long) gdp->bg_inode_bitmap);
-+                          "block_group = %lu, inode_bitmap = %u",
-+                          block_group, gdp->bg_inode_bitmap);
-               retval = -EIO;
-       }
-       /*
-@@ -533,19 +533,19 @@ out:
- }
- /* Verify that we are loading a valid orphan from disk */
--struct inode *ext3_orphan_get (struct super_block * sb, ino_t ino)
-+struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
- {
--      ino_t max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count);
-+      unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count);
-       unsigned long block_group;
-       int bit;
-       int bitmap_nr;
-       struct buffer_head *bh;
-       struct inode *inode = NULL;
--      
-+
-       /* Error cases - e2fsck has already cleaned up for us */
-       if (ino > max_ino) {
-               ext3_warning(sb, __FUNCTION__,
--                           "bad orphan ino %ld!  e2fsck was run?\n", ino);
-+                           "bad orphan ino %lu!  e2fsck was run?\n", ino);
-               return NULL;
-       }
-@@ -554,7 +554,7 @@ struct inode *ext3_orphan_get (struct su
-       if ((bitmap_nr = load_inode_bitmap(sb, block_group)) < 0 ||
-           !(bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr])) {
-               ext3_warning(sb, __FUNCTION__,
--                           "inode bitmap error for orphan %ld\n", ino);
-+                           "inode bitmap error for orphan %lu\n", ino);
-               return NULL;
-       }
-@@ -565,16 +565,16 @@ struct inode *ext3_orphan_get (struct su
-       if (!ext3_test_bit(bit, bh->b_data) || !(inode = iget(sb, ino)) ||
-           is_bad_inode(inode) || NEXT_ORPHAN(inode) > max_ino) {
-               ext3_warning(sb, __FUNCTION__,
--                           "bad orphan inode %ld!  e2fsck was run?\n", ino);
-+                           "bad orphan inode %lu!  e2fsck was run?\n", ino);
-               printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%ld) = %d\n",
-                      bit, bh->b_blocknr, ext3_test_bit(bit, bh->b_data));
-               printk(KERN_NOTICE "inode=%p\n", inode);
-               if (inode) {
-                       printk(KERN_NOTICE "is_bad_inode(inode)=%d\n",
-                              is_bad_inode(inode));
--                      printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%d\n",
-+                      printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n",
-                              NEXT_ORPHAN(inode));
--                      printk(KERN_NOTICE "max_ino=%ld\n", max_ino);
-+                      printk(KERN_NOTICE "max_ino=%lu\n", max_ino);
-               }
-               /* Avoid freeing blocks if we got a bad deleted inode */
-               if (inode && inode->i_nlink == 0)
---- linux-2.4.20/fs/ext3/namei.c~ext3-2.4-ino_t        2003-04-08 23:35:24.000000000 -0600
-+++ linux-2.4.20-braam/fs/ext3/namei.c 2003-04-08 23:35:24.000000000 -0600
-@@ -1808,10 +1808,10 @@ int ext3_orphan_del(handle_t *handle, st
-       struct list_head *prev;
-       struct ext3_inode_info *ei = EXT3_I(inode);
-       struct ext3_sb_info *sbi;
--      ino_t ino_next; 
-+      unsigned long ino_next;
-       struct ext3_iloc iloc;
-       int err = 0;
--      
-+
-       lock_super(inode->i_sb);
-       if (list_empty(&ei->i_orphan)) {
-               unlock_super(inode->i_sb);
-@@ -1822,7 +1822,7 @@ int ext3_orphan_del(handle_t *handle, st
-       prev = ei->i_orphan.prev;
-       sbi = EXT3_SB(inode->i_sb);
--      jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino);
-+      jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
-       list_del(&ei->i_orphan);
-       INIT_LIST_HEAD(&ei->i_orphan);
-@@ -1833,13 +1833,13 @@ int ext3_orphan_del(handle_t *handle, st
-        * list in memory. */
-       if (!handle)
-               goto out;
--      
-+
-       err = ext3_reserve_inode_write(handle, inode, &iloc);
-       if (err)
-               goto out_err;
-       if (prev == &sbi->s_orphan) {
--              jbd_debug(4, "superblock will point to %ld\n", ino_next);
-+              jbd_debug(4, "superblock will point to %lu\n", ino_next);
-               BUFFER_TRACE(sbi->s_sbh, "get_write_access");
-               err = ext3_journal_get_write_access(handle, sbi->s_sbh);
-               if (err)
-@@ -1850,8 +1850,8 @@ int ext3_orphan_del(handle_t *handle, st
-               struct ext3_iloc iloc2;
-               struct inode *i_prev =
-                       list_entry(prev, struct inode, u.ext3_i.i_orphan);
--              
--              jbd_debug(4, "orphan inode %ld will point to %ld\n",
-+
-+              jbd_debug(4, "orphan inode %lu will point to %lu\n",
-                         i_prev->i_ino, ino_next);
-               err = ext3_reserve_inode_write(handle, i_prev, &iloc2);
-               if (err)
-@@ -1866,7 +1866,7 @@ int ext3_orphan_del(handle_t *handle, st
-       if (err)
-               goto out_brelse;
--out_err:      
-+out_err: 
-       ext3_std_error(inode->i_sb, err);
- out:
-       unlock_super(inode->i_sb);
---- linux-2.4.20/include/linux/ext3_fs.h~ext3-2.4-ino_t        2003-04-08 23:35:24.000000000 -0600
-+++ linux-2.4.20-braam/include/linux/ext3_fs.h 2003-04-08 23:35:24.000000000 -0600
-@@ -673,7 +673,7 @@ extern int ext3fs_dirhash(const char *na
- /* ialloc.c */
- extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
- extern void ext3_free_inode (handle_t *, struct inode *);
--extern struct inode * ext3_orphan_get (struct super_block *, ino_t);
-+extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
- extern unsigned long ext3_count_free_inodes (struct super_block *);
- extern void ext3_check_inodes_bitmap (struct super_block *);
- extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
-
-_
diff --git a/lustre/kernel_patches/patches/ext3-2.4.18-fixes.patch b/lustre/kernel_patches/patches/ext3-2.4.18-fixes.patch
deleted file mode 100644 (file)
index 56e841e..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-diff -ru lum-2.4.18-um30/fs/ext3/balloc.c uml-2.4.18-12.5/fs/ext3/balloc.c
---- lum-2.4.18-um30/fs/ext3/balloc.c   Mon Feb 25 12:38:08 2002
-+++ uml-2.4.18-12.5/fs/ext3/balloc.c   Thu Sep 19 13:40:11 2002
-@@ -276,7 +276,8 @@
-       }
-       lock_super (sb);
-       es = sb->u.ext3_sb.s_es;
--      if (block < le32_to_cpu(es->s_first_data_block) || 
-+      if (block < le32_to_cpu(es->s_first_data_block) ||
-+          block + count < block ||
-           (block + count) > le32_to_cpu(es->s_blocks_count)) {
-               ext3_error (sb, "ext3_free_blocks",
-                           "Freeing blocks not in datazone - "
-@@ -309,17 +310,6 @@
-       if (!gdp)
-               goto error_return;
--      if (in_range (le32_to_cpu(gdp->bg_block_bitmap), block, count) ||
--          in_range (le32_to_cpu(gdp->bg_inode_bitmap), block, count) ||
--          in_range (block, le32_to_cpu(gdp->bg_inode_table),
--                    sb->u.ext3_sb.s_itb_per_group) ||
--          in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table),
--                    sb->u.ext3_sb.s_itb_per_group))
--              ext3_error (sb, "ext3_free_blocks",
--                          "Freeing blocks in system zones - "
--                          "Block = %lu, count = %lu",
--                          block, count);
--
-       /*
-        * We are about to start releasing blocks in the bitmap,
-        * so we need undo access.
-@@ -345,14 +335,24 @@
-       if (err)
-               goto error_return;
--      for (i = 0; i < count; i++) {
-+      for (i = 0; i < count; i++, block++) {
-+              if (block == le32_to_cpu(gdp->bg_block_bitmap) ||
-+                  block == le32_to_cpu(gdp->bg_inode_bitmap) ||
-+                  in_range(block, le32_to_cpu(gdp->bg_inode_table),
-+                           sb->u.ext2_sb.s_itb_per_group)) {
-+                      ext3_error(sb, __FUNCTION__,
-+                                 "Freeing block in system zone - block = %lu",
-+                                 block);
-+                      continue;
-+              }
-+
-               /*
-                * An HJ special.  This is expensive...
-                */
- #ifdef CONFIG_JBD_DEBUG
-               {
-                       struct buffer_head *debug_bh;
--                      debug_bh = sb_get_hash_table(sb, block + i);
-+                      debug_bh = sb_get_hash_table(sb, block);
-                       if (debug_bh) {
-                               BUFFER_TRACE(debug_bh, "Deleted!");
-                               if (!bh2jh(bitmap_bh)->b_committed_data)
-@@ -365,9 +365,8 @@
- #endif
-               BUFFER_TRACE(bitmap_bh, "clear bit");
-               if (!ext3_clear_bit (bit + i, bitmap_bh->b_data)) {
--                      ext3_error (sb, __FUNCTION__,
--                                    "bit already cleared for block %lu", 
--                                    block + i);
-+                      ext3_error(sb, __FUNCTION__,
-+                                 "bit already cleared for block %lu", block);
-                       BUFFER_TRACE(bitmap_bh, "bit already cleared");
-               } else {
-                       dquot_freed_blocks++;
-@@ -415,7 +417,6 @@
-       if (!err) err = ret;
-       if (overflow && !err) {
--              block += count;
-               count = overflow;
-               goto do_more;
-       }
-@@ -542,6 +543,7 @@
-       int i, j, k, tmp, alloctmp;
-       int bitmap_nr;
-       int fatal = 0, err;
-+      int performed_allocation = 0;
-       struct super_block * sb;
-       struct ext3_group_desc * gdp;
-       struct ext3_super_block * es;
-@@ -575,6 +577,7 @@
-       ext3_debug ("goal=%lu.\n", goal);
-+repeat:
-       /*
-        * First, test whether the goal block is free.
-        */
-@@ -644,8 +647,7 @@
-       }
-       /* No space left on the device */
--      unlock_super (sb);
--      return 0;
-+      goto out;
- search_back:
-       /* 
-@@ -684,16 +686,28 @@
-       if (tmp == le32_to_cpu(gdp->bg_block_bitmap) ||
-           tmp == le32_to_cpu(gdp->bg_inode_bitmap) ||
-           in_range (tmp, le32_to_cpu(gdp->bg_inode_table),
--                    sb->u.ext3_sb.s_itb_per_group))
--              ext3_error (sb, "ext3_new_block",
--                          "Allocating block in system zone - "
--                          "block = %u", tmp);
-+                    EXT3_SB(sb)->s_itb_per_group)) {
-+              ext3_error(sb, __FUNCTION__,
-+                         "Allocating block in system zone - block = %u", tmp);
-+
-+              /* Note: This will potentially use up one of the handle's
-+               * buffer credits.  Normally we have way too many credits,
-+               * so that is OK.  In _very_ rare cases it might not be OK.
-+               * We will trigger an assertion if we run out of credits,
-+               * and we will have to do a full fsck of the filesystem -
-+               * better than randomly corrupting filesystem metadata.
-+               */
-+              ext3_set_bit(j, bh->b_data);
-+              goto repeat;
-+      }
-+
-       /* The superblock lock should guard against anybody else beating
-        * us to this point! */
-       J_ASSERT_BH(bh, !ext3_test_bit(j, bh->b_data));
-       BUFFER_TRACE(bh, "setting bitmap bit");
-       ext3_set_bit(j, bh->b_data);
-+      performed_allocation = 1;
- #ifdef CONFIG_JBD_DEBUG
-       {
-@@ -815,6 +829,11 @@
-               ext3_std_error(sb, fatal);
-       }
-       unlock_super (sb);
-+      /*
-+       * Undo the block allocation
-+       */
-+      if (!performed_allocation)
-+              DQUOT_FREE_BLOCK(inode, 1);
-       return 0;
-       
- }
-diff -ru lum-2.4.18-um30/fs/ext3/file.c uml-2.4.18-12.5/fs/ext3/file.c
---- lum-2.4.18-um30/fs/ext3/file.c     Thu Nov 15 14:37:55 2001
-+++ uml-2.4.18-12.5/fs/ext3/file.c     Thu Sep 19 13:40:11 2002
-@@ -61,19 +61,52 @@
- static ssize_t
- ext3_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
- {
-+      int ret, err;
-       struct inode *inode = file->f_dentry->d_inode;
--      /*
--       * Nasty: if the file is subject to synchronous writes then we need
--       * to force generic_osync_inode() to call ext3_write_inode().
--       * We do that by marking the inode dirty.  This adds much more
--       * computational expense than we need, but we're going to sync
--       * anyway.
--       */
--      if (IS_SYNC(inode) || (file->f_flags & O_SYNC))
--              mark_inode_dirty(inode);
-+      ret = generic_file_write(file, buf, count, ppos);
--      return generic_file_write(file, buf, count, ppos);
-+      /* Skip file flushing code if there was an error, or if nothing
-+         was written. */
-+      if (ret <= 0)
-+              return ret;
-+      
-+      /* If the inode is IS_SYNC, or is O_SYNC and we are doing
-+           data-journaling, then we need to make sure that we force the
-+           transaction to disk to keep all metadata uptodate
-+           synchronously. */
-+
-+      if (file->f_flags & O_SYNC) {
-+              /* If we are non-data-journaled, then the dirty data has
-+                   already been flushed to backing store by
-+                   generic_osync_inode, and the inode has been flushed
-+                   too if there have been any modifications other than
-+                   mere timestamp updates.
-+                 
-+                 Open question --- do we care about flushing
-+                 timestamps too if the inode is IS_SYNC? */
-+              if (!ext3_should_journal_data(inode))
-+                      return ret;
-+
-+              goto force_commit;
-+      }
-+
-+      /* So we know that there has been no forced data flush.  If the
-+           inode is marked IS_SYNC, we need to force one ourselves. */
-+      if (!IS_SYNC(inode))
-+              return ret;
-+      
-+      /* Open question #2 --- should we force data to disk here too?
-+           If we don't, the only impact is that data=writeback
-+           filesystems won't flush data to disk automatically on
-+           IS_SYNC, only metadata (but historically, that is what ext2
-+           has done.) */
-+      
-+force_commit:
-+      err = ext3_force_commit(inode->i_sb);
-+      if (err) 
-+              return err;
-+      return ret;
- }
- struct file_operations ext3_file_operations = {
-diff -ru lum-2.4.18-um30/fs/ext3/fsync.c uml-2.4.18-12.5/fs/ext3/fsync.c
---- lum-2.4.18-um30/fs/ext3/fsync.c    Tue Nov 20 22:34:13 2001
-+++ uml-2.4.18-12.5/fs/ext3/fsync.c    Thu Sep 19 13:40:11 2002
-@@ -62,7 +62,12 @@
-        * we'll end up waiting on them in commit.
-        */
-       ret = fsync_inode_buffers(inode);
--      ret |= fsync_inode_data_buffers(inode);
-+
-+      /* In writeback mode, we need to force out data buffers too.  In
-+       * the other modes, ext3_force_commit takes care of forcing out
-+       * just the right data blocks. */
-+      if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
-+              ret |= fsync_inode_data_buffers(inode);
-       ext3_force_commit(inode->i_sb);
-diff -ru lum-2.4.18-um30/fs/ext3/ialloc.c uml-2.4.18-12.5/fs/ext3/ialloc.c
---- lum-2.4.18-um30/fs/ext3/ialloc.c   Mon Feb 25 12:38:08 2002
-+++ uml-2.4.18-12.5/fs/ext3/ialloc.c   Thu Sep 19 13:40:11 2002
-@@ -392,7 +392,7 @@
-       err = -ENOSPC;
-       if (!gdp)
--              goto fail;
-+              goto out;
-       err = -EIO;
-       bitmap_nr = load_inode_bitmap (sb, i);
-@@ -523,9 +523,10 @@
-       return inode;
- fail:
-+      ext3_std_error(sb, err);
-+out:
-       unlock_super(sb);
-       iput(inode);
--      ext3_std_error(sb, err);
-       return ERR_PTR(err);
- }
-diff -ru lum-2.4.18-um30/fs/ext3/inode.c uml-2.4.18-12.5/fs/ext3/inode.c
---- lum-2.4.18-um30/fs/ext3/inode.c    Mon Feb 25 12:38:08 2002
-+++ uml-2.4.18-12.5/fs/ext3/inode.c    Thu Sep 19 13:40:11 2002
-@@ -412,6 +412,7 @@
-       return NULL;
- changed:
-+      brelse(bh);
-       *err = -EAGAIN;
-       goto no_block;
- failure:
-@@ -581,8 +582,6 @@
-                       
-                       parent = nr;
-               }
--              if (IS_SYNC(inode))
--                      handle->h_sync = 1;
-       }
-       if (n == num)
-               return 0;
-@@ -1015,8 +1018,8 @@
-                             unsigned from, unsigned to)
- {
-       struct inode *inode = page->mapping->host;
--      handle_t *handle = ext3_journal_current_handle();
-       int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
-+      handle_t *handle;
-       lock_kernel();
-       handle = ext3_journal_start(inode, needed_blocks);
-diff -ru lum-2.4.18-um30/fs/ext3/namei.c uml-2.4.18-12.5/fs/ext3/namei.c
---- lum-2.4.18-um30/fs/ext3/namei.c    Fri Nov  9 15:25:04 2001
-+++ uml-2.4.18-12.5/fs/ext3/namei.c    Thu Sep 19 13:40:11 2002
-@@ -354,8 +355,8 @@
-                        */
-                       dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-                       dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
--                      ext3_mark_inode_dirty(handle, dir);
-                       dir->i_version = ++event;
-+                      ext3_mark_inode_dirty(handle, dir);
-                       BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
-                       ext3_journal_dirty_metadata(handle, bh);
-                       brelse(bh);
-@@ -464,8 +465,8 @@
-               inode->i_op = &ext3_file_inode_operations;
-               inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
--              ext3_mark_inode_dirty(handle, inode);
-               err = ext3_add_nondir(handle, dentry, inode);
-+              ext3_mark_inode_dirty(handle, inode);
-       }
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -489,8 +490,8 @@
-       err = PTR_ERR(inode);
-       if (!IS_ERR(inode)) {
-               init_special_inode(inode, mode, rdev);
--              ext3_mark_inode_dirty(handle, inode);
-               err = ext3_add_nondir(handle, dentry, inode);
-+              ext3_mark_inode_dirty(handle, inode);
-       }
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -933,8 +934,8 @@
-               inode->i_size = l-1;
-       }
-       inode->u.ext3_i.i_disksize = inode->i_size;
--      ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_nondir(handle, dentry, inode);
-+      ext3_mark_inode_dirty(handle, inode);
- out_stop:
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -970,8 +971,8 @@
-       ext3_inc_count(handle, inode);
-       atomic_inc(&inode->i_count);
--      ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_nondir(handle, dentry, inode);
-+      ext3_mark_inode_dirty(handle, inode);
-       ext3_journal_stop(handle, dir);
-       return err;
- }
-diff -ru lum-2.4.18-um30/fs/ext3/super.c uml-2.4.18-12.5/fs/ext3/super.c
---- lum-2.4.18-um30/fs/ext3/super.c    Fri Jul 12 17:59:37 2002
-+++ uml-2.4.18-12.5/fs/ext3/super.c    Thu Sep 19 13:40:11 2002
-@@ -1589,8 +1589,10 @@
-               journal_t *journal = EXT3_SB(sb)->s_journal;
-               /* Now we set up the journal barrier. */
-+              unlock_super(sb);
-               journal_lock_updates(journal);
-               journal_flush(journal);
-+              lock_super(sb);
-               /* Journal blocked and flushed, clear needs_recovery flag. */
-               EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
diff --git a/lustre/kernel_patches/patches/ext3-2.4.18-ino_sb_macro.patch b/lustre/kernel_patches/patches/ext3-2.4.18-ino_sb_macro.patch
deleted file mode 100644 (file)
index 2ddff7d..0000000
+++ /dev/null
@@ -1,1540 +0,0 @@
---- ./fs/ext3/balloc.c.orig    Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/balloc.c Tue May  7 15:35:59 2002
-@@ -46,18 +46,18 @@ struct ext3_group_desc * ext3_get_group_
-       unsigned long desc;
-       struct ext3_group_desc * gdp;
--      if (block_group >= sb->u.ext3_sb.s_groups_count) {
-+      if (block_group >= EXT3_SB(sb)->s_groups_count) {
-               ext3_error (sb, "ext3_get_group_desc",
-                           "block_group >= groups_count - "
-                           "block_group = %d, groups_count = %lu",
--                          block_group, sb->u.ext3_sb.s_groups_count);
-+                          block_group, EXT3_SB(sb)->s_groups_count);
-               return NULL;
-       }
-       
-       group_desc = block_group / EXT3_DESC_PER_BLOCK(sb);
-       desc = block_group % EXT3_DESC_PER_BLOCK(sb);
--      if (!sb->u.ext3_sb.s_group_desc[group_desc]) {
-+      if (!EXT3_SB(sb)->s_group_desc[group_desc]) {
-               ext3_error (sb, "ext3_get_group_desc",
-                           "Group descriptor not loaded - "
-                           "block_group = %d, group_desc = %lu, desc = %lu",
-@@ -66,9 +66,9 @@ struct ext3_group_desc * ext3_get_group_
-       }
-       
-       gdp = (struct ext3_group_desc *) 
--            sb->u.ext3_sb.s_group_desc[group_desc]->b_data;
-+            EXT3_SB(sb)->s_group_desc[group_desc]->b_data;
-       if (bh)
--              *bh = sb->u.ext3_sb.s_group_desc[group_desc];
-+              *bh = EXT3_SB(sb)->s_group_desc[group_desc];
-       return gdp + desc;
- }
-@@ -104,8 +104,8 @@ static int read_block_bitmap (struct sup
-        * this group.  The IO will be retried next time.
-        */
- error_out:
--      sb->u.ext3_sb.s_block_bitmap_number[bitmap_nr] = block_group;
--      sb->u.ext3_sb.s_block_bitmap[bitmap_nr] = bh;
-+      EXT3_SB(sb)->s_block_bitmap_number[bitmap_nr] = block_group;
-+      EXT3_SB(sb)->s_block_bitmap[bitmap_nr] = bh;
-       return retval;
- }
-@@ -128,16 +128,17 @@ static int __load_block_bitmap (struct s
-       int i, j, retval = 0;
-       unsigned long block_bitmap_number;
-       struct buffer_head * block_bitmap;
-+      struct ext3_sb_info *sbi = EXT3_SB(sb);
--      if (block_group >= sb->u.ext3_sb.s_groups_count)
-+      if (block_group >= sbi->s_groups_count)
-               ext3_panic (sb, "load_block_bitmap",
-                           "block_group >= groups_count - "
-                           "block_group = %d, groups_count = %lu",
--                          block_group, sb->u.ext3_sb.s_groups_count);
-+                          block_group, EXT3_SB(sb)->s_groups_count);
--      if (sb->u.ext3_sb.s_groups_count <= EXT3_MAX_GROUP_LOADED) {
--              if (sb->u.ext3_sb.s_block_bitmap[block_group]) {
--                      if (sb->u.ext3_sb.s_block_bitmap_number[block_group] ==
-+      if (sbi->s_groups_count <= EXT3_MAX_GROUP_LOADED) {
-+              if (sbi->s_block_bitmap[block_group]) {
-+                      if (sbi->s_block_bitmap_number[block_group] ==
-                           block_group)
-                               return block_group;
-                       ext3_error (sb, "__load_block_bitmap",
-@@ -149,21 +150,20 @@ static int __load_block_bitmap (struct s
-               return block_group;
-       }
--      for (i = 0; i < sb->u.ext3_sb.s_loaded_block_bitmaps &&
--                  sb->u.ext3_sb.s_block_bitmap_number[i] != block_group; i++)
-+      for (i = 0; i < sbi->s_loaded_block_bitmaps &&
-+                  sbi->s_block_bitmap_number[i] != block_group; i++)
-               ;
--      if (i < sb->u.ext3_sb.s_loaded_block_bitmaps &&
--          sb->u.ext3_sb.s_block_bitmap_number[i] == block_group) {
--              block_bitmap_number = sb->u.ext3_sb.s_block_bitmap_number[i];
--              block_bitmap = sb->u.ext3_sb.s_block_bitmap[i];
-+      if (i < sbi->s_loaded_block_bitmaps &&
-+          sbi->s_block_bitmap_number[i] == block_group) {
-+              block_bitmap_number = sbi->s_block_bitmap_number[i];
-+              block_bitmap = sbi->s_block_bitmap[i];
-               for (j = i; j > 0; j--) {
--                      sb->u.ext3_sb.s_block_bitmap_number[j] =
--                              sb->u.ext3_sb.s_block_bitmap_number[j - 1];
--                      sb->u.ext3_sb.s_block_bitmap[j] =
--                              sb->u.ext3_sb.s_block_bitmap[j - 1];
-+                      sbi->s_block_bitmap_number[j] =
-+                              sbi->s_block_bitmap_number[j - 1];
-+                      sbi->s_block_bitmap[j] = sbi->s_block_bitmap[j - 1];
-               }
--              sb->u.ext3_sb.s_block_bitmap_number[0] = block_bitmap_number;
--              sb->u.ext3_sb.s_block_bitmap[0] = block_bitmap;
-+              sbi->s_block_bitmap_number[0] = block_bitmap_number;
-+              sbi->s_block_bitmap[0] = block_bitmap;
-               /*
-                * There's still one special case here --- if block_bitmap == 0
-@@ -173,17 +173,14 @@ static int __load_block_bitmap (struct s
-               if (!block_bitmap)
-                       retval = read_block_bitmap (sb, block_group, 0);
-       } else {
--              if (sb->u.ext3_sb.s_loaded_block_bitmaps<EXT3_MAX_GROUP_LOADED)
--                      sb->u.ext3_sb.s_loaded_block_bitmaps++;
-+              if (sbi->s_loaded_block_bitmaps<EXT3_MAX_GROUP_LOADED)
-+                      sbi->s_loaded_block_bitmaps++;
-               else
--                      brelse (sb->u.ext3_sb.s_block_bitmap
--                                      [EXT3_MAX_GROUP_LOADED - 1]);
--              for (j = sb->u.ext3_sb.s_loaded_block_bitmaps - 1;
--                                      j > 0;  j--) {
--                      sb->u.ext3_sb.s_block_bitmap_number[j] =
--                              sb->u.ext3_sb.s_block_bitmap_number[j - 1];
--                      sb->u.ext3_sb.s_block_bitmap[j] =
--                              sb->u.ext3_sb.s_block_bitmap[j - 1];
-+                      brelse(sbi->s_block_bitmap[EXT3_MAX_GROUP_LOADED - 1]);
-+              for (j = sbi->s_loaded_block_bitmaps - 1; j > 0;  j--) {
-+                      sbi->s_block_bitmap_number[j] =
-+                              sbi->s_block_bitmap_number[j - 1];
-+                      sbi->s_block_bitmap[j] = sbi->s_block_bitmap[j - 1];
-               }
-               retval = read_block_bitmap (sb, block_group, 0);
-       }
-@@ -206,24 +203,25 @@ static int __load_block_bitmap (struct s
- static inline int load_block_bitmap (struct super_block * sb,
-                                    unsigned int block_group)
- {
-+      struct ext3_sb_info *sbi = EXT3_SB(sb);
-       int slot;
--      
-+
-       /*
-        * Do the lookup for the slot.  First of all, check if we're asking
-        * for the same slot as last time, and did we succeed that last time?
-        */
--      if (sb->u.ext3_sb.s_loaded_block_bitmaps > 0 &&
--          sb->u.ext3_sb.s_block_bitmap_number[0] == block_group &&
--          sb->u.ext3_sb.s_block_bitmap[0]) {
-+      if (sbi->s_loaded_block_bitmaps > 0 &&
-+          sbi->s_block_bitmap_number[0] == block_group &&
-+          sbi->s_block_bitmap[0]) {
-               return 0;
-       }
-       /*
-        * Or can we do a fast lookup based on a loaded group on a filesystem
-        * small enough to be mapped directly into the superblock?
-        */
--      else if (sb->u.ext3_sb.s_groups_count <= EXT3_MAX_GROUP_LOADED && 
--               sb->u.ext3_sb.s_block_bitmap_number[block_group]==block_group
--                      && sb->u.ext3_sb.s_block_bitmap[block_group]) {
-+      else if (sbi->s_groups_count <= EXT3_MAX_GROUP_LOADED &&
-+               sbi->s_block_bitmap_number[block_group] == block_group
-+                      && sbi->s_block_bitmap[block_group]) {
-               slot = block_group;
-       }
-       /*
-@@ -243,7 +241,7 @@ static inline int load_block_bitmap (str
-        * If it's a valid slot, we may still have cached a previous IO error,
-        * in which case the bh in the superblock cache will be zero.
-        */
--      if (!sb->u.ext3_sb.s_block_bitmap[slot])
-+      if (!sbi->s_block_bitmap[slot])
-               return -EIO;
-       
-       /*
-@@ -275,7 +273,7 @@ void ext3_free_blocks (handle_t *handle,
-               return;
-       }
-       lock_super (sb);
--      es = sb->u.ext3_sb.s_es;
-+      es = EXT3_SB(sb)->s_es;
-       if (block < le32_to_cpu(es->s_first_data_block) ||
-           block + count < block ||
-           (block + count) > le32_to_cpu(es->s_blocks_count)) {
-@@ -304,7 +302,7 @@ do_more:
-       if (bitmap_nr < 0)
-               goto error_return;
-       
--      bitmap_bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr];
-+      bitmap_bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr];
-       gdp = ext3_get_group_desc (sb, block_group, &gd_bh);
-       if (!gdp)
-               goto error_return;
-@@ -330,8 +328,8 @@ do_more:
-       if (err)
-               goto error_return;
--      BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access");
--      err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh);
-+      BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-       if (err)
-               goto error_return;
-@@ -341,7 +339,7 @@
-               if (block == le32_to_cpu(gdp->bg_block_bitmap) ||
-                   block == le32_to_cpu(gdp->bg_inode_bitmap) ||
-                   in_range(block, le32_to_cpu(gdp->bg_inode_table),
--                           sb->u.ext2_sb.s_itb_per_group)) {
-+                           EXT3_SB(sb)->s_itb_per_group)) {
-                       ext3_error(sb, __FUNCTION__,
-                                  "Freeing block in system zone - block = %lu",
-                                  block);
-@@ -410,8 +407,8 @@ do_more:
-       if (!err) err = ret;
-       /* And the superblock */
--      BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "dirtied superblock");
--      ret = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh);
-+      BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "dirtied superblock");
-+      ret = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-       if (!err) err = ret;
-       if (overflow && !err) {
-@@ -564,12 +560,12 @@ int ext3_new_block (handle_t *handle, st
-       }
-       lock_super (sb);
--      es = sb->u.ext3_sb.s_es;
-+      es = EXT3_SB(sb)->s_es;
-       if (le32_to_cpu(es->s_free_blocks_count) <=
-                       le32_to_cpu(es->s_r_blocks_count) &&
--          ((sb->u.ext3_sb.s_resuid != current->fsuid) &&
--           (sb->u.ext3_sb.s_resgid == 0 ||
--            !in_group_p (sb->u.ext3_sb.s_resgid)) && 
-+          ((EXT3_SB(sb)->s_resuid != current->fsuid) &&
-+           (EXT3_SB(sb)->s_resgid == 0 ||
-+            !in_group_p (EXT3_SB(sb)->s_resgid)) &&
-            !capable(CAP_SYS_RESOURCE)))
-               goto out;
-@@ -598,7 +595,7 @@ int ext3_new_block (handle_t *handle, st
-               if (bitmap_nr < 0)
-                       goto io_error;
-               
--              bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr];
-+              bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr];
-               ext3_debug ("goal is at %d:%d.\n", i, j);
-@@ -621,9 +618,9 @@ int ext3_new_block (handle_t *handle, st
-        * Now search the rest of the groups.  We assume that 
-        * i and gdp correctly point to the last group visited.
-        */
--      for (k = 0; k < sb->u.ext3_sb.s_groups_count; k++) {
-+      for (k = 0; k < EXT3_SB(sb)->s_groups_count; k++) {
-               i++;
--              if (i >= sb->u.ext3_sb.s_groups_count)
-+              if (i >= EXT3_SB(sb)->s_groups_count)
-                       i = 0;
-               gdp = ext3_get_group_desc (sb, i, &bh2);
-               if (!gdp) {
-@@ -635,7 +632,7 @@ int ext3_new_block (handle_t *handle, st
-                       if (bitmap_nr < 0)
-                               goto io_error;
-       
--                      bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr];
-+                      bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr];
-                       j = find_next_usable_block(-1, bh, 
-                                                  EXT3_BLOCKS_PER_GROUP(sb));
-                       if (j >= 0) 
-@@ -674,8 +671,8 @@ got_block:
-       fatal = ext3_journal_get_write_access(handle, bh2);
-       if (fatal) goto out;
--      BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access");
--      fatal = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh);
-+      BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access");
-+      fatal = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-       if (fatal) goto out;
-       tmp = j + i * EXT3_BLOCKS_PER_GROUP(sb)
-@@ -796,7 +804,7 @@ got_block:
-       if (!fatal) fatal = err;
-       
-       BUFFER_TRACE(bh, "journal_dirty_metadata for superblock");
--      err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh);
-+      err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-       if (!fatal) fatal = err;
-       sb->s_dirt = 1;
-@@ -829,11 +837,11 @@ unsigned long ext3_count_free_blocks (st
-       int i;
-       
-       lock_super (sb);
--      es = sb->u.ext3_sb.s_es;
-+      es = EXT3_SB(sb)->s_es;
-       desc_count = 0;
-       bitmap_count = 0;
-       gdp = NULL;
--      for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) {
-+      for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
-               gdp = ext3_get_group_desc (sb, i, NULL);
-               if (!gdp)
-                       continue;
-@@ -842,7 +850,7 @@ unsigned long ext3_count_free_blocks (st
-               if (bitmap_nr < 0)
-                       continue;
-               
--              x = ext3_count_free (sb->u.ext3_sb.s_block_bitmap[bitmap_nr],
-+              x = ext3_count_free (EXT3_SB(sb)->s_block_bitmap[bitmap_nr],
-                                    sb->s_blocksize);
-               printk ("group %d: stored = %d, counted = %lu\n",
-                       i, le16_to_cpu(gdp->bg_free_blocks_count), x);
-@@ -853,7 +861,7 @@ unsigned long ext3_count_free_blocks (st
-       unlock_super (sb);
-       return bitmap_count;
- #else
--      return le32_to_cpu(sb->u.ext3_sb.s_es->s_free_blocks_count);
-+      return le32_to_cpu(EXT3_SB(sb)->s_es->s_free_blocks_count);
- #endif
- }
-@@ -862,7 +870,7 @@ static inline int block_in_use (unsigned
-                               unsigned char * map)
- {
-       return ext3_test_bit ((block -
--              le32_to_cpu(sb->u.ext3_sb.s_es->s_first_data_block)) %
-+              le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) %
-                        EXT3_BLOCKS_PER_GROUP(sb), map);
- }
-@@ -930,11 +938,11 @@ void ext3_check_blocks_bitmap (struct su
-       struct ext3_group_desc * gdp;
-       int i;
--      es = sb->u.ext3_sb.s_es;
-+      es = EXT3_SB(sb)->s_es;
-       desc_count = 0;
-       bitmap_count = 0;
-       gdp = NULL;
--      for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) {
-+      for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
-               gdp = ext3_get_group_desc (sb, i, NULL);
-               if (!gdp)
-                       continue;
-@@ -968,7 +976,7 @@ void ext3_check_blocks_bitmap (struct su
-                                   "Inode bitmap for group %d is marked free",
-                                   i);
--              for (j = 0; j < sb->u.ext3_sb.s_itb_per_group; j++)
-+              for (j = 0; j < EXT3_SB(sb)->s_itb_per_group; j++)
-                       if (!block_in_use (le32_to_cpu(gdp->bg_inode_table) + j,
-                                                       sb, bh->b_data))
-                               ext3_error (sb, "ext3_check_blocks_bitmap",
---- ./fs/ext3/dir.c.orig       Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/dir.c    Tue May  7 14:54:13 2002
-@@ -52,7 +52,7 @@ int ext3_check_dir_entry (const char * f
-       else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
-               error_msg = "directory entry across blocks";
-       else if (le32_to_cpu(de->inode) >
--                      le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count))
-+                      le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))
-               error_msg = "inode out of bounds";
-       if (error_msg != NULL)
---- ./fs/ext3/ialloc.c.orig    Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/ialloc.c Tue May  7 15:39:26 2002
-@@ -73,8 +73,8 @@ static int read_inode_bitmap (struct sup
-        * this group.  The IO will be retried next time.
-        */
- error_out:
--      sb->u.ext3_sb.s_inode_bitmap_number[bitmap_nr] = block_group;
--      sb->u.ext3_sb.s_inode_bitmap[bitmap_nr] = bh;
-+      EXT3_SB(sb)->s_inode_bitmap_number[bitmap_nr] = block_group;
-+      EXT3_SB(sb)->s_inode_bitmap[bitmap_nr] = bh;
-       return retval;
- }
-@@ -225,7 +225,7 @@ void ext3_free_inode (handle_t *handle, 
-       clear_inode (inode);
-       lock_super (sb);
--      es = sb->u.ext3_sb.s_es;
-+      es = EXT3_SB(sb)->s_es;
-       if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
-               ext3_error (sb, "ext3_free_inode",
-                           "reserved or nonexistent inode %lu", ino);
-@@ -237,7 +237,7 @@ void ext3_free_inode (handle_t *handle, 
-       if (bitmap_nr < 0)
-               goto error_return;
--      bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
-+      bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
-       BUFFER_TRACE(bh, "get_write_access");
-       fatal = ext3_journal_get_write_access(handle, bh);
-@@ -255,8 +255,8 @@ void ext3_free_inode (handle_t *handle, 
-               fatal = ext3_journal_get_write_access(handle, bh2);
-               if (fatal) goto error_return;
--              BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get write access");
--              fatal = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh);
-+              BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get write access");
-+              fatal = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-               if (fatal) goto error_return;
-               if (gdp) {
-@@ -271,9 +271,9 @@ void ext3_free_inode (handle_t *handle, 
-               if (!fatal) fatal = err;
-               es->s_free_inodes_count =
-                       cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) + 1);
--              BUFFER_TRACE(sb->u.ext3_sb.s_sbh,
-+              BUFFER_TRACE(EXT3_SB(sb)->s_sbh,
-                                       "call ext3_journal_dirty_metadata");
--              err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh);
-+              err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-               if (!fatal) fatal = err;
-       }
-       BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
-@@ -305,6 +305,8 @@ struct inode * ext3_new_inode (handle_t 
-       int i, j, avefreei;
-       struct inode * inode;
-       int bitmap_nr;
-+      struct ext3_inode_info *ei;
-+      struct ext3_sb_info *sbi;
-       struct ext3_group_desc * gdp;
-       struct ext3_group_desc * tmp;
-       struct ext3_super_block * es;
-@@ -318,7 +320,9 @@ struct inode * ext3_new_inode (handle_t 
-       inode = new_inode(sb);
-       if (!inode)
-               return ERR_PTR(-ENOMEM);
--      init_rwsem(&inode->u.ext3_i.truncate_sem);
-+      sbi = EXT3_SB(sb);
-+      ei = EXT3_I(inode);
-+      init_rwsem(&ei->truncate_sem);
-       lock_super (sb);
-       es = sb->u.ext3_sb.s_es;
-@@ -328,9 +332,9 @@ struct inode * ext3_new_inode (handle_t 
-       if (S_ISDIR(mode)) {
-               avefreei = le32_to_cpu(es->s_free_inodes_count) /
--                      sb->u.ext3_sb.s_groups_count;
-+                      sbi->s_groups_count;
-               if (!gdp) {
--                      for (j = 0; j < sb->u.ext3_sb.s_groups_count; j++) {
-+                      for (j = 0; j < sbi->s_groups_count; j++) {
-                               struct buffer_head *temp_buffer;
-                               tmp = ext3_get_group_desc (sb, j, &temp_buffer);
-                               if (tmp &&
-@@ -350,7 +354,7 @@ repeat:
-               /*
-                * Try to place the inode in its parent directory
-                */
--              i = dir->u.ext3_i.i_block_group;
-+              i = EXT3_I(dir)->i_block_group;
-               tmp = ext3_get_group_desc (sb, i, &bh2);
-               if (tmp && le16_to_cpu(tmp->bg_free_inodes_count))
-                       gdp = tmp;
-@@ -360,10 +364,10 @@ repeat:
-                        * Use a quadratic hash to find a group with a
-                        * free inode
-                        */
--                      for (j = 1; j < sb->u.ext3_sb.s_groups_count; j <<= 1) {
-+                      for (j = 1; j < sbi->s_groups_count; j <<= 1) {
-                               i += j;
--                              if (i >= sb->u.ext3_sb.s_groups_count)
--                                      i -= sb->u.ext3_sb.s_groups_count;
-+                              if (i >= sbi->s_groups_count)
-+                                      i -= sbi->s_groups_count;
-                               tmp = ext3_get_group_desc (sb, i, &bh2);
-                               if (tmp &&
-                                   le16_to_cpu(tmp->bg_free_inodes_count)) {
-@@ -376,9 +380,9 @@ repeat:
-                       /*
-                        * That failed: try linear search for a free inode
-                        */
--                      i = dir->u.ext3_i.i_block_group + 1;
--                      for (j = 2; j < sb->u.ext3_sb.s_groups_count; j++) {
--                              if (++i >= sb->u.ext3_sb.s_groups_count)
-+                      i = EXT3_I(dir)->i_block_group + 1;
-+                      for (j = 2; j < sbi->s_groups_count; j++) {
-+                              if (++i >= sbi->s_groups_count)
-                                       i = 0;
-                               tmp = ext3_get_group_desc (sb, i, &bh2);
-                               if (tmp &&
-@@ -399,11 +403,11 @@ repeat:
-       if (bitmap_nr < 0)
-               goto fail;
--      bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
-+      bh = sbi->s_inode_bitmap[bitmap_nr];
-       if ((j = ext3_find_first_zero_bit ((unsigned long *) bh->b_data,
--                                    EXT3_INODES_PER_GROUP(sb))) <
--          EXT3_INODES_PER_GROUP(sb)) {
-+                                    sbi->s_inodes_per_group)) <
-+          sbi->s_inodes_per_group) {
-               BUFFER_TRACE(bh, "get_write_access");
-               err = ext3_journal_get_write_access(handle, bh);
-               if (err) goto fail;
-@@ -457,13 +461,13 @@ repeat:
-       err = ext3_journal_dirty_metadata(handle, bh2);
-       if (err) goto fail;
-       
--      BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access");
--      err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh);
-+      BUFFER_TRACE(sbi->s_sbh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, sbi->s_sbh);
-       if (err) goto fail;
-       es->s_free_inodes_count =
-               cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1);
--      BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "call ext3_journal_dirty_metadata");
--      err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh);
-+      BUFFER_TRACE(sbi->s_sbh, "call ext3_journal_dirty_metadata");
-+      err = ext3_journal_dirty_metadata(handle, sbi->s_sbh);
-       sb->s_dirt = 1;
-       if (err) goto fail;
-@@ -483,31 +487,31 @@ repeat:
-       inode->i_blksize = PAGE_SIZE;
-       inode->i_blocks = 0;
-       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
--      inode->u.ext3_i.i_flags = dir->u.ext3_i.i_flags & ~EXT3_INDEX_FL;
-+      ei->i_flags = EXT3_I(dir)->i_flags & ~EXT3_INDEX_FL;
-       if (S_ISLNK(mode))
--              inode->u.ext3_i.i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
-+              ei->i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
- #ifdef EXT3_FRAGMENTS
--      inode->u.ext3_i.i_faddr = 0;
--      inode->u.ext3_i.i_frag_no = 0;
--      inode->u.ext3_i.i_frag_size = 0;
-+      ei->i_faddr = 0;
-+      ei->i_frag_no = 0;
-+      ei->i_frag_size = 0;
- #endif
--      inode->u.ext3_i.i_file_acl = 0;
--      inode->u.ext3_i.i_dir_acl = 0;
--      inode->u.ext3_i.i_dtime = 0;
--      INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
-+      ei->i_file_acl = 0;
-+      ei->i_dir_acl = 0;
-+      ei->i_dtime = 0;
-+      INIT_LIST_HEAD(&ei->i_orphan);
- #ifdef EXT3_PREALLOCATE
--      inode->u.ext3_i.i_prealloc_count = 0;
-+      ei->i_prealloc_count = 0;
- #endif
--      inode->u.ext3_i.i_block_group = i;
-+      ei->i_block_group = i;
-       
--      if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL)
-+      if (ei->i_flags & EXT3_SYNC_FL)
-               inode->i_flags |= S_SYNC;
-       if (IS_SYNC(inode))
-               handle->h_sync = 1;
-       insert_inode_hash(inode);
--      inode->i_generation = sb->u.ext3_sb.s_next_generation++;
-+      inode->i_generation = sbi->s_next_generation++;
--      inode->u.ext3_i.i_state = EXT3_STATE_NEW;
-+      ei->i_state = EXT3_STATE_NEW;
-       err = ext3_mark_inode_dirty(handle, inode);
-       if (err) goto fail;
-       
-@@ -585,19 +589,19 @@ struct inode *ext3_orphan_get (struct su
- unsigned long ext3_count_free_inodes (struct super_block * sb)
- {
-+      struct ext3_sb_info *sbi = EXT3_SB(sb);
-+      struct ext3_super_block *es = sbi->s_es;
- #ifdef EXT3FS_DEBUG
--      struct ext3_super_block * es;
-       unsigned long desc_count, bitmap_count, x;
-       int bitmap_nr;
-       struct ext3_group_desc * gdp;
-       int i;
-       lock_super (sb);
--      es = sb->u.ext3_sb.s_es;
-       desc_count = 0;
-       bitmap_count = 0;
-       gdp = NULL;
--      for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) {
-+      for (i = 0; i < sbi->s_groups_count; i++) {
-               gdp = ext3_get_group_desc (sb, i, NULL);
-               if (!gdp)
-                       continue;
-@@ -606,8 +610,8 @@ unsigned long ext3_count_free_inodes (st
-               if (bitmap_nr < 0)
-                       continue;
--              x = ext3_count_free (sb->u.ext3_sb.s_inode_bitmap[bitmap_nr],
--                                   EXT3_INODES_PER_GROUP(sb) / 8);
-+              x = ext3_count_free(sbi->s_inode_bitmap[bitmap_nr],
-+                                  sbi->s_inodes_per_group / 8);
-               printk ("group %d: stored = %d, counted = %lu\n",
-                       i, le16_to_cpu(gdp->bg_free_inodes_count), x);
-               bitmap_count += x;
-@@ -617,7 +621,7 @@ unsigned long ext3_count_free_inodes (st
-       unlock_super (sb);
-       return desc_count;
- #else
--      return le32_to_cpu(sb->u.ext3_sb.s_es->s_free_inodes_count);
-+      return le32_to_cpu(es->s_free_inodes_count);
- #endif
- }
-@@ -626,16 +630,18 @@ unsigned long ext3_count_free_inodes (st
- void ext3_check_inodes_bitmap (struct super_block * sb)
- {
-       struct ext3_super_block * es;
-+      struct ext3_sb_info *sbi;
-       unsigned long desc_count, bitmap_count, x;
-       int bitmap_nr;
-       struct ext3_group_desc * gdp;
-       int i;
--      es = sb->u.ext3_sb.s_es;
-+      sbi = EXT3_SB(sb);
-+      es = sbi->s_es;
-       desc_count = 0;
-       bitmap_count = 0;
-       gdp = NULL;
--      for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) {
-+      for (i = 0; i < sbi->s_groups_count; i++) {
-               gdp = ext3_get_group_desc (sb, i, NULL);
-               if (!gdp)
-                       continue;
-@@ -644,7 +650,7 @@ void ext3_check_inodes_bitmap (struct su
-               if (bitmap_nr < 0)
-                       continue;
--              x = ext3_count_free (sb->u.ext3_sb.s_inode_bitmap[bitmap_nr],
-+              x = ext3_count_free (sbi->s_inode_bitmap[bitmap_nr],
-                                    EXT3_INODES_PER_GROUP(sb) / 8);
-               if (le16_to_cpu(gdp->bg_free_inodes_count) != x)
-                       ext3_error (sb, "ext3_check_inodes_bitmap",
---- ./fs/ext3/inode.c.orig     Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/inode.c  Tue May  7 15:41:23 2002
-@@ -196,7 +196,7 @@ void ext3_delete_inode (struct inode * i
-        * (Well, we could do this if we need to, but heck - it works)
-        */
-       ext3_orphan_del(handle, inode);
--      inode->u.ext3_i.i_dtime = CURRENT_TIME;
-+      EXT3_I(inode)->i_dtime = CURRENT_TIME;
-       /* 
-        * One subtle ordering requirement: if anything has gone wrong
-@@ -220,13 +220,14 @@ no_delete:
- void ext3_discard_prealloc (struct inode * inode)
- {
- #ifdef EXT3_PREALLOCATE
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-       lock_kernel();
-       /* Writer: ->i_prealloc* */
--      if (inode->u.ext3_i.i_prealloc_count) {
--              unsigned short total = inode->u.ext3_i.i_prealloc_count;
--              unsigned long block = inode->u.ext3_i.i_prealloc_block;
--              inode->u.ext3_i.i_prealloc_count = 0;
--              inode->u.ext3_i.i_prealloc_block = 0;
-+      if (ei->i_prealloc_count) {
-+              unsigned short total = ei->i_prealloc_count;
-+              unsigned long block = ei->i_prealloc_block;
-+              ei->i_prealloc_count = 0;
-+              ei->i_prealloc_block = 0;
-               /* Writer: end */
-               ext3_free_blocks (inode, block, total);
-       }
-@@ -243,13 +244,15 @@ static int ext3_alloc_block (handle_t *h
-       unsigned long result;
- #ifdef EXT3_PREALLOCATE
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-+
-       /* Writer: ->i_prealloc* */
--      if (inode->u.ext3_i.i_prealloc_count &&
--          (goal == inode->u.ext3_i.i_prealloc_block ||
--           goal + 1 == inode->u.ext3_i.i_prealloc_block))
-+      if (ei->i_prealloc_count &&
-+          (goal == ei->i_prealloc_block ||
-+           goal + 1 == ei->i_prealloc_block))
-       {
--              result = inode->u.ext3_i.i_prealloc_block++;
--              inode->u.ext3_i.i_prealloc_count--;
-+              result = ei->i_prealloc_block++;
-+              ei->i_prealloc_count--;
-               /* Writer: end */
-               ext3_debug ("preallocation hit (%lu/%lu).\n",
-                           ++alloc_hits, ++alloc_attempts);
-@@ -259,8 +262,8 @@ static int ext3_alloc_block (handle_t *h
-                           alloc_hits, ++alloc_attempts);
-               if (S_ISREG(inode->i_mode))
-                       result = ext3_new_block (inode, goal, 
--                               &inode->u.ext3_i.i_prealloc_count,
--                               &inode->u.ext3_i.i_prealloc_block, err);
-+                               &ei->i_prealloc_count,
-+                               &ei->i_prealloc_block, err);
-               else
-                       result = ext3_new_block (inode, goal, 0, 0, err);
-               /*
-@@ -394,7 +397,7 @@ static Indirect *ext3_get_branch(struct 
-       *err = 0;
-       /* i_data is not going away, no lock needed */
--      add_chain (chain, NULL, inode->u.ext3_i.i_data + *offsets);
-+      add_chain (chain, NULL, EXT3_I(inode)->i_data + *offsets);
-       if (!p->key)
-               goto no_block;
-       while (--depth) {
-@@ -437,7 +440,8 @@ no_block:
- static inline unsigned long ext3_find_near(struct inode *inode, Indirect *ind)
- {
--      u32 *start = ind->bh ? (u32*) ind->bh->b_data : inode->u.ext3_i.i_data;
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-+      u32 *start = ind->bh ? (u32*) ind->bh->b_data : ei->i_data;
-       u32 *p;
-       /* Try to find previous block */
-@@ -453,9 +456,8 @@ static inline unsigned long ext3_find_ne
-        * It is going to be refered from inode itself? OK, just put it into
-        * the same cylinder group then.
-        */
--      return (inode->u.ext3_i.i_block_group * 
--              EXT3_BLOCKS_PER_GROUP(inode->i_sb)) +
--             le32_to_cpu(inode->i_sb->u.ext3_sb.s_es->s_first_data_block);
-+      return (ei->i_block_group * EXT3_BLOCKS_PER_GROUP(inode->i_sb)) +
-+             le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block);
- }
- /**
-@@ -474,14 +477,15 @@
- static int ext3_find_goal(struct inode *inode, long block, Indirect chain[4],
-                         Indirect *partial, unsigned long *goal)
- {
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-       /* Writer: ->i_next_alloc* */
--      if (block == inode->u.ext3_i.i_next_alloc_block + 1) {
--              inode->u.ext3_i.i_next_alloc_block++;
--              inode->u.ext3_i.i_next_alloc_goal++;
-+      if (block == ei->i_next_alloc_block + 1) {
-+              ei->i_next_alloc_block++;
-+              ei->i_next_alloc_goal++;
-       }
- #ifdef SEARCH_FROM_ZERO
--      inode->u.ext3_i.i_next_alloc_block = 0;
--      inode->u.ext3_i.i_next_alloc_goal = 0;
-+      ei->i_next_alloc_block = 0;
-+      ei->i_next_alloc_goal = 0;
- #endif
-       /* Writer: end */
-       /* Reader: pointers, ->i_next_alloc* */
-@@ -490,8 +493,8 @@ static int ext3_find_goal(struct inode *
-                * try the heuristic for sequential allocation,
-                * failing that at least try to get decent locality.
-                */
--              if (block == inode->u.ext3_i.i_next_alloc_block)
--                      *goal = inode->u.ext3_i.i_next_alloc_goal;
-+              if (block == ei->i_next_alloc_block)
-+                      *goal = ei->i_next_alloc_goal;
-               if (!*goal)
-                       *goal = ext3_find_near(inode, partial);
- #ifdef SEARCH_FROM_ZERO
-@@ -619,6 +621,7 @@
- {
-       int i;
-       int err = 0;
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-       /*
-        * If we're splicing into a [td]indirect block (as opposed to the
-@@ -641,11 +644,11 @@ static int ext3_splice_branch(handle_t *
-       /* That's it */
-       *where->p = where->key;
--      inode->u.ext3_i.i_next_alloc_block = block;
--      inode->u.ext3_i.i_next_alloc_goal = le32_to_cpu(where[num-1].key);
-+      ei->i_next_alloc_block = block;
-+      ei->i_next_alloc_goal = le32_to_cpu(where[num-1].key);
- #ifdef SEARCH_FROM_ZERO
--      inode->u.ext3_i.i_next_alloc_block = 0;
--      inode->u.ext3_i.i_next_alloc_goal = 0;
-+      ei->i_next_alloc_block = 0;
-+      ei->i_next_alloc_goal = 0;
- #endif
-       /* Writer: end */
-@@ -729,6 +732,7 @@
-       unsigned long goal;
-       int left;
-       int depth = ext3_block_to_path(inode, iblock, offsets);
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-       loff_t new_size;
-       J_ASSERT(handle != NULL || create == 0);
-@@ -782,7 +785,7 @@ out:
-       /*
-        * Block out ext3_truncate while we alter the tree
-        */
--      down_read(&inode->u.ext3_i.truncate_sem);
-+      down_read(&ei->truncate_sem);
-       err = ext3_alloc_branch(handle, inode, left, goal,
-                                       offsets+(partial-chain), partial);
-@@ -794,7 +797,7 @@ out:
-       if (!err)
-               err = ext3_splice_branch(handle, inode, iblock, chain,
-                                        partial, left);
--      up_read(&inode->u.ext3_i.truncate_sem);
-+      up_read(&ei->truncate_sem);
-       if (err == -EAGAIN)
-               goto changed;
-       if (err)
-@@ -807,8 +810,8 @@ out:
-        * truncate is in progress.  It is racy between multiple parallel
-        * instances of get_block, but we have the BKL.
-        */
--      if (new_size > inode->u.ext3_i.i_disksize)
--              inode->u.ext3_i.i_disksize = new_size;
-+      if (new_size > ei->i_disksize)
-+              ei->i_disksize = new_size;
-       bh_result->b_state |= (1UL << BH_New);
-       goto got_it;
-@@ -921,7 +924,7 @@ struct buffer_head *ext3_bread(handle_t 
-               struct buffer_head *tmp_bh;
-               for (i = 1;
--                   inode->u.ext3_i.i_prealloc_count &&
-+                   EXT3_I(inode)->i_prealloc_count &&
-                    i < EXT3_SB(inode->i_sb)->s_es->s_prealloc_dir_blocks;
-                    i++) {
-                       /*
-@@ -1131,8 +1134,8 @@ static int ext3_commit_write(struct file
-                       kunmap(page);
-               }
-       }
--      if (inode->i_size > inode->u.ext3_i.i_disksize) {
--              inode->u.ext3_i.i_disksize = inode->i_size;
-+      if (inode->i_size > EXT3_I(inode)->i_disksize) {
-+              EXT3_I(inode)->i_disksize = inode->i_size;
-               ret2 = ext3_mark_inode_dirty(handle, inode);
-               if (!ret) 
-                       ret = ret2;
-@@ -1832,7 +1835,8 @@ static void ext3_free_branches(handle_t 
- void ext3_truncate(struct inode * inode)
- {
-       handle_t *handle;
--      u32 *i_data = inode->u.ext3_i.i_data;
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-+      u32 *i_data = EXT3_I(inode)->i_data;
-       int addr_per_block = EXT3_ADDR_PER_BLOCK(inode->i_sb);
-       int offsets[4];
-       Indirect chain[4];
-@@ -1884,13 +1887,13 @@ void ext3_truncate(struct inode * inode)
-        * on-disk inode. We do this via i_disksize, which is the value which
-        * ext3 *really* writes onto the disk inode.
-        */
--      inode->u.ext3_i.i_disksize = inode->i_size;
-+      ei->i_disksize = inode->i_size;
-       /*
-        * From here we block out all ext3_get_block() callers who want to
-        * modify the block allocation tree.
-        */
--      down_write(&inode->u.ext3_i.truncate_sem);
-+      down_write(&ei->truncate_sem);
-       if (n == 1) {           /* direct blocks */
-               ext3_free_data(handle, inode, NULL, i_data+offsets[0],
-@@ -1954,7 +1957,7 @@ do_indirects:
-               case EXT3_TIND_BLOCK:
-                       ;
-       }
--      up_write(&inode->u.ext3_i.truncate_sem);
-+      up_write(&ei->truncate_sem);
-       inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-       ext3_mark_inode_dirty(handle, inode);
-@@ -1983,6 +1986,8 @@ out_stop:
- int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
- {
-+      struct super_block *sb = inode->i_sb;
-+      struct ext3_sb_info *sbi = EXT3_SB(sb);
-       struct buffer_head *bh = 0;
-       unsigned long block;
-       unsigned long block_group;
-@@ -1997,23 +2010,19 @@ int ext3_get_inode_loc (struct inode *in
-               inode->i_ino != EXT3_JOURNAL_INO &&
--              inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
--              inode->i_ino > le32_to_cpu(
--                      inode->i_sb->u.ext3_sb.s_es->s_inodes_count)) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "bad inode number: %lu", inode->i_ino);
-+              inode->i_ino < EXT3_FIRST_INO(sb)) ||
-+              inode->i_ino > le32_to_cpu(sbi->s_es->s_inodes_count)) {
-+              ext3_error (sb, __FUNCTION__, "bad inode #%lu", inode->i_ino);
-               goto bad_inode;
-       }
--      block_group = (inode->i_ino - 1) / EXT3_INODES_PER_GROUP(inode->i_sb);
--      if (block_group >= inode->i_sb->u.ext3_sb.s_groups_count) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "group >= groups count");
-+      block_group = (inode->i_ino - 1) / sbi->s_inodes_per_group;
-+      if (block_group >= sbi->s_groups_count) {
-+              ext3_error(sb, __FUNCTION__, "group >= groups count");
-               goto bad_inode;
-       }
--      group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(inode->i_sb);
--      desc = block_group & (EXT3_DESC_PER_BLOCK(inode->i_sb) - 1);
--      bh = inode->i_sb->u.ext3_sb.s_group_desc[group_desc];
-+      group_desc = block_group >> sbi->s_desc_per_block_bits;
-+      desc = block_group & (sbi->s_desc_per_block - 1);
-+      bh = sbi->s_group_desc[group_desc];
-       if (!bh) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "Descriptor not loaded");
-+              ext3_error(sb, __FUNCTION__, "Descriptor not loaded");
-               goto bad_inode;
-       }
-@@ -2021,17 +2022,17 @@ int ext3_get_inode_loc (struct inode *in
-       /*
-        * Figure out the offset within the block group inode table
-        */
--      offset = ((inode->i_ino - 1) % EXT3_INODES_PER_GROUP(inode->i_sb)) *
--              EXT3_INODE_SIZE(inode->i_sb);
-+      offset = ((inode->i_ino - 1) % sbi->s_inodes_per_group) *
-+              sbi->s_inode_size;
-       block = le32_to_cpu(gdp[desc].bg_inode_table) +
--              (offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb));
--      if (!(bh = sb_bread(inode->i_sb, block))) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
-+              (offset >> EXT3_BLOCK_SIZE_BITS(sb));
-+      if (!(bh = sb_bread(sb, block))) {
-+              ext3_error (sb, __FUNCTION__,
-                           "unable to read inode block - "
-                           "inode=%lu, block=%lu", inode->i_ino, block);
-               goto bad_inode;
-       }
--      offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1);
-+      offset &= (EXT3_BLOCK_SIZE(sb) - 1);
-       iloc->bh = bh;
-       iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset);
-@@ -2047,6 +2048,7 @@ void ext3_read_inode(struct inode * inod
- {
-       struct ext3_iloc iloc;
-       struct ext3_inode *raw_inode;
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-       struct buffer_head *bh;
-       int block;
-       
-@@ -2054,7 +2056,7 @@ void ext3_read_inode(struct inode * inod
-               goto bad_inode;
-       bh = iloc.bh;
-       raw_inode = iloc.raw_inode;
--      init_rwsem(&inode->u.ext3_i.truncate_sem);
-+      init_rwsem(&ei->truncate_sem);
-       inode->i_mode = le16_to_cpu(raw_inode->i_mode);
-       inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
-       inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
-@@ -2067,7 +2069,7 @@ void ext3_read_inode(struct inode * inod
-       inode->i_atime = le32_to_cpu(raw_inode->i_atime);
-       inode->i_ctime = le32_to_cpu(raw_inode->i_ctime);
-       inode->i_mtime = le32_to_cpu(raw_inode->i_mtime);
--      inode->u.ext3_i.i_dtime = le32_to_cpu(raw_inode->i_dtime);
-+      ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
-       /* We now have enough fields to check if the inode was active or not.
-        * This is needed because nfsd might try to access dead inodes
-        * the test is that same one that e2fsck uses
-@@ -2075,7 +2077,7 @@ void ext3_read_inode(struct inode * inod
-        */
-       if (inode->i_nlink == 0) {
-               if (inode->i_mode == 0 ||
--                  !(inode->i_sb->u.ext3_sb.s_mount_state & EXT3_ORPHAN_FS)) {
-+                  !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ORPHAN_FS)) {
-                       /* this inode is deleted */
-                       brelse (bh);
-                       goto bad_inode;
-@@ -2090,33 +2092,33 @@ void ext3_read_inode(struct inode * inod
-                                        * size */  
-       inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
-       inode->i_version = ++event;
--      inode->u.ext3_i.i_flags = le32_to_cpu(raw_inode->i_flags);
-+      ei->i_flags = le32_to_cpu(raw_inode->i_flags);
- #ifdef EXT3_FRAGMENTS
--      inode->u.ext3_i.i_faddr = le32_to_cpu(raw_inode->i_faddr);
--      inode->u.ext3_i.i_frag_no = raw_inode->i_frag;
--      inode->u.ext3_i.i_frag_size = raw_inode->i_fsize;
-+      ei->i_faddr = le32_to_cpu(raw_inode->i_faddr);
-+      ei->i_frag_no = raw_inode->i_frag;
-+      ei->i_frag_size = raw_inode->i_fsize;
- #endif
--      inode->u.ext3_i.i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
-+      ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
-       if (!S_ISREG(inode->i_mode)) {
--              inode->u.ext3_i.i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);
-+              ei->i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);
-       } else {
-               inode->i_size |=
-                       ((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32;
-       }
--      inode->u.ext3_i.i_disksize = inode->i_size;
-+      ei->i_disksize = inode->i_size;
-       inode->i_generation = le32_to_cpu(raw_inode->i_generation);
- #ifdef EXT3_PREALLOCATE
--      inode->u.ext3_i.i_prealloc_count = 0;
-+      ei->i_prealloc_count = 0;
- #endif
--      inode->u.ext3_i.i_block_group = iloc.block_group;
-+      ei->i_block_group = iloc.block_group;
-       /*
-        * NOTE! The in-memory inode i_data array is in little-endian order
-        * even on big-endian machines: we do NOT byteswap the block numbers!
-        */
-       for (block = 0; block < EXT3_N_BLOCKS; block++)
--              inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block];
--      INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
-+              ei->i_data[block] = iloc.raw_inode->i_block[block];
-+      INIT_LIST_HEAD(&ei->i_orphan);
-       brelse (iloc.bh);
-@@ -2143,17 +2145,17 @@ void ext3_read_inode(struct inode * inod
-       /* inode->i_attr_flags = 0;                             unused */
--      if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) {
-+      if (ei->i_flags & EXT3_SYNC_FL) {
-               /* inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS; unused */
-               inode->i_flags |= S_SYNC;
-       }
--      if (inode->u.ext3_i.i_flags & EXT3_APPEND_FL) {
-+      if (ei->i_flags & EXT3_APPEND_FL) {
-               /* inode->i_attr_flags |= ATTR_FLAG_APPEND;     unused */
-               inode->i_flags |= S_APPEND;
-       }
--      if (inode->u.ext3_i.i_flags & EXT3_IMMUTABLE_FL) {
-+      if (ei->i_flags & EXT3_IMMUTABLE_FL) {
-               /* inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE;  unused */
-               inode->i_flags |= S_IMMUTABLE;
-       }
--      if (inode->u.ext3_i.i_flags & EXT3_NOATIME_FL) {
-+      if (ei->i_flags & EXT3_NOATIME_FL) {
-               /* inode->i_attr_flags |= ATTR_FLAG_NOATIME;    unused */
-               inode->i_flags |= S_NOATIME;
-       }
-@@ -2175,6 +2177,7 @@ static int ext3_do_update_inode(handle_t
-                               struct ext3_iloc *iloc)
- {
-       struct ext3_inode *raw_inode = iloc->raw_inode;
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-       struct buffer_head *bh = iloc->bh;
-       int err = 0, rc, block;
-@@ -2192,7 +2195,7 @@ static int ext3_do_update_inode(handle_t
-  * Fix up interoperability with old kernels. Otherwise, old inodes get
-  * re-used with the upper 16 bits of the uid/gid intact
-  */
--              if(!inode->u.ext3_i.i_dtime) {
-+              if(!ei->i_dtime) {
-                       raw_inode->i_uid_high =
-                               cpu_to_le16(high_16_bits(inode->i_uid));
-                       raw_inode->i_gid_high =
-@@ -2210,34 +2213,33 @@ static int ext3_do_update_inode(handle_t
-               raw_inode->i_gid_high = 0;
-       }
-       raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
--      raw_inode->i_size = cpu_to_le32(inode->u.ext3_i.i_disksize);
-+      raw_inode->i_size = cpu_to_le32(ei->i_disksize);
-       raw_inode->i_atime = cpu_to_le32(inode->i_atime);
-       raw_inode->i_ctime = cpu_to_le32(inode->i_ctime);
-       raw_inode->i_mtime = cpu_to_le32(inode->i_mtime);
-       raw_inode->i_blocks = cpu_to_le32(inode->i_blocks);
--      raw_inode->i_dtime = cpu_to_le32(inode->u.ext3_i.i_dtime);
--      raw_inode->i_flags = cpu_to_le32(inode->u.ext3_i.i_flags);
-+      raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
-+      raw_inode->i_flags = cpu_to_le32(ei->i_flags);
- #ifdef EXT3_FRAGMENTS
--      raw_inode->i_faddr = cpu_to_le32(inode->u.ext3_i.i_faddr);
--      raw_inode->i_frag = inode->u.ext3_i.i_frag_no;
--      raw_inode->i_fsize = inode->u.ext3_i.i_frag_size;
-+      raw_inode->i_faddr = cpu_to_le32(ei->i_faddr);
-+      raw_inode->i_frag = ei->i_frag_no;
-+      raw_inode->i_fsize = ei->i_frag_size;
- #else
-       /* If we are not tracking these fields in the in-memory inode,
-        * then preserve them on disk, but still initialise them to zero
-        * for new inodes. */
--      if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) {
-+      if (ei->i_state & EXT3_STATE_NEW) {
-               raw_inode->i_faddr = 0;
-               raw_inode->i_frag = 0;
-               raw_inode->i_fsize = 0;
-       }
- #endif
--      raw_inode->i_file_acl = cpu_to_le32(inode->u.ext3_i.i_file_acl);
-+      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(inode->u.ext3_i.i_dir_acl);
-+              raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl);
-       } else {
--              raw_inode->i_size_high =
--                      cpu_to_le32(inode->u.ext3_i.i_disksize >> 32);
--              if (inode->u.ext3_i.i_disksize > 0x7fffffffULL) {
-+              raw_inode->i_size_high = cpu_to_le32(ei->i_disksize >> 32);
-+              if (ei->i_disksize > MAX_NON_LFS) {
-                       struct super_block *sb = inode->i_sb;
-                       if (!EXT3_HAS_RO_COMPAT_FEATURE(sb,
-                                       EXT3_FEATURE_RO_COMPAT_LARGE_FILE) ||
-@@ -2247,7 +2249,7 @@ static int ext3_do_update_inode(handle_t
-                               * created, add a flag to the superblock.
-                               */
-                               err = ext3_journal_get_write_access(handle,
--                                              sb->u.ext3_sb.s_sbh);
-+                                              EXT3_SB(sb)->s_sbh);
-                               if (err)
-                                       goto out_brelse;
-                               ext3_update_dynamic_rev(sb);
-@@ -2256,7 +2258,7 @@ static int ext3_do_update_inode(handle_t
-                               sb->s_dirt = 1;
-                               handle->h_sync = 1;
-                               err = ext3_journal_dirty_metadata(handle,
--                                              sb->u.ext3_sb.s_sbh);
-+                                              EXT3_SB(sb)->s_sbh);
-                       }
-               }
-       }
-@@ -2265,13 +2267,13 @@ static int ext3_do_update_inode(handle_t
-               raw_inode->i_block[0] =
-                       cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
-       else for (block = 0; block < EXT3_N_BLOCKS; block++)
--              raw_inode->i_block[block] = inode->u.ext3_i.i_data[block];
-+              raw_inode->i_block[block] = ei->i_data[block];
-       BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
-       rc = ext3_journal_dirty_metadata(handle, bh);
-       if (!err)
-               err = rc;
--      EXT3_I(inode)->i_state &= ~EXT3_STATE_NEW;
-+      ei->i_state &= ~EXT3_STATE_NEW;
- out_brelse:
-       brelse (bh);
-@@ -2379,7 +2381,7 @@ int ext3_setattr(struct dentry *dentry, 
-               }
-               
-               error = ext3_orphan_add(handle, inode);
--              inode->u.ext3_i.i_disksize = attr->ia_size;
-+              EXT3_I(inode)->i_disksize = attr->ia_size;
-               rc = ext3_mark_inode_dirty(handle, inode);
-               if (!error)
-                       error = rc;
-@@ -2622,9 +2624,9 @@ int ext3_change_inode_journal_flag(struc
-        */
-       if (val)
--              inode->u.ext3_i.i_flags |= EXT3_JOURNAL_DATA_FL;
-+              EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL;
-       else
--              inode->u.ext3_i.i_flags &= ~EXT3_JOURNAL_DATA_FL;
-+              EXT3_I(inode)->i_flags &= ~EXT3_JOURNAL_DATA_FL;
-       journal_unlock_updates(journal);
---- ./fs/ext3/ioctl.c.orig     Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/ioctl.c  Tue May  7 15:20:52 2002
-@@ -18,13 +18,14 @@
- int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
-               unsigned long arg)
- {
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-       unsigned int flags;
-       ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
-       switch (cmd) {
-       case EXT3_IOC_GETFLAGS:
--              flags = inode->u.ext3_i.i_flags & EXT3_FL_USER_VISIBLE;
-+              flags = ei->i_flags & EXT3_FL_USER_VISIBLE;
-               return put_user(flags, (int *) arg);
-       case EXT3_IOC_SETFLAGS: {
-               handle_t *handle = NULL;
-@@ -42,7 +42,7 @@ int ext3_ioctl (struct inode * inode, st
-               if (get_user(flags, (int *) arg))
-                       return -EFAULT;
--              oldflags = inode->u.ext3_i.i_flags;
-+              oldflags = ei->i_flags;
-               /* The JOURNAL_DATA flag is modifiable only by root */
-               jflag = flags & EXT3_JOURNAL_DATA_FL;
-@@ -79,7 +79,7 @@ int ext3_ioctl (struct inode * inode, st
-               
-               flags = flags & EXT3_FL_USER_MODIFIABLE;
-               flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE;
--              inode->u.ext3_i.i_flags = flags;
-+              ei->i_flags = flags;
-               if (flags & EXT3_SYNC_FL)
-                       inode->i_flags |= S_SYNC;
-@@ -155,12 +155,12 @@ flags_err:
-                       int ret = 0;
-                       set_current_state(TASK_INTERRUPTIBLE);
--                      add_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait);
--                      if (timer_pending(&sb->u.ext3_sb.turn_ro_timer)) {
-+                      add_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait);
-+                      if (timer_pending(&EXT3_SB(sb)->turn_ro_timer)) {
-                               schedule();
-                               ret = 1;
-                       }
--                      remove_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait);
-+                      remove_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait);
-                       return ret;
-               }
- #endif
---- ./fs/ext3/namei.c.orig     Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/namei.c  Tue May  7 16:05:51 2002
-@@ -636,7 +636,7 @@ static struct buffer_head * ext3_find_en
-       }
-       
-       nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
--      start = dir->u.ext3_i.i_dir_start_lookup;
-+      start = EXT3_I(dir)->i_dir_start_lookup;
-       if (start >= nblocks)
-               start = 0;
-       block = start;
-@@ -677,7 +677,7 @@ restart:
-               i = search_dirblock(bh, dir, dentry,
-                           block << EXT3_BLOCK_SIZE_BITS(sb), res_dir);
-               if (i == 1) {
--                      dir->u.ext3_i.i_dir_start_lookup = block;
-+                      EXT3_I(dir)->i_dir_start_lookup = block;
-                       ret = bh;
-                       goto cleanup_and_exit;
-               } else {
-@@ -1419,7 +1419,7 @@ int ext3_orphan_add(handle_t *handle, st
-       int err = 0, rc;
-       
-       lock_super(sb);
--      if (!list_empty(&inode->u.ext3_i.i_orphan))
-+      if (!list_empty(&EXT3_I(inode)->i_orphan))
-               goto out_unlock;
-       /* Orphan handling is only valid for files with data blocks
-@@ -1430,8 +1430,8 @@ int ext3_orphan_add(handle_t *handle, st
-       J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-               S_ISLNK(inode->i_mode)) || inode->i_nlink == 0);
--      BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access");
--      err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh);
-+      BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-       if (err)
-               goto out_unlock;
-       
-@@ -1442,7 +1442,7 @@ int ext3_orphan_add(handle_t *handle, st
-       /* Insert this inode at the head of the on-disk orphan list... */
-       NEXT_ORPHAN(inode) = le32_to_cpu(EXT3_SB(sb)->s_es->s_last_orphan);
-       EXT3_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
--      err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh);
-+      err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-       rc = ext3_mark_iloc_dirty(handle, inode, &iloc);
-       if (!err)
-               err = rc;
-@@ -1456,7 +1456,7 @@ int ext3_orphan_add(handle_t *handle, st
-        * This is safe: on error we're going to ignore the orphan list
-        * anyway on the next recovery. */
-       if (!err)
--              list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan);
-+              list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
-       jbd_debug(4, "superblock will point to %ld\n", inode->i_ino);
-       jbd_debug(4, "orphan inode %ld will point to %d\n",
-@@ -714,25 +770,25 @@
- int ext3_orphan_del(handle_t *handle, struct inode *inode)
- {
-       struct list_head *prev;
-+      struct ext3_inode_info *ei = EXT3_I(inode);
-       struct ext3_sb_info *sbi;
-       unsigned long ino_next;
-       struct ext3_iloc iloc;
-       int err = 0;
-       lock_super(inode->i_sb);
--      if (list_empty(&inode->u.ext3_i.i_orphan)) {
-+      if (list_empty(&ei->i_orphan)) {
-               unlock_super(inode->i_sb);
-               return 0;
-       }
-       ino_next = NEXT_ORPHAN(inode);
--      prev = inode->u.ext3_i.i_orphan.prev;
-+      prev = ei->i_orphan.prev;
-       sbi = EXT3_SB(inode->i_sb);
-       jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
--      list_del(&inode->u.ext3_i.i_orphan);
--      INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
-+      list_del_init(&ei->i_orphan);
-       /* If we're on an error path, we may not have a valid
-        * transaction handle with which to update the orphan list on
-@@ -1520,8 +1520,7 @@ int ext3_orphan_del(handle_t *handle, st
-               err = ext3_journal_dirty_metadata(handle, sbi->s_sbh);
-       } else {
-               struct ext3_iloc iloc2;
--              struct inode *i_prev =
--                      list_entry(prev, struct inode, u.ext3_i.i_orphan);
-+              struct inode *i_prev = orphan_list_entry(prev);
-               jbd_debug(4, "orphan inode %lu will point to %lu\n",
-                         i_prev->i_ino, ino_next);
-@@ -1695,10 +1695,10 @@ static int ext3_symlink (struct inode * 
-                       goto out_no_entry;
-       } else {
-               inode->i_op = &ext3_fast_symlink_inode_operations;
--              memcpy((char*)&inode->u.ext3_i.i_data,symname,l);
-+              memcpy((char*)&EXT3_I(inode)->i_data,symname,l);
-               inode->i_size = l-1;
-       }
--      inode->u.ext3_i.i_disksize = inode->i_size;
-+      EXT3_I(inode)->i_disksize = inode->i_size;
-       err = ext3_add_nondir(handle, dentry, inode);
-       ext3_mark_inode_dirty(handle, inode);
- out_stop:
---- ./fs/ext3/super.c.orig     Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/super.c  Tue May  7 16:05:44 2002
-@@ -121,7 +121,7 @@ static int ext3_error_behaviour(struct s
-       /* If no overrides were specified on the mount, then fall back
-        * to the default behaviour set in the filesystem's superblock
-        * on disk. */
--      switch (le16_to_cpu(sb->u.ext3_sb.s_es->s_errors)) {
-+      switch (le16_to_cpu(EXT3_SB(sb)->s_es->s_errors)) {
-       case EXT3_ERRORS_PANIC:
-               return EXT3_ERRORS_PANIC;
-       case EXT3_ERRORS_RO:
-@@ -269,9 +269,9 @@ void ext3_abort (struct super_block * sb
-               return;
-       
-       printk (KERN_CRIT "Remounting filesystem read-only\n");
--      sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS;
-+      EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
-       sb->s_flags |= MS_RDONLY;
--      sb->u.ext3_sb.s_mount_opt |= EXT3_MOUNT_ABORT;
-+      EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT;
-       journal_abort(EXT3_SB(sb)->s_journal, -EIO);
- }
-@@ -377,8 +377,6 @@ static int ext3_blkdev_remove(struct ext3
-       return ret;
- }
--#define orphan_list_entry(l) list_entry((l), struct inode, u.ext3_i.i_orphan)
--
- static void dump_orphan_list(struct super_block *sb, struct ext3_sb_info *sbi)
- {
-       struct list_head *l;
-@@ -818,7 +818,7 @@ static void ext3_orphan_cleanup (struct 
-               sb->s_flags &= ~MS_RDONLY;
-       }
--      if (sb->u.ext3_sb.s_mount_state & EXT3_ERROR_FS) {
-+      if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) {
-               if (es->s_last_orphan)
-                       jbd_debug(1, "Errors on filesystem, "
-                                 "clearing orphan list.\n");
-@@ -1463,12 +1463,14 @@ static void ext3_commit_super (struct su
-                              struct ext3_super_block * es,
-                              int sync)
- {
-+      struct buffer_head *sbh = EXT3_SB(sb)->s_sbh;
-+
-       es->s_wtime = cpu_to_le32(CURRENT_TIME);
--      BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "marking dirty");
--      mark_buffer_dirty(sb->u.ext3_sb.s_sbh);
-+      BUFFER_TRACE(sbh, "marking dirty");
-+      mark_buffer_dirty(sbh);
-       if (sync) {
--              ll_rw_block(WRITE, 1, &sb->u.ext3_sb.s_sbh);
--              wait_on_buffer(sb->u.ext3_sb.s_sbh);
-+              ll_rw_block(WRITE, 1, &sbh);
-+              wait_on_buffer(sbh);
-       }
- }
-@@ -1519,7 +1521,7 @@ static void ext3_clear_journal_err(struc
-               ext3_warning(sb, __FUNCTION__, "Marking fs in need of "
-                            "filesystem check.");
-               
--              sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS;
-+              EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
-               es->s_state |= cpu_to_le16(EXT3_ERROR_FS);
-               ext3_commit_super (sb, es, 1);
---- ./fs/ext3/symlink.c.orig   Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/symlink.c        Tue May  7 15:25:39 2002
-@@ -23,13 +23,13 @@
- static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
--      char *s = (char *)dentry->d_inode->u.ext3_i.i_data;
--      return vfs_readlink(dentry, buffer, buflen, s);
-+      struct ext3_inode_info *ei = EXT3_I(dentry->d_inode);
-+      return vfs_readlink(dentry, buffer, buflen, (char *)ei->i_data);
- }
- static int ext3_follow_link(struct dentry *dentry, struct nameidata *nd)
- {
--      char *s = (char *)dentry->d_inode->u.ext3_i.i_data;
--      return vfs_follow_link(nd, s);
-+      struct ext3_inode_info *ei = EXT3_I(dentry->d_inode);
-+      return vfs_follow_link(nd, (char*)ei->i_data);
- }
---- ./include/linux/ext3_fs.h.orig     Tue Apr 16 14:27:25 2002
-+++ ./include/linux/ext3_fs.h  Tue May  7 16:47:36 2002
-@@ -84,22 +84,25 @@
- #define EXT3_MIN_BLOCK_SIZE           1024
- #define       EXT3_MAX_BLOCK_SIZE             4096
- #define EXT3_MIN_BLOCK_LOG_SIZE                 10
-+
- #ifdef __KERNEL__
--# define EXT3_BLOCK_SIZE(s)           ((s)->s_blocksize)
--#else
--# define EXT3_BLOCK_SIZE(s)           (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
--#endif
--#define       EXT3_ADDR_PER_BLOCK(s)          (EXT3_BLOCK_SIZE(s) / sizeof (__u32))
--#ifdef __KERNEL__
--# define EXT3_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
--#else
--# define EXT3_BLOCK_SIZE_BITS(s)      ((s)->s_log_block_size + 10)
--#endif
--#ifdef __KERNEL__
--#define       EXT3_ADDR_PER_BLOCK_BITS(s)     ((s)->u.ext3_sb.s_addr_per_block_bits)
--#define EXT3_INODE_SIZE(s)            ((s)->u.ext3_sb.s_inode_size)
--#define EXT3_FIRST_INO(s)             ((s)->u.ext3_sb.s_first_ino)
-+#define EXT3_SB(sb)   (&((sb)->u.ext3_sb))
-+#define EXT3_I(inode) (&((inode)->u.ext3_i))
-+
-+#define EXT3_BLOCK_SIZE(s)            ((s)->s_blocksize)
-+#define EXT3_BLOCK_SIZE_BITS(s)               ((s)->s_blocksize_bits)
-+#define       EXT3_ADDR_PER_BLOCK_BITS(s)     (EXT3_SB(s)->s_addr_per_block_bits)
-+#define EXT3_INODE_SIZE(s)            (EXT3_SB(s)->s_inode_size)
-+#define EXT3_FIRST_INO(s)             (EXT3_SB(s)->s_first_ino)
- #else
-+
-+/* Assume that user mode programs are passing in an ext3fs superblock, not
-+ * a kernel struct super_block.  This will allow us to call the feature-test
-+ * macros from user land. */
-+#define EXT3_SB(sb)   (sb)
-+
-+#define EXT3_BLOCK_SIZE(s)    (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
-+#define EXT3_BLOCK_SIZE_BITS(s)       ((s)->s_log_block_size + 10)
- #define EXT3_INODE_SIZE(s)    (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \
-                                EXT3_GOOD_OLD_INODE_SIZE : \
-                                (s)->s_inode_size)
-@@ -108,6 +110,7 @@
-                                EXT3_GOOD_OLD_FIRST_INO : \
-                                (s)->s_first_ino)
- #endif
-+#define EXT3_ADDR_PER_BLOCK(s)        (EXT3_BLOCK_SIZE(s) / sizeof (__u32))
- /*
-  * Macro-instructions used to manage fragments
-@@ -116,8 +120,8 @@
- #define       EXT3_MAX_FRAG_SIZE              4096
- #define EXT3_MIN_FRAG_LOG_SIZE                  10
- #ifdef __KERNEL__
--# define EXT3_FRAG_SIZE(s)            ((s)->u.ext3_sb.s_frag_size)
--# define EXT3_FRAGS_PER_BLOCK(s)      ((s)->u.ext3_sb.s_frags_per_block)
-+# define EXT3_FRAG_SIZE(s)            (EXT3_SB(s)->s_frag_size)
-+# define EXT3_FRAGS_PER_BLOCK(s)      (EXT3_SB(s)->s_frags_per_block)
- #else
- # define EXT3_FRAG_SIZE(s)            (EXT3_MIN_FRAG_SIZE << (s)->s_log_frag_size)
- # define EXT3_FRAGS_PER_BLOCK(s)      (EXT3_BLOCK_SIZE(s) / EXT3_FRAG_SIZE(s))
-@@ -163,15 +167,13 @@
- /*
-  * Macro-instructions used to manage group descriptors
-  */
-+# define EXT3_BLOCKS_PER_GROUP(s)     (EXT3_SB(s)->s_blocks_per_group)
-+# define EXT3_INODES_PER_GROUP(s)     (EXT3_SB(s)->s_inodes_per_group)
- #ifdef __KERNEL__
--# define EXT3_BLOCKS_PER_GROUP(s)     ((s)->u.ext3_sb.s_blocks_per_group)
--# define EXT3_DESC_PER_BLOCK(s)               ((s)->u.ext3_sb.s_desc_per_block)
--# define EXT3_INODES_PER_GROUP(s)     ((s)->u.ext3_sb.s_inodes_per_group)
--# define EXT3_DESC_PER_BLOCK_BITS(s)  ((s)->u.ext3_sb.s_desc_per_block_bits)
-+# define EXT3_DESC_PER_BLOCK(s)               (EXT3_SB(s)->s_desc_per_block)
-+# define EXT3_DESC_PER_BLOCK_BITS(s)  (EXT3_SB(s)->s_desc_per_block_bits)
- #else
--# define EXT3_BLOCKS_PER_GROUP(s)     ((s)->s_blocks_per_group)
- # define EXT3_DESC_PER_BLOCK(s)               (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_group_desc))
--# define EXT3_INODES_PER_GROUP(s)     ((s)->s_inodes_per_group)
- #endif
- /*
-@@ -344,7 +347,7 @@
- #ifndef _LINUX_EXT2_FS_H
- #define clear_opt(o, opt)             o &= ~EXT3_MOUNT_##opt
- #define set_opt(o, opt)                       o |= EXT3_MOUNT_##opt
--#define test_opt(sb, opt)             ((sb)->u.ext3_sb.s_mount_opt & \
-+#define test_opt(sb, opt)             (EXT3_SB(sb)->s_mount_opt & \
-                                        EXT3_MOUNT_##opt)
- #else
- #define EXT2_MOUNT_NOLOAD             EXT3_MOUNT_NOLOAD
-@@ -441,17 +443,11 @@
- /*EC*/        __u32   s_reserved[197];        /* Padding to the end of the block */
- };
--#ifdef __KERNEL__
--#define EXT3_SB(sb)   (&((sb)->u.ext3_sb))
--#define EXT3_I(inode) (&((inode)->u.ext3_i))
--#else
--/* Assume that user mode programs are passing in an ext3fs superblock, not
-- * a kernel struct super_block.  This will allow us to call the feature-test
-- * macros from user land. */
--#define EXT3_SB(sb)   (sb)
--#endif
--
--#define NEXT_ORPHAN(inode) (inode)->u.ext3_i.i_dtime
-+#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime
-+static inline struct inode *orphan_list_entry(struct list_head *l)
-+{
-+      return list_entry(l, struct inode, u.ext3_i.i_orphan);
-+}
- /*
-  * Codes for operating systems
---- ./include/linux/ext3_jbd.h.orig    Tue May  7 14:44:08 2002
-+++ ./include/linux/ext3_jbd.h Tue May  7 14:44:43 2002
-@@ -291,7 +291,7 @@
-               return 1;
-       if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
-               return 1;
--      if (inode->u.ext3_i.i_flags & EXT3_JOURNAL_DATA_FL)
-+      if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL)
-               return 1;
-       return 0;
- }
diff --git a/lustre/kernel_patches/patches/ext3-2.4.20-fixes.patch b/lustre/kernel_patches/patches/ext3-2.4.20-fixes.patch
deleted file mode 100644 (file)
index 5f566de..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-
-
-
- fs/ext3/balloc.c |   53 +++++++++++++++++++++++++++++++----------------------
- 1 files changed, 31 insertions(+), 22 deletions(-)
-
---- linux-2.4.20/fs/ext3/balloc.c~ext3-2.4.20-fixes    2003-04-08 23:35:17.000000000 -0600
-+++ linux-2.4.20-braam/fs/ext3/balloc.c        2003-04-08 23:35:17.000000000 -0600
-@@ -276,7 +276,8 @@ void ext3_free_blocks (handle_t *handle,
-       }
-       lock_super (sb);
-       es = sb->u.ext3_sb.s_es;
--      if (block < le32_to_cpu(es->s_first_data_block) || 
-+      if (block < le32_to_cpu(es->s_first_data_block) ||
-+          block + count < block ||
-           (block + count) > le32_to_cpu(es->s_blocks_count)) {
-               ext3_error (sb, "ext3_free_blocks",
-                           "Freeing blocks not in datazone - "
-@@ -309,17 +310,6 @@ do_more:
-       if (!gdp)
-               goto error_return;
--      if (in_range (le32_to_cpu(gdp->bg_block_bitmap), block, count) ||
--          in_range (le32_to_cpu(gdp->bg_inode_bitmap), block, count) ||
--          in_range (block, le32_to_cpu(gdp->bg_inode_table),
--                    sb->u.ext3_sb.s_itb_per_group) ||
--          in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table),
--                    sb->u.ext3_sb.s_itb_per_group))
--              ext3_error (sb, "ext3_free_blocks",
--                          "Freeing blocks in system zones - "
--                          "Block = %lu, count = %lu",
--                          block, count);
--
-       /*
-        * We are about to start releasing blocks in the bitmap,
-        * so we need undo access.
-@@ -345,14 +335,24 @@ do_more:
-       if (err)
-               goto error_return;
--      for (i = 0; i < count; i++) {
-+      for (i = 0; i < count; i++, block++) {
-+              if (block == le32_to_cpu(gdp->bg_block_bitmap) ||
-+                  block == le32_to_cpu(gdp->bg_inode_bitmap) ||
-+                  in_range(block, le32_to_cpu(gdp->bg_inode_table),
-+                           EXT3_SB(sb)->s_itb_per_group)) {
-+                      ext3_error(sb, __FUNCTION__,
-+                                 "Freeing block in system zone - block = %lu",
-+                                 block);
-+                      continue;
-+              }
-+
-               /*
-                * An HJ special.  This is expensive...
-                */
- #ifdef CONFIG_JBD_DEBUG
-               {
-                       struct buffer_head *debug_bh;
--                      debug_bh = sb_get_hash_table(sb, block + i);
-+                      debug_bh = sb_get_hash_table(sb, block);
-                       if (debug_bh) {
-                               BUFFER_TRACE(debug_bh, "Deleted!");
-                               if (!bh2jh(bitmap_bh)->b_committed_data)
-@@ -365,9 +365,8 @@ do_more:
- #endif
-               BUFFER_TRACE(bitmap_bh, "clear bit");
-               if (!ext3_clear_bit (bit + i, bitmap_bh->b_data)) {
--                      ext3_error (sb, __FUNCTION__,
--                                    "bit already cleared for block %lu", 
--                                    block + i);
-+                      ext3_error(sb, __FUNCTION__,
-+                                 "bit already cleared for block %lu", block);
-                       BUFFER_TRACE(bitmap_bh, "bit already cleared");
-               } else {
-                       dquot_freed_blocks++;
-@@ -415,7 +414,6 @@ do_more:
-       if (!err) err = ret;
-       if (overflow && !err) {
--              block += count;
-               count = overflow;
-               goto do_more;
-       }
-@@ -576,6 +574,7 @@ int ext3_new_block (handle_t *handle, st
-       ext3_debug ("goal=%lu.\n", goal);
-+repeat:
-       /*
-        * First, test whether the goal block is free.
-        */
-@@ -684,10 +683,20 @@ got_block:
-       if (tmp == le32_to_cpu(gdp->bg_block_bitmap) ||
-           tmp == le32_to_cpu(gdp->bg_inode_bitmap) ||
-           in_range (tmp, le32_to_cpu(gdp->bg_inode_table),
--                    sb->u.ext3_sb.s_itb_per_group))
--              ext3_error (sb, "ext3_new_block",
--                          "Allocating block in system zone - "
--                          "block = %u", tmp);
-+                    EXT3_SB(sb)->s_itb_per_group)) {
-+              ext3_error(sb, __FUNCTION__,
-+                         "Allocating block in system zone - block = %u", tmp);
-+
-+              /* Note: This will potentially use up one of the handle's
-+               * buffer credits.  Normally we have way too many credits,
-+               * so that is OK.  In _very_ rare cases it might not be OK.
-+               * We will trigger an assertion if we run out of credits,
-+               * and we will have to do a full fsck of the filesystem -
-+               * better than randomly corrupting filesystem metadata.
-+               */
-+              ext3_set_bit(j, bh->b_data);
-+              goto repeat;
-+      }
-       /* The superblock lock should guard against anybody else beating
-        * us to this point! */
-
-_
diff --git a/lustre/kernel_patches/patches/ext3-2.5-noread.patch b/lustre/kernel_patches/patches/ext3-2.5-noread.patch
deleted file mode 100644 (file)
index f1c611f..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-===== fs/ext3/ialloc.c 1.26 vs edited =====
---- 1.26/fs/ext3/ialloc.c      Fri Feb 14 19:24:09 2003
-+++ edited/fs/ext3/ialloc.c    Sat Mar  8 01:20:55 2003
-@@ -195,6 +195,36 @@
- }
- /*
-+ * @block_group: block group of inode
-+ * @offset: relative offset of inode within @block_group
-+ *
-+ * Check whether any of the inodes in this disk block are in use.
-+ *
-+ * Caller must be holding superblock lock (group/bitmap read lock in
-+ * future).
-+ */
-+int ext3_itable_block_used(struct super_block *sb, unsigned int block_group,
-+                         int offset)
-+{
-+      struct buffer_head *ibitmap = read_inode_bitmap(sb, block_group);
-+      int inodes_per_block;
-+      unsigned long inum, iend;
-+
-+      if (!ibitmap)
-+              return 1;
-+
-+      inodes_per_block = sb->s_blocksize / EXT3_SB(sb)->s_inode_size;
-+      inum = offset & ~(inodes_per_block - 1);
-+      iend = inum + inodes_per_block;
-+      for (; inum < iend; inum++) {
-+              if (inum != offset && ext3_test_bit(inum, ibitmap->b_data))
-+                      return 1;
-+      }
-+
-+      return 0;
-+}
-+
-+/*
-  * There are two policies for allocating an inode.  If the new inode is
-  * a directory, then a forward search is made for a block group with both
-  * free space and a low directory-to-inode ratio; if that fails, then of
-@@ -422,8 +452,9 @@
-       struct ext3_group_desc * gdp;
-       struct ext3_super_block * es;
-       struct ext3_inode_info *ei;
--      int err = 0;
-+      struct ext3_iloc iloc;
-       struct inode *ret;
-+      int err = 0;
-       /* Cannot create files in a deleted directory */
-       if (!dir || !dir->i_nlink)
-@@ -587,16 +618,23 @@
-               goto fail2;
-       }
-       err = ext3_init_acl(handle, inode, dir);
-+      if (err)
-+              goto fail3;
-+
-+      err = ext3_get_inode_loc_new(inode, &iloc, 1);
-+      if (err)
-+              goto fail3;
-+
-+      BUFFER_TRACE(iloc->bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, iloc.bh);
-       if (err) {
--              DQUOT_FREE_INODE(inode);
--              goto fail2;
--      }
--      err = ext3_mark_inode_dirty(handle, inode);
--      if (err) {
--              ext3_std_error(sb, err);
--              DQUOT_FREE_INODE(inode);
--              goto fail2;
--      }
-+              brelse(iloc.bh);
-+              iloc.bh = NULL;
-+              goto fail3;
-+      }
-+      err = ext3_mark_iloc_dirty(handle, inode, &iloc);
-+      if (err)
-+              goto fail3;
-       ext3_debug("allocating inode %lu\n", inode->i_ino);
-       goto really_out;
-@@ -610,6 +648,9 @@
-       brelse(bitmap_bh);
-       return ret;
-+fail3:
-+      ext3_std_error(sb, err);
-+      DQUOT_FREE_INODE(inode);
- fail2:
-       inode->i_flags |= S_NOQUOTA;
-       inode->i_nlink = 0;
-===== fs/ext3/inode.c 1.62 vs edited =====
---- 1.62/fs/ext3/inode.c       Fri Feb 14 19:24:09 2003
-+++ edited/fs/ext3/inode.c     Sat Mar  8 02:10:39 2003
-@@ -2144,69 +2144,118 @@
-       unlock_kernel();
- }
--/* 
-- * ext3_get_inode_loc returns with an extra refcount against the
-- * inode's underlying buffer_head on success. 
-- */
-+#define NUM_INODE_PREREAD 16
--int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
-+/*
-+ * ext3_get_inode_loc returns with an extra refcount against the inode's
-+ * underlying buffer_head on success.  If this is for a new inode allocation
-+ * (new is non-zero) then we may be able to optimize away the read if there
-+ * are no other in-use inodes in this inode table block.  If we need to do
-+ * a read, then read in a whole chunk of blocks to avoid blocking again soon
-+ * if we are doing lots of creates/updates.
-+ */
-+int ext3_get_inode_loc_new(struct inode *inode, struct ext3_iloc *iloc, int new)
- {
--      struct buffer_head *bh = 0;
-+      struct buffer_head *bh[NUM_INODE_PREREAD];
-+      struct super_block *sb = inode->i_sb;
-+      struct ext3_sb_info *sbi = EXT3_SB(sb);
-+      unsigned long ino = inode->i_ino;
-       unsigned long block;
-       unsigned long block_group;
-       unsigned long group_desc;
-       unsigned long desc;
-       unsigned long offset;
-       struct ext3_group_desc * gdp;
--              
--      if ((inode->i_ino != EXT3_ROOT_INO &&
--              inode->i_ino != EXT3_JOURNAL_INO &&
--              inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
--              inode->i_ino > le32_to_cpu(
--                      EXT3_SB(inode->i_sb)->s_es->s_inodes_count)) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "bad inode number: %lu", inode->i_ino);
-+
-+      if ((ino != EXT3_ROOT_INO && ino != EXT3_JOURNAL_INO &&
-+           ino < EXT3_FIRST_INO(sb)) ||
-+          ino > le32_to_cpu(sbi->s_es->s_inodes_count)) {
-+              ext3_error(sb, "ext3_get_inode_loc", "bad inode number: %lu",
-+                         ino);
-               goto bad_inode;
-       }
--      block_group = (inode->i_ino - 1) / EXT3_INODES_PER_GROUP(inode->i_sb);
--      if (block_group >= EXT3_SB(inode->i_sb)->s_groups_count) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "group >= groups count");
-+      block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb);
-+      if (block_group >= EXT3_SB(sb)->s_groups_count) {
-+              ext3_error(sb, "ext3_get_inode_loc", "group >= groups count");
-               goto bad_inode;
-       }
--      group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(inode->i_sb);
--      desc = block_group & (EXT3_DESC_PER_BLOCK(inode->i_sb) - 1);
--      bh = EXT3_SB(inode->i_sb)->s_group_desc[group_desc];
--      if (!bh) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "Descriptor not loaded");
-+      group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(sb);
-+      desc = block_group & (EXT3_DESC_PER_BLOCK(sb) - 1);
-+      if (!sbi->s_group_desc[group_desc]) {
-+              ext3_error(sb, "ext3_get_inode_loc", "Descriptor not loaded");
-               goto bad_inode;
-       }
--      gdp = (struct ext3_group_desc *) bh->b_data;
-+      gdp = (struct ext3_group_desc *)(sbi->s_group_desc[group_desc]->b_data);
-       /*
-        * Figure out the offset within the block group inode table
-        */
--      offset = ((inode->i_ino - 1) % EXT3_INODES_PER_GROUP(inode->i_sb)) *
--              EXT3_INODE_SIZE(inode->i_sb);
-+      offset = ((ino - 1) % EXT3_INODES_PER_GROUP(sb));
-       block = le32_to_cpu(gdp[desc].bg_inode_table) +
--              (offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb));
--      if (!(bh = sb_bread(inode->i_sb, block))) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "unable to read inode block - "
--                          "inode=%lu, block=%lu", inode->i_ino, block);
--              goto bad_inode;
-+              (offset * sbi->s_inode_size >> EXT3_BLOCK_SIZE_BITS(sb));
-+      bh[0] = sb_getblk(sb, block);
-+      if (buffer_uptodate(bh[0]))
-+              goto done;
-+
-+      /* If we don't really need to read this block, and it isn't already
-+       * in memory, then we just zero it out.  Otherwise, we keep the
-+       * current block contents (deleted inode data) for posterity.
-+       */
-+      if (new && !ext3_itable_block_used(sb, block_group, offset)) {
-+              lock_buffer(bh[0]);
-+              memset(bh[0]->b_data, 0, bh[0]->b_size);
-+              set_buffer_uptodate(bh[0]);
-+              unlock_buffer(bh[0]);
-+      } else {
-+              unsigned long block_end, itable_end;
-+              int count = 1;
-+
-+              itable_end = le32_to_cpu(gdp[desc].bg_inode_table) +
-+                      sbi->s_itb_per_group;
-+              block_end = block + NUM_INODE_PREREAD;
-+              if (block_end > itable_end)
-+                      block_end = itable_end;
-+
-+              for (; block < block_end; block++) {
-+                      bh[count] = sb_getblk(sb, block);
-+                      if (count && (buffer_uptodate(bh[count]) ||
-+                                    buffer_locked(bh[count]))) {
-+                              __brelse(bh[count]);
-+                      } else
-+                              count++;
-+              }
-+
-+              ll_rw_block(READ, count, bh);
-+
-+              /* Release all but the block we actually need (bh[0]) */
-+              while (--count > 0)
-+                      __brelse(bh[count]);
-+
-+              wait_on_buffer(bh[0]);
-+              if (!buffer_uptodate(bh[0])) {
-+                      ext3_error(sb, __FUNCTION__,
-+                                 "unable to read inode block - "
-+                                 "inode=%lu, block=%llu", ino,
-+                                 (unsigned long long)bh[0]->b_blocknr);
-+                      goto bad_inode;
-+              }
-       }
--      offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1);
-+done:
-+      offset = (offset * sbi->s_inode_size) & (EXT3_BLOCK_SIZE(sb) - 1);
--      iloc->bh = bh;
--      iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset);
-+      iloc->bh = bh[0];
-+      iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset);
-       iloc->block_group = block_group;
--      
-+
-       return 0;
--      
-+
-  bad_inode:
-       return -EIO;
-+}
-+
-+int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc)
-+{
-+      return ext3_get_inode_loc_new(inode, iloc, 0);
- }
- void ext3_read_inode(struct inode * inode)
-===== include/linux/ext3_fs.h 1.22 vs edited =====
---- 1.22/include/linux/ext3_fs.h       Tue Jan 14 00:56:29 2003
-+++ edited/include/linux/ext3_fs.h     Sat Mar  8 01:56:28 2003
-@@ -719,6 +719,8 @@
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
-+extern int ext3_itable_block_used(struct super_block *, unsigned int, int);
-+extern int ext3_get_inode_loc_new(struct inode *, struct ext3_iloc *, int);
- extern int  ext3_get_inode_loc (struct inode *, struct ext3_iloc *);
- extern void ext3_read_inode (struct inode *);
- extern void ext3_write_inode (struct inode *, int);
diff --git a/lustre/kernel_patches/patches/ext3-delete_thread-2.4.20.patch b/lustre/kernel_patches/patches/ext3-delete_thread-2.4.20.patch
deleted file mode 100644 (file)
index 5f67fef..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-diff -puNr origin/fs/ext3/super.c linux/fs/ext3/super.c
---- origin/fs/ext3/super.c     2003-05-04 17:23:52.000000000 +0400
-+++ linux/fs/ext3/super.c      2003-05-04 17:09:20.000000000 +0400
-@@ -398,6 +398,210 @@ static void dump_orphan_list(struct supe
-       }
- }
-+#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("EXT3-fs: delete thread on %s started\n",
-+             kdevname(sb->s_dev));
-+
-+      /* main loop */
-+      for (;;) {
-+              sleep_on(&sbi->s_delete_thread_queue);
-+              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)) {
-+                      memset(&sbi->s_delete_list, 0,
-+                             sizeof(sbi->s_delete_list));
-+                      spin_unlock(&sbi->s_delete_lock);
-+                      ext3_debug("ext3 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", sb,
-+                                   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);
-+      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(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)
-+{
-+      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
-+ * 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
-+ * truncate thread when we run out of space.
-+ *
-+ * In 2.5 this can be done much more cleanly by just registering a "drop"
-+ * method in the super_operations struct.
-+ */
-+static void ext3_delete_inode_thread(struct inode *old_inode)
-+{
-+      struct ext3_sb_info *sbi = EXT3_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;
-+      }
-+      
-+      if (!test_opt (old_inode->i_sb, ASYNCDEL)) {
-+              ext3_delete_inode(old_inode);
-+              return;
-+      }
-+
-+      /* We may want to delete the inode immediately and not defer it */
-+      if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS ||
-+          !sbi->s_delete_list.next) {
-+              ext3_delete_inode(old_inode);
-+              return;
-+      }
-+
-+      if (EXT3_I(old_inode)->i_state & EXT3_STATE_DELETE) {
-+              ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
-+                         old_inode->i_ino, blocks);
-+              ext3_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);
-+
-+      EXT3_SB(old_inode->i_sb)->s_mount_state |= EXT3_ORPHAN_FS;
-+      new_inode = iget(old_inode->i_sb, old_inode->i_ino);
-+      EXT3_SB(old_inode->i_sb)->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(KERN_DEBUG "delete inode %lu directly (bad read)\n",
-+                         old_inode->i_ino);
-+              ext3_delete_inode(old_inode);
-+              return;
-+      }
-+      J_ASSERT(new_inode != old_inode);
-+
-+      J_ASSERT(!list_empty(&EXT3_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
-+       * in the same order as the on-disk orphan list (badness otherwise).
-+       */
-+      EXT3_I(new_inode)->i_orphan = EXT3_I(old_inode)->i_orphan;
-+      EXT3_I(new_inode)->i_orphan.next->prev = &EXT3_I(new_inode)->i_orphan;
-+      EXT3_I(new_inode)->i_orphan.prev->next = &EXT3_I(new_inode)->i_orphan;
-+      EXT3_I(new_inode)->i_state |= EXT3_STATE_DELETE;
-+      up(&sbi->s_orphan_lock);
-+
-+      clear_inode(old_inode);
-+
-+      ext3_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 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);
-@@ -405,6 +611,7 @@ void ext3_put_super (struct super_block 
-       kdev_t j_dev = sbi->s_journal->j_dev;
-       int i;
-+      ext3_stop_delete_thread(sbi);
-       ext3_xattr_put_super(sb);
-       journal_destroy(sbi->s_journal);
-       if (!(sb->s_flags & MS_RDONLY)) {
-@@ -453,7 +660,11 @@ static struct super_operations ext3_sops
-       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 */
-+#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 */
-       write_super_lockfs: ext3_write_super_lockfs, /* BKL not held. Take it */
-@@ -514,6 +725,11 @@ static int parse_options (char * options
-            this_char = strtok (NULL, ",")) {
-               if ((value = strchr (this_char, '=')) != NULL)
-                       *value++ = 0;
-+#ifdef EXT3_DELETE_THREAD
-+              if (!strcmp(this_char, "asyncdel"))
-+                      set_opt(*mount_options, ASYNCDEL);
-+              else
-+#endif
- #ifdef CONFIG_EXT3_FS_XATTR_USER
-               if (!strcmp (this_char, "user_xattr"))
-                       set_opt (*mount_options, XATTR_USER);
-@@ -1220,6 +1436,7 @@ struct super_block * ext3_read_super (st
-       }
-       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
-diff -puNr origin/include/linux/ext3_fs.h linux/include/linux/ext3_fs.h
---- origin/include/linux/ext3_fs.h     2003-05-04 17:22:49.000000000 +0400
-+++ linux/include/linux/ext3_fs.h      2003-05-04 15:06:10.000000000 +0400
-@@ -193,6 +193,7 @@ struct ext3_group_desc
-  */
- #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
-@@ -321,6 +322,7 @@ struct ext3_inode {
- #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          0x10000  /* Delayed deletion */
- /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
- #ifndef _LINUX_EXT2_FS_H
-diff -puNr origin/include/linux/ext3_fs_sb.h linux/include/linux/ext3_fs_sb.h
---- origin/include/linux/ext3_fs_sb.h  2003-05-04 17:23:52.000000000 +0400
-+++ linux/include/linux/ext3_fs_sb.h   2003-05-04 11:37:04.000000000 +0400
-@@ -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 ext3_sb_info {
-       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 */
diff --git a/lustre/kernel_patches/patches/ext3-largefile.patch b/lustre/kernel_patches/patches/ext3-largefile.patch
deleted file mode 100644 (file)
index aa7a2f2..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
- fs/ext3/inode.c |    2 +-
- 1 files changed, 1 insertion(+), 1 deletion(-)
-
---- linux-2.4.20/fs/ext3/inode.c~ext3-largefile        2003-04-08 23:35:36.000000000 -0600
-+++ linux-2.4.20-braam/fs/ext3/inode.c 2003-04-08 23:35:36.000000000 -0600
-@@ -2562,7 +2562,7 @@ void ext3_dirty_inode(struct inode *inod
-       handle_t *handle;
-       lock_kernel();
--      handle = ext3_journal_start(inode, 1);
-+      handle = ext3_journal_start(inode, 2);
-       if (IS_ERR(handle))
-               goto out;
-       if (current_handle &&
-
-_
diff --git a/lustre/kernel_patches/patches/ext3-noread-2.4.20.patch b/lustre/kernel_patches/patches/ext3-noread-2.4.20.patch
deleted file mode 100644 (file)
index 8c2fcd7..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
- fs/ext3/ialloc.c        |   47 ++++++++++++++++++++++-
- fs/ext3/inode.c         |   96 +++++++++++++++++++++++++++++++++++++-----------
- include/linux/ext3_fs.h |    2 +
- 3 files changed, 121 insertions(+), 24 deletions(-)
-
---- linux-2.4.20/fs/ext3/ialloc.c~extN-noread-2.4.20   2003-05-04 16:41:22.000000000 +0800
-+++ linux-2.4.20-root/fs/ext3/ialloc.c 2003-05-04 17:19:29.000000000 +0800
-@@ -289,6 +289,37 @@ error_return:
- }
- /*
-+ * @block_group: block group of inode
-+ * @offset: relative offset of inode within @block_group
-+ *
-+ * Check whether any of the inodes in this disk block are in use.
-+ *
-+ * Caller must be holding superblock lock (group/bitmap read lock in future).
-+ */
-+int ext3_itable_block_used(struct super_block *sb, unsigned int block_group,
-+                         int offset)
-+{
-+      int bitmap_nr = load_inode_bitmap(sb, block_group);
-+      int inodes_per_block;
-+      unsigned long inum, iend;
-+      struct buffer_head *ibitmap;
-+
-+      if (bitmap_nr < 0)
-+              return 1;
-+
-+      inodes_per_block = sb->s_blocksize / EXT3_SB(sb)->s_inode_size;
-+      inum = offset & ~(inodes_per_block - 1);
-+      iend = inum + inodes_per_block;
-+      ibitmap = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
-+      for (; inum < iend; inum++) {
-+              if (inum != offset && ext3_test_bit(inum, ibitmap->b_data))
-+                      return 1;
-+      }
-+
-+      return 0;
-+}
-+
-+/*
-  * There are two policies for allocating an inode.  If the new inode is
-  * a directory, then a forward search is made for a block group with both
-  * free space and a low directory-to-inode ratio; if that fails, then of
-@@ -310,6 +341,7 @@ struct inode * ext3_new_inode (handle_t 
-       struct ext3_group_desc * gdp;
-       struct ext3_group_desc * tmp;
-       struct ext3_super_block * es;
-+      struct ext3_iloc iloc;
-       int err = 0;
-       /* Cannot create files in a deleted directory */
-@@ -510,8 +542,19 @@ repeat:
-       inode->i_generation = sb->u.ext3_sb.s_next_generation++;
-       inode->u.ext3_i.i_state = EXT3_STATE_NEW;
--      err = ext3_mark_inode_dirty(handle, inode);
--      if (err) goto fail;
-+      err = ext3_get_inode_loc_new(inode, &iloc, 1);
-+      if (err) goto fail;
-+      BUFFER_TRACE(iloc->bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, iloc.bh);
-+      if (err) {
-+              brelse(iloc.bh);
-+              iloc.bh = NULL;
-+              goto fail;
-+      }
-+      err = ext3_mark_iloc_dirty(handle, inode, &iloc);
-+      if (err) goto fail;
-+ 
-+
-       
-       unlock_super (sb);
-       if(DQUOT_ALLOC_INODE(inode)) {
---- linux-2.4.20/fs/ext3/inode.c~extN-noread-2.4.20    2003-05-04 16:41:26.000000000 +0800
-+++ linux-2.4.20-root/fs/ext3/inode.c  2003-05-04 17:22:49.000000000 +0800
-@@ -2013,14 +2013,19 @@ out_stop:
-       ext3_journal_stop(handle, inode);
- }
--/* 
-- * ext3_get_inode_loc returns with an extra refcount against the
-- * inode's underlying buffer_head on success. 
-- */
--
--int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
-+#define NUM_INODE_PREREAD     16
-+  
-+/*
-+  * ext3_get_inode_loc returns with an extra refcount against the inode's
-+  * underlying buffer_head on success.  If this is for a new inode allocation
-+  * (new is non-zero) then we may be able to optimize away the read if there
-+  * are no other in-use inodes in this inode table block.  If we need to do
-+  * a read, then read in a whole chunk of blocks to avoid blocking again soon
-+  * if we are doing lots of creates/updates.
-+  */
-+int ext3_get_inode_loc_new(struct inode *inode, struct ext3_iloc *iloc, int new)
- {
--      struct buffer_head *bh = 0;
-+      struct buffer_head *bh[NUM_INODE_PREREAD];
-       unsigned long block;
-       unsigned long block_group;
-       unsigned long group_desc;
-@@ -2045,31 +2050,73 @@ int ext3_get_inode_loc (struct inode *in
-       }
-       group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(inode->i_sb);
-       desc = block_group & (EXT3_DESC_PER_BLOCK(inode->i_sb) - 1);
--      bh = inode->i_sb->u.ext3_sb.s_group_desc[group_desc];
--      if (!bh) {
-+      if (!(inode->i_sb->u.ext3_sb.s_group_desc[group_desc])) {
-               ext3_error (inode->i_sb, "ext3_get_inode_loc",
-                           "Descriptor not loaded");
-               goto bad_inode;
-       }
--      gdp = (struct ext3_group_desc *) bh->b_data;
-+      gdp = (struct ext3_group_desc *)(inode->i_sb->u.ext3_sb.s_group_desc[group_desc]->b_data);
-       /*
-        * Figure out the offset within the block group inode table
-        */
--      offset = ((inode->i_ino - 1) % EXT3_INODES_PER_GROUP(inode->i_sb)) *
--              EXT3_INODE_SIZE(inode->i_sb);
-+      offset = ((inode->i_ino - 1) % EXT3_INODES_PER_GROUP(inode->i_sb));
-+
-       block = le32_to_cpu(gdp[desc].bg_inode_table) +
--              (offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb));
--      if (!(bh = sb_bread(inode->i_sb, block))) {
--              ext3_error (inode->i_sb, "ext3_get_inode_loc",
--                          "unable to read inode block - "
--                          "inode=%lu, block=%lu", inode->i_ino, block);
--              goto bad_inode;
--      }
--      offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1);
-+              (offset * EXT3_INODE_SIZE(inode->i_sb) >> EXT3_BLOCK_SIZE_BITS(inode->i_sb));
--      iloc->bh = bh;
--      iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset);
-+      bh[0] = sb_getblk(inode->i_sb, block);
-+      if (buffer_uptodate(bh[0]))
-+              goto done;
-+ 
-+      /* If we don't really need to read this block, and it isn't already
-+       * in memory, then we just zero it out.  Otherwise, we keep the
-+       * current block contents (deleted inode data) for posterity.
-+       */
-+      if (new && !ext3_itable_block_used(inode->i_sb, block_group, offset)) {
-+              lock_buffer(bh[0]);
-+              memset(bh[0]->b_data, 0, bh[0]->b_size);
-+              mark_buffer_uptodate(bh[0], 1);
-+              unlock_buffer(bh[0]);
-+      } else {
-+              unsigned long block_end, itable_end;
-+              int count = 1;
-+ 
-+              itable_end = le32_to_cpu(gdp[desc].bg_inode_table) +
-+                              inode->i_sb->u.ext3_sb.s_itb_per_group;
-+              block_end = block + NUM_INODE_PREREAD;
-+              if (block_end > itable_end)
-+                      block_end = itable_end;
-+ 
-+              for (; block < block_end; block++) {
-+                      bh[count] = sb_getblk(inode->i_sb, block);
-+                      if (count && (buffer_uptodate(bh[count]) ||
-+                                    buffer_locked(bh[count]))) {
-+                              __brelse(bh[count]);
-+                      } else
-+                              count++;
-+              }
-+ 
-+              ll_rw_block(READ, count, bh);
-+ 
-+              /* Release all but the block we actually need (bh[0]) */
-+              while (--count > 0)
-+                      __brelse(bh[count]);
-+ 
-+              wait_on_buffer(bh[0]);
-+              if (!buffer_uptodate(bh[0])) {
-+                      ext3_error(inode->i_sb, __FUNCTION__,
-+                                 "unable to read inode block - "
-+                                 "inode=%lu, block=%lu", inode->i_ino,
-+                                 bh[0]->b_blocknr);
-+                      goto bad_inode;
-+              }
-+      }
-+  done:
-+      offset = (offset * EXT3_INODE_SIZE(inode->i_sb)) & (EXT3_BLOCK_SIZE(inode->i_sb) - 1);
-+  
-+      iloc->bh = bh[0];
-+      iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset);
-       iloc->block_group = block_group;
-       
-       return 0;
-@@ -2078,6 +2125,11 @@ int ext3_get_inode_loc (struct inode *in
-       return -EIO;
- }
-+int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc)
-+{
-+      return ext3_get_inode_loc_new(inode, iloc, 0);
-+}
-+ 
- void ext3_read_inode(struct inode * inode)
- {
-       struct ext3_iloc iloc;
---- linux-2.4.20/include/linux/ext3_fs.h~extN-noread-2.4.20    2003-05-04 16:41:22.000000000 +0800
-+++ linux-2.4.20-root/include/linux/ext3_fs.h  2003-05-04 17:19:29.000000000 +0800
-@@ -683,6 +683,8 @@ extern int ext3_forget(handle_t *, int, 
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
-+extern int ext3_itable_block_used(struct super_block *sb, unsigned int, int);
-+extern int ext3_get_inode_loc_new(struct inode *, struct ext3_iloc *, int);
- extern int  ext3_get_inode_loc (struct inode *, struct ext3_iloc *);
- extern void ext3_read_inode (struct inode *);
- extern void ext3_write_inode (struct inode *, int);
-
-_
diff --git a/lustre/kernel_patches/patches/ext3-orphan_lock.patch b/lustre/kernel_patches/patches/ext3-orphan_lock.patch
deleted file mode 100644 (file)
index d1e5c8d..0000000
+++ /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/kernel_patches/patches/ext3-san-2.4.20-hp.patch b/lustre/kernel_patches/patches/ext3-san-2.4.20-hp.patch
deleted file mode 100644 (file)
index 148f4e3..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
- fs/ext3/ext3-exports.c |    9 ++++-
- fs/ext3/inode.c        |   81 +++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 89 insertions(+), 1 deletion(-)
-
---- linux/fs/ext3/inode.c~ext3-san-2.4.20-hp   Tue Apr 29 11:01:52 2003
-+++ linux-mmonroe/fs/ext3/inode.c      Tue Apr 29 11:01:53 2003
-@@ -2734,3 +2734,84 @@ int ext3_change_inode_journal_flag(struc
-  * here, in ext3_aops_journal_start() to ensure that the forthcoming "see if we
-  * need to extend" test in ext3_prepare_write() succeeds.  
-  */
-+
-+/* for each block: 1 ind + 1 dind + 1 tind
-+ * for each block: 3 bitmap blocks
-+ * for each block: 3 group descriptor blocks
-+ * i inode block
-+ * 1 superblock
-+ * 2 * EXT3_SINGLEDATA_TRANS_BLOCKS for the quote files
-+ * ((1+1+1) * 3 * nblocks) + 1 + 1 + 2 * EXT3_SINGLEDATA_TRANS_BLOCKS
-+ *
-+ * XXX assuming:
-+ * (1) fs logic block size == page size
-+ * (2) ext3 in writeback mode
-+ */
-+static inline int ext3_san_write_trans_blocks(int nblocks)
-+{
-+      int ret;
-+      
-+      ret = (1 + 1 + 1) * 3 * nblocks + 1 + 1;
-+
-+#ifdef CONFIG_QUOTA
-+      ret += 2 * EXT3_SINGLEDATA_TRANS_BLOCKS;
-+#endif
-+
-+      return ret;
-+}
-+
-+/* Alloc blocks for an inode, while don't create any buffer/page
-+ * for data I/O; set the inode size if file is extended.
-+ *
-+ * @inode:    target inode
-+ * @blocks:   array of logic block number
-+ * @nblocks:  how many blocks need be alloced
-+ * @newsize:  new filesize we should set
-+ *
-+ * return:    0 success, otherwise failed
-+ *            (*blocks) contains physical block number alloced
-+ *
-+ * XXX this assume the fs block size == page size
-+ */
-+int ext3_prep_san_write(struct inode *inode, long *blocks,
-+                      int nblocks, loff_t newsize)
-+{
-+      handle_t *handle;
-+      struct buffer_head bh_tmp;
-+      int needed_blocks;
-+      int i, ret = 0, ret2;
-+
-+      needed_blocks = ext3_san_write_trans_blocks(nblocks);
-+
-+      lock_kernel();
-+      handle = ext3_journal_start(inode, needed_blocks);
-+      if (IS_ERR(handle)) {
-+              unlock_kernel();
-+              return PTR_ERR(handle);
-+      }
-+      unlock_kernel();
-+
-+      /* alloc blocks one by one */
-+      for (i = 0; i < nblocks; i++) {
-+              ret = ext3_get_block_handle(handle, inode, blocks[i],
-+                                              &bh_tmp, 1);
-+              if (ret)
-+                      break;
-+
-+              blocks[i] = bh_tmp.b_blocknr;
-+      }
-+
-+      /* set inode size if needed */
-+      if (!ret && (newsize > inode->i_size)) {
-+              inode->i_size = newsize;
-+              ext3_mark_inode_dirty(handle, inode);
-+      }
-+
-+      lock_kernel();
-+      ret2 = ext3_journal_stop(handle, inode);
-+      unlock_kernel();
-+
-+      if (!ret)
-+              ret = ret2;
-+      return ret;
-+}
---- linux/fs/ext3/ext3-exports.c~ext3-san-2.4.20-hp    Tue Apr 29 11:01:51 2003
-+++ linux-mmonroe/fs/ext3/ext3-exports.c       Tue Apr 29 11:07:19 2003
-@@ -1,9 +1,15 @@
- #include <linux/config.h>
- #include <linux/module.h>
--#include <linux/ext3_fs.h>
-+#include <linux/fs.h>
-+#include <linux/locks.h>
-+#include <linux/slab.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
- #include <linux/ext3_xattr.h>
-+int ext3_prep_san_write(struct inode *inode, long *blocks,
-+                      int nblocks, loff_t newsize);
-+
- EXPORT_SYMBOL(ext3_force_commit);
- EXPORT_SYMBOL(ext3_bread);
- EXPORT_SYMBOL(ext3_xattr_register);
-@@ -11,3 +17,4 @@ EXPORT_SYMBOL(ext3_xattr_unregister);
- EXPORT_SYMBOL(ext3_xattr_get);
- EXPORT_SYMBOL(ext3_xattr_list);
- EXPORT_SYMBOL(ext3_xattr_set);
-+EXPORT_SYMBOL(ext3_prep_san_write);
-
-_
diff --git a/lustre/kernel_patches/patches/ext3-truncate_blocks-chaos.patch.patch b/lustre/kernel_patches/patches/ext3-truncate_blocks-chaos.patch.patch
deleted file mode 100644 (file)
index ce3928d..0000000
+++ /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/kernel_patches/patches/ext3-truncate_blocks.patch b/lustre/kernel_patches/patches/ext3-truncate_blocks.patch
deleted file mode 100644 (file)
index ce3928d..0000000
+++ /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/kernel_patches/patches/ext3-unmount_sync.patch b/lustre/kernel_patches/patches/ext3-unmount_sync.patch
deleted file mode 100644 (file)
index c57903c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
- fs/ext3/super.c |    7 ++++++-
- 1 files changed, 6 insertions(+), 1 deletion(-)
-
---- linux-2.4.20/fs/ext3/super.c~ext3-unmount_sync     2003-04-08 23:35:44.000000000 -0600
-+++ linux-2.4.20-braam/fs/ext3/super.c 2003-04-08 23:35:44.000000000 -0600
-@@ -1612,7 +1612,12 @@ void ext3_write_super (struct super_bloc
-       sb->s_dirt = 0;
-       target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
--      if (do_sync_supers) {
-+      /*
-+       * Tricky --- if we are unmounting, the write really does need
-+       * to be synchronous.  We can detect that by looking for NULL in
-+       * sb->s_root.
-+       */
-+      if (do_sync_supers || !sb->s_root) {
-               unlock_super(sb);
-               log_wait_commit(EXT3_SB(sb)->s_journal, target);
-               lock_super(sb);
-
-_
diff --git a/lustre/kernel_patches/patches/ext3-use-after-free-hp-2.4.19.patch b/lustre/kernel_patches/patches/ext3-use-after-free-hp-2.4.19.patch
deleted file mode 100644 (file)
index cc2e873..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-./fs/ext3/namei.c |   11 +++++------
-1 files changed, 5 insertions(+), 6 deletions(-)
-
---- linux-2.4.19-hp3_pnnl1/./fs/ext3/namei.c~ext3-use-after-free-chaos 2003-04-10 21:39:30.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/./fs/ext3/namei.c      2003-04-10 21:48:48.000000000 +0800
-@@ -1523,8 +1523,11 @@ static int ext3_add_nondir(handle_t *han
- {
-       int err = ext3_add_entry(handle, dentry, inode);
-       if (!err) {
--              d_instantiate(dentry, inode);
--              return 0;
-+              err = ext3_mark_inode_dirty(handle, inode);
-+              if (err == 0) {
-+                      d_instantiate(dentry, inode);
-+                      return 0;
-+              }
-       }
-       ext3_dec_count(handle, inode);
-       iput(inode);
-@@ -1560,7 +1563,6 @@ static int ext3_create (struct inode * d
-               inode->i_op = &ext3_file_inode_operations;
-               inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
--              ext3_mark_inode_dirty(handle, inode);
-               err = ext3_add_nondir(handle, dentry, inode);
-       }
-       ext3_journal_stop(handle, dir);
-@@ -1587,7 +1589,6 @@ static int ext3_mknod (struct inode * di
-       err = PTR_ERR(inode);
-       if (!IS_ERR(inode)) {
-               init_special_inode(inode, mode, rdev);
--              ext3_mark_inode_dirty(handle, inode);
-               err = ext3_add_nondir(handle, dentry, inode);
-       }
-       ext3_journal_stop(handle, dir);
-@@ -2037,7 +2038,6 @@ static int ext3_symlink (struct inode * 
-       }
-       EXT3_I(inode)->i_disksize = inode->i_size;
-       err = ext3_add_nondir(handle, dentry, inode);
--      ext3_mark_inode_dirty(handle, inode);
-   out_stop:
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -2071,7 +2071,6 @@ static int ext3_link (struct dentry * ol
-       ext3_inc_count(handle, inode);
-       atomic_inc(&inode->i_count);
--      ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_nondir(handle, dentry, inode);
-       ext3_journal_stop(handle, dir);
-       return err;
-
-_
diff --git a/lustre/kernel_patches/patches/ext3-use-after-free.patch b/lustre/kernel_patches/patches/ext3-use-after-free.patch
deleted file mode 100644 (file)
index dd999bf..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
- ./fs/ext3/namei.c |   11 +++++------
- 1 files changed, 5 insertions(+), 6 deletions(-)
-
---- linux-2.4.20/./fs/ext3/namei.c~ext3-use-after-free 2003-04-08 23:35:51.000000000 -0600
-+++ linux-2.4.20-braam/./fs/ext3/namei.c       2003-04-08 23:35:51.000000000 -0600
-@@ -1521,8 +1521,11 @@ static int ext3_add_nondir(handle_t *han
- {
-       int err = ext3_add_entry(handle, dentry, inode);
-       if (!err) {
--              d_instantiate(dentry, inode);
--              return 0;
-+              err = ext3_mark_inode_dirty(handle, inode);
-+              if (err == 0) {
-+                      d_instantiate(dentry, inode);
-+                      return 0;
-+              }
-       }
-       ext3_dec_count(handle, inode);
-       iput(inode);
-@@ -1559,7 +1562,6 @@ static int ext3_create (struct inode * d
-               inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-               err = ext3_add_nondir(handle, dentry, inode);
--              ext3_mark_inode_dirty(handle, inode);
-       }
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -1586,7 +1588,6 @@ static int ext3_mknod (struct inode * di
-       if (!IS_ERR(inode)) {
-               init_special_inode(inode, mode, rdev);
-               err = ext3_add_nondir(handle, dentry, inode);
--              ext3_mark_inode_dirty(handle, inode);
-       }
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -2035,7 +2036,6 @@ static int ext3_symlink (struct inode * 
-       }
-       EXT3_I(inode)->i_disksize = inode->i_size;
-       err = ext3_add_nondir(handle, dentry, inode);
--      ext3_mark_inode_dirty(handle, inode);
- out_stop:
-       ext3_journal_stop(handle, dir);
-       return err;
-@@ -2069,7 +2069,6 @@ static int ext3_link (struct dentry * ol
-       atomic_inc(&inode->i_count);
-       err = ext3_add_nondir(handle, dentry, inode);
--      ext3_mark_inode_dirty(handle, inode);
-       ext3_journal_stop(handle, dir);
-       return err;
- }
-
-_
diff --git a/lustre/kernel_patches/patches/extN-2.4.18-ino_sb_fixup.patch b/lustre/kernel_patches/patches/extN-2.4.18-ino_sb_fixup.patch
deleted file mode 100644 (file)
index df46643..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
---- ./include/linux/ext3_fs.h.orig     Tue May  7 17:06:03 2002
-+++ ./include/linux/ext3_fs.h  Tue May  7 17:07:11 2002
-@@ -17,6 +17,8 @@
- #define _LINUX_EXT3_FS_H
- #include <linux/types.h>
-+#include <linux/ext3_fs_sb.h>
-+#include <linux/ext3_fs_i.h>
- /*
-  * The second extended filesystem constants/structures
-@@ -86,8 +88,8 @@
- #define EXT3_MIN_BLOCK_LOG_SIZE                 10
- #ifdef __KERNEL__
--#define EXT3_SB(sb)   (&((sb)->u.ext3_sb))
--#define EXT3_I(inode) (&((inode)->u.ext3_i))
-+#define EXT3_SB(sb)   ((struct ext3_sb_info *)&((sb)->u.generic_sbp))
-+#define EXT3_I(inode) ((struct ext3_inode_info *)&((inode)->u.generic_ip))
- #define EXT3_BLOCK_SIZE(s)            ((s)->s_blocksize)
- #define EXT3_BLOCK_SIZE_BITS(s)               ((s)->s_blocksize_bits)
-@@ -447,7 +447,9 @@
- #define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime
- static inline struct inode *orphan_list_entry(struct list_head *l)
- {
--      return list_entry(l, struct inode, u.ext3_i.i_orphan);
-+      return ((struct inode *)((char *)l -
-+              (unsigned long)(offsetof(struct inode, u.generic_ip) +
-+                              offsetof(struct ext3_inode_info, i_orphan))));
- }
- /*
diff --git a/lustre/kernel_patches/patches/extN-delete_thread.patch b/lustre/kernel_patches/patches/extN-delete_thread.patch
deleted file mode 100644 (file)
index 33f43d6..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
---- linux/include/linux/ext3_fs.h.orig Fri Mar 14 18:09:02 2003
-+++ linux/include/linux/ext3_fs.h      Fri Mar 14 18:10:20 2003
-@@ -190,7 +192,8 @@
-  */
- #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
---- linux/include/linux/ext3_fs_sb.h.orig      Tue Feb 11 16:34:33 2003
-+++ linux/include/linux/ext3_fs_sb.h   Mon Mar 10 14:42:07 2003
-@@ -29,6 +29,8 @@
- #define EXT3_MAX_GROUP_LOADED 32
-+#define EXT3_DELETE_THREAD
-+
- /*
-  * third extended-fs super-block data in memory
-  */
-@@ -73,7 +75,15 @@
-       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 */
---- linux/fs/ext3/super.c.orig Wed Mar 12 14:05:30 2003
-+++ linux/fs/ext3/super.c      Thu Mar 13 19:05:26 2003
-@@ -396,6 +396,207 @@
-       }
- }
-+#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);
-+      printk(KERN_INFO "EXT3-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 "ext3 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 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);
-+      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(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)
-+{
-+      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 ext3_delete_inode_thread(struct inode *old_inode)
-+{
-+      struct ext3_sb_info *sbi = EXT3_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 <= EXT3_NDIR_BLOCKS ||
-+          !sbi->s_delete_list.next) {
-+              ext3_delete_inode(old_inode);
-+              return;
-+      }
-+
-+      if (EXT3_I(old_inode)->i_state & EXT3_STATE_DELETE) {
-+              ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
-+                         old_inode->i_ino, blocks);
-+              ext3_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);
-+
-+      EXT3_SB(old_inode->i_sb)->s_mount_state |= EXT3_ORPHAN_FS;
-+      new_inode = iget(old_inode->i_sb, old_inode->i_ino);
-+      EXT3_SB(old_inode->i_sb)->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(KERN_DEBUG "delete inode %lu directly (bad read)\n",
-+                         old_inode->i_ino);
-+              ext3_delete_inode(old_inode);
-+              return;
-+      }
-+      J_ASSERT(new_inode != old_inode);
-+
-+      J_ASSERT(!list_empty(&EXT3_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.
-+       */
-+      EXT3_I(new_inode)->i_orphan = EXT3_I(old_inode)->i_orphan;
-+      EXT3_I(new_inode)->i_orphan.next->prev = &EXT3_I(new_inode)->i_orphan;
-+      EXT3_I(new_inode)->i_orphan.prev->next = &EXT3_I(new_inode)->i_orphan;
-+      EXT3_I(new_inode)->i_state |= EXT3_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 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);
-@@ -403,6 +578,7 @@
-       kdev_t j_dev = sbi->s_journal->j_dev;
-       int i;
-+      ext3_stop_delete_thread(sbi);
-       ext3_xattr_put_super(sb);
-       journal_destroy(sbi->s_journal);
-       if (!(sb->s_flags & MS_RDONLY)) {
-@@ -451,7 +627,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 */
-+#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 */
-       write_super_lockfs: ext3_write_super_lockfs, /* BKL not held. Take it */
-@@ -1205,6 +1385,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
diff --git a/lustre/kernel_patches/patches/extN-iget-debug.patch b/lustre/kernel_patches/patches/extN-iget-debug.patch
deleted file mode 100644 (file)
index dbe90c8..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
---- linux/fs/ext3/namei.c.orig Thu Jan 30 01:15:13 2003
-+++ linux/fs/ext3/namei.c      Sat Feb  1 00:33:46 2003
-@@ -710,6 +710,24 @@
-       return ret;
- }
-+static int ext3_find_inode(struct inode *inode, unsigned long ino,
-+                         void *opaque)
-+{
-+      const char *name = NULL;
-+      int len = 0;
-+
-+      if (opaque) {
-+              struct dentry *dentry = opaque;
-+              name = dentry->d_name.name;
-+              len = dentry->d_name.len;
-+      }
-+      printk(KERN_INFO "finding inode %s:%lu (%p) count %d (%p = %*s)\n",
-+             kdevname(inode->i_dev), ino, inode, atomic_read(&inode->i_count),
-+             opaque, len, name ? name : "");
-+
-+      return 1;
-+}
-+
- static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
- {
-       struct inode * inode;
-@@ -724,8 +742,8 @@
-       if (bh) {
-               unsigned long ino = le32_to_cpu(de->inode);
-               brelse (bh);
--              inode = iget(dir->i_sb, ino);
-+              inode = iget4(dir->i_sb, ino, ext3_find_inode, dentry);
-               if (!inode)
-                       return ERR_PTR(-EACCES);
---- linux/fs/ext3/inode.c.orig Thu Jan 30 01:15:13 2003
-+++ linux/fs/ext3/inode.c      Sat Feb  1 00:34:45 2003
-@@ -166,6 +166,9 @@
-  */
- void ext3_put_inode (struct inode * inode)
- {
-+      printk(KERN_INFO "putting inode %s:%lu (%p) count %d\n",
-+             kdevname(inode->i_dev), inode->i_ino, inode,
-+             atomic_read(&inode->i_count));
-       ext3_discard_prealloc (inode);
- }
diff --git a/lustre/kernel_patches/patches/extN-misc-fixup.patch b/lustre/kernel_patches/patches/extN-misc-fixup.patch
deleted file mode 100644 (file)
index 06ea72a..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
---- linux-2.4.17/fs/ext3/super.c.orig  Fri Dec 21 10:41:55 2001
-+++ linux-2.4.17/fs/ext3/super.c       Fri Mar 22 11:00:41 2002
-@@ -1344,10 +1342,10 @@
-               printk(KERN_ERR "EXT3-fs: I/O error on journal device\n");
-               goto out_journal;
-       }
--      if (ntohl(journal->j_superblock->s_nr_users) != 1) {
-+      if (be32_to_cpu(journal->j_superblock->s_nr_users) != 1) {
-               printk(KERN_ERR "EXT3-fs: External journal has more than one "
-                                       "user (unsupported) - %d\n",
--                      ntohl(journal->j_superblock->s_nr_users));
-+                      be32_to_cpu(journal->j_superblock->s_nr_users));
-               goto out_journal;
-       }
-       EXT3_SB(sb)->journal_bdev = bdev;
-@@ -1560,6 +1560,7 @@
-       unlock_kernel();
-       return ret;
- }
-+EXPORT_SYMBOL(ext3_force_commit); /* here to avoid potential patch collisions */
- /*
-  * Ext3 always journals updates to the superblock itself, so we don't
diff --git a/lustre/kernel_patches/patches/extN-noread.patch b/lustre/kernel_patches/patches/extN-noread.patch
deleted file mode 100644 (file)
index b104177..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-diff -ru lustre-head/fs/ext3/ialloc.c lustre/fs/ext3/ialloc.c
---- lustre-head/fs/ext3/ialloc.c       Mon Dec 23 10:02:58 2002
-+++ lustre/fs/ext3/ialloc.c    Mon Dec 23 09:46:20 2002
-@@ -289,6 +289,37 @@
- }
- /*
-+ * @block_group: block group of inode
-+ * @offset: relative offset of inode within @block_group
-+ *
-+ * Check whether any of the inodes in this disk block are in use.
-+ *
-+ * Caller must be holding superblock lock (group/bitmap read lock in future).
-+ */
-+int ext3_itable_block_used(struct super_block *sb, unsigned int block_group,
-+                         int offset)
-+{
-+      int bitmap_nr = load_inode_bitmap(sb, block_group);
-+      int inodes_per_block;
-+      unsigned long inum, iend;
-+      struct buffer_head *ibitmap;
-+
-+      if (bitmap_nr < 0)
-+              return 1;
-+
-+      inodes_per_block = sb->s_blocksize / EXT3_SB(sb)->s_inode_size;
-+      inum = offset & ~(inodes_per_block - 1);
-+      iend = inum + inodes_per_block;
-+      ibitmap = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
-+      for (; inum < iend; inum++) {
-+              if (inum != offset && ext3_test_bit(inum, ibitmap->b_data))
-+                      return 1;
-+      }
-+
-+      return 0;
-+}
-+
-+/*
-  * There are two policies for allocating an inode.  If the new inode is
-  * a directory, then a forward search is made for a block group with both
-  * free space and a low directory-to-inode ratio; if that fails, then of
-@@ -312,6 +343,7 @@
-       struct ext3_group_desc * gdp;
-       struct ext3_group_desc * tmp;
-       struct ext3_super_block * es;
-+      struct ext3_iloc iloc;
-       int err = 0;
-       /* Cannot create files in a deleted directory */
-@@ -505,7 +538,7 @@
-       ei->i_prealloc_count = 0;
- #endif
-       ei->i_block_group = i;
--      
-+
-       if (ei->i_flags & EXT3_SYNC_FL)
-               inode->i_flags |= S_SYNC;
-       if (IS_SYNC(inode))
-@@ -514,9 +547,18 @@
-       inode->i_generation = sbi->s_next_generation++;
-       ei->i_state = EXT3_STATE_NEW;
--      err = ext3_mark_inode_dirty(handle, inode);
-+      err = ext3_get_inode_loc_new(inode, &iloc, 1);
-       if (err) goto fail;
--      
-+      BUFFER_TRACE(iloc->bh, "get_write_access");
-+      err = ext3_journal_get_write_access(handle, iloc.bh);
-+      if (err) {
-+              brelse(iloc.bh);
-+              iloc.bh = NULL;
-+              goto fail;
-+      }
-+      err = ext3_mark_iloc_dirty(handle, inode, &iloc);
-+      if (err) goto fail;
-+
-       unlock_super (sb);
-       if(DQUOT_ALLOC_INODE(inode)) {
-               DQUOT_DROP(inode);
-diff -ru lustre-head/fs/ext3/inode.c lustre/fs/ext3/inode.c
---- lustre-head/fs/ext3/inode.c        Mon Dec 23 10:02:58 2002
-+++ lustre/fs/ext3/inode.c     Mon Dec 23 09:50:25 2002
-@@ -2011,23 +1994,28 @@
-       ext3_journal_stop(handle, inode);
- }
--/* 
-- * ext3_get_inode_loc returns with an extra refcount against the
-- * inode's underlying buffer_head on success. 
-- */
-+#define NUM_INODE_PREREAD     16
--int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
-+/*
-+ * ext3_get_inode_loc returns with an extra refcount against the inode's
-+ * underlying buffer_head on success.  If this is for a new inode allocation
-+ * (new is non-zero) then we may be able to optimize away the read if there
-+ * are no other in-use inodes in this inode table block.  If we need to do
-+ * a read, then read in a whole chunk of blocks to avoid blocking again soon
-+ * if we are doing lots of creates/updates.
-+ */
-+int ext3_get_inode_loc_new(struct inode *inode, struct ext3_iloc *iloc, int new)
- {
-       struct super_block *sb = inode->i_sb;
-       struct ext3_sb_info *sbi = EXT3_SB(sb);
--      struct buffer_head *bh = 0;
-+      struct buffer_head *bh[NUM_INODE_PREREAD];
-       unsigned long block;
-       unsigned long block_group;
-       unsigned long group_desc;
-       unsigned long desc;
-       unsigned long offset;
-       struct ext3_group_desc * gdp;
--              
-+
-       if ((inode->i_ino != EXT3_ROOT_INO &&
-               inode->i_ino != EXT3_JOURNAL_INO &&
-               inode->i_ino < EXT3_FIRST_INO(sb)) ||
-@@ -2042,38 +2034,86 @@
-       }
-       group_desc = block_group >> sbi->s_desc_per_block_bits;
-       desc = block_group & (sbi->s_desc_per_block - 1);
--      bh = sbi->s_group_desc[group_desc];
--      if (!bh) {
-+      if (!sbi->s_group_desc[group_desc]) {
-               ext3_error(sb, __FUNCTION__, "Descriptor not loaded");
-               goto bad_inode;
-       }
--      gdp = (struct ext3_group_desc *) bh->b_data;
-+      gdp = (struct ext3_group_desc *)(sbi->s_group_desc[group_desc]->b_data);
-+
-       /*
-        * Figure out the offset within the block group inode table
-        */
--      offset = ((inode->i_ino - 1) % sbi->s_inodes_per_group) *
--              sbi->s_inode_size;
-+      offset = ((inode->i_ino - 1) % sbi->s_inodes_per_group);
-+
-       block = le32_to_cpu(gdp[desc].bg_inode_table) +
--              (offset >> EXT3_BLOCK_SIZE_BITS(sb));
--      if (!(bh = sb_bread(sb, block))) {
--              ext3_error (sb, __FUNCTION__,
--                          "unable to read inode block - "
--                          "inode=%lu, block=%lu", inode->i_ino, block);
--              goto bad_inode;
-+              (offset * sbi->s_inode_size >> EXT3_BLOCK_SIZE_BITS(sb));
-+
-+      bh[0] = sb_getblk(sb, block);
-+      if (buffer_uptodate(bh[0]))
-+              goto done;
-+
-+      /* If we don't really need to read this block, and it isn't already
-+       * in memory, then we just zero it out.  Otherwise, we keep the
-+       * current block contents (deleted inode data) for posterity.
-+       */
-+      if (new && !ext3_itable_block_used(sb, block_group, offset)) {
-+              lock_buffer(bh[0]);
-+              memset(bh[0]->b_data, 0, bh[0]->b_size);
-+              mark_buffer_uptodate(bh[0], 1);
-+              unlock_buffer(bh[0]);
-+      } else {
-+              unsigned long block_end, itable_end;
-+              int count = 1;
-+
-+              itable_end = le32_to_cpu(gdp[desc].bg_inode_table) +
-+                              sbi->s_itb_per_group;
-+              block_end = block + NUM_INODE_PREREAD;
-+              if (block_end > itable_end)
-+                      block_end = itable_end;
-+
-+              for (; block < block_end; block++) {
-+                      bh[count] = sb_getblk(sb, block);
-+                      if (count && (buffer_uptodate(bh[count]) ||
-+                                    buffer_locked(bh[count]))) {
-+                              __brelse(bh[count]);
-+                      } else
-+                              count++;
-+              }
-+
-+              ll_rw_block(READ, count, bh);
-+
-+              /* Release all but the block we actually need (bh[0]) */
-+              while (--count > 0)
-+                      __brelse(bh[count]);
-+
-+              wait_on_buffer(bh[0]);
-+              if (!buffer_uptodate(bh[0])) {
-+                      ext3_error(sb, __FUNCTION__,
-+                                 "unable to read inode block - "
-+                                 "inode=%lu, block=%lu", inode->i_ino,
-+                                 bh[0]->b_blocknr);
-+                      goto bad_inode;
-+              }
-       }
--      offset &= (EXT3_BLOCK_SIZE(sb) - 1);
-+ done:
-+      offset = (offset * sbi->s_inode_size) & (EXT3_BLOCK_SIZE(sb) - 1);
--      iloc->bh = bh;
--      iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset);
-+      iloc->bh = bh[0];
-+      iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset);
-       iloc->block_group = block_group;
--      
-+
-       return 0;
--      
-+
-  bad_inode:
-       return -EIO;
- }
-+int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc)
-+{
-+      return ext3_get_inode_loc_new(inode, iloc, 0);
-+}
-+
- void ext3_read_inode(struct inode * inode)
- {
-       struct ext3_iloc iloc;
-diff -ru include/linux/ext3_fs.h.orig include/linux/ext3_fs.h
---- lustre/include/linux/ext3_fs.h.orig        Sat Mar  8 01:23:09 2003
-+++ lustre/include/linux/ext3_fs.h     Sat Mar  8 01:24:31 2003
-@@ -642,6 +646,8 @@
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
-+extern int ext3_itable_block_used(struct super_block *sb, unsigned int, int);
-+extern int ext3_get_inode_loc_new(struct inode *, struct ext3_iloc *, int);
- extern int  ext3_get_inode_loc (struct inode *, struct ext3_iloc *);
- extern void ext3_read_inode (struct inode *);
- extern void ext3_write_inode (struct inode *, int);
diff --git a/lustre/kernel_patches/patches/extN-san.patch b/lustre/kernel_patches/patches/extN-san.patch
deleted file mode 100644 (file)
index d8486f4..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
- fs/ext3/inode.c |   82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 files changed, 82 insertions(+)
-
---- linux-2.4.20/fs/ext3/inode.c~extN-san      2003-04-08 23:35:59.000000000 -0600
-+++ linux-2.4.20-braam/fs/ext3/inode.c 2003-04-08 23:35:59.000000000 -0600
-@@ -2734,3 +2734,85 @@ int ext3_change_inode_journal_flag(struc
-  * here, in ext3_aops_journal_start() to ensure that the forthcoming "see if we
-  * need to extend" test in ext3_prepare_write() succeeds.  
-  */
-+
-+/* for each block: 1 ind + 1 dind + 1 tind
-+ * for each block: 3 bitmap blocks
-+ * for each block: 3 group descriptor blocks
-+ * i inode block
-+ * 1 superblock
-+ * 2 * EXT3_SINGLEDATA_TRANS_BLOCKS for the quote files
-+ * ((1+1+1) * 3 * nblocks) + 1 + 1 + 2 * EXT3_SINGLEDATA_TRANS_BLOCKS
-+ *
-+ * XXX assuming:
-+ * (1) fs logic block size == page size
-+ * (2) ext3 in writeback mode
-+ */
-+static inline int ext3_san_write_trans_blocks(int nblocks)
-+{
-+      int ret;
-+      
-+      ret = (1 + 1 + 1) * 3 * nblocks + 1 + 1;
-+
-+#ifdef CONFIG_QUOTA
-+      ret += 2 * EXT3_SINGLEDATA_TRANS_BLOCKS;
-+#endif
-+
-+      return ret;
-+}
-+
-+/* Alloc blocks for an inode, while don't create any buffer/page
-+ * for data I/O; set the inode size if file is extended.
-+ *
-+ * @inode:    target inode
-+ * @blocks:   array of logic block number
-+ * @nblocks:  how many blocks need be alloced
-+ * @newsize:  new filesize we should set
-+ *
-+ * return:    0 success, otherwise failed
-+ *            (*blocks) contains physical block number alloced
-+ *
-+ * XXX this assume the fs block size == page size
-+ */
-+int ext3_prep_san_write(struct inode *inode, long *blocks,
-+                      int nblocks, loff_t newsize)
-+{
-+      handle_t *handle;
-+      struct buffer_head bh_tmp;
-+      int needed_blocks;
-+      int i, ret = 0, ret2;
-+
-+      needed_blocks = ext3_san_write_trans_blocks(nblocks);
-+
-+      lock_kernel();
-+      handle = ext3_journal_start(inode, needed_blocks);
-+      if (IS_ERR(handle)) {
-+              unlock_kernel();
-+              return PTR_ERR(handle);
-+      }
-+      unlock_kernel();
-+
-+      /* alloc blocks one by one */
-+      for (i = 0; i < nblocks; i++) {
-+              ret = ext3_get_block_handle(handle, inode, blocks[i],
-+                                              &bh_tmp, 1);
-+              if (ret)
-+                      break;
-+
-+              blocks[i] = bh_tmp.b_blocknr;
-+      }
-+
-+      /* set inode size if needed */
-+      if (!ret && (newsize > inode->i_size)) {
-+              inode->i_size = newsize;
-+              ext3_mark_inode_dirty(handle, inode);
-+      }
-+
-+      lock_kernel();
-+      ret2 = ext3_journal_stop(handle, inode);
-+      unlock_kernel();
-+
-+      if (!ret)
-+              ret = ret2;
-+      return ret;
-+}
-+EXPORT_SYMBOL(ext3_prep_san_write);
-
-_
diff --git a/lustre/kernel_patches/patches/extN-wantedi.patch b/lustre/kernel_patches/patches/extN-wantedi.patch
deleted file mode 100644 (file)
index fc74c6b..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
- fs/ext3/ialloc.c        |   38 ++++++++++++++++++++++++++++++++++++--
- fs/ext3/ioctl.c         |   25 +++++++++++++++++++++++++
- fs/ext3/namei.c         |   12 ++++++++----
- include/linux/ext3_fs.h |    5 ++++-
- 4 files changed, 73 insertions(+), 7 deletions(-)
-
---- linux-2.4.20/fs/ext3/namei.c~extN-wantedi  2003-04-08 23:35:55.000000000 -0600
-+++ linux-2.4.20-braam/fs/ext3/namei.c 2003-04-08 23:35:55.000000000 -0600
-@@ -1555,7 +1555,8 @@ static int ext3_create (struct inode * d
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
--      inode = ext3_new_inode (handle, dir, mode);
-+      inode = ext3_new_inode (handle, dir, mode,
-+                              (unsigned long)dentry->d_fsdata);
-       err = PTR_ERR(inode);
-       if (!IS_ERR(inode)) {
-               inode->i_op = &ext3_file_inode_operations;
-@@ -1583,7 +1584,8 @@ static int ext3_mknod (struct inode * di
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
--      inode = ext3_new_inode (handle, dir, mode);
-+      inode = ext3_new_inode (handle, dir, mode,
-+                              (unsigned long)dentry->d_fsdata);
-       err = PTR_ERR(inode);
-       if (!IS_ERR(inode)) {
-               init_special_inode(inode, mode, rdev);
-@@ -1613,7 +1615,8 @@ static int ext3_mkdir(struct inode * dir
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
--      inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
-+      inode = ext3_new_inode (handle, dir, S_IFDIR | mode,
-+                              (unsigned long)dentry->d_fsdata);
-       err = PTR_ERR(inode);
-       if (IS_ERR(inode))
-               goto out_stop;
-@@ -2009,7 +2012,8 @@ static int ext3_symlink (struct inode * 
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
--      inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
-+      inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO,
-+                              (unsigned long)dentry->d_fsdata);
-       err = PTR_ERR(inode);
-       if (IS_ERR(inode))
-               goto out_stop;
---- linux-2.4.20/fs/ext3/ialloc.c~extN-wantedi 2003-04-08 23:35:55.000000000 -0600
-+++ linux-2.4.20-braam/fs/ext3/ialloc.c        2003-04-08 23:35:55.000000000 -0600
-@@ -299,7 +299,8 @@ error_return:
-  * group to find a free inode.
-  */
- struct inode * ext3_new_inode (handle_t *handle,
--                              const struct inode * dir, int mode)
-+                              const struct inode * dir, int mode,
-+                              unsigned long goal)
- {
-       struct super_block * sb;
-       struct buffer_head * bh;
-@@ -323,7 +324,39 @@ struct inode * ext3_new_inode (handle_t 
-       init_rwsem(&inode->u.ext3_i.truncate_sem);
-       lock_super (sb);
--      es = sb->u.ext3_sb.s_es;
-+      es = EXT3_SB(sb)->s_es;
-+
-+      if (goal) {
-+              i = (goal - 1) / EXT3_INODES_PER_GROUP(sb);
-+              j = (goal - 1) % EXT3_INODES_PER_GROUP(sb);
-+              gdp = ext3_get_group_desc(sb, i, &bh2);
-+
-+              bitmap_nr = load_inode_bitmap (sb, i);
-+              if (bitmap_nr < 0)
-+                      goto fail;
-+
-+              bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
-+
-+              BUFFER_TRACE(bh, "get_write_access");
-+              err = ext3_journal_get_write_access(handle, bh);
-+              if (err) goto fail;
-+
-+              if (ext3_set_bit(j, bh->b_data)) {
-+                      printk(KERN_ERR "goal inode %lu unavailable\n", goal);
-+                      /* Oh well, we tried. */
-+                      goto repeat;
-+              }
-+
-+              BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
-+              err = ext3_journal_dirty_metadata(handle, bh);
-+              if (err) goto fail;
-+
-+              /* We've shortcircuited the allocation system successfully,
-+               * now finish filling in the inode.
-+               */
-+              goto have_bit_and_group;
-+      }
-+
- repeat:
-       gdp = NULL;
-       i = 0;
-@@ -438,6 +471,7 @@ repeat:
-               }
-               goto repeat;
-       }
-+ have_bit_and_group:
-       j += i * EXT3_INODES_PER_GROUP(sb) + 1;
-       if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) {
-               ext3_error (sb, "ext3_new_inode",
---- linux-2.4.20/fs/ext3/ioctl.c~extN-wantedi  2003-04-08 23:35:55.000000000 -0600
-+++ linux-2.4.20-braam/fs/ext3/ioctl.c 2003-04-08 23:35:55.000000000 -0600
-@@ -23,6 +23,31 @@ int ext3_ioctl (struct inode * inode, st
-       ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
-       switch (cmd) {
-+      case EXT3_IOC_CREATE_INUM: {
-+              char name[32];
-+              struct dentry *dchild, *dparent;
-+              int rc = 0;
-+
-+              dparent = list_entry(inode->i_dentry.next, struct dentry,
-+                                   d_alias);
-+              snprintf(name, sizeof name, "%lu", arg);
-+              dchild = lookup_one_len(name, dparent, strlen(name));
-+              if (dchild->d_inode) {
-+                      printk(KERN_ERR "%*s/%lu already exists (ino %lu)\n",
-+                             dparent->d_name.len, dparent->d_name.name, arg,
-+                             dchild->d_inode->i_ino);
-+                      rc = -EEXIST;
-+              } else {
-+                      dchild->d_fsdata = (void *)arg;
-+                      rc = vfs_create(inode, dchild, 0644);
-+                      if (rc)
-+                              printk(KERN_ERR "vfs_create: %d\n", rc);
-+                      else if (dchild->d_inode->i_ino != arg)
-+                              rc = -EEXIST;
-+              }
-+              dput(dchild);
-+              return rc;
-+      }
-       case EXT3_IOC_GETFLAGS:
-               flags = inode->u.ext3_i.i_flags & EXT3_FL_USER_VISIBLE;
-               return put_user(flags, (int *) arg);
---- linux-2.4.20/include/linux/ext3_fs.h~extN-wantedi  2003-04-08 23:35:55.000000000 -0600
-+++ linux-2.4.20-braam/include/linux/ext3_fs.h 2003-04-08 23:35:55.000000000 -0600
-@@ -201,6 +201,7 @@ struct ext3_group_desc
- #define       EXT3_IOC_SETFLAGS               _IOW('f', 2, long)
- #define       EXT3_IOC_GETVERSION             _IOR('f', 3, long)
- #define       EXT3_IOC_SETVERSION             _IOW('f', 4, long)
-+/* EXT3_IOC_CREATE_INUM at bottom of file (visible to kernel and user). */
- #define       EXT3_IOC_GETVERSION_OLD         _IOR('v', 1, long)
- #define       EXT3_IOC_SETVERSION_OLD         _IOW('v', 2, long)
- #ifdef CONFIG_JBD_DEBUG
-@@ -671,7 +672,8 @@ extern int ext3fs_dirhash(const char *na
-                         dx_hash_info *hinfo);
- /* ialloc.c */
--extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
-+extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int,
-+                                    unsigned long);
- extern void ext3_free_inode (handle_t *, struct inode *);
- extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
- extern unsigned long ext3_count_free_inodes (struct super_block *);
-@@ -757,4 +759,5 @@ extern struct inode_operations ext3_fast
- #endif        /* __KERNEL__ */
-+#define EXT3_IOC_CREATE_INUM                  _IOW('f', 5, long)
- #endif        /* _LINUX_EXT3_FS_H */
-
-_
diff --git a/lustre/kernel_patches/patches/htree-ext3-2.4.18.patch b/lustre/kernel_patches/patches/htree-ext3-2.4.18.patch
deleted file mode 100644 (file)
index a54e9ca..0000000
+++ /dev/null
@@ -1,1201 +0,0 @@
---- ./fs/ext3/super.c  2002/03/05 06:18:59     2.1
-+++ ./fs/ext3/super.c  2002/03/05 06:26:56
-@@ -529,6 +529,12 @@
-                                      "EXT3 Check option not supported\n");
- #endif
-               }
-+              else if (!strcmp (this_char, "index"))
-+#ifdef CONFIG_EXT3_INDEX
-+                      set_opt (*mount_options, INDEX);
-+#else
-+                      printk("EXT3 index option not supported\n");
-+#endif
-               else if (!strcmp (this_char, "debug"))
-                       set_opt (*mount_options, DEBUG);
-               else if (!strcmp (this_char, "errors")) {
-@@ -702,6 +708,12 @@
-       es->s_mtime = cpu_to_le32(CURRENT_TIME);
-       ext3_update_dynamic_rev(sb);
-       EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
-+
-+      if (test_opt(sb, INDEX))
-+              EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX);
-+      else if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
-+              set_opt (EXT3_SB(sb)->s_mount_opt, INDEX);
-+
-       ext3_commit_super (sb, es, 1);
-       if (test_opt (sb, DEBUG))
-               printk (KERN_INFO
---- ./fs/ext3/namei.c  2002/03/05 06:18:59     2.1
-+++ ./fs/ext3/namei.c  2002/03/06 00:13:18
-@@ -16,6 +16,10 @@
-  *        David S. Miller (davem@caip.rutgers.edu), 1995
-  *  Directory entry file type support and forward compatibility hooks
-  *    for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
-+ *  Hash Tree Directory indexing (c)
-+ *    Daniel Phillips, 2001
-+ *  Hash Tree Directory indexing porting
-+ *    Christopher Li, 2002
-  */
- #include <linux/fs.h>
-@@ -33,7 +33,7 @@
- #include <linux/string.h>
- #include <linux/locks.h>
- #include <linux/quotaops.h>
--
-+#include <linux/slab.h>
- /*
-  * define how far ahead to read directories while searching them.
-@@ -38,6 +42,437 @@
- #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
- #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
-+static struct buffer_head *ext3_append(handle_t *handle,
-+                                      struct inode *inode,
-+                                      u32 *block, int *err)
-+{
-+      struct buffer_head *bh;
-+
-+      *block = inode->i_size >> inode->i_sb->s_blocksize_bits;
-+
-+      if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
-+              inode->i_size += inode->i_sb->s_blocksize;
-+              EXT3_I(inode)->i_disksize = inode->i_size;
-+              ext3_journal_get_write_access(handle,bh);
-+      }
-+      return bh;
-+}
-+
-+#ifndef assert
-+#define assert(test) J_ASSERT(test)
-+#endif
-+
-+#ifndef swap
-+#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
-+#endif
-+
-+typedef struct { u32 v; } le_u32;
-+typedef struct { u16 v; } le_u16;
-+
-+#define dxtrace_on(command) command
-+#define dxtrace_off(command)
-+
-+struct fake_dirent
-+{
-+      /*le*/u32 inode;
-+      /*le*/u16 rec_len;
-+      u8 name_len;
-+      u8 file_type;
-+};
-+
-+struct dx_countlimit
-+{
-+      le_u16 limit;
-+      le_u16 count;
-+};
-+
-+struct dx_entry
-+{
-+      le_u32 hash;
-+      le_u32 block;
-+};
-+
-+/*
-+ * dx_root_info is laid out so that if it should somehow get overlaid by a
-+ * dirent the two low bits of the hash version will be zero.  Therefore, the
-+ * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
-+ */
-+
-+struct dx_root
-+{
-+      struct fake_dirent dot;
-+      char dot_name[4];
-+      struct fake_dirent dotdot;
-+      char dotdot_name[4];
-+      struct dx_root_info
-+      {
-+              le_u32 reserved_zero;
-+              u8 hash_version; /* 0 now, 1 at release */
-+              u8 info_length; /* 8 */
-+              u8 indirect_levels;
-+              u8 unused_flags;
-+      }
-+      info;
-+      struct dx_entry entries[0];
-+};
-+
-+struct dx_node
-+{
-+      struct fake_dirent fake;
-+      struct dx_entry entries[0];
-+};
-+
-+
-+struct dx_frame
-+{
-+      struct buffer_head *bh;
-+      struct dx_entry *entries;
-+      struct dx_entry *at;
-+};
-+
-+struct dx_map_entry
-+{
-+      u32 hash;
-+      u32 offs;
-+};
-+
-+typedef struct ext3_dir_entry_2 ext3_dirent;
-+static inline unsigned dx_get_block (struct dx_entry *entry);
-+static void dx_set_block (struct dx_entry *entry, unsigned value);
-+static inline unsigned dx_get_hash (struct dx_entry *entry);
-+static void dx_set_hash (struct dx_entry *entry, unsigned value);
-+static unsigned dx_get_count (struct dx_entry *entries);
-+static unsigned dx_get_limit (struct dx_entry *entries);
-+static void dx_set_count (struct dx_entry *entries, unsigned value);
-+static void dx_set_limit (struct dx_entry *entries, unsigned value);
-+static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
-+static unsigned dx_node_limit (struct inode *dir);
-+static unsigned dx_hack_hash (const u8 *name, int len);
-+static struct dx_frame *dx_probe (struct inode *dir, u32 hash, struct dx_frame *frame);
-+static void dx_release (struct dx_frame *frames);
-+static int dx_make_map (ext3_dirent *de, int size, struct dx_map_entry map[]);
-+static void dx_sort_map(struct dx_map_entry *map, unsigned count);
-+static ext3_dirent *dx_copy_dirents (char *from, char *to,
-+     struct dx_map_entry *map, int count);
-+static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
-+
-+
-+#ifdef CONFIG_EXT3_INDEX
-+/*
-+ * Future: use high four bits of block for coalesce-on-delete flags
-+ * Mask them off for now.
-+ */
-+
-+static inline unsigned dx_get_block (struct dx_entry *entry)
-+{
-+      return le32_to_cpu(entry->block.v) & 0x00ffffff;
-+}
-+
-+static inline void dx_set_block (struct dx_entry *entry, unsigned value)
-+{
-+      entry->block.v = cpu_to_le32(value);
-+}
-+
-+static inline unsigned dx_get_hash (struct dx_entry *entry)
-+{
-+      return le32_to_cpu(entry->hash.v);
-+}
-+
-+static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
-+{
-+      entry->hash.v = cpu_to_le32(value);
-+}
-+
-+static inline unsigned dx_get_count (struct dx_entry *entries)
-+{
-+      return le16_to_cpu(((struct dx_countlimit *) entries)->count.v);
-+}
-+
-+static inline unsigned dx_get_limit (struct dx_entry *entries)
-+{
-+      return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v);
-+}
-+
-+static inline void dx_set_count (struct dx_entry *entries, unsigned value)
-+{
-+      ((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value);
-+}
-+
-+static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
-+{
-+      ((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value);
-+}
-+
-+static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
-+{
-+      unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) -
-+              EXT3_DIR_REC_LEN(2) - infosize;
-+      return 0? 20: entry_space / sizeof(struct dx_entry);
-+}
-+
-+static inline unsigned dx_node_limit (struct inode *dir)
-+{
-+      unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0);
-+      return 0? 22: entry_space / sizeof(struct dx_entry);
-+}
-+
-+/* Hash function - not bad, but still looking for an ideal default */
-+
-+static unsigned dx_hack_hash (const u8 *name, int len)
-+{
-+      u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
-+      while (len--)
-+      {
-+              u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
-+              if (hash & 0x80000000) hash -= 0x7fffffff;
-+              hash1 = hash0;
-+              hash0 = hash;
-+      }
-+      return hash0;
-+}
-+
-+#define dx_hash(s,n) (dx_hack_hash(s,n) << 1)
-+
-+/*
-+ * Debug
-+ */
-+#ifdef DX_DEBUG
-+#define dxtrace dxtrace_on
-+static void dx_show_index (char * label, struct dx_entry *entries)
-+{
-+      int i, n = dx_get_count (entries);
-+      printk("%s index ", label);
-+      for (i = 0; i < n; i++)
-+      {
-+              printk("%x->%u ", i? dx_get_hash(entries + i): 0, dx_get_block(entries + i));
-+      }
-+      printk("\n");
-+}
-+
-+struct stats
-+{ 
-+      unsigned names;
-+      unsigned space;
-+      unsigned bcount;
-+};
-+
-+static struct stats dx_show_leaf (ext3_dirent *de, int size, int show_names)
-+{
-+      unsigned names = 0, space = 0;
-+      char *base = (char *) de;
-+      printk("names: ");
-+      while ((char *) de < base + size)
-+      {
-+              if (de->inode)
-+              {
-+                      if (show_names)
-+                      {
-+                              int len = de->name_len;
-+                              char *name = de->name;
-+                              while (len--) printk("%c", *name++);
-+                              printk(":%x.%u ", dx_hash (de->name, de->name_len), ((char *) de - base));
-+                      }
-+                      space += EXT3_DIR_REC_LEN(de->name_len);
-+                      names++;
-+              }
-+              de = (ext3_dirent *) ((char *) de + le16_to_cpu(de->rec_len));
-+      }
-+      printk("(%i)\n", names);
-+      return (struct stats) { names, space, 1 };
-+}
-+
-+struct stats dx_show_entries (struct inode *dir, struct dx_entry *entries, int levels)
-+{
-+      unsigned blocksize = dir->i_sb->s_blocksize;
-+      unsigned count = dx_get_count (entries), names = 0, space = 0, i;
-+      unsigned bcount = 0;
-+      struct buffer_head *bh;
-+      int err;
-+      printk("%i indexed blocks...\n", count);
-+      for (i = 0; i < count; i++, entries++)
-+      {
-+              u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0;
-+              u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
-+              struct stats stats;
-+              printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
-+              if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue;
-+              stats = levels?
-+                 dx_show_entries (dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
-+                 dx_show_leaf ((ext3_dirent *) bh->b_data, blocksize, 0);
-+              names += stats.names;
-+              space += stats.space;
-+              bcount += stats.bcount;
-+              brelse (bh);
-+      }
-+      if (bcount)
-+              printk("%snames %u, fullness %u (%u%%)\n", levels?"":"   ",
-+                      names, space/bcount,(space/bcount)*100/blocksize);
-+      return (struct stats) { names, space, bcount};
-+}
-+#else
-+#define dxtrace dxtrace_off
-+#endif
-+
-+/*
-+ * Probe for a directory leaf block to search
-+ */
-+
-+static struct dx_frame *
-+dx_probe(struct inode *dir, u32 hash, struct dx_frame *frame_in)
-+{
-+      unsigned count, indirect;
-+      struct dx_entry *at, *entries, *p, *q, *m;
-+      struct dx_root *root;
-+      struct buffer_head *bh;
-+      struct dx_frame *frame = frame_in;
-+      int err;
-+
-+      frame->bh = NULL;
-+      if (!(bh = ext3_bread(NULL, dir, 0, 0, &err)))
-+              goto fail;
-+      root = (struct dx_root *) bh->b_data;
-+      if (root->info.hash_version > 0 || root->info.unused_flags & 1) {
-+              brelse(bh);
-+              goto fail;
-+      }
-+      if ((indirect = root->info.indirect_levels) > 1) {
-+              brelse(bh);
-+              goto fail;
-+      }
-+      entries = (struct dx_entry *) (((char *) &root->info) + root->info.info_length);
-+      assert (dx_get_limit(entries) == dx_root_limit(dir, root->info.info_length));
-+      dxtrace (printk("Look up %x", hash));
-+      while (1)
-+      {
-+              count = dx_get_count(entries);
-+              assert (count && count <= dx_get_limit(entries));
-+              p = entries + 1;
-+              q = entries + count - 1;
-+              while (p <= q)
-+              {
-+                      m = p + (q - p)/2;
-+                      dxtrace(printk("."));
-+                      if (dx_get_hash(m) > hash)
-+                              q = m - 1;
-+                      else
-+                              p = m + 1;
-+              }
-+
-+              if (0) // linear search cross check
-+              {
-+                      unsigned n = count - 1;
-+                      at = entries;
-+                      while (n--)
-+                      {
-+                              dxtrace(printk(","));
-+                              if (dx_get_hash(++at) > hash)
-+                              {
-+                                      at--;
-+                                      break;
-+                              }
-+                      }
-+                      assert (at == p - 1);
-+              }
-+
-+              at = p - 1;
-+              dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
-+              frame->bh = bh;
-+              frame->entries = entries;
-+              frame->at = at;
-+              if (!indirect--) return frame;
-+              if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0,&err)))
-+                      goto fail2;
-+              at = entries = ((struct dx_node *) bh->b_data)->entries;
-+              assert (dx_get_limit(entries) == dx_node_limit (dir));
-+              frame++;
-+      }
-+fail2:
-+      while (frame >= frame_in) {
-+              brelse(frame->bh);
-+              frame--;
-+      }
-+fail:
-+      return NULL;
-+}
-+
-+static void dx_release (struct dx_frame *frames)
-+{
-+      if (frames[0].bh == NULL)
-+              return;
-+
-+      if (((struct dx_root *)frames[0].bh->b_data)->info.indirect_levels)
-+              brelse (frames[1].bh);
-+      brelse (frames[0].bh);
-+}
-+
-+/*
-+ * Directory block splitting, compacting
-+ */
-+
-+static int dx_make_map (ext3_dirent *de, int size, struct dx_map_entry map[])
-+{
-+      int count = 0;
-+      char *base = (char *) de;
-+      while ((char *) de < base + size) {
-+              if (de->name_len && de->inode) {
-+                      map[count].hash = dx_hash (de->name, de->name_len);
-+                      map[count].offs = (u32) ((char *) de - base);
-+                      count++;
-+              }
-+              de = (ext3_dirent *) ((char *) de + le16_to_cpu(de->rec_len));
-+      }
-+      return count;
-+}
-+
-+static void dx_sort_map (struct dx_map_entry *map, unsigned count)
-+{
-+        struct dx_map_entry *p, *q, *top = map + count - 1;
-+        int more;
-+        /* Combsort until bubble sort doesn't suck */
-+        while (count > 2)
-+      {
-+                count = count*10/13;
-+                if (count - 9 < 2) /* 9, 10 -> 11 */
-+                        count = 11;
-+                for (p = top, q = p - count; q >= map; p--, q--)
-+                        if (p->hash < q->hash)
-+                                swap(*p, *q);
-+        }
-+        /* Garden variety bubble sort */
-+        do {
-+                more = 0;
-+                q = top;
-+                while (q-- > map)
-+              {
-+                        if (q[1].hash >= q[0].hash)
-+                              continue;
-+                        swap(*(q+1), *q);
-+                        more = 1;
-+              }
-+      } while(more);
-+}
-+
-+static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
-+{
-+      struct dx_entry *entries = frame->entries;
-+      struct dx_entry *old = frame->at, *new = old + 1;
-+      int count = dx_get_count(entries);
-+
-+      assert(count < dx_get_limit(entries));
-+      assert(old < entries + count);
-+      memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
-+      dx_set_hash(new, hash);
-+      dx_set_block(new, block);
-+      dx_set_count(entries, count + 1);
-+}
-+#endif
-+
-+static void ext3_update_dx_flag(struct inode *inode)
-+{
-+      if (!test_opt(inode->i_sb, INDEX))
-+              EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL;
-+}
-+
- /*
-  * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure.
-  *
-@@ -95,6 +529,15 @@
- }
- /*
-+ * p is at least 6 bytes before the end of page
-+ */
-+static inline ext3_dirent *ext3_next_entry(ext3_dirent *p)
-+{
-+      return (ext3_dirent *)((char*)p + le16_to_cpu(p->rec_len));
-+}
-+
-+
-+/*
-  *    ext3_find_entry()
-  *
-  * finds an entry in the specified directory with the wanted name. It
-@@ -105,6 +548,8 @@
-  * The returned buffer_head has ->b_count elevated.  The caller is expected
-  * to brelse() it when appropriate.
-  */
-+
-+      
- static struct buffer_head * ext3_find_entry (struct dentry *dentry,
-                                       struct ext3_dir_entry_2 ** res_dir)
- {
-@@ -119,10 +564,70 @@
-       int num = 0;
-       int nblocks, i, err;
-       struct inode *dir = dentry->d_parent->d_inode;
-+      ext3_dirent *de, *top;
-       *res_dir = NULL;
-       sb = dir->i_sb;
-+      if (dentry->d_name.len > EXT3_NAME_LEN)
-+              return NULL;
-+      if (ext3_dx && is_dx(dir)) {
-+              u32 hash = dx_hash(dentry->d_name.name, dentry->d_name.len);
-+              struct dx_frame frames[2], *frame;
-+              if (!(frame = dx_probe (dir, hash, frames)))
-+                      return NULL;
-+dxnext:
-+              block = dx_get_block(frame->at);
-+              if (!(bh = ext3_bread (NULL,dir, block, 0, &err)))
-+                      goto dxfail;
-+              de = (ext3_dirent *) bh->b_data;
-+              top = (ext3_dirent *) ((char *) de + sb->s_blocksize -
-+                              EXT3_DIR_REC_LEN(0));
-+              for (; de < top; de = ext3_next_entry(de))
-+                      if (ext3_match(dentry->d_name.len, dentry->d_name.name, de)) {
-+                              if (!ext3_check_dir_entry("ext3_find_entry",
-+                                        dir, de, bh,
-+                                        (block<<EXT3_BLOCK_SIZE_BITS(sb))
-+                                         +((char *)de - bh->b_data))) {
-+                                      brelse (bh);
-+                                      goto dxfail;
-+                              }
-+                              *res_dir = de;
-+                              goto dxfound;
-+                      }
-+              brelse (bh);
-+              /* Same hash continues in next block?  Search on. */
-+              if (++(frame->at) == frame->entries + dx_get_count(frame->entries))
-+              {
-+                      struct buffer_head *bh2;
-+                      if (frame == frames)
-+                              goto dxfail;
-+                      if (++(frames->at) == frames->entries + dx_get_count(frames->entries))
-+                              goto dxfail;
-+                      /* should omit read if not continued */
-+                      if (!(bh2 = ext3_bread (NULL, dir,
-+                                              dx_get_block(frames->at),
-+                                              0, &err)))
-+                              goto dxfail;
-+                      brelse (frame->bh);
-+                      frame->bh = bh2;
-+                      frame->at = frame->entries = ((struct dx_node *) bh2->b_data)->entries;
-+                      /* Subtle: the 0th entry has the count, find the hash in frame above */
-+                      if ((dx_get_hash(frames->at) & -2) == hash)
-+                              goto dxnext;
-+                      goto dxfail;
-+              }
-+              if ((dx_get_hash(frame->at) & -2) == hash)
-+                      goto dxnext;
-+dxfail:
-+              dxtrace(printk("%s not found\n", name));
-+              dx_release (frames);
-+              return NULL;
-+dxfound:
-+              dx_release (frames);
-+              return bh;
-+      }
-+      
-       nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
-       start = dir->u.ext3_i.i_dir_start_lookup;
-       if (start >= nblocks)
-@@ -237,6 +748,90 @@
-               de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
- }
-+static ext3_dirent *
-+dx_copy_dirents (char *from, char *to, struct dx_map_entry *map, int count)
-+{
-+      unsigned rec_len = 0;
-+
-+      while (count--) {
-+              ext3_dirent *de = (ext3_dirent *) (from + map->offs);
-+              rec_len = EXT3_DIR_REC_LEN(de->name_len);
-+              memcpy (to, de, rec_len);
-+              ((ext3_dirent *) to)->rec_len = rec_len;
-+              to += rec_len;
-+              map++;
-+      }
-+      return (ext3_dirent *) (to - rec_len);
-+}
-+
-+#ifdef CONFIG_EXT3_INDEX
-+static ext3_dirent *do_split(handle_t *handle, struct inode *dir,
-+                      struct buffer_head **bh,struct dx_frame *frame,
-+                      u32 hash, int *error)
-+{
-+      unsigned count;
-+      struct buffer_head *bh2;
-+      u32 newblock;
-+      u32 hash2;
-+      struct dx_map_entry *map;
-+      char *data1 = (*bh)->b_data, *data2, *data3;
-+      unsigned split;
-+      ext3_dirent *de, *de2;
-+
-+      bh2 = ext3_append (handle, dir, &newblock, error);
-+      if (!(bh2))
-+      {
-+              brelse(*bh);
-+              *bh = NULL;
-+              return (ext3_dirent *)bh2;
-+      }
-+
-+      BUFFER_TRACE(*bh, "get_write_access");
-+      ext3_journal_get_write_access(handle, *bh);
-+      BUFFER_TRACE(frame->bh, "get_write_access");
-+      ext3_journal_get_write_access(handle, frame->bh);
-+
-+      data2 = bh2->b_data;
-+
-+      map = kmalloc(sizeof(*map) * PAGE_CACHE_SIZE/EXT3_DIR_REC_LEN(1) + 1,
-+                    GFP_KERNEL);
-+      if (!map)
-+              panic("no memory for do_split\n");
-+      count = dx_make_map((ext3_dirent *)data1, dir->i_sb->s_blocksize, map);
-+      split = count/2; // need to adjust to actual middle
-+      dx_sort_map (map, count);
-+      hash2 = map[split].hash;
-+      dxtrace(printk("Split block %i at %x, %i/%i\n",
-+              dx_get_block(frame->at), hash2, split, count-split));
-+
-+      /* Fancy dance to stay within two buffers */
-+      de2 = dx_copy_dirents (data1, data2, map + split, count - split);
-+      data3 = (char *) de2 + de2->rec_len;
-+      de = dx_copy_dirents (data1, data3, map, split);
-+      memcpy(data1, data3, (char *) de + de->rec_len - data3);
-+      de = (ext3_dirent *) ((char *) de - data3 + data1); // relocate de
-+      de->rec_len = cpu_to_le16(data1 + dir->i_sb->s_blocksize - (char *)de);
-+      de2->rec_len = cpu_to_le16(data2 + dir->i_sb->s_blocksize-(char *)de2);
-+      dxtrace(dx_show_leaf((ext3_dirent *)data1, dir->i_sb->s_blocksize, 1));
-+      dxtrace(dx_show_leaf((ext3_dirent *)data2, dir->i_sb->s_blocksize, 1));
-+
-+      /* Which block gets the new entry? */
-+      if (hash >= hash2)
-+      {
-+              swap(*bh, bh2);
-+              de = de2;
-+      }
-+      dx_insert_block(frame, hash2 + (hash2 == map[split-1].hash), newblock);
-+      ext3_journal_dirty_metadata (handle, bh2);
-+      brelse (bh2);
-+      ext3_journal_dirty_metadata (handle, frame->bh);
-+      dxtrace(dx_show_index ("frame", frame->entries));
-+      kfree(map);
-+      return de;
-+}
-+#endif
-+
-+
- /*
-  *    ext3_add_entry()
-  *
-@@ -255,118 +849,278 @@
-       struct inode *inode)
- {
-       struct inode *dir = dentry->d_parent->d_inode;
--      const char *name = dentry->d_name.name;
--      int namelen = dentry->d_name.len;
-       unsigned long offset;
--      unsigned short rec_len;
-       struct buffer_head * bh;
--      struct ext3_dir_entry_2 * de, * de1;
--      struct super_block * sb;
-+      ext3_dirent *de;
-+      struct super_block * sb = dir->i_sb;
-       int     retval;
-+      unsigned short reclen = EXT3_DIR_REC_LEN(dentry->d_name.len);
--      sb = dir->i_sb;
-+      unsigned nlen, rlen;
-+      u32 block, blocks;
-+      char *top;
--      if (!namelen)
-+      if (!dentry->d_name.len)
-               return -EINVAL;
--      bh = ext3_bread (handle, dir, 0, 0, &retval);
--      if (!bh)
--              return retval;
--      rec_len = EXT3_DIR_REC_LEN(namelen);
--      offset = 0;
--      de = (struct ext3_dir_entry_2 *) bh->b_data;
--      while (1) {
--              if ((char *)de >= sb->s_blocksize + bh->b_data) {
--                      brelse (bh);
--                      bh = NULL;
--                      bh = ext3_bread (handle, dir,
--                              offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval);
--                      if (!bh)
--                              return retval;
--                      if (dir->i_size <= offset) {
--                              if (dir->i_size == 0) {
--                                      brelse(bh);
--                                      return -ENOENT;
-+      if (ext3_dx && is_dx(dir)) {
-+              struct dx_frame frames[2], *frame;
-+              struct dx_entry *entries, *at;
-+              u32 hash;
-+              char *data1;
-+
-+              hash = dx_hash(dentry->d_name.name, dentry->d_name.len);
-+              /* FIXME: do something if dx_probe() fails here */
-+              frame = dx_probe(dir, hash, frames);
-+              entries = frame->entries;
-+              at = frame->at;
-+
-+              if (!(bh = ext3_bread(handle,dir, dx_get_block(at), 0,&retval)))
-+                      goto dxfail1;
-+
-+              BUFFER_TRACE(bh, "get_write_access");
-+              ext3_journal_get_write_access(handle, bh);
-+
-+              data1 = bh->b_data;
-+              de = (ext3_dirent *) data1;
-+              top = data1 + (0? 200: sb->s_blocksize);
-+              while ((char *) de < top)
-+              {
-+                      /* FIXME: check EEXIST and dir */
-+                      nlen = EXT3_DIR_REC_LEN(de->name_len);
-+                      rlen = le16_to_cpu(de->rec_len);
-+                      if ((de->inode? rlen - nlen: rlen) >= reclen)
-+                              goto dx_add;
-+                      de = (ext3_dirent *) ((char *) de + rlen);
-+              }
-+              /* Block full, should compress but for now just split */
-+              dxtrace(printk("using %u of %u node entries\n",
-+                      dx_get_count(entries), dx_get_limit(entries)));
-+              /* Need to split index? */
-+              if (dx_get_count(entries) == dx_get_limit(entries))
-+              {
-+                      u32 newblock;
-+                      unsigned icount = dx_get_count(entries);
-+                      int levels = frame - frames;
-+                      struct dx_entry *entries2;
-+                      struct dx_node *node2;
-+                      struct buffer_head *bh2;
-+                      if (levels && dx_get_count(frames->entries) == dx_get_limit(frames->entries))
-+                              goto dxfull;
-+                      bh2 = ext3_append (handle, dir, &newblock, &retval);
-+                      if (!(bh2))
-+                              goto dxfail2;
-+                      node2 = (struct dx_node *)(bh2->b_data);
-+                      entries2 = node2->entries;
-+                      node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
-+                      node2->fake.inode = 0;
-+                      BUFFER_TRACE(frame->bh, "get_write_access");
-+                      ext3_journal_get_write_access(handle, frame->bh);
-+                      if (levels)
-+                      {
-+                              unsigned icount1 = icount/2, icount2 = icount - icount1;
-+                              unsigned hash2 = dx_get_hash(entries + icount1);
-+                              dxtrace(printk("Split index %i/%i\n", icount1, icount2));
-+                              
-+                              BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
-+                              ext3_journal_get_write_access(handle, frames[0].bh);
-+                              
-+                              memcpy ((char *) entries2, (char *) (entries + icount1),
-+                                      icount2 * sizeof(struct dx_entry));
-+                              dx_set_count (entries, icount1);
-+                              dx_set_count (entries2, icount2);
-+                              dx_set_limit (entries2, dx_node_limit(dir));
-+
-+                              /* Which index block gets the new entry? */
-+                              if (at - entries >= icount1) {
-+                                      frame->at = at = at - entries - icount1 + entries2;
-+                                      frame->entries = entries = entries2;
-+                                      swap(frame->bh, bh2);
-                               }
--
--                              ext3_debug ("creating next block\n");
--
--                              BUFFER_TRACE(bh, "get_write_access");
--                              ext3_journal_get_write_access(handle, bh);
--                              de = (struct ext3_dir_entry_2 *) bh->b_data;
--                              de->inode = 0;
--                              de->rec_len = le16_to_cpu(sb->s_blocksize);
--                              dir->u.ext3_i.i_disksize =
--                                      dir->i_size = offset + sb->s_blocksize;
--                              dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
--                              ext3_mark_inode_dirty(handle, dir);
-+                              dx_insert_block (frames + 0, hash2, newblock);
-+                              dxtrace(dx_show_index ("node", frames[1].entries));
-+                              dxtrace(dx_show_index ("node",
-+                                      ((struct dx_node *) bh2->b_data)->entries));
-+                              ext3_journal_dirty_metadata(handle, bh2);
-+                              brelse (bh2);
-                       } else {
--
--                              ext3_debug ("skipping to next block\n");
--
--                              de = (struct ext3_dir_entry_2 *) bh->b_data;
-+                              dxtrace(printk("Creating second level index...\n"));
-+                              memcpy((char *) entries2, (char *) entries,
-+                                      icount * sizeof(struct dx_entry));
-+                              dx_set_limit(entries2, dx_node_limit(dir));
-+
-+                              /* Set up root */
-+                              dx_set_count(entries, 1);
-+                              dx_set_block(entries + 0, newblock);
-+                              ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
-+
-+                              /* Add new access path frame */
-+                              frame = frames + 1;
-+                              frame->at = at = at - entries + entries2;
-+                              frame->entries = entries = entries2;
-+                              frame->bh = bh2;
-+                              ext3_journal_get_write_access(handle, frame->bh);
-                       }
-+                      ext3_journal_dirty_metadata(handle, frames[0].bh);
-               }
--              if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh,
--                                         offset)) {
--                      brelse (bh);
--                      return -ENOENT;
--              }
--              if (ext3_match (namelen, name, de)) {
-+              de = do_split(handle, dir, &bh, frame, hash, &retval);
-+              dx_release (frames);
-+              if (!(de))
-+                      goto fail;
-+              nlen = EXT3_DIR_REC_LEN(de->name_len);
-+              rlen = le16_to_cpu(de->rec_len);
-+              goto add;
-+
-+dx_add:
-+              dx_release (frames);
-+              goto add;
-+
-+dxfull:
-+              ext3_warning(sb, __FUNCTION__, "Directory index full!\n");
-+              retval = -ENOSPC;
-+dxfail2:
-+              brelse(bh);
-+dxfail1:
-+              dx_release (frames);
-+              goto fail1;
-+      }
-+
-+      blocks = dir->i_size >> sb->s_blocksize_bits;
-+      for (block = 0, offset = 0; block < blocks; block++) {
-+              bh = ext3_bread(handle, dir, block, 0, &retval);
-+              if(!bh)
-+                      return retval;
-+              de = (ext3_dirent *)bh->b_data;
-+              top = bh->b_data + sb->s_blocksize - reclen;
-+              while ((char *) de <= top) {
-+                      if (!ext3_check_dir_entry("ext3_add_entry", dir, de,
-+                                                bh, offset)) {
-+                              brelse (bh);
-+                              return -EIO;
-+                      }
-+                      if (ext3_match(dentry->d_name.len,dentry->d_name.name,de)) {
-                               brelse (bh);
-                               return -EEXIST;
--              }
--              if ((le32_to_cpu(de->inode) == 0 &&
--                              le16_to_cpu(de->rec_len) >= rec_len) ||
--                  (le16_to_cpu(de->rec_len) >=
--                              EXT3_DIR_REC_LEN(de->name_len) + rec_len)) {
--                      BUFFER_TRACE(bh, "get_write_access");
--                      ext3_journal_get_write_access(handle, bh);
--                      /* By now the buffer is marked for journaling */
--                      offset += le16_to_cpu(de->rec_len);
--                      if (le32_to_cpu(de->inode)) {
--                              de1 = (struct ext3_dir_entry_2 *) ((char *) de +
--                                      EXT3_DIR_REC_LEN(de->name_len));
--                              de1->rec_len =
--                                      cpu_to_le16(le16_to_cpu(de->rec_len) -
--                                      EXT3_DIR_REC_LEN(de->name_len));
--                              de->rec_len = cpu_to_le16(
--                                              EXT3_DIR_REC_LEN(de->name_len));
--                              de = de1;
-                       }
--                      de->file_type = EXT3_FT_UNKNOWN;
--                      if (inode) {
--                              de->inode = cpu_to_le32(inode->i_ino);
--                              ext3_set_de_type(dir->i_sb, de, inode->i_mode);
--                      } else
--                              de->inode = 0;
--                      de->name_len = namelen;
--                      memcpy (de->name, name, namelen);
--                      /*
--                       * XXX shouldn't update any times until successful
--                       * completion of syscall, but too many callers depend
--                       * on this.
--                       *
--                       * XXX similarly, too many callers depend on
--                       * ext3_new_inode() setting the times, but error
--                       * recovery deletes the inode, so the worst that can
--                       * happen is that the times are slightly out of date
--                       * and/or different from the directory change time.
--                       */
--                      dir->i_mtime = dir->i_ctime = CURRENT_TIME;
--                      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
--                      dir->i_version = ++event;
--                      ext3_mark_inode_dirty(handle, dir);
--                      BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
--                      ext3_journal_dirty_metadata(handle, bh);
-+                      nlen = EXT3_DIR_REC_LEN(de->name_len);
-+                      rlen = le16_to_cpu(de->rec_len);
-+                      if ((de->inode ? rlen - nlen: rlen) >= reclen)
-+                              goto add;
-+                      de = (ext3_dirent *)((char *)de + rlen);
-+                      offset += rlen;
-+              }
-+              if (ext3_dx && blocks == 1 && test_opt(sb, INDEX))
-+                      goto dx_make_index;
-+              brelse(bh);
-+      }
-+      bh = ext3_append(handle, dir, &block, &retval);
-+      if (!bh)
-+              return retval;
-+      de = (ext3_dirent *) bh->b_data;
-+      de->inode = 0;
-+      de->rec_len = cpu_to_le16(rlen = sb->s_blocksize);
-+      nlen = 0;
-+      goto add;
-+
-+add:
-+      BUFFER_TRACE(bh, "get_write_access");
-+      ext3_journal_get_write_access(handle, bh);
-+      /* By now the buffer is marked for journaling */
-+      if (de->inode) {
-+              ext3_dirent *de1 = (ext3_dirent *)((char *)de + nlen);
-+              de1->rec_len = cpu_to_le16(rlen - nlen);
-+              de->rec_len = cpu_to_le16(nlen);
-+              de = de1;
-+      }
-+      de->file_type = EXT3_FT_UNKNOWN;
-+      if (inode) {
-+              de->inode = cpu_to_le32(inode->i_ino);
-+              ext3_set_de_type(dir->i_sb, de, inode->i_mode);
-+      } else
-+              de->inode = 0;
-+      de->name_len = dentry->d_name.len;
-+      memcpy (de->name, dentry->d_name.name, dentry->d_name.len);
-+      /*
-+       * XXX shouldn't update any times until successful
-+       * completion of syscall, but too many callers depend
-+       * on this.
-+       *
-+       * XXX similarly, too many callers depend on
-+       * ext3_new_inode() setting the times, but error
-+       * recovery deletes the inode, so the worst that can
-+       * happen is that the times are slightly out of date
-+       * and/or different from the directory change time.
-+       */
-+      dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-+      ext3_update_dx_flag(dir);
-+      dir->i_version = ++event;
-+      ext3_mark_inode_dirty(handle, dir);
-+      BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
-+      ext3_journal_dirty_metadata(handle, bh);
-+      brelse(bh);
-+      return 0;
-+
-+dx_make_index:
-+      {
-+              struct buffer_head *bh2;
-+              struct dx_root *root;
-+              struct dx_frame frames[2], *frame;
-+              struct dx_entry *entries;
-+              ext3_dirent *de2;
-+              char *data1;
-+              unsigned len;
-+              u32 hash;
-+              
-+              dxtrace(printk("Creating index\n"));
-+              ext3_journal_get_write_access(handle, bh);
-+              root = (struct dx_root *) bh->b_data;
-+              
-+              EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
-+              bh2 = ext3_append (handle, dir, &block, &retval);
-+              if (!(bh2))
-+              {
-                       brelse(bh);
--                      return 0;
-+                      return retval;
-               }
--              offset += le16_to_cpu(de->rec_len);
--              de = (struct ext3_dir_entry_2 *)
--                      ((char *) de + le16_to_cpu(de->rec_len));
-+              data1 = bh2->b_data;
-+
-+              /* The 0th block becomes the root, move the dirents out */
-+              de = (ext3_dirent *) &root->info;
-+              len = ((char *) root) + sb->s_blocksize - (char *) de;
-+              memcpy (data1, de, len);
-+              de = (ext3_dirent *) data1;
-+              top = data1 + len;
-+              while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top)
-+                      de = de2;
-+              de->rec_len = cpu_to_le16(data1 + sb->s_blocksize - (char *)de);
-+              /* Initialize the root; the dot dirents already exist */
-+              de = (ext3_dirent *) (&root->dotdot);
-+              de->rec_len = cpu_to_le16(sb->s_blocksize-EXT3_DIR_REC_LEN(2));
-+              memset (&root->info, 0, sizeof(root->info));
-+              root->info.info_length = sizeof(root->info);
-+              entries = root->entries;
-+              dx_set_block (entries, 1);
-+              dx_set_count (entries, 1);
-+              dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
-+
-+              /* Initialize as for dx_probe */
-+              hash = dx_hash (dentry->d_name.name, dentry->d_name.len);
-+              frame = frames;
-+              frame->entries = entries;
-+              frame->at = entries;
-+              frame->bh = bh;
-+              bh = bh2;
-+              de = do_split(handle,dir, &bh, frame, hash, &retval);
-+              dx_release (frames);
-+              if (!(de))
-+                      return retval;
-+              nlen = EXT3_DIR_REC_LEN(de->name_len);
-+              rlen = le16_to_cpu(de->rec_len);
-+              goto add;
-       }
--      brelse (bh);
--      return -ENOSPC;
-+fail1:
-+      return retval;
-+fail:
-+      return -ENOENT;
- }
- /*
-@@ -451,7 +1212,8 @@
-       struct inode * inode;
-       int err;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
-@@ -478,7 +1240,8 @@
-       struct inode *inode;
-       int err;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
-@@ -507,7 +1270,8 @@
-       if (dir->i_nlink >= EXT3_LINK_MAX)
-               return -EMLINK;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
-@@ -550,7 +1320,7 @@
-       if (err)
-               goto out_no_entry;
-       dir->i_nlink++;
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
-       d_instantiate(dentry, inode);
- out_stop:
-@@ -832,7 +1596,7 @@
-       ext3_mark_inode_dirty(handle, inode);
-       dir->i_nlink--;
-       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
- end_rmdir:
-@@ -878,7 +1642,7 @@
-       if (retval)
-               goto end_unlink;
-       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
--      dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(dir);
-       ext3_mark_inode_dirty(handle, dir);
-       inode->i_nlink--;
-       if (!inode->i_nlink)
-@@ -904,7 +1668,8 @@
-       if (l > dir->i_sb->s_blocksize)
-               return -ENAMETOOLONG;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5);
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5);
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
-@@ -959,7 +1724,8 @@
-       if (inode->i_nlink >= EXT3_LINK_MAX)
-               return -EMLINK;
--      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS);
-+      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS);
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
-@@ -995,7 +1761,8 @@
-       old_bh = new_bh = dir_bh = NULL;
--      handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2);
-+      handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
-+                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
-@@ -1077,7 +1844,7 @@
-               new_inode->i_ctime = CURRENT_TIME;
-       }
-       old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
--      old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+      ext3_update_dx_flag(old_dir);
-       if (dir_bh) {
-               BUFFER_TRACE(dir_bh, "get_write_access");
-               ext3_journal_get_write_access(handle, dir_bh);
-@@ -1089,7 +1856,7 @@
-                       new_inode->i_nlink--;
-               } else {
-                       new_dir->i_nlink++;
--                      new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
-+                      ext3_update_dx_flag(new_dir);
-                       ext3_mark_inode_dirty(handle, new_dir);
-               }
-       }
---- ./include/linux/ext3_fs.h  2002/03/05 06:18:59     2.1
-+++ ./include/linux/ext3_fs.h  2002/03/05 06:26:56
-@@ -339,6 +339,7 @@
-   #define EXT3_MOUNT_WRITEBACK_DATA   0x0C00  /* No data ordering */
- #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 */
- /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
- #ifndef _LINUX_EXT2_FS_H
-@@ -575,6 +576,24 @@
- #define EXT3_DIR_ROUND                        (EXT3_DIR_PAD - 1)
- #define EXT3_DIR_REC_LEN(name_len)    (((name_len) + 8 + EXT3_DIR_ROUND) & \
-                                        ~EXT3_DIR_ROUND)
-+/*
-+ * Hash Tree Directory indexing
-+ * (c) Daniel Phillips, 2001
-+ */
-+
-+#define CONFIG_EXT3_INDEX
-+
-+#ifdef CONFIG_EXT3_INDEX
-+  enum {ext3_dx = 1};
-+  #define is_dx(dir) (EXT3_I(dir)->i_flags & EXT3_INDEX_FL)
-+#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
-+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
-+#else
-+  enum {ext3_dx = 0};
-+  #define is_dx(dir) 0
-+#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
-+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
-+#endif
- #ifdef __KERNEL__
- /*
---- ./include/linux/ext3_jbd.h 2002/03/05 06:18:59     2.1
-+++ ./include/linux/ext3_jbd.h 2002/03/05 06:33:54
-@@ -63,6 +63,8 @@
- #define EXT3_RESERVE_TRANS_BLOCKS     12
-+#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8
-+
- int
- ext3_mark_iloc_dirty(handle_t *handle, 
-                    struct inode *inode,
diff --git a/lustre/kernel_patches/patches/invalidate_show.patch b/lustre/kernel_patches/patches/invalidate_show.patch
deleted file mode 100644 (file)
index c3ae2f5..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
---- lum/fs/inode.c     Sat Oct 19 11:42:42 2002
-+++ linux-2.4.18-uml35-ext3online/fs/inode.c   Mon Oct 14 00:41:20 2002
-@@ -606,7 +553,8 @@ static void dispose_list(struct list_hea
- /*
-  * Invalidate all inodes for a device.
-  */
--static int invalidate_list(struct list_head *head, struct super_block * sb, struct list_head * dispose)
-+static int invalidate_list(struct list_head *head, struct super_block * sb,
-+                         struct list_head * dispose, int show)
- {
-       struct list_head *next;
-       int busy = 0, count = 0;
-@@ -631,6 +579,11 @@ static int invalidate_list(struct list_h
-                       count++;
-                       continue;
-               }
-+              if (show)
-+                      printk(KERN_ERR
-+                             "inode busy: dev %s:%lu (%p) mode %o count %u\n",
-+                             kdevname(sb->s_dev), inode->i_ino, inode,
-+                             inode->i_mode, atomic_read(&inode->i_count));
-               busy = 1;
-       }
-       /* only unused inodes may be cached with i_count zero */
-@@ -649,22 +601,23 @@ static int invalidate_list(struct list_h
- /**
-  *    invalidate_inodes       - discard the inodes on a device
-  *    @sb: superblock
-+ *    @show: whether we should display any busy inodes found
-  *
-  *    Discard all of the inodes for a given superblock. If the discard
-  *    fails because there are busy inodes then a non zero value is returned.
-  *    If the discard is successful all the inodes have been discarded.
-  */
-  
--int invalidate_inodes(struct super_block * sb)
-+int invalidate_inodes(struct super_block * sb, int show)
- {
-       int busy;
-       LIST_HEAD(throw_away);
-       spin_lock(&inode_lock);
--      busy = invalidate_list(&inode_in_use, sb, &throw_away);
--      busy |= invalidate_list(&inode_unused, sb, &throw_away);
--      busy |= invalidate_list(&sb->s_dirty, sb, &throw_away);
--      busy |= invalidate_list(&sb->s_locked_inodes, sb, &throw_away);
-+      busy = invalidate_list(&inode_in_use, sb, &throw_away, show);
-+      busy |= invalidate_list(&inode_unused, sb, &throw_away, show);
-+      busy |= invalidate_list(&sb->s_dirty, sb, &throw_away, show);
-+      busy |= invalidate_list(&sb->s_locked_inodes, sb, &throw_away, show);
-       spin_unlock(&inode_lock);
-       dispose_list(&throw_away);
-@@ -690,7 +643,7 @@ int invalidate_device(kdev_t dev, int do
-                * hold).
-                */
-               shrink_dcache_sb(sb);
--              res = invalidate_inodes(sb);
-+              res = invalidate_inodes(sb, 0);
-               drop_super(sb);
-       }
-       invalidate_buffers(dev);
---- lum/fs/super.c.orig        Sat Oct 19 11:42:42 2002
-+++ lum/fs/super.c     Wed Oct 30 17:16:55 2002
-@@ -936,7 +936,7 @@
-       lock_super(sb);
-       lock_kernel();
-       sb->s_flags &= ~MS_ACTIVE;
--      invalidate_inodes(sb);  /* bad name - it should be evict_inodes() */
-+      invalidate_inodes(sb, 0);  /* bad name - it should be evict_inodes() */
-       if (sop) {
-               if (sop->write_super && sb->s_dirt)
-                       sop->write_super(sb);
-@@ -945,7 +945,7 @@
-       }
-       /* Forget any remaining inodes */
--      if (invalidate_inodes(sb)) {
-+      if (invalidate_inodes(sb, 1)) {
-               printk(KERN_ERR "VFS: Busy inodes after unmount. "
-                       "Self-destruct in 5 seconds.  Have a nice day...\n");
-       }
---- lum/include/linux/fs.h     Wed Oct 30 17:10:42 2002
-+++ lum/include/linux/fs.h.orig        Tue Oct 22 23:15:00 2002
-@@ -1261,7 +1261,7 @@
- extern void set_buffer_flushtime(struct buffer_head *);
- extern void balance_dirty(void);
- extern int check_disk_change(kdev_t);
--extern int invalidate_inodes(struct super_block *);
-+extern int invalidate_inodes(struct super_block *, int);
- extern int invalidate_device(kdev_t, int);
- extern void invalidate_inode_pages(struct inode *);
- extern void invalidate_inode_pages2(struct address_space *);
---- lum/fs/smbfs/inode.c.orig  Mon Feb 25 12:38:09 2002
-+++ lum/fs/smbfs/inode.c       Thu Feb  6 21:34:26 2003
-@@ -166,7 +166,7 @@
- {
-       VERBOSE("\n");
-       shrink_dcache_sb(SB_of(server));
--      invalidate_inodes(SB_of(server));
-+      invalidate_inodes(SB_of(server), 0);
- }
- /*
diff --git a/lustre/kernel_patches/patches/iod-rmap-exports-2.4.20.patch b/lustre/kernel_patches/patches/iod-rmap-exports-2.4.20.patch
deleted file mode 100644 (file)
index 3fdf3fd..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
- fs/Makefile     |    4 +++-
- fs/inode.c      |    4 +++-
- mm/Makefile     |    2 +-
- mm/page_alloc.c |    1 +
- mm/vmscan.c     |    3 +++
- 5 files changed, 11 insertions(+), 3 deletions(-)
-
---- linux-rh-2.4.20-6/fs/inode.c~iod-rmap-exports      Tue Apr  1 01:01:56 2003
-+++ linux-rh-2.4.20-6-braam/fs/inode.c Tue Apr  1 01:01:56 2003
-@@ -5,6 +5,7 @@
-  */
- #include <linux/config.h>
-+#include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/string.h>
- #include <linux/mm.h>
-@@ -66,7 +67,8 @@ static LIST_HEAD(anon_hash_chain); /* fo
-  * NOTE! You also have to own the lock if you change
-  * the i_state of an inode while it is in use..
-  */
--static spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
-+spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
-+EXPORT_SYMBOL(inode_lock);
- /*
-  * Statistics gathering..
---- linux-rh-2.4.20-6/fs/Makefile~iod-rmap-exports     Tue Apr  1 01:01:56 2003
-+++ linux-rh-2.4.20-6-braam/fs/Makefile        Tue Apr  1 01:02:34 2003
-@@ -1,3 +1,5 @@
-+
-+
- #
- # Makefile for the Linux filesystems.
- #
-@@ -7,7 +9,7 @@
- O_TARGET := fs.o
--export-objs :=        filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o
-+export-objs :=        filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o inode.o
- mod-subdirs :=        nls
- obj-y :=      open.o read_write.o devices.o file_table.o buffer.o \
---- linux-rh-2.4.20-6/mm/vmscan.c~iod-rmap-exports     Tue Apr  1 01:01:56 2003
-+++ linux-rh-2.4.20-6-braam/mm/vmscan.c        Tue Apr  1 01:01:56 2003
-@@ -15,6 +15,8 @@
-  *  O(1) rmap vm, Arjan van de ven <arjanv@redhat.com>
-  */
-+#include <linux/config.h>
-+#include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/kernel_stat.h>
- #include <linux/swap.h>
-@@ -1061,6 +1063,7 @@ void wakeup_kswapd(unsigned int gfp_mask
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&kswapd_done, &wait);
- }
-+EXPORT_SYMBOL(wakeup_kswapd);
- static void wakeup_memwaiters(void)
- {
---- linux-rh-2.4.20-6/mm/Makefile~iod-rmap-exports     Tue Apr  1 01:01:56 2003
-+++ linux-rh-2.4.20-6-braam/mm/Makefile        Tue Apr  1 01:01:56 2003
-@@ -9,7 +9,7 @@
- O_TARGET := mm.o
--export-objs := shmem.o filemap.o memory.o page_alloc.o mempool.o
-+export-objs := shmem.o filemap.o memory.o page_alloc.o mempool.o vmscan.o
- obj-y  := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
-           vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \
---- linux-rh-2.4.20-6/mm/page_alloc.c~iod-rmap-exports Tue Apr  1 01:01:56 2003
-+++ linux-rh-2.4.20-6-braam/mm/page_alloc.c    Tue Apr  1 01:01:56 2003
-@@ -27,6 +27,7 @@
- int nr_swap_pages;
- pg_data_t *pgdat_list;
-+EXPORT_SYMBOL(pgdat_list);
- /*
-  *
-
-_
diff --git a/lustre/kernel_patches/patches/iod-rmap-exports.patch b/lustre/kernel_patches/patches/iod-rmap-exports.patch
deleted file mode 100644 (file)
index 00eba97..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
---- linux-chaos/fs/inode.c.b_io_export Wed Jan 29 16:56:15 2003
-+++ linux-chaos/fs/inode.c     Wed Jan 29 16:56:27 2003
-@@ -66,7 +66,8 @@
-  * NOTE! You also have to own the lock if you change
-  * the i_state of an inode while it is in use..
-  */
--static spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
-+spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
-+EXPORT_SYMBOL(inode_lock);
- /*
-  * Statistics gathering..
---- linux-chaos/fs/Makefile.b_io_export        Wed Jan 29 16:56:45 2003
-+++ linux-chaos/fs/Makefile    Wed Jan 29 16:56:53 2003
-@@ -7,7 +7,7 @@
- O_TARGET := fs.o
--export-objs :=        filesystems.o open.o dcache.o buffer.o
-+export-objs :=        filesystems.o open.o dcache.o buffer.o inode.o
- mod-subdirs :=        nls
- obj-y :=      open.o read_write.o devices.o file_table.o buffer.o \
---- linux-chaos/mm/filemap.c.b_io_export       Wed Jan 29 16:50:39 2003
-+++ linux-chaos/mm/filemap.c   Wed Jan 29 16:51:11 2003
-@@ -65,6 +65,7 @@
-  *                    pagecache_lock
-  */
- spinlock_cacheline_t pagemap_lru_lock_cacheline = {SPIN_LOCK_UNLOCKED};
-+EXPORT_SYMBOL(pagemap_lru_lock_cacheline);
- #define CLUSTER_PAGES         (1 << page_cluster)
- #define CLUSTER_OFFSET(x)     (((x) >> page_cluster) << page_cluster)
---- linux-chaos/mm/vmscan.c.b_io_export        Wed Jan 29 16:51:58 2003
-+++ linux-chaos/mm/vmscan.c    Wed Jan 29 16:55:16 2003
-@@ -839,6 +839,7 @@
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&kswapd_done, &wait);
- }
-+EXPORT_SYMBOL(wakeup_kswapd);
- static void wakeup_memwaiters(void)
- {
---- linux-chaos/mm/Makefile.b_io_export        Wed Jan 29 16:52:46 2003
-+++ linux-chaos/mm/Makefile    Wed Jan 29 16:54:23 2003
-@@ -9,7 +9,7 @@
- O_TARGET := mm.o
--export-objs := shmem.o filemap.o memory.o page_alloc.o mempool.o
-+export-objs := shmem.o filemap.o memory.o page_alloc.o mempool.o vmscan.c
- obj-y  := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
-           vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \
---- linux-chaos/mm/page_alloc.c.b_io_export    Wed Jan 29 17:00:32 2003
-+++ linux-chaos/mm/page_alloc.c        Wed Jan 29 17:01:31 2003
-@@ -31,6 +31,7 @@
- int nr_inactive_dirty_pages;
- int nr_inactive_clean_pages;
- pg_data_t *pgdat_list;
-+EXPORT_SYMBOL(pgdat_list);
- /*
-  * The zone_table array is used to look up the address of the
diff --git a/lustre/kernel_patches/patches/iod-stock-24-exports.patch b/lustre/kernel_patches/patches/iod-stock-24-exports.patch
deleted file mode 100644 (file)
index 2070377..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
- fs/Makefile     |    2 +-
- fs/inode.c      |    4 +++-
- mm/page_alloc.c |    1 +
- 3 files changed, 5 insertions(+), 2 deletions(-)
-
---- linux-2.4.20/fs/inode.c~iod-stock-24-exports       Wed Apr  2 23:21:20 2003
-+++ linux-2.4.20-braam/fs/inode.c      Wed Apr  2 23:21:20 2003
-@@ -5,6 +5,7 @@
-  */
- #include <linux/config.h>
-+#include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/string.h>
- #include <linux/mm.h>
-@@ -66,7 +67,8 @@ static LIST_HEAD(anon_hash_chain); /* fo
-  * NOTE! You also have to own the lock if you change
-  * the i_state of an inode while it is in use..
-  */
--static spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
-+spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
-+EXPORT_SYMBOL(inode_lock);
- /*
-  * Statistics gathering..
---- linux-2.4.20/fs/Makefile~iod-stock-24-exports      Wed Apr  2 23:21:20 2003
-+++ linux-2.4.20-braam/fs/Makefile     Wed Apr  2 23:21:53 2003
-@@ -7,7 +7,7 @@
- O_TARGET := fs.o
--export-objs :=        filesystems.o open.o dcache.o buffer.o
-+export-objs :=        filesystems.o open.o dcache.o buffer.o inode.o
- mod-subdirs :=        nls
- obj-y :=      open.o read_write.o devices.o file_table.o buffer.o \
---- linux-2.4.20/mm/page_alloc.c~iod-stock-24-exports  Wed Apr  2 23:21:20 2003
-+++ linux-2.4.20-braam/mm/page_alloc.c Wed Apr  2 23:21:20 2003
-@@ -28,6 +28,7 @@ int nr_inactive_pages;
- LIST_HEAD(inactive_list);
- LIST_HEAD(active_list);
- pg_data_t *pgdat_list;
-+EXPORT_SYMBOL(pgdat_list);
- /*
-  *
-
-_
diff --git a/lustre/kernel_patches/patches/iod-stock-24-exports_hp.patch b/lustre/kernel_patches/patches/iod-stock-24-exports_hp.patch
deleted file mode 100644 (file)
index 669b44d..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
---- linux-2.4.19-hp2_pnnl4_Lv13/fs/inode.c.iod-export  2003-02-27 14:28:04.000000000 -0800
-+++ linux-2.4.19-hp2_pnnl4_Lv13/fs/inode.c     2003-03-03 13:54:59.000000000 -0800
-@@ -5,6 +5,7 @@
-  */
- #include <linux/config.h>
-+#include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/string.h>
- #include <linux/mm.h>
-@@ -66,7 +67,8 @@
-  * NOTE! You also have to own the lock if you change
-  * the i_state of an inode while it is in use..
-  */
--static spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
-+spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
-+EXPORT_SYMBOL(inode_lock);
- /*
-  * Statistics gathering..
---- linux-2.4.19-hp2_pnnl4_Lv13/fs/Makefile.iod-export 2003-02-27 14:28:01.000000000 -0800
-+++ linux-2.4.19-hp2_pnnl4_Lv13/fs/Makefile    2003-03-03 13:56:11.000000000 -0800
-@@ -7,7 +7,7 @@
- O_TARGET := fs.o
--export-objs :=        filesystems.o open.o dcache.o buffer.o dquot.o
-+export-objs :=        filesystems.o open.o dcache.o buffer.o dquot.o inode.o
- mod-subdirs :=        nls xfs
- obj-y :=      open.o read_write.o devices.o file_table.o buffer.o \
---- linux-2.4.19-hp2_pnnl4_Lv13/mm/page_alloc.c.iod-export     2003-02-27 14:28:01.000000000 -0800
-+++ linux-2.4.19-hp2_pnnl4_Lv13/mm/page_alloc.c        2003-03-03 13:54:59.000000000 -0800
-@@ -28,6 +28,7 @@
- LIST_HEAD(inactive_list);
- LIST_HEAD(active_list);
- pg_data_t *pgdat_list;
-+EXPORT_SYMBOL(pgdat_list);
- /* Used to look up the address of the struct zone encoded in page->zone */
- zone_t *zone_table[MAX_NR_ZONES*MAX_NR_NODES];
diff --git a/lustre/kernel_patches/patches/jbd-transno-cb.patch b/lustre/kernel_patches/patches/jbd-transno-cb.patch
deleted file mode 100644 (file)
index ceb086d..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-
-
-
- fs/jbd/commit.c      |   27 +++++++++++++++++++++---
- fs/jbd/journal.c     |    1 
- fs/jbd/transaction.c |   56 ++++++++++++++++++++++++++++++++++++++++-----------
- include/linux/jbd.h  |   20 ++++++++++++++++++
- 4 files changed, 90 insertions(+), 14 deletions(-)
-
---- linux-2.4.19/fs/jbd/commit.c~vanilla-2.4.19        Sun Jan 19 19:46:42 2003
-+++ linux-2.4.19-root/fs/jbd/commit.c  Sun Jan 19 19:46:42 2003
-@@ -475,7 +475,7 @@ start_journal_io:
-            transaction's t_log_list queue, and metadata buffers are on
-            the t_iobuf_list queue.
--         Wait for the transactions in reverse order.  That way we are
-+         Wait for the buffers in reverse order.  That way we are
-          less likely to be woken up until all IOs have completed, and
-          so we incur less scheduling load.
-       */
-@@ -566,8 +566,10 @@ start_journal_io:
-       jbd_debug(3, "JBD: commit phase 6\n");
--      if (is_journal_aborted(journal))
-+      if (is_journal_aborted(journal)) {
-+              unlock_journal(journal);
-               goto skip_commit;
-+      }
-       /* Done it all: now write the commit record.  We should have
-        * cleaned up our previous buffers by now, so if we are in abort
-@@ -577,6 +579,7 @@ start_journal_io:
-       descriptor = journal_get_descriptor_buffer(journal);
-       if (!descriptor) {
-               __journal_abort_hard(journal);
-+              unlock_journal(journal);
-               goto skip_commit;
-       }
-       
-@@ -600,7 +603,6 @@ start_journal_io:
-               put_bh(bh);             /* One for getblk() */
-               journal_unlock_journal_head(descriptor);
-       }
--      lock_journal(journal);
-       /* End of a transaction!  Finally, we can do checkpoint
-            processing: any buffers committed as a result of this
-@@ -609,6 +611,25 @@ start_journal_io:
- skip_commit:
-+      /* Call any callbacks that had been registered for handles in this
-+       * transaction.  It is up to the callback to free any allocated
-+       * memory.
-+       */
-+      if (!list_empty(&commit_transaction->t_jcb)) {
-+              struct list_head *p, *n;
-+              int error = is_journal_aborted(journal);
-+
-+              list_for_each_safe(p, n, &commit_transaction->t_jcb) {
-+                      struct journal_callback *jcb;
-+
-+                      jcb = list_entry(p, struct journal_callback, jcb_list);
-+                      list_del(p);
-+                      jcb->jcb_func(jcb, error);
-+              }
-+      }
-+
-+      lock_journal(journal);
-+
-       jbd_debug(3, "JBD: commit phase 7\n");
-       J_ASSERT(commit_transaction->t_sync_datalist == NULL);
---- linux-2.4.19/fs/jbd/journal.c~vanilla-2.4.19       Sun Jan 19 19:46:42 2003
-+++ linux-2.4.19-root/fs/jbd/journal.c Sun Jan 19 19:46:42 2003
-@@ -58,6 +58,7 @@ EXPORT_SYMBOL(journal_sync_buffer);
- #endif
- EXPORT_SYMBOL(journal_flush);
- EXPORT_SYMBOL(journal_revoke);
-+EXPORT_SYMBOL(journal_callback_set);
- EXPORT_SYMBOL(journal_init_dev);
- EXPORT_SYMBOL(journal_init_inode);
---- linux-2.4.19/fs/jbd/transaction.c~vanilla-2.4.19   Sun Jan 19 19:46:42 2003
-+++ linux-2.4.19-root/fs/jbd/transaction.c     Sun Jan 19 19:46:42 2003
-@@ -57,6 +57,7 @@ static transaction_t * get_transaction (
-       transaction->t_state = T_RUNNING;
-       transaction->t_tid = journal->j_transaction_sequence++;
-       transaction->t_expires = jiffies + journal->j_commit_interval;
-+      INIT_LIST_HEAD(&transaction->t_jcb);
-       /* Set up the commit timer for the new transaction. */
-       J_ASSERT (!journal->j_commit_timer_active);
-@@ -201,6 +202,20 @@ repeat_locked:
-       return 0;
- }
-+/* Allocate a new handle.  This should probably be in a slab... */
-+static handle_t *new_handle(int nblocks)
-+{
-+      handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
-+      if (!handle)
-+              return NULL;
-+      memset(handle, 0, sizeof (handle_t));
-+      handle->h_buffer_credits = nblocks;
-+      handle->h_ref = 1;
-+      INIT_LIST_HEAD(&handle->h_jcb);
-+
-+      return handle;
-+}
-+
- /*
-  * Obtain a new handle.  
-  *
-@@ -227,14 +242,11 @@ handle_t *journal_start(journal_t *journ
-               handle->h_ref++;
-               return handle;
-       }
--      
--      handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
-+
-+      handle = new_handle(nblocks);
-       if (!handle)
-               return ERR_PTR(-ENOMEM);
--      memset (handle, 0, sizeof (handle_t));
--      handle->h_buffer_credits = nblocks;
--      handle->h_ref = 1;
-       current->journal_info = handle;
-       err = start_this_handle(journal, handle);
-@@ -333,14 +345,11 @@ handle_t *journal_try_start(journal_t *j
-       
-       if (is_journal_aborted(journal))
-               return ERR_PTR(-EIO);
--      
--      handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
-+
-+      handle = new_handle(nblocks);
-       if (!handle)
-               return ERR_PTR(-ENOMEM);
--      memset (handle, 0, sizeof (handle_t));
--      handle->h_buffer_credits = nblocks;
--      handle->h_ref = 1;
-       current->journal_info = handle;
-       err = try_start_this_handle(journal, handle);
-@@ -1328,6 +1337,28 @@ out:
- #endif
- /*
-+ * Register a callback function for this handle.  The function will be
-+ * called when the transaction that this handle is part of has been
-+ * committed to disk with the original callback data struct and the
-+ * error status of the journal as parameters.  There is no guarantee of
-+ * ordering between handles within a single transaction, nor between
-+ * callbacks registered on the same handle.
-+ *
-+ * The caller is responsible for allocating the journal_callback struct.
-+ * This is to allow the caller to add as much extra data to the callback
-+ * as needed, but reduce the overhead of multiple allocations.  The caller
-+ * allocated struct must start with a struct journal_callback at offset 0,
-+ * and has the caller-specific data afterwards.
-+ */
-+void journal_callback_set(handle_t *handle,
-+                        void (*func)(struct journal_callback *jcb, int error),
-+                        struct journal_callback *jcb)
-+{
-+      list_add(&jcb->jcb_list, &handle->h_jcb);
-+      jcb->jcb_func = func;
-+}
-+
-+/*
-  * All done for a particular handle.
-  *
-  * There is not much action needed here.  We just return any remaining
-@@ -1393,7 +1424,10 @@ int journal_stop(handle_t *handle)
-                       wake_up(&journal->j_wait_transaction_locked);
-       }
--      /* 
-+      /* Move callbacks from the handle to the transaction. */
-+      list_splice(&handle->h_jcb, &transaction->t_jcb);
-+
-+      /*
-        * If the handle is marked SYNC, we need to set another commit
-        * going!  We also want to force a commit if the current
-        * transaction is occupying too much of the log, or if the
---- linux-2.4.19/include/linux/jbd.h~vanilla-2.4.19    Sun Jan 19 19:46:42 2003
-+++ linux-2.4.19-root/include/linux/jbd.h      Sun Jan 19 19:46:42 2003
-@@ -249,6 +249,13 @@ static inline struct journal_head *bh2jh
-       return bh->b_private;
- }
-+#define HAVE_JOURNAL_CALLBACK_STATUS
-+struct journal_callback {
-+      struct list_head jcb_list;
-+      void (*jcb_func)(struct journal_callback *jcb, int error);
-+      /* user data goes here */
-+};
-+
- struct jbd_revoke_table_s;
- /* The handle_t type represents a single atomic update being performed
-@@ -279,6 +286,12 @@ struct handle_s 
-          operations */
-       int                     h_err;
-+      /* List of application registered callbacks for this handle.
-+       * The function(s) will be called after the transaction that
-+       * this handle is part of has been committed to disk.
-+       */
-+      struct list_head        h_jcb;
-+
-       /* Flags */
-       unsigned int    h_sync:         1;      /* sync-on-close */
-       unsigned int    h_jdata:        1;      /* force data journaling */
-@@ -398,6 +411,10 @@ struct transaction_s 
-       /* How many handles used this transaction? */
-       int t_handle_count;
-+
-+      /* List of registered callback functions for this transaction.
-+       * Called when the transaction is committed. */
-+      struct list_head        t_jcb;
- };
-@@ -646,6 +663,9 @@ extern int  journal_flushpage(journal_t 
- extern int     journal_try_to_free_buffers(journal_t *, struct page *, int);
- extern int     journal_stop(handle_t *);
- extern int     journal_flush (journal_t *);
-+extern void    journal_callback_set(handle_t *handle,
-+                                    void (*fn)(struct journal_callback *,int),
-+                                    struct journal_callback *jcb);
- extern void    journal_lock_updates (journal_t *);
- extern void    journal_unlock_updates (journal_t *);
diff --git a/lustre/kernel_patches/patches/kmem_cache_validate.patch b/lustre/kernel_patches/patches/kmem_cache_validate.patch
deleted file mode 100644 (file)
index 52880d8..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
- 0 files changed
-
---- linux-2.4.18-17.8.0/arch/i386/mm/init.c~kmem_cache_validate        2002-12-06 14:52:30.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/arch/i386/mm/init.c        2002-12-06 14:52:30.000000000 -0800
-@@ -43,6 +43,12 @@ unsigned long highstart_pfn, highend_pfn
- static unsigned long totalram_pages;
- static unsigned long totalhigh_pages;
-+struct page *check_get_page(unsigned long kaddr)
-+{
-+#warning FIXME: Lustre team, is this solid?
-+      return virt_to_page(kaddr);
-+}
-+
- int do_check_pgt_cache(int low, int high)
- {
-       int freed = 0;
---- linux-2.4.18-17.8.0/arch/ia64/mm/init.c~kmem_cache_validate        2002-12-06 14:52:30.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/arch/ia64/mm/init.c        2002-12-06 14:52:30.000000000 -0800
-@@ -37,6 +37,12 @@ unsigned long MAX_DMA_ADDRESS = PAGE_OFF
- static unsigned long totalram_pages;
-+struct page *check_get_page(unsigned long kaddr)
-+{
-+#warning FIXME: Lustre team, is this solid?
-+      return virt_to_page(kaddr);
-+}
-+
- int
- do_check_pgt_cache (int low, int high)
- {
---- linux-2.4.18-17.8.0/include/linux/slab.h~kmem_cache_validate       2002-12-06 14:52:30.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/include/linux/slab.h       2002-12-06 14:52:30.000000000 -0800
-@@ -57,6 +57,7 @@ extern int kmem_cache_destroy(kmem_cache
- extern int kmem_cache_shrink(kmem_cache_t *);
- extern void *kmem_cache_alloc(kmem_cache_t *, int);
- extern void kmem_cache_free(kmem_cache_t *, void *);
-+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
- extern void *kmalloc(size_t, int);
- extern void kfree(const void *);
---- linux-2.4.18-17.8.0/kernel/ksyms.c~kmem_cache_validate     2002-12-06 14:52:30.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/kernel/ksyms.c     2002-12-06 14:52:30.000000000 -0800
-@@ -119,6 +119,7 @@ EXPORT_SYMBOL(kmem_cache_destroy);
- EXPORT_SYMBOL(kmem_cache_shrink);
- EXPORT_SYMBOL(kmem_cache_alloc);
- EXPORT_SYMBOL(kmem_cache_free);
-+EXPORT_SYMBOL(kmem_cache_validate);
- EXPORT_SYMBOL(kmalloc);
- EXPORT_SYMBOL(kfree);
- EXPORT_SYMBOL(vfree);
---- linux-2.4.18-17.8.0/mm/slab.c~kmem_cache_validate  2002-12-06 14:52:30.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/mm/slab.c  2002-12-06 14:52:30.000000000 -0800
-@@ -1208,6 +1208,59 @@ failed:
-  * Called with the cache-lock held.
-  */
-+extern struct page *check_get_page(unsigned long kaddr);
-+struct page *page_mem_map(struct page *page);
-+static int kmem_check_cache_obj (kmem_cache_t * cachep,
-+                               slab_t *slabp, void * objp)
-+{
-+      int i;
-+      unsigned int objnr;
-+
-+#if DEBUG
-+      if (cachep->flags & SLAB_RED_ZONE) {
-+              objp -= BYTES_PER_WORD;
-+              if ( *(unsigned long *)objp != RED_MAGIC2)
-+                      /* Either write before start, or a double free. */
-+                      return 0;
-+              if (*(unsigned long *)(objp+cachep->objsize -
-+                              BYTES_PER_WORD) != RED_MAGIC2)
-+                      /* Either write past end, or a double free. */
-+                      return 0;
-+      }
-+#endif
-+
-+      objnr = (objp-slabp->s_mem)/cachep->objsize;
-+      if (objnr >= cachep->num)
-+              return 0;
-+      if (objp != slabp->s_mem + objnr*cachep->objsize)
-+              return 0;
-+
-+      /* Check slab's freelist to see if this obj is there. */
-+      for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
-+              if (i == objnr)
-+                      return 0;
-+      }
-+      return 1;
-+}
-+
-+
-+int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
-+{
-+      struct page *page = check_get_page((unsigned long)objp);
-+
-+      if (!VALID_PAGE(page))
-+              return 0;
-+
-+      if (!PageSlab(page))
-+              return 0;
-+
-+      /* XXX check for freed slab objects ? */
-+      if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
-+              return 0;
-+
-+      return (cachep == GET_PAGE_CACHE(page));
-+}
-+
- #if DEBUG
- static int kmem_extra_free_checks (kmem_cache_t * cachep,
-                       slab_t *slabp, void * objp)
-
-_
diff --git a/lustre/kernel_patches/patches/kmem_cache_validate_2.4.20-rh.patch b/lustre/kernel_patches/patches/kmem_cache_validate_2.4.20-rh.patch
deleted file mode 100644 (file)
index 8113828..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-
- arch/i386/mm/init.c  |    6 +++++
- arch/ia64/mm/init.c  |    6 +++++
- include/linux/slab.h |    1 
- kernel/ksyms.c       |    1 
- mm/slab.c            |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++
- 5 files changed, 67 insertions(+)
-
---- rh-2.4.20/arch/i386/mm/init.c~kmem_cache_validate_2.4.20-rh        2003-04-11 14:05:09.000000000 +0800
-+++ rh-2.4.20-root/arch/i386/mm/init.c 2003-04-13 10:51:58.000000000 +0800
-@@ -43,6 +43,12 @@ unsigned long highstart_pfn, highend_pfn
- static unsigned long totalram_pages;
- static unsigned long totalhigh_pages;
-+struct page *check_get_page(unsigned long kaddr)
-+{
-+#warning FIXME: Lustre team, is this solid?
-+      return virt_to_page(kaddr);
-+}
-+
- int do_check_pgt_cache(int low, int high)
- {
-       return 0;       /* FIXME! */
---- rh-2.4.20/arch/ia64/mm/init.c~kmem_cache_validate_2.4.20-rh        2003-04-11 14:04:43.000000000 +0800
-+++ rh-2.4.20-root/arch/ia64/mm/init.c 2003-04-13 10:51:58.000000000 +0800
-@@ -45,6 +45,12 @@ unsigned long vmalloc_end = VMALLOC_END_
- static struct page *vmem_map;
- static unsigned long num_dma_physpages;
-+struct page *check_get_page(unsigned long kaddr)
-+{
-+#warning FIXME: Lustre team, is this solid?
-+      return virt_to_page(kaddr);
-+}
-+
- int
- do_check_pgt_cache (int low, int high)
- {
---- rh-2.4.20/include/linux/slab.h~kmem_cache_validate_2.4.20-rh       2003-04-12 15:46:39.000000000 +0800
-+++ rh-2.4.20-root/include/linux/slab.h        2003-04-13 10:53:00.000000000 +0800
-@@ -57,6 +57,7 @@ extern int kmem_cache_destroy(kmem_cache
- extern int kmem_cache_shrink(kmem_cache_t *);
- extern void *kmem_cache_alloc(kmem_cache_t *, int);
- extern void kmem_cache_free(kmem_cache_t *, void *);
-+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
- extern unsigned int kmem_cache_size(kmem_cache_t *);
- extern void *kmalloc(size_t, int);
---- rh-2.4.20/kernel/ksyms.c~kmem_cache_validate_2.4.20-rh     2003-04-12 16:15:26.000000000 +0800
-+++ rh-2.4.20-root/kernel/ksyms.c      2003-04-13 10:54:10.000000000 +0800
-@@ -123,6 +123,7 @@ EXPORT_SYMBOL(kmem_cache_destroy);
- EXPORT_SYMBOL(kmem_cache_shrink);
- EXPORT_SYMBOL(kmem_cache_alloc);
- EXPORT_SYMBOL(kmem_cache_free);
-+EXPORT_SYMBOL(kmem_cache_validate);
- EXPORT_SYMBOL(kmem_cache_size);
- EXPORT_SYMBOL(kmalloc);
- EXPORT_SYMBOL(kfree);
---- rh-2.4.20/mm/slab.c~kmem_cache_validate_2.4.20-rh  2003-04-11 14:04:56.000000000 +0800
-+++ rh-2.4.20-root/mm/slab.c   2003-04-13 10:51:58.000000000 +0800
-@@ -1208,6 +1208,59 @@ failed:
-  * Called with the cache-lock held.
-  */
-+extern struct page *check_get_page(unsigned long kaddr);
-+struct page *page_mem_map(struct page *page);
-+static int kmem_check_cache_obj (kmem_cache_t * cachep,
-+                               slab_t *slabp, void * objp)
-+{
-+      int i;
-+      unsigned int objnr;
-+
-+#if DEBUG
-+      if (cachep->flags & SLAB_RED_ZONE) {
-+              objp -= BYTES_PER_WORD;
-+              if ( *(unsigned long *)objp != RED_MAGIC2)
-+                      /* Either write before start, or a double free. */
-+                      return 0;
-+              if (*(unsigned long *)(objp+cachep->objsize -
-+                              BYTES_PER_WORD) != RED_MAGIC2)
-+                      /* Either write past end, or a double free. */
-+                      return 0;
-+      }
-+#endif
-+
-+      objnr = (objp-slabp->s_mem)/cachep->objsize;
-+      if (objnr >= cachep->num)
-+              return 0;
-+      if (objp != slabp->s_mem + objnr*cachep->objsize)
-+              return 0;
-+
-+      /* Check slab's freelist to see if this obj is there. */
-+      for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
-+              if (i == objnr)
-+                      return 0;
-+      }
-+      return 1;
-+}
-+
-+
-+int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
-+{
-+      struct page *page = check_get_page((unsigned long)objp);
-+
-+      if (!VALID_PAGE(page))
-+              return 0;
-+
-+      if (!PageSlab(page))
-+              return 0;
-+
-+      /* XXX check for freed slab objects ? */
-+      if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
-+              return 0;
-+
-+      return (cachep == GET_PAGE_CACHE(page));
-+}
-+
- #if DEBUG
- static int kmem_extra_free_checks (kmem_cache_t * cachep,
-                       slab_t *slabp, void * objp)
-
-_
diff --git a/lustre/kernel_patches/patches/lin-2.5.44.patch b/lustre/kernel_patches/patches/lin-2.5.44.patch
deleted file mode 100644 (file)
index 39f01ff..0000000
+++ /dev/null
@@ -1,3895 +0,0 @@
-# This is a BitKeeper generated patch for the following project:
-# Project Name: Linux kernel tree
-# This patch format is intended for GNU patch command version 2.5 or higher.
-# This patch includes the following deltas:
-#                 ChangeSet    1.809   -> 1.814  
-#            kernel/ksyms.c    1.149   -> 1.152  
-#                 fs/open.c    1.28    -> 1.29   
-#          fs/ext3/Makefile    1.4     -> 1.5    
-#      include/linux/ext3_jbd.h        1.5     -> 1.6    
-#       fs/driverfs/inode.c    1.52    -> 1.53   
-#               fs/dcache.c    1.33    -> 1.34   
-#                 fs/stat.c    1.13    -> 1.14   
-#        include/linux/fs.h    1.175   -> 1.178  
-#      include/linux/namei.h   1.3     -> 1.4    
-#                fs/namei.c    1.56    -> 1.61   
-#             fs/nfsd/vfs.c    1.44    -> 1.45   
-#      arch/um/kernel/mem.c    1.5     -> 1.6    
-#          fs/ext3/ialloc.c    1.17    -> 1.18   
-#         fs/ext3/symlink.c    1.3     -> 1.4    
-#               fs/Makefile    1.42    -> 1.43   
-#           fs/ext3/namei.c    1.22    -> 1.23   
-#      include/linux/ext3_fs.h 1.11    -> 1.12   
-#        net/unix/af_unix.c    1.29    -> 1.30   
-#              fs/Config.in    1.39    -> 1.40   
-#           fs/ext3/inode.c    1.42    -> 1.43   
-#            fs/Config.help    1.21    -> 1.22   
-#                 mm/slab.c    1.33    -> 1.34   
-#          fs/sysfs/inode.c    1.55    -> 1.56   
-#           fs/ext3/super.c    1.33    -> 1.34   
-#            fs/ext3/file.c    1.9     -> 1.10   
-#      include/linux/slab.h    1.13    -> 1.14   
-#      include/linux/dcache.h  1.19    -> 1.20   
-#                     (new)            -> 1.1     fs/ext3/xattr.h
-#                     (new)            -> 1.1     include/linux/mbcache.h
-#                     (new)            -> 1.1     include/linux/lustre_version.h
-#                     (new)            -> 1.2     fs/ext3/xattr.c
-#                     (new)            -> 1.1     fs/mbcache.c   
-#                     (new)            -> 1.1     fs/ext3/xattr_user.c
-#
-# The following is the BitKeeper ChangeSet Log
-# --------------------------------------------
-# 02/10/20     braam@clusterfs.com     1.810
-# xattrs for UML bk repository
-# --------------------------------------------
-# 02/10/20     braam@clusterfs.com     1.811
-# Changes for Lustre
-# --------------------------------------------
-# 02/12/17     root@kai.(none) 1.812
-# changed for lustre
-# --------------------------------------------
-# 03/01/01     root@kai.(none) 1.813
-# changes for intent of lustre
-# --------------------------------------------
-# 03/01/04     root@kai.(none) 1.814
-# fix error for intent
-# --------------------------------------------
-#
-diff -Nru a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
---- a/arch/um/kernel/mem.c     Sat Jan  4 18:24:12 2003
-+++ b/arch/um/kernel/mem.c     Sat Jan  4 18:24:12 2003
-@@ -656,6 +656,22 @@
-       return(phys_mem_map(pte_val(pte)));
- }
-+struct page *check_get_page(unsigned long kaddr)
-+{
-+        struct page *page;
-+        struct mem_region *mr;
-+        unsigned long phys = __pa(kaddr);
-+      unsigned int n = phys_region_index(phys);
-+
-+      if(regions[n] == NULL) 
-+                return NULL; 
-+
-+        mr = regions[n];
-+        page = (struct page *) mr->mem_map;
-+      return page + ((phys_addr(phys)) >> PAGE_SHIFT);
-+}
-+
-+
- struct mem_region *page_region(struct page *page, int *index_out)
- {
-       int i;
-@@ -743,7 +759,7 @@
-                  (addr <= region->start + region->len))
-                       return(mk_phys(addr - region->start, i));
-       }
--      panic("region_pa : no region for virtual address");
-+      //panic("region_pa : no region for virtual address");
-       return(0);
- }
-diff -Nru a/fs/Config.help b/fs/Config.help
---- a/fs/Config.help   Sat Jan  4 18:24:12 2003
-+++ b/fs/Config.help   Sat Jan  4 18:24:12 2003
-@@ -154,6 +154,13 @@
-   of your root partition (the one containing the directory /) cannot
-   be compiled as a module, and so this may be dangerous.
-+CONFIG_EXT3_FS_XATTR
-+  Extended attributes are name:value pairs associated with inodes by
-+  the kernel or by users (see the attr(5) manual page, or visit
-+  <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
- CONFIG_JBD
-   This is a generic journaling layer for block devices.  It is
-   currently used by the ext3 file system, but it could also be used to
-diff -Nru a/fs/Config.in b/fs/Config.in
---- a/fs/Config.in     Sat Jan  4 18:24:12 2003
-+++ b/fs/Config.in     Sat Jan  4 18:24:12 2003
-@@ -27,6 +27,7 @@
- dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
- tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS
-+dep_mbool '  Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS
- # CONFIG_JBD could be its own option (even modular), but until there are
- # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
- # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
-@@ -180,6 +181,17 @@
-    define_tristate CONFIG_ZISOFS_FS $CONFIG_ISO9660_FS
- else
-    define_tristate CONFIG_ZISOFS_FS n
-+fi
-+
-+# Meta block cache for Extended Attributes (ext2/ext3)
-+if [ "$CONFIG_EXT2_FS_XATTR" = "y" -o "$CONFIG_EXT3_FS_XATTR" = "y" ]; then
-+   if [ "$CONFIG_EXT2_FS" = "y" -o "$CONFIG_EXT3_FS" = "y" ]; then
-+      define_tristate CONFIG_FS_MBCACHE y
-+   else
-+      if [ "$CONFIG_EXT2_FS" = "m" -o "$CONFIG_EXT3_FS" = "m" ]; then
-+         define_tristate CONFIG_FS_MBCACHE m
-+      fi
-+   fi
- fi
- mainmenu_option next_comment
-diff -Nru a/fs/Makefile b/fs/Makefile
---- a/fs/Makefile      Sat Jan  4 18:24:12 2003
-+++ b/fs/Makefile      Sat Jan  4 18:24:12 2003
-@@ -6,7 +6,7 @@
- # 
- export-objs :=        open.o dcache.o buffer.o bio.o inode.o dquot.o mpage.o aio.o \
--                fcntl.o read_write.o dcookies.o
-+                fcntl.o read_write.o dcookies.o mbcache.o
- obj-y :=      open.o read_write.o devices.o file_table.o buffer.o \
-               bio.o super.o block_dev.o char_dev.o stat.o exec.o pipe.o \
-@@ -29,6 +29,8 @@
- obj-y                         += binfmt_script.o
- obj-$(CONFIG_BINFMT_ELF)      += binfmt_elf.o
-+
-+obj-$(CONFIG_FS_MBCACHE)      += mbcache.o
- obj-$(CONFIG_QUOTA)           += dquot.o
- obj-$(CONFIG_QFMT_V1)         += quota_v1.o
-diff -Nru a/fs/dcache.c b/fs/dcache.c
---- a/fs/dcache.c      Sat Jan  4 18:24:12 2003
-+++ b/fs/dcache.c      Sat Jan  4 18:24:12 2003
-@@ -638,6 +638,7 @@
-       dentry->d_fsdata = NULL;
-       dentry->d_mounted = 0;
-       dentry->d_cookie = NULL;
-+      dentry->d_it = NULL;
-       INIT_LIST_HEAD(&dentry->d_hash);
-       INIT_LIST_HEAD(&dentry->d_lru);
-       INIT_LIST_HEAD(&dentry->d_subdirs);
-diff -Nru a/fs/driverfs/inode.c b/fs/driverfs/inode.c
---- a/fs/driverfs/inode.c      Sat Jan  4 18:24:12 2003
-+++ b/fs/driverfs/inode.c      Sat Jan  4 18:24:12 2003
-@@ -523,7 +523,7 @@
-       qstr.name = name;
-       qstr.len = strlen(name);
-       qstr.hash = full_name_hash(name,qstr.len);
--      return lookup_hash(&qstr,parent);
-+      return lookup_hash(&qstr,parent, NULL);
- }
- /**
-diff -Nru a/fs/ext3/Makefile b/fs/ext3/Makefile
---- a/fs/ext3/Makefile Sat Jan  4 18:24:12 2003
-+++ b/fs/ext3/Makefile Sat Jan  4 18:24:12 2003
-@@ -7,4 +7,10 @@
- ext3-objs    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-               ioctl.o namei.o super.o symlink.o hash.o
-+export-objs += xattr.o
-+
-+ifeq ($(CONFIG_EXT3_FS_XATTR),y)
-+ext3-objs += xattr.o xattr_user.o
-+endif
-+
- include $(TOPDIR)/Rules.make
-diff -Nru a/fs/ext3/file.c b/fs/ext3/file.c
---- a/fs/ext3/file.c   Sat Jan  4 18:24:12 2003
-+++ b/fs/ext3/file.c   Sat Jan  4 18:24:12 2003
-@@ -23,7 +23,7 @@
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
--#include <linux/smp_lock.h>
-+#include "xattr.h"
- /*
-  * Called when an inode is released. Note that this is different
-@@ -98,5 +98,9 @@
- struct inode_operations ext3_file_inode_operations = {
-       .truncate       = ext3_truncate,
-       .setattr        = ext3_setattr,
-+      .setxattr       = ext3_setxattr,
-+      .getxattr       = ext3_getxattr,
-+      .listxattr      = ext3_listxattr,
-+      .removexattr    = ext3_removexattr,
- };
-diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
---- a/fs/ext3/ialloc.c Sat Jan  4 18:24:12 2003
-+++ b/fs/ext3/ialloc.c Sat Jan  4 18:24:12 2003
-@@ -25,6 +25,8 @@
- #include <asm/bitops.h>
- #include <asm/byteorder.h>
-+#include "xattr.h"
-+
- /*
-  * ialloc.c contains the inodes allocation and deallocation routines
-  */
-@@ -118,6 +120,7 @@
-        * as writing the quota to disk may need the lock as well.
-        */
-       DQUOT_INIT(inode);
-+      ext3_xattr_delete_inode(handle, inode);
-       DQUOT_FREE_INODE(inode);
-       DQUOT_DROP(inode);
-diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
---- a/fs/ext3/inode.c  Sat Jan  4 18:24:12 2003
-+++ b/fs/ext3/inode.c  Sat Jan  4 18:24:12 2003
-@@ -42,6 +42,18 @@
-  */
- #undef SEARCH_FROM_ZERO
-+/*
-+ * Test whether an inode is a fast symlink.
-+ */
-+static inline int ext3_inode_is_fast_symlink(struct inode *inode)
-+{
-+      int ea_blocks = EXT3_I(inode)->i_file_acl ?
-+              (inode->i_sb->s_blocksize >> 9) : 0;
-+
-+      return (S_ISLNK(inode->i_mode) &&
-+              inode->i_blocks - ea_blocks == 0);
-+}
-+
- /* The ext3 forget function must perform a revoke if we are freeing data
-  * which has been journaled.  Metadata (eg. indirect blocks) must be
-  * revoked in all cases. 
-@@ -51,7 +63,7 @@
-  * still needs to be revoked.
-  */
--static int ext3_forget(handle_t *handle, int is_metadata,
-+int ext3_forget(handle_t *handle, int is_metadata,
-                      struct inode *inode, struct buffer_head *bh,
-                      int blocknr)
- {
-@@ -167,9 +179,7 @@
- {
-       handle_t *handle;
-       
--      if (is_bad_inode(inode) ||
--          inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
-+      if (is_bad_inode(inode))
-               goto no_delete;
-       lock_kernel();
-@@ -1979,6 +1989,8 @@
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-+      if (ext3_inode_is_fast_symlink(inode))
-+              return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-@@ -2130,8 +2142,6 @@
-       struct ext3_group_desc * gdp;
-               
-       if ((inode->i_ino != EXT3_ROOT_INO &&
--              inode->i_ino != EXT3_ACL_IDX_INO &&
--              inode->i_ino != EXT3_ACL_DATA_INO &&
-               inode->i_ino != EXT3_JOURNAL_INO &&
-               inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
-               inode->i_ino > le32_to_cpu(
-@@ -2263,10 +2273,7 @@
-       brelse (iloc.bh);
--      if (inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
--              /* Nothing to do */ ;
--      else if (S_ISREG(inode->i_mode)) {
-+      if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &ext3_file_inode_operations;
-               inode->i_fop = &ext3_file_operations;
-               if (ext3_should_writeback_data(inode))
-@@ -2277,18 +2284,20 @@
-               inode->i_op = &ext3_dir_inode_operations;
-               inode->i_fop = &ext3_dir_operations;
-       } else if (S_ISLNK(inode->i_mode)) {
--              if (!inode->i_blocks)
-+              if (ext3_inode_is_fast_symlink(inode))
-                       inode->i_op = &ext3_fast_symlink_inode_operations;
-               else {
--                      inode->i_op = &page_symlink_inode_operations;
-+                      inode->i_op = &ext3_symlink_inode_operations;
-                       if (ext3_should_writeback_data(inode))
-                               inode->i_mapping->a_ops = &ext3_writeback_aops;
-                       else
-                               inode->i_mapping->a_ops = &ext3_aops;
-               }
--      } else 
-+      } else {
-+              inode->i_op = &ext3_special_inode_operations;
-               init_special_inode(inode, inode->i_mode,
-                                  le32_to_cpu(iloc.raw_inode->i_block[0]));
-+      }
-       if (ei->i_flags & EXT3_SYNC_FL)
-               inode->i_flags |= S_SYNC;
-       if (ei->i_flags & EXT3_APPEND_FL)
-diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
---- a/fs/ext3/namei.c  Sat Jan  4 18:24:12 2003
-+++ b/fs/ext3/namei.c  Sat Jan  4 18:24:12 2003
-@@ -36,6 +36,7 @@
- #include <linux/quotaops.h>
- #include <linux/buffer_head.h>
- #include <linux/smp_lock.h>
-+#include "xattr.h"
- /*
-@@ -1654,7 +1655,7 @@
-       if (IS_DIRSYNC(dir))
-               handle->h_sync = 1;
--      inode = ext3_new_inode (handle, dir, S_IFDIR);
-+      inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
-       err = PTR_ERR(inode);
-       if (IS_ERR(inode))
-               goto out_stop;
-@@ -1662,7 +1663,6 @@
-       inode->i_op = &ext3_dir_inode_operations;
-       inode->i_fop = &ext3_dir_operations;
-       inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
--      inode->i_blocks = 0;    
-       dir_block = ext3_bread (handle, inode, 0, 1, &err);
-       if (!dir_block) {
-               inode->i_nlink--; /* is this nlink == 0? */
-@@ -1689,9 +1689,6 @@
-       BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
-       ext3_journal_dirty_metadata(handle, dir_block);
-       brelse (dir_block);
--      inode->i_mode = S_IFDIR | mode;
--      if (dir->i_mode & S_ISGID)
--              inode->i_mode |= S_ISGID;
-       ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_entry (handle, dentry, inode);
-       if (err) {
-@@ -2068,7 +2065,7 @@
-               goto out_stop;
-       if (l > sizeof (EXT3_I(inode)->i_data)) {
--              inode->i_op = &page_symlink_inode_operations;
-+              inode->i_op = &ext3_symlink_inode_operations;
-               if (ext3_should_writeback_data(inode))
-                       inode->i_mapping->a_ops = &ext3_writeback_aops;
-               else
-@@ -2284,4 +2281,17 @@
-       .rmdir          = ext3_rmdir,
-       .mknod          = ext3_mknod,
-       .rename         = ext3_rename,
-+      .setxattr       = ext3_setxattr,        
-+      .getxattr       = ext3_getxattr,        
-+      .listxattr      = ext3_listxattr,       
-+      .removexattr    = ext3_removexattr,
- };
-+
-+struct inode_operations ext3_special_inode_operations = {
-+      .setxattr       = ext3_setxattr,
-+      .getxattr       = ext3_getxattr,
-+      .listxattr      = ext3_listxattr,
-+      .removexattr    = ext3_removexattr,
-+};
-+
-+ 
-diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
---- a/fs/ext3/super.c  Sat Jan  4 18:24:12 2003
-+++ b/fs/ext3/super.c  Sat Jan  4 18:24:12 2003
-@@ -30,6 +30,7 @@
- #include <linux/smp_lock.h>
- #include <linux/buffer_head.h>
- #include <asm/uaccess.h>
-+#include "xattr.h"
- #ifdef CONFIG_JBD_DEBUG
- static int ext3_ro_after; /* Make fs read-only after this many jiffies */
-@@ -405,6 +406,7 @@
-       struct ext3_super_block *es = sbi->s_es;
-       int i;
-+      ext3_xattr_put_super(sb);
-       journal_destroy(sbi->s_journal);
-       if (!(sb->s_flags & MS_RDONLY)) {
-               EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
-@@ -554,6 +556,7 @@
-                         int is_remount)
- {
-       unsigned long *mount_options = &sbi->s_mount_opt;
-+      
-       uid_t *resuid = &sbi->s_resuid;
-       gid_t *resgid = &sbi->s_resgid;
-       char * this_char;
-@@ -566,6 +569,13 @@
-                       continue;
-               if ((value = strchr (this_char, '=')) != NULL)
-                       *value++ = 0;
-+#ifdef CONFIG_EXT3_FS_XATTR
-+              if (!strcmp (this_char, "user_xattr"))
-+                      set_opt (*mount_options, XATTR_USER);
-+              else if (!strcmp (this_char, "nouser_xattr"))
-+                      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")) {
-@@ -982,6 +992,12 @@
-       sbi->s_mount_opt = 0;
-       sbi->s_resuid = EXT3_DEF_RESUID;
-       sbi->s_resgid = EXT3_DEF_RESGID;
-+
-+      /* Default extended attribute flags */
-+#ifdef CONFIG_EXT3_FS_XATTR
-+      set_opt(sbi->s_mount_opt, XATTR_USER);
-+#endif
-+
-       if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0))
-               goto out_fail;
-@@ -1820,7 +1836,10 @@
- static int __init init_ext3_fs(void)
- {
--      int err = init_inodecache();
-+      int err = init_ext3_xattr();
-+      if (err)
-+              return err;
-+      err = init_inodecache();
-       if (err)
-               goto out1;
-         err = register_filesystem(&ext3_fs_type);
-@@ -1830,6 +1849,7 @@
- out:
-       destroy_inodecache();
- out1:
-+      exit_ext3_xattr();
-       return err;
- }
-@@ -1837,6 +1857,7 @@
- {
-       unregister_filesystem(&ext3_fs_type);
-       destroy_inodecache();
-+      exit_ext3_xattr();
- }
- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
-diff -Nru a/fs/ext3/symlink.c b/fs/ext3/symlink.c
---- a/fs/ext3/symlink.c        Sat Jan  4 18:24:12 2003
-+++ b/fs/ext3/symlink.c        Sat Jan  4 18:24:12 2003
-@@ -20,6 +20,7 @@
- #include <linux/fs.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include "xattr.h"
- static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
-@@ -33,7 +34,20 @@
-       return vfs_follow_link(nd, (char*)ei->i_data);
- }
-+struct inode_operations ext3_symlink_inode_operations = {
-+      .readlink       = page_readlink,
-+      .follow_link    = page_follow_link,
-+      .setxattr       = ext3_setxattr,
-+      .getxattr       = ext3_getxattr,
-+      .listxattr      = ext3_listxattr,
-+      .removexattr    = ext3_removexattr,
-+};
-+
- struct inode_operations ext3_fast_symlink_inode_operations = {
--      .readlink       = ext3_readlink,                /* BKL not held.  Don't need */
-+      .readlink       = ext3_readlink,        /* BKL not held.  Don't need */
-       .follow_link    = ext3_follow_link,     /* BKL not held.  Don't need */
-+      .setxattr       = ext3_setxattr,
-+      .getxattr       = ext3_getxattr,
-+      .listxattr      = ext3_listxattr,
-+      .removexattr    = ext3_removexattr,
- };
-diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c
---- /dev/null  Wed Dec 31 16:00:00 1969
-+++ b/fs/ext3/xattr.c  Sat Jan  4 18:24:12 2003
-@@ -0,0 +1,1131 @@
-+/*
-+ * linux/fs/ext3/xattr.c
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
-+ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
-+ * Extended attributes for symlinks and special files added per
-+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
-+ */
-+
-+/*
-+ * Extended attributes are stored on disk blocks allocated outside of
-+ * any inode. The i_file_acl field is then made to point to this allocated
-+ * block. If all extended attributes of an inode are identical, these
-+ * inodes may share the same extended attribute block. Such situations
-+ * are automatically detected by keeping a cache of recent attribute block
-+ * numbers and hashes over the block's contents in memory.
-+ *
-+ *
-+ * Extended attribute block layout:
-+ *
-+ *   +------------------+
-+ *   | header           |
-+ *   Â¦ entry 1          | |
-+ *   | entry 2          | | growing downwards
-+ *   | entry 3          | v
-+ *   | four null bytes  |
-+ *   | . . .            |
-+ *   | value 1          | ^
-+ *   | value 3          | | growing upwards
-+ *   | value 2          | |
-+ *   +------------------+
-+ *
-+ * The block header is followed by multiple entry descriptors. These entry
-+ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
-+ * byte boundaries. The entry descriptors are sorted by attribute name,
-+ * so that two extended attribute blocks can be compared efficiently.
-+ *
-+ * Attribute values are aligned to the end of the block, stored in
-+ * no specific order. They are also padded to EXT3_XATTR_PAD byte
-+ * boundaries. No additional gaps are left between them.
-+ *
-+ * Locking strategy
-+ * ----------------
-+ * The VFS holdsinode->i_sem semaphore when any of the xattr inode
-+ * operations are called, so we are guaranteed that only one
-+ * processes accesses extended attributes of an inode at any time.
-+ *
-+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
-+ * only a single process is modifying an extended attribute block, even
-+ * if the block is shared among inodes.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <linux/slab.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/mbcache.h>
-+#include <linux/module.h>
-+#include <linux/quotaops.h>
-+#include <asm/semaphore.h>
-+#include "xattr.h"
-+
-+#define EXT3_EA_USER "user."
-+
-+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
-+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
-+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
-+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
-+
-+#ifdef EXT3_XATTR_DEBUG
-+# define ea_idebug(inode, f...) do { \
-+              printk(KERN_DEBUG "inode %s:%ld: ", \
-+                      kdevname(inode->i_dev), inode->i_ino); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+# define ea_bdebug(bh, f...) do { \
-+              printk(KERN_DEBUG "block %s:%ld: ", \
-+                      kdevname(bh->b_dev), bh->b_blocknr); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+#else
-+# define ea_idebug(f...)
-+# define ea_bdebug(f...)
-+#endif
-+
-+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
-+                         struct ext3_xattr_header *);
-+
-+static int ext3_xattr_cache_insert(struct buffer_head *);
-+static struct buffer_head *ext3_xattr_cache_find(struct inode *,
-+                                               struct ext3_xattr_header *);
-+static void ext3_xattr_cache_remove(struct buffer_head *);
-+static void ext3_xattr_rehash(struct ext3_xattr_header *,
-+                            struct ext3_xattr_entry *);
-+
-+static struct mb_cache *ext3_xattr_cache;
-+
-+/*
-+ * If a file system does not share extended attributes among inodes,
-+ * we should not need the ext3_xattr_sem semaphore. However, the
-+ * filesystem may still contain shared blocks, so we always take
-+ * the lock.
-+ */
-+
-+static DECLARE_MUTEX(ext3_xattr_sem);
-+static struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
-+static rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
-+
-+int
-+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      int error = -EINVAL;
-+
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              if (!ext3_xattr_handlers[name_index-1]) {
-+                      ext3_xattr_handlers[name_index-1] = handler;
-+                      error = 0;
-+              }
-+              write_unlock(&ext3_handler_lock);
-+      }
-+      return error;
-+}
-+
-+void
-+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              ext3_xattr_handlers[name_index-1] = NULL;
-+              write_unlock(&ext3_handler_lock);
-+      }
-+}
-+
-+static inline const char *
-+strcmp_prefix(const char *a, const char *a_prefix)
-+{
-+      while (*a_prefix && *a == *a_prefix) {
-+              a++;
-+              a_prefix++;
-+      }
-+      return *a_prefix ? NULL : a;
-+}
-+
-+/*
-+ * Decode the extended attribute name, and translate it into
-+ * the name_index and name suffix.
-+ */
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_resolve_name(const char **name)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      int i;
-+
-+      if (!*name)
-+              return NULL;
-+      read_lock(&ext3_handler_lock);
-+      for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
-+              if (ext3_xattr_handlers[i]) {
-+                      const char *n = strcmp_prefix(*name,
-+                              ext3_xattr_handlers[i]->prefix);
-+                      if (n) {
-+                              handler = ext3_xattr_handlers[i];
-+                              *name = n;
-+                              break;
-+                      }
-+              }
-+      }
-+      read_unlock(&ext3_handler_lock);
-+      return handler;
-+}
-+
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_handler(int name_index)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              read_lock(&ext3_handler_lock);
-+              handler = ext3_xattr_handlers[name_index-1];
-+              read_unlock(&ext3_handler_lock);
-+      }
-+      return handler;
-+}
-+
-+/*
-+ * Inode operation getxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ */
-+ssize_t
-+ext3_getxattr(struct dentry *dentry, const char *name,
-+            void *buffer, size_t size)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -EOPNOTSUPP;
-+      return handler->get(inode, name, buffer, size);
-+}
-+
-+/*
-+ * Inode operation listxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ */
-+ssize_t
-+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
-+{
-+      return ext3_xattr_list(dentry->d_inode, buffer, size);
-+}
-+
-+/*
-+ * Inode operation setxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ */
-+int
-+ext3_setxattr(struct dentry *dentry, const char *name,
-+            void *value, size_t size, int flags)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      if (size == 0)
-+              value = "";  /* empty EA, do not remove */
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -EOPNOTSUPP;
-+      return handler->set(inode, name, value, size, flags);
-+}
-+
-+/*
-+ * Inode operation removexattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ */
-+int
-+ext3_removexattr(struct dentry *dentry, const char *name)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -EOPNOTSUPP;
-+      return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
-+}
-+
-+/*
-+ * ext3_xattr_get()
-+ *
-+ * Copy an extended attribute into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size;
-+      char *end;
-+      int name_len, error;
-+
-+      ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
-+                name_index, name, buffer, (long)buffer_size);
-+
-+      if (name == NULL)
-+              return -EINVAL;
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return -ENODATA;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_get",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* find named attribute */
-+      name_len = strlen(name);
-+
-+      error = -ERANGE;
-+      if (name_len > 255)
-+              goto cleanup;
-+      entry = FIRST_ENTRY(bh);
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              if (name_index == entry->e_name_index &&
-+                  name_len == entry->e_name_len &&
-+                  memcmp(name, entry->e_name, name_len) == 0)
-+                      goto found;
-+              entry = next;
-+      }
-+      /* Check the remaining name entries */
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              entry = next;
-+      }
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      error = -ENODATA;
-+      goto cleanup;
-+found:
-+      /* check the buffer size */
-+      if (entry->e_value_block != 0)
-+              goto bad_block;
-+      size = le32_to_cpu(entry->e_value_size);
-+      if (size > inode->i_sb->s_blocksize ||
-+          le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-+              goto bad_block;
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (buffer) {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+              /* return value of attribute */
-+              memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-+                      size);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_list()
-+ *
-+ * Copy a list of attribute names into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size = 0;
-+      char *buf, *end;
-+      int error;
-+
-+      ea_idebug(inode, "buffer=%p, buffer_size=%ld",
-+                buffer, (long)buffer_size);
-+
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return 0;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_list",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* compute the size required for the list of attribute names */
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler) {
-+                      size += handler->list(NULL, inode, entry->e_name,
-+                                            entry->e_name_len) + 1;
-+              }
-+      }
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (!buffer) {
-+              error = size;
-+              goto cleanup;
-+      } else {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+      }
-+
-+      /* list the attribute names */
-+      buf = buffer;
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler) {
-+                      buf += handler->list(buf, inode, entry->e_name,
-+                                           entry->e_name_len);
-+                      *buf++ = '\0';
-+              }
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
-+ * not set, set it.
-+ */
-+static void ext3_xattr_update_super_block(handle_t *handle,
-+                                        struct super_block *sb)
-+{
-+      if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
-+              return;
-+
-+      lock_super(sb);
-+      ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-+      EXT3_SB(sb)->s_es->s_feature_compat |=
-+              cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
-+      sb->s_dirt = 1;
-+      ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-+      unlock_super(sb);
-+}
-+
-+/*
-+ * ext3_xattr_set()
-+ *
-+ * Create, replace or remove an extended attribute for this inode. Buffer
-+ * is NULL to remove an existing extended attribute, and non-NULL to
-+ * either replace an existing extended attribute, or create a new extended
-+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
-+ * specify that an extended attribute must exist and must not exist
-+ * previous to the call, respectively.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, const void *value, size_t value_len, int flags)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_header *header = NULL;
-+      struct ext3_xattr_entry *here, *last;
-+      unsigned int name_len;
-+      int min_offs = sb->s_blocksize, not_found = 1, free, error;
-+      char *end;
-+      
-+      /*
-+       * header -- Points either into bh, or to a temporarily
-+       *           allocated buffer.
-+       * here -- The named entry found, or the place for inserting, within
-+       *         the block pointed to by header.
-+       * last -- Points right after the last named entry within the block
-+       *         pointed to by header.
-+       * min_offs -- The offset of the first value (values are aligned
-+       *             towards the end of the block).
-+       * end -- Points right after the block pointed to by header.
-+       */
-+      
-+      ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-+                name_index, name, value, (long)value_len);
-+
-+      if (IS_RDONLY(inode))
-+              return -EROFS;
-+      if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-+              return -EPERM;
-+      if (value == NULL)
-+              value_len = 0;
-+      if (name == NULL)
-+              return -EINVAL;
-+      name_len = strlen(name);
-+      if (name_len > 255 || value_len > sb->s_blocksize)
-+              return -ERANGE;
-+      down(&ext3_xattr_sem);
-+
-+      if (EXT3_I(inode)->i_file_acl) {
-+              /* The inode already has an extended attribute block. */
-+              int block = EXT3_I(inode)->i_file_acl;
-+
-+              bh = sb_bread(sb, block);
-+              error = -EIO;
-+              if (!bh)
-+                      goto cleanup;
-+              ea_bdebug(bh, "b_count=%d, refcount=%d",
-+                      atomic_read(&(bh->b_count)),
-+                      le32_to_cpu(HDR(bh)->h_refcount));
-+              header = HDR(bh);
-+              end = bh->b_data + bh->b_size;
-+              if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+                  header->h_blocks != cpu_to_le32(1)) {
-+bad_block:            ext3_error(sb, "ext3_xattr_set",
-+                              "inode %ld: bad block %d", inode->i_ino, block);
-+                      error = -EIO;
-+                      goto cleanup;
-+              }
-+              /* Find the named attribute. */
-+              here = FIRST_ENTRY(bh);
-+              while (!IS_LAST_ENTRY(here)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!here->e_value_block && here->e_value_size) {
-+                              int offs = le16_to_cpu(here->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      not_found = name_index - here->e_name_index;
-+                      if (!not_found)
-+                              not_found = name_len - here->e_name_len;
-+                      if (!not_found)
-+                              not_found = memcmp(name, here->e_name,name_len);
-+                      if (not_found <= 0)
-+                              break;
-+                      here = next;
-+              }
-+              last = here;
-+              /* We still need to compute min_offs and last. */
-+              while (!IS_LAST_ENTRY(last)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!last->e_value_block && last->e_value_size) {
-+                              int offs = le16_to_cpu(last->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      last = next;
-+              }
-+
-+              /* Check whether we have enough space left. */
-+              free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-+      } else {
-+              /* We will use a new extended attribute block. */
-+              free = sb->s_blocksize -
-+                      sizeof(struct ext3_xattr_header) - sizeof(__u32);
-+              here = last = NULL;  /* avoid gcc uninitialized warning. */
-+      }
-+
-+      if (not_found) {
-+              /* Request to remove a nonexistent attribute? */
-+              error = -ENODATA;
-+              if (flags & XATTR_REPLACE)
-+                      goto cleanup;
-+              error = 0;
-+              if (value == NULL)
-+                      goto cleanup;
-+              else
-+                      free -= EXT3_XATTR_LEN(name_len);
-+      } else {
-+              /* Request to create an existing attribute? */
-+              error = -EEXIST;
-+              if (flags & XATTR_CREATE)
-+                      goto cleanup;
-+              if (!here->e_value_block && here->e_value_size) {
-+                      unsigned int size = le32_to_cpu(here->e_value_size);
-+
-+                      if (le16_to_cpu(here->e_value_offs) + size > 
-+                          sb->s_blocksize || size > sb->s_blocksize)
-+                              goto bad_block;
-+                      free += EXT3_XATTR_SIZE(size);
-+              }
-+      }
-+      free -= EXT3_XATTR_SIZE(value_len);
-+      error = -ENOSPC;
-+      if (free < 0)
-+              goto cleanup;
-+
-+      /* Here we know that we can set the new attribute. */
-+
-+      if (header) {
-+              if (header->h_refcount == cpu_to_le32(1)) {
-+                      ea_bdebug(bh, "modifying in-place");
-+                      ext3_xattr_cache_remove(bh);
-+                      error = ext3_journal_get_write_access(handle, bh);
-+                      if (error)
-+                              goto cleanup;
-+              } else {
-+                      int offset;
-+
-+                      ea_bdebug(bh, "cloning");
-+                      header = kmalloc(bh->b_size, GFP_KERNEL);
-+                      error = -ENOMEM;
-+                      if (header == NULL)
-+                              goto cleanup;
-+                      memcpy(header, HDR(bh), bh->b_size);
-+                      header->h_refcount = cpu_to_le32(1);
-+                      offset = (char *)header - bh->b_data;
-+                      here = ENTRY((char *)here + offset);
-+                      last = ENTRY((char *)last + offset);
-+              }
-+      } else {
-+              /* Allocate a buffer where we construct the new block. */
-+              header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-+              error = -ENOMEM;
-+              if (header == NULL)
-+                      goto cleanup;
-+              memset(header, 0, sb->s_blocksize);
-+              end = (char *)header + sb->s_blocksize;
-+              header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
-+              header->h_blocks = header->h_refcount = cpu_to_le32(1);
-+              last = here = ENTRY(header+1);
-+      }
-+
-+      if (not_found) {
-+              /* Insert the new name. */
-+              int size = EXT3_XATTR_LEN(name_len);
-+              int rest = (char *)last - (char *)here;
-+              memmove((char *)here + size, here, rest);
-+              memset(here, 0, size);
-+              here->e_name_index = name_index;
-+              here->e_name_len = name_len;
-+              memcpy(here->e_name, name, name_len);
-+      } else {
-+              /* Remove the old value. */
-+              if (!here->e_value_block && here->e_value_size) {
-+                      char *first_val = (char *)header + min_offs;
-+                      int offs = le16_to_cpu(here->e_value_offs);
-+                      char *val = (char *)header + offs;
-+                      size_t size = EXT3_XATTR_SIZE(
-+                              le32_to_cpu(here->e_value_size));
-+                      memmove(first_val + size, first_val, val - first_val);
-+                      memset(first_val, 0, size);
-+                      here->e_value_offs = 0;
-+                      min_offs += size;
-+
-+                      /* Adjust all value offsets. */
-+                      last = ENTRY(header+1);
-+                      while (!IS_LAST_ENTRY(last)) {
-+                              int o = le16_to_cpu(last->e_value_offs);
-+                              if (!last->e_value_block && o < offs)
-+                                      last->e_value_offs =
-+                                              cpu_to_le16(o + size);
-+                              last = EXT3_XATTR_NEXT(last);
-+                      }
-+              }
-+              if (value == NULL) {
-+                      /* Remove this attribute. */
-+                      if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
-+                              /* This block is now empty. */
-+                              error = ext3_xattr_set2(handle, inode, bh,NULL);
-+                              goto cleanup;
-+                      } else {
-+                              /* Remove the old name. */
-+                              int size = EXT3_XATTR_LEN(name_len);
-+                              last = ENTRY((char *)last - size);
-+                              memmove(here, (char*)here + size,
-+                                      (char*)last - (char*)here);
-+                              memset(last, 0, size);
-+                      }
-+              }
-+      }
-+
-+      if (value != NULL) {
-+              /* Insert the new value. */
-+              here->e_value_size = cpu_to_le32(value_len);
-+              if (value_len) {
-+                      size_t size = EXT3_XATTR_SIZE(value_len);
-+                      char *val = (char *)header + min_offs - size;
-+                      here->e_value_offs =
-+                              cpu_to_le16((char *)val - (char *)header);
-+                      memset(val + size - EXT3_XATTR_PAD, 0,
-+                             EXT3_XATTR_PAD); /* Clear the pad bytes. */
-+                      memcpy(val, value, value_len);
-+              }
-+      }
-+      ext3_xattr_rehash(header, here);
-+
-+      error = ext3_xattr_set2(handle, inode, bh, header);
-+
-+cleanup:
-+      brelse(bh);
-+      if (!(bh && header == HDR(bh)))
-+              kfree(header);
-+      up(&ext3_xattr_sem);
-+
-+      return error;
-+}
-+
-+/*
-+ * Second half of ext3_xattr_set(): Update the file system.
-+ */
-+static int
-+ext3_xattr_set2(handle_t *handle, struct inode *inode,
-+              struct buffer_head *old_bh, struct ext3_xattr_header *header)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *new_bh = NULL;
-+      int error;
-+
-+      if (header) {
-+              new_bh = ext3_xattr_cache_find(inode, header);
-+              if (new_bh) {
-+                      /*
-+                       * We found an identical block in the cache.
-+                       * The old block will be released after updating
-+                       * the inode.
-+                       */
-+                      ea_bdebug(old_bh, "reusing block %ld",
-+                              new_bh->b_blocknr);
-+                      
-+                      error = -EDQUOT;
-+                      if (DQUOT_ALLOC_BLOCK(inode, 1))
-+                              goto cleanup;
-+                      
-+                      error = ext3_journal_get_write_access(handle, new_bh);
-+                      if (error)
-+                              goto cleanup;
-+                      HDR(new_bh)->h_refcount = cpu_to_le32(
-+                              le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
-+                      ea_bdebug(new_bh, "refcount now=%d",
-+                              le32_to_cpu(HDR(new_bh)->h_refcount));
-+              } else if (old_bh && header == HDR(old_bh)) {
-+                      /* Keep this block. */
-+                      new_bh = old_bh;
-+                      ext3_xattr_cache_insert(new_bh);
-+              } else {
-+                      /* We need to allocate a new block */
-+                      int block;
-+                      int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
-+                              EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb);
-+
-+                      block = ext3_new_block(handle, inode, goal, 0,
-+                                             0, &error);
-+                      if (error)
-+                              goto cleanup;
-+                      ea_idebug(inode, "creating block %d", block);
-+
-+                      new_bh = sb_getblk(sb, block);
-+                      if (!new_bh) {
-+getblk_failed:
-+                              ext3_free_blocks(handle, inode, block, 1);
-+                              error = -EIO;
-+                              goto cleanup;
-+                      }
-+                      lock_buffer(new_bh);
-+                      error = ext3_journal_get_create_access(handle, new_bh);
-+                      if (error) {
-+                              unlock_buffer(new_bh);
-+                              goto getblk_failed;
-+                      }
-+                      memcpy(new_bh->b_data, header, new_bh->b_size);
-+                      set_buffer_uptodate(new_bh);
-+                      unlock_buffer(new_bh);
-+                      ext3_xattr_cache_insert(new_bh);
-+                      
-+                      ext3_xattr_update_super_block(handle, sb);
-+              }
-+              error = ext3_journal_dirty_metadata(handle, new_bh);
-+              if (error)
-+                      goto cleanup;
-+      }
-+
-+      /* Update the inode. */
-+      EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-+      inode->i_ctime = CURRENT_TIME;
-+      ext3_mark_inode_dirty(handle, inode);
-+      if (IS_SYNC(inode))
-+              handle->h_sync = 1;
-+
-+      error = 0;
-+      if (old_bh && old_bh != new_bh) {
-+              /*
-+               * If there was an old block, and we are not still using it,
-+               * we now release the old block.
-+              */
-+              unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
-+
-+              error = ext3_journal_get_write_access(handle, old_bh);
-+              if (error)
-+                      goto cleanup;
-+              if (refcount == 1) {
-+                      /* Free the old block. */
-+                      ea_bdebug(old_bh, "freeing");
-+                      ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1);
-+
-+                      /* ext3_forget() calls bforget() for us, but we
-+                         let our caller release old_bh, so we need to
-+                         duplicate the handle before. */
-+                      get_bh(old_bh);
-+                      ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
-+              } else {
-+                      /* Decrement the refcount only. */
-+                      refcount--;
-+                      HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
-+                      DQUOT_FREE_BLOCK(inode, 1);
-+                      ext3_journal_dirty_metadata(handle, old_bh);
-+                      ea_bdebug(old_bh, "refcount now=%d", refcount);
-+              }
-+      }
-+
-+cleanup:
-+      if (old_bh != new_bh)
-+              brelse(new_bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_delete_inode()
-+ *
-+ * Free extended attribute resources associated with this inode. This
-+ * is called immediately before an inode is freed.
-+ */
-+void
-+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
-+{
-+      struct buffer_head *bh;
-+      unsigned int block = EXT3_I(inode)->i_file_acl;
-+
-+      if (!block)
-+              return;
-+      down(&ext3_xattr_sem);
-+
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh) {
-+              ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
-+                      "inode %ld: block %d read error", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+              ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ext3_journal_get_write_access(handle, bh);
-+      ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+      if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-+              ext3_xattr_cache_remove(bh);
-+              ext3_free_blocks(handle, inode, block, 1);
-+              ext3_forget(handle, 1, inode, bh, block);
-+              bh = NULL;
-+      } else {
-+              HDR(bh)->h_refcount = cpu_to_le32(
-+                      le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+              ext3_journal_dirty_metadata(handle, bh);
-+              if (IS_SYNC(inode))
-+                      handle->h_sync = 1;
-+              DQUOT_FREE_BLOCK(inode, 1);
-+      }
-+      EXT3_I(inode)->i_file_acl = 0;
-+
-+cleanup:
-+      brelse(bh);
-+      up(&ext3_xattr_sem);
-+}
-+
-+/*
-+ * ext3_xattr_put_super()
-+ *
-+ * This is called when a file system is unmounted.
-+ */
-+void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+      mb_cache_shrink(ext3_xattr_cache, sb->s_bdev);
-+}
-+
-+/*
-+ * ext3_xattr_cache_insert()
-+ *
-+ * Create a new entry in the extended attribute cache, and insert
-+ * it unless such an entry is already in the cache.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+static int
-+ext3_xattr_cache_insert(struct buffer_head *bh)
-+{
-+      __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
-+      struct mb_cache_entry *ce;
-+      int error;
-+
-+      ce = mb_cache_entry_alloc(ext3_xattr_cache);
-+      if (!ce)
-+              return -ENOMEM;
-+      error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash);
-+      if (error) {
-+              mb_cache_entry_free(ce);
-+              if (error == -EBUSY) {
-+                      ea_bdebug(bh, "already in cache (%d cache entries)",
-+                              atomic_read(&ext3_xattr_cache->c_entry_count));
-+                      error = 0;
-+              }
-+      } else {
-+              ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-+                        atomic_read(&ext3_xattr_cache->c_entry_count));
-+              mb_cache_entry_release(ce);
-+      }
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_cmp()
-+ *
-+ * Compare two extended attribute blocks for equality.
-+ *
-+ * Returns 0 if the blocks are equal, 1 if they differ, and
-+ * a negative error number on errors.
-+ */
-+static int
-+ext3_xattr_cmp(struct ext3_xattr_header *header1,
-+             struct ext3_xattr_header *header2)
-+{
-+      struct ext3_xattr_entry *entry1, *entry2;
-+
-+      entry1 = ENTRY(header1+1);
-+      entry2 = ENTRY(header2+1);
-+      while (!IS_LAST_ENTRY(entry1)) {
-+              if (IS_LAST_ENTRY(entry2))
-+                      return 1;
-+              if (entry1->e_hash != entry2->e_hash ||
-+                  entry1->e_name_len != entry2->e_name_len ||
-+                  entry1->e_value_size != entry2->e_value_size ||
-+                  memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
-+                      return 1;
-+              if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
-+                      return -EIO;
-+              if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
-+                         (char *)header2 + le16_to_cpu(entry2->e_value_offs),
-+                         le32_to_cpu(entry1->e_value_size)))
-+                      return 1;
-+
-+              entry1 = EXT3_XATTR_NEXT(entry1);
-+              entry2 = EXT3_XATTR_NEXT(entry2);
-+      }
-+      if (!IS_LAST_ENTRY(entry2))
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * ext3_xattr_cache_find()
-+ *
-+ * Find an identical extended attribute block.
-+ *
-+ * Returns a pointer to the block found, or NULL if such a block was
-+ * not found or an error occurred.
-+ */
-+static struct buffer_head *
-+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
-+{
-+      __u32 hash = le32_to_cpu(header->h_hash);
-+      struct mb_cache_entry *ce;
-+
-+      if (!header->h_hash)
-+              return NULL;  /* never share */
-+      ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
-+      ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_bdev, hash);
-+      while (ce) {
-+              struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
-+
-+              if (!bh) {
-+                      ext3_error(inode->i_sb, "ext3_xattr_cache_find",
-+                              "inode %ld: block %ld read error",
-+                              inode->i_ino, (unsigned long) ce->e_block);
-+              } else if (le32_to_cpu(HDR(bh)->h_refcount) >
-+                         EXT3_XATTR_REFCOUNT_MAX) {
-+                      ea_idebug(inode, "block %ld refcount %d>%d",
-+                                (unsigned long) ce->e_block,
-+                                le32_to_cpu(HDR(bh)->h_refcount),
-+                                EXT3_XATTR_REFCOUNT_MAX);
-+              } else if (!ext3_xattr_cmp(header, HDR(bh))) {
-+                      ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
-+                      mb_cache_entry_release(ce);
-+                      return bh;
-+              }
-+              brelse(bh);
-+              ce = mb_cache_entry_find_next(ce, 0, inode->i_bdev, hash);
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * ext3_xattr_cache_remove()
-+ *
-+ * Remove the cache entry of a block from the cache. Called when a
-+ * block becomes invalid.
-+ */
-+static void
-+ext3_xattr_cache_remove(struct buffer_head *bh)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev,
-+                              bh->b_blocknr);
-+      if (ce) {
-+              ea_bdebug(bh, "removing (%d cache entries remaining)",
-+                        atomic_read(&ext3_xattr_cache->c_entry_count)-1);
-+              mb_cache_entry_free(ce);
-+      } else 
-+              ea_bdebug(bh, "no cache entry");
-+}
-+
-+#define NAME_HASH_SHIFT 5
-+#define VALUE_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_hash_entry()
-+ *
-+ * Compute the hash of an extended attribute.
-+ */
-+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
-+                                       struct ext3_xattr_entry *entry)
-+{
-+      __u32 hash = 0;
-+      char *name = entry->e_name;
-+      int n;
-+
-+      for (n=0; n < entry->e_name_len; n++) {
-+              hash = (hash << NAME_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
-+                     *name++;
-+      }
-+
-+      if (entry->e_value_block == 0 && entry->e_value_size != 0) {
-+              __u32 *value = (__u32 *)((char *)header +
-+                      le16_to_cpu(entry->e_value_offs));
-+              for (n = (le32_to_cpu(entry->e_value_size) +
-+                   EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
-+                      hash = (hash << VALUE_HASH_SHIFT) ^
-+                             (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
-+                             le32_to_cpu(*value++);
-+              }
-+      }
-+      entry->e_hash = cpu_to_le32(hash);
-+}
-+
-+#undef NAME_HASH_SHIFT
-+#undef VALUE_HASH_SHIFT
-+
-+#define BLOCK_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_rehash()
-+ *
-+ * Re-compute the extended attribute hash value after an entry has changed.
-+ */
-+static void ext3_xattr_rehash(struct ext3_xattr_header *header,
-+                            struct ext3_xattr_entry *entry)
-+{
-+      struct ext3_xattr_entry *here;
-+      __u32 hash = 0;
-+      
-+      ext3_xattr_hash_entry(header, entry);
-+      here = ENTRY(header+1);
-+      while (!IS_LAST_ENTRY(here)) {
-+              if (!here->e_hash) {
-+                      /* Block is not shared if an entry's hash value == 0 */
-+                      hash = 0;
-+                      break;
-+              }
-+              hash = (hash << BLOCK_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
-+                     le32_to_cpu(here->e_hash);
-+              here = EXT3_XATTR_NEXT(here);
-+      }
-+      header->h_hash = cpu_to_le32(hash);
-+}
-+
-+#undef BLOCK_HASH_SHIFT
-+EXPORT_SYMBOL(ext3_xattr_get);
-+EXPORT_SYMBOL(ext3_xattr_set);
-+EXPORT_SYMBOL(ext3_bread);
-+
-+int __init
-+init_ext3_xattr(void)
-+{
-+      int     err;
-+      
-+      err = ext3_xattr_register(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler);
-+      if (err)
-+              return err;
-+      ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
-+              sizeof(struct mb_cache_entry) +
-+              sizeof(struct mb_cache_entry_index), 1, 6);
-+      if (!ext3_xattr_cache) {
-+              ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler);
-+              return -ENOMEM;
-+      }
-+
-+      return 0;
-+}
-+
-+void
-+exit_ext3_xattr(void)
-+{
-+      if (ext3_xattr_cache)
-+              mb_cache_destroy(ext3_xattr_cache);
-+      ext3_xattr_cache = NULL;
-+      ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler);
-+}
-+
-diff -Nru a/fs/ext3/xattr.h b/fs/ext3/xattr.h
---- /dev/null  Wed Dec 31 16:00:00 1969
-+++ b/fs/ext3/xattr.h  Sat Jan  4 18:24:12 2003
-@@ -0,0 +1,133 @@
-+/*
-+  File: fs/ext3/xattr.h
-+
-+  On-disk format of extended attributes for the ext3 filesystem.
-+
-+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/xattr.h>
-+
-+/* Magic value in attribute blocks */
-+#define EXT3_XATTR_MAGIC              0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT3_XATTR_REFCOUNT_MAX               1024
-+
-+/* Name indexes */
-+#define EXT3_XATTR_INDEX_MAX                  10
-+#define EXT3_XATTR_INDEX_USER                 1
-+#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS     2
-+#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT    3
-+
-+struct ext3_xattr_header {
-+      __u32   h_magic;        /* magic number for identification */
-+      __u32   h_refcount;     /* reference count */
-+      __u32   h_blocks;       /* number of disk blocks used */
-+      __u32   h_hash;         /* hash value of all attributes */
-+      __u32   h_reserved[4];  /* zero right now */
-+};
-+
-+struct ext3_xattr_entry {
-+      __u8    e_name_len;     /* length of name */
-+      __u8    e_name_index;   /* attribute name index */
-+      __u16   e_value_offs;   /* offset in disk block of value */
-+      __u32   e_value_block;  /* disk block attribute is stored on (n/i) */
-+      __u32   e_value_size;   /* size of attribute value */
-+      __u32   e_hash;         /* hash value of name and value */
-+      char    e_name[0];      /* attribute name */
-+};
-+
-+#define EXT3_XATTR_PAD_BITS           2
-+#define EXT3_XATTR_PAD                (1<<EXT3_XATTR_PAD_BITS)
-+#define EXT3_XATTR_ROUND              (EXT3_XATTR_PAD-1)
-+#define EXT3_XATTR_LEN(name_len) \
-+      (((name_len) + EXT3_XATTR_ROUND + \
-+      sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
-+#define EXT3_XATTR_NEXT(entry) \
-+      ( (struct ext3_xattr_entry *)( \
-+        (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
-+#define EXT3_XATTR_SIZE(size) \
-+      (((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
-+
-+# ifdef CONFIG_EXT3_FS_XATTR
-+
-+struct ext3_xattr_handler {
-+      char *prefix;
-+      size_t (*list)(char *list, struct inode *inode, const char *name,
-+                     int name_len);
-+      int (*get)(struct inode *inode, const char *name, void *buffer,
-+                 size_t size);
-+      int (*set)(struct inode *inode, const char *name, const void *buffer,
-+                 size_t size, int flags);
-+};
-+
-+extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
-+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
-+
-+extern int ext3_setxattr(struct dentry *, const char *, void *, size_t, int);
-+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
-+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
-+extern int ext3_removexattr(struct dentry *, const char *);
-+
-+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
-+extern int ext3_xattr_list(struct inode *, char *, size_t);
-+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
-+
-+extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
-+extern void ext3_xattr_put_super(struct super_block *);
-+
-+extern int init_ext3_xattr(void);
-+extern void exit_ext3_xattr(void);
-+
-+# else  /* CONFIG_EXT3_FS_XATTR */
-+#  define ext3_setxattr               NULL
-+#  define ext3_getxattr               NULL
-+#  define ext3_listxattr      NULL
-+#  define ext3_removexattr    NULL
-+
-+static inline int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t size, int flags)
-+{
-+      return -EOPNOTSUPP;
-+}
-+
-+static inline int
-+ext3_xattr_list(struct inode *inode, void *buffer, size_t size, int flags)
-+{
-+      return -EOPNOTSUPP;
-+}
-+
-+static inline int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, const void *value, size_t size, int flags)
-+{
-+      return -EOPNOTSUPP;
-+}
-+
-+static inline void
-+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
-+{
-+}
-+
-+static inline void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+}
-+
-+static inline int
-+init_ext3_xattr(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext3_xattr(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT3_FS_XATTR */
-+
-+extern struct ext3_xattr_handler ext3_xattr_user_handler;
-diff -Nru a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c
---- /dev/null  Wed Dec 31 16:00:00 1969
-+++ b/fs/ext3/xattr_user.c     Sat Jan  4 18:24:12 2003
-@@ -0,0 +1,99 @@
-+/*
-+ * linux/fs/ext3/xattr_user.c
-+ * Handler for extended user attributes.
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/fs.h>
-+#include <linux/smp_lock.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
-+#include "xattr.h"
-+
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+# include <linux/ext3_acl.h>
-+#endif
-+
-+#define XATTR_USER_PREFIX "user."
-+
-+static size_t
-+ext3_xattr_user_list(char *list, struct inode *inode,
-+                   const char *name, int name_len)
-+{
-+      const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
-+
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return 0;
-+
-+      if (list) {
-+              memcpy(list, XATTR_USER_PREFIX, prefix_len);
-+              memcpy(list+prefix_len, name, name_len);
-+      }
-+      return prefix_len + name_len;
-+}
-+
-+static int
-+ext3_xattr_user_get(struct inode *inode, const char *name,
-+                  void *buffer, size_t size)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -EOPNOTSUPP;
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+      error = ext3_permission_locked(inode, MAY_READ);
-+#else
-+      error = permission(inode, MAY_READ);
-+#endif
-+      if (error)
-+              return error;
-+
-+      return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name,
-+                            buffer, size);
-+}
-+
-+static int
-+ext3_xattr_user_set(struct inode *inode, const char *name,
-+                  const void *value, size_t size, int flags)
-+{
-+      handle_t *handle;
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -EOPNOTSUPP;
-+      if ( !S_ISREG(inode->i_mode) &&
-+          (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-+              return -EPERM;
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+      error = ext3_permission_locked(inode, MAY_WRITE);
-+#else
-+      error = permission(inode, MAY_WRITE);
-+#endif
-+      if (error)
-+              return error;
-+  
-+      lock_kernel();
-+      handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
-+      if (IS_ERR(handle))
-+              return PTR_ERR(handle);
-+      error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name,
-+                             value, size, flags);
-+      ext3_journal_stop(handle, inode);
-+      unlock_kernel();
-+
-+      return error;
-+}
-+
-+struct ext3_xattr_handler ext3_xattr_user_handler = {
-+      prefix: XATTR_USER_PREFIX,
-+      list:   ext3_xattr_user_list,
-+      get:    ext3_xattr_user_get,
-+      set:    ext3_xattr_user_set,
-+};
-diff -Nru a/fs/mbcache.c b/fs/mbcache.c
---- /dev/null  Wed Dec 31 16:00:00 1969
-+++ b/fs/mbcache.c     Sat Jan  4 18:24:12 2003
-@@ -0,0 +1,702 @@
-+/*
-+ * linux/fs/mbcache.c
-+ * (C) 2001-2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+/*
-+ * Filesystem Meta Information Block Cache (mbcache)
-+ *
-+ * The mbcache caches blocks of block devices that need to be located
-+ * by their device/block number, as well as by other criteria (such
-+ * as the block's contents).
-+ *
-+ * There can only be one cache entry in a cache per device and block number.
-+ * Additional indexes need not be unique in this sense. The number of
-+ * additional indexes (=other criteria) can be hardwired (at compile time)
-+ * or specified at cache create time.
-+ *
-+ * Each cache entry is of fixed size. An entry may be `valid' or `invalid'
-+ * in the cache. A valid entry is in the main hash tables of the cache,
-+ * and may also be in the lru list. An invalid entry is not in any hashes
-+ * or lists.
-+ *
-+ * A valid cache entry is only in the lru list if no handles refer to it.
-+ * Invalid cache entries will be freed when the last handle to the cache
-+ * entry is released.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+
-+#include <linux/hash.h>
-+#include <linux/fs.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/mbcache.h>
-+
-+
-+#ifdef MB_CACHE_DEBUG
-+# define mb_debug(f...) do { \
-+              printk(KERN_DEBUG f); \
-+              printk("\n"); \
-+      } while (0)
-+#define mb_assert(c) do { if (!(c)) \
-+              printk(KERN_ERR "assertion " #c " failed\n"); \
-+      } while(0)
-+#else
-+# define mb_debug(f...) do { } while(0)
-+# define mb_assert(c) do { } while(0)
-+#endif
-+#define mb_error(f...) do { \
-+              printk(KERN_ERR f); \
-+              printk("\n"); \
-+      } while(0)
-+              
-+MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
-+MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
-+MODULE_LICENSE("GPL");
-+
-+EXPORT_SYMBOL(mb_cache_create);
-+EXPORT_SYMBOL(mb_cache_shrink);
-+EXPORT_SYMBOL(mb_cache_destroy);
-+EXPORT_SYMBOL(mb_cache_entry_alloc);
-+EXPORT_SYMBOL(mb_cache_entry_insert);
-+EXPORT_SYMBOL(mb_cache_entry_release);
-+EXPORT_SYMBOL(mb_cache_entry_takeout);
-+EXPORT_SYMBOL(mb_cache_entry_free);
-+EXPORT_SYMBOL(mb_cache_entry_dup);
-+EXPORT_SYMBOL(mb_cache_entry_get);
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+EXPORT_SYMBOL(mb_cache_entry_find_first);
-+EXPORT_SYMBOL(mb_cache_entry_find_next);
-+#endif
-+
-+
-+/*
-+ * Global data: list of all mbcache's, lru list, and a spinlock for
-+ * accessing cache data structures on SMP machines. (The lru list is
-+ * global across all mbcaches.)
-+ */
-+
-+static LIST_HEAD(mb_cache_list);
-+static LIST_HEAD(mb_cache_lru_list);
-+static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED;
-+static struct shrinker *mb_shrinker;
-+
-+static inline int
-+mb_cache_indexes(struct mb_cache *cache)
-+{
-+#ifdef MB_CACHE_INDEXES_COUNT
-+      return MB_CACHE_INDEXES_COUNT;
-+#else
-+      return cache->c_indexes_count;
-+#endif
-+}
-+
-+/*
-+ * What the mbcache registers as to get shrunk dynamically.
-+ */
-+
-+static int mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask);
-+
-+static inline void
-+__mb_cache_entry_takeout_lru(struct mb_cache_entry *ce)
-+{
-+      if (!list_empty(&ce->e_lru_list))
-+              list_del_init(&ce->e_lru_list);
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_into_lru(struct mb_cache_entry *ce)
-+{
-+      list_add(&ce->e_lru_list, &mb_cache_lru_list);
-+}
-+
-+
-+static inline int
-+__mb_cache_entry_in_lru(struct mb_cache_entry *ce)
-+{
-+      return (!list_empty(&ce->e_lru_list));
-+}
-+
-+
-+/*
-+ * Insert the cache entry into all hashes.
-+ */
-+static inline void
-+__mb_cache_entry_link(struct mb_cache_entry *ce)
-+{
-+      struct mb_cache *cache = ce->e_cache;
-+      unsigned int bucket;
-+      int n;
-+      
-+      bucket = hash_long((unsigned long)ce->e_bdev +
-+                         (ce->e_block & 0xffffff), cache->c_bucket_bits);
-+      list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
-+      for (n=0; n<mb_cache_indexes(cache); n++) {
-+              bucket = hash_long(ce->e_indexes[n].o_key,
-+                                 cache->c_bucket_bits);
-+              list_add(&ce->e_indexes[n].o_list,
-+                       &cache->c_indexes_hash[n][bucket]);
-+      }
-+}
-+
-+
-+/*
-+ * Remove the cache entry from all hashes.
-+ */
-+static inline void
-+__mb_cache_entry_unlink(struct mb_cache_entry *ce)
-+{
-+      int n;
-+
-+      list_del_init(&ce->e_block_list);
-+      for (n = 0; n < mb_cache_indexes(ce->e_cache); n++)
-+              list_del(&ce->e_indexes[n].o_list);
-+}
-+
-+
-+static inline int
-+__mb_cache_entry_is_linked(struct mb_cache_entry *ce)
-+{
-+      return (!list_empty(&ce->e_block_list));
-+}
-+
-+
-+static inline struct mb_cache_entry *
-+__mb_cache_entry_read(struct mb_cache_entry *ce)
-+{
-+      __mb_cache_entry_takeout_lru(ce);
-+      atomic_inc(&ce->e_used);
-+      return ce;
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_forget(struct mb_cache_entry *ce)
-+{
-+      struct mb_cache *cache = ce->e_cache;
-+
-+      mb_assert(atomic_read(&ce->e_used) == 0);
-+      atomic_dec(&cache->c_entry_count);
-+      if (cache->c_op.free)
-+              cache->c_op.free(ce);
-+      kmem_cache_free(cache->c_entry_cache, ce);
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
-+{
-+      if (atomic_dec_and_test(&ce->e_used)) {
-+              if (!__mb_cache_entry_is_linked(ce))
-+                      goto forget;
-+              __mb_cache_entry_into_lru(ce);
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+      return;
-+forget:
-+      spin_unlock(&mb_cache_spinlock);
-+      __mb_cache_entry_forget(ce);
-+}
-+
-+
-+/*
-+ * mb_cache_shrink_fn()  memory pressure callback
-+ *
-+ * This function is called by the kernel memory management when memory
-+ * gets low.
-+ *
-+ * @nr_to_scan: Number of objects to scan
-+ * @gfp_mask: (ignored)
-+ *
-+ * Returns the number of objects which are present in the cache.
-+ */
-+static int
-+mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l;
-+      int count = 0;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each_prev(l, &mb_cache_list) {
-+              struct mb_cache *cache =
-+                      list_entry(l, struct mb_cache, c_cache_list);
-+              mb_debug("cache %s (%d)", cache->c_name,
-+                        atomic_read(&cache->c_entry_count));
-+              count += atomic_read(&cache->c_entry_count);
-+      }
-+      mb_debug("trying to free %d entries", nr_to_scan);
-+      if (nr_to_scan == 0) {
-+              spin_unlock(&mb_cache_spinlock);
-+              goto out;
-+      }
-+      while (nr_to_scan && !list_empty(&mb_cache_lru_list)) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(mb_cache_lru_list.prev,
-+                                 struct mb_cache_entry, e_lru_list);
-+              list_move(&ce->e_lru_list, &free_list);
-+              if (__mb_cache_entry_is_linked(ce))
-+                      __mb_cache_entry_unlink(ce);
-+              nr_to_scan--;
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+      l = free_list.prev;
-+      while (l != &free_list) {
-+              struct mb_cache_entry *ce = list_entry(l,
-+                      struct mb_cache_entry, e_lru_list);
-+              l = l->prev;
-+              __mb_cache_entry_forget(ce);
-+              count--;
-+      }
-+out:
-+      mb_debug("%d remaining entries ", count);
-+      return count;
-+}
-+
-+
-+/*
-+ * mb_cache_create()  create a new cache
-+ *
-+ * All entries in one cache are equal size. Cache entries may be from
-+ * multiple devices. If this is the first mbcache created, registers
-+ * the cache with kernel memory management. Returns NULL if no more
-+ * memory was available.
-+ *
-+ * @name: name of the cache (informal)
-+ * @cache_op: contains the callback called when freeing a cache entry
-+ * @entry_size: The size of a cache entry, including
-+ *              struct mb_cache_entry
-+ * @indexes_count: number of additional indexes in the cache. Must equal
-+ *                 MB_CACHE_INDEXES_COUNT if the number of indexes is
-+ *                 hardwired.
-+ * @bucket_bits: log2(number of hash buckets)
-+ */
-+struct mb_cache *
-+mb_cache_create(const char *name, struct mb_cache_op *cache_op,
-+              size_t entry_size, int indexes_count, int bucket_bits)
-+{
-+      int m=0, n, bucket_count = 1 << bucket_bits;
-+      struct mb_cache *cache = NULL;
-+
-+      if(entry_size < sizeof(struct mb_cache_entry) +
-+         indexes_count * sizeof(struct mb_cache_entry_index))
-+              return NULL;
-+
-+      cache = kmalloc(sizeof(struct mb_cache) +
-+                      indexes_count * sizeof(struct list_head), GFP_KERNEL);
-+      if (!cache)
-+              goto fail;
-+      cache->c_name = name;
-+      if (cache_op)
-+              cache->c_op.free = cache_op->free;
-+      else
-+              cache->c_op.free = NULL;
-+      atomic_set(&cache->c_entry_count, 0);
-+      cache->c_bucket_bits = bucket_bits;
-+#ifdef MB_CACHE_INDEXES_COUNT
-+      mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT);
-+#else
-+      cache->c_indexes_count = indexes_count;
-+#endif
-+      cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
-+                                    GFP_KERNEL);
-+      if (!cache->c_block_hash)
-+              goto fail;
-+      for (n=0; n<bucket_count; n++)
-+              INIT_LIST_HEAD(&cache->c_block_hash[n]);
-+      for (m=0; m<indexes_count; m++) {
-+              cache->c_indexes_hash[m] = kmalloc(bucket_count *
-+                                               sizeof(struct list_head),
-+                                               GFP_KERNEL);
-+              if (!cache->c_indexes_hash[m])
-+                      goto fail;
-+              for (n=0; n<bucket_count; n++)
-+                      INIT_LIST_HEAD(&cache->c_indexes_hash[m][n]);
-+      }
-+      cache->c_entry_cache = kmem_cache_create(name, entry_size, 0,
-+              0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL);
-+      if (!cache->c_entry_cache)
-+              goto fail;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      if (list_empty(&mb_cache_list)) {
-+              if (mb_shrinker) {
-+                      printk(KERN_ERR "%s: already have a shrinker!\n",
-+                                      __FUNCTION__);
-+                      remove_shrinker(mb_shrinker);
-+              }
-+              mb_shrinker = set_shrinker(DEFAULT_SEEKS, mb_cache_shrink_fn);
-+      }
-+      list_add(&cache->c_cache_list, &mb_cache_list);
-+      spin_unlock(&mb_cache_spinlock);
-+      return cache;
-+
-+fail:
-+      if (cache) {
-+              while (--m >= 0)
-+                      kfree(cache->c_indexes_hash[m]);
-+              if (cache->c_block_hash)
-+                      kfree(cache->c_block_hash);
-+              kfree(cache);
-+      }
-+      return NULL;
-+}
-+
-+
-+/*
-+ * mb_cache_shrink()
-+ *
-+ * Removes all cache entires of a device from the cache. All cache entries
-+ * currently in use cannot be freed, and thus remain in the cache. All others
-+ * are freed.
-+ *
-+ * @cache: which cache to shrink
-+ * @bdev: which device's cache entries to shrink
-+ */
-+void
-+mb_cache_shrink(struct mb_cache *cache, struct block_device *bdev)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      l = mb_cache_lru_list.prev;
-+      while (l != &mb_cache_lru_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              l = l->prev;
-+              if (ce->e_bdev == bdev) {
-+                      list_move(&ce->e_lru_list, &free_list);
-+                      if (__mb_cache_entry_is_linked(ce))
-+                              __mb_cache_entry_unlink(ce);
-+              }
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+      l = free_list.prev;
-+      while (l != &free_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              l = l->prev;
-+              __mb_cache_entry_forget(ce);
-+      }
-+}
-+
-+
-+/*
-+ * mb_cache_destroy()
-+ *
-+ * Shrinks the cache to its minimum possible size (hopefully 0 entries),
-+ * and then destroys it. If this was the last mbcache, un-registers the
-+ * mbcache from kernel memory management.
-+ */
-+void
-+mb_cache_destroy(struct mb_cache *cache)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l;
-+      int n;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      l = mb_cache_lru_list.prev;
-+      while (l != &mb_cache_lru_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              l = l->prev;
-+              if (ce->e_cache == cache) {
-+                      list_move(&ce->e_lru_list, &free_list);
-+                      if (__mb_cache_entry_is_linked(ce))
-+                              __mb_cache_entry_unlink(ce);
-+              }
-+      }
-+      list_del(&cache->c_cache_list);
-+      if (list_empty(&mb_cache_list) && mb_shrinker) {
-+              remove_shrinker(mb_shrinker);
-+              mb_shrinker = 0;
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+
-+      l = free_list.prev;
-+      while (l != &free_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              l = l->prev;
-+              __mb_cache_entry_forget(ce);
-+      }
-+
-+      if (atomic_read(&cache->c_entry_count) > 0) {
-+              mb_error("cache %s: %d orphaned entries",
-+                        cache->c_name,
-+                        atomic_read(&cache->c_entry_count));
-+      }
-+
-+      kmem_cache_destroy(cache->c_entry_cache);
-+
-+      for (n=0; n < mb_cache_indexes(cache); n++)
-+              kfree(cache->c_indexes_hash[n]);
-+      kfree(cache->c_block_hash);
-+
-+      kfree(cache);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_alloc()
-+ *
-+ * Allocates a new cache entry. The new entry will not be valid initially,
-+ * and thus cannot be looked up yet. It should be filled with data, and
-+ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL
-+ * if no more memory was available.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_alloc(struct mb_cache *cache)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      atomic_inc(&cache->c_entry_count);
-+      ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
-+      if (ce) {
-+              INIT_LIST_HEAD(&ce->e_lru_list);
-+              INIT_LIST_HEAD(&ce->e_block_list);
-+              ce->e_cache = cache;
-+              atomic_set(&ce->e_used, 1);
-+      }
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_insert()
-+ *
-+ * Inserts an entry that was allocated using mb_cache_entry_alloc() into
-+ * the cache. After this, the cache entry can be looked up, but is not yet
-+ * in the lru list as the caller still holds a handle to it. Returns 0 on
-+ * success, or -EBUSY if a cache entry for that device + inode exists
-+ * already (this may happen after a failed lookup, but when another process
-+ * has inserted the same cache entry in the meantime).
-+ *
-+ * @bdev: device the cache entry belongs to
-+ * @block: block number
-+ * @keys: array of additional keys. There must be indexes_count entries
-+ *        in the array (as specified when creating the cache).
-+ */
-+int
-+mb_cache_entry_insert(struct mb_cache_entry *ce, struct block_device *bdev,
-+                    sector_t block, unsigned int keys[])
-+{
-+      struct mb_cache *cache = ce->e_cache;
-+      unsigned int bucket;
-+      struct list_head *l;
-+      int error = -EBUSY, n;
-+
-+      bucket =  hash_long((unsigned long)bdev + (block & 0xffffffff), 
-+                          cache->c_bucket_bits);
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each_prev(l, &cache->c_block_hash[bucket]) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_block_list);
-+              if (ce->e_bdev == bdev && ce->e_block == block)
-+                      goto out;
-+      }
-+      mb_assert(!__mb_cache_entry_is_linked(ce));
-+      ce->e_bdev = bdev;
-+      ce->e_block = block;
-+      for (n=0; n<mb_cache_indexes(cache); n++)
-+              ce->e_indexes[n].o_key = keys[n];
-+      __mb_cache_entry_link(ce);
-+out:
-+      spin_unlock(&mb_cache_spinlock);
-+      return error;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_release()
-+ *
-+ * Release a handle to a cache entry. When the last handle to a cache entry
-+ * is released it is either freed (if it is invalid) or otherwise inserted
-+ * in to the lru list.
-+ */
-+void
-+mb_cache_entry_release(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      __mb_cache_entry_release_unlock(ce);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_takeout()
-+ *
-+ * Take a cache entry out of the cache, making it invalid. The entry can later
-+ * be re-inserted using mb_cache_entry_insert(), or released using
-+ * mb_cache_entry_release().
-+ */
-+void
-+mb_cache_entry_takeout(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      mb_assert(!__mb_cache_entry_in_lru(ce));
-+      if (__mb_cache_entry_is_linked(ce))
-+              __mb_cache_entry_unlink(ce);
-+      spin_unlock(&mb_cache_spinlock);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_free()
-+ *
-+ * This is equivalent to the sequence mb_cache_entry_takeout() --
-+ * mb_cache_entry_release().
-+ */
-+void
-+mb_cache_entry_free(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      mb_assert(!__mb_cache_entry_in_lru(ce));
-+      if (__mb_cache_entry_is_linked(ce))
-+              __mb_cache_entry_unlink(ce);
-+      __mb_cache_entry_release_unlock(ce);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_dup()
-+ *
-+ * Duplicate a handle to a cache entry (does not duplicate the cache entry
-+ * itself). After the call, both the old and the new handle must be released.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_dup(struct mb_cache_entry *ce)
-+{
-+      atomic_inc(&ce->e_used);
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_get()
-+ *
-+ * Get a cache entry  by device / block number. (There can only be one entry
-+ * in the cache per device and block.) Returns NULL if no such cache entry
-+ * exists.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_get(struct mb_cache *cache, struct block_device *bdev,
-+                 sector_t block)
-+{
-+      unsigned int bucket;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      bucket = hash_long((unsigned long)bdev + (block & 0xffffffff),
-+                         cache->c_bucket_bits);
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &cache->c_block_hash[bucket]) {
-+              ce = list_entry(l, struct mb_cache_entry, e_block_list);
-+              if (ce->e_bdev == bdev && ce->e_block == block) {
-+                      ce = __mb_cache_entry_read(ce);
-+                      goto cleanup;
-+              }
-+      }
-+      ce = NULL;
-+
-+cleanup:
-+      spin_unlock(&mb_cache_spinlock);
-+      return ce;
-+}
-+
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+
-+static struct mb_cache_entry *
-+__mb_cache_entry_find(struct list_head *l, struct list_head *head,
-+                    int index, struct block_device *bdev, unsigned int key)
-+{
-+      while (l != head) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry,
-+                                 e_indexes[index].o_list);
-+              if (ce->e_bdev == bdev &&
-+                  ce->e_indexes[index].o_key == key) {
-+                      ce = __mb_cache_entry_read(ce);
-+                      if (ce)
-+                              return ce;
-+              }
-+              l = l->next;
-+      }
-+      return NULL;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_find_first()
-+ *
-+ * Find the first cache entry on a given device with a certain key in
-+ * an additional index. Additonal matches can be found with
-+ * mb_cache_entry_find_next(). Returns NULL if no match was found.
-+ *
-+ * @cache: the cache to search
-+ * @index: the number of the additonal index to search (0<=index<indexes_count)
-+ * @bdev: the device the cache entry should belong to
-+ * @key: the key in the index
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_find_first(struct mb_cache *cache, int index,
-+                        struct block_device *bdev, unsigned int key)
-+{
-+      unsigned int bucket = hash_long(key, cache->c_bucket_bits);
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      mb_assert(index < mb_cache_indexes(cache));
-+      spin_lock(&mb_cache_spinlock);
-+      l = cache->c_indexes_hash[index][bucket].next;
-+      ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
-+                                 index, bdev, key);
-+      spin_unlock(&mb_cache_spinlock);
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_find_next()
-+ *
-+ * Find the next cache entry on a given device with a certain key in an
-+ * additional index. Returns NULL if no match could be found. The previous
-+ * entry is atomatically released, so that mb_cache_entry_find_next() can
-+ * be called like this:
-+ *
-+ * entry = mb_cache_entry_find_first();
-+ * while (entry) {
-+ *    ...
-+ *    entry = mb_cache_entry_find_next(entry, ...);
-+ * }
-+ *
-+ * @prev: The previous match
-+ * @index: the number of the additonal index to search (0<=index<indexes_count)
-+ * @bdev: the device the cache entry should belong to
-+ * @key: the key in the index
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_find_next(struct mb_cache_entry *prev, int index,
-+                       struct block_device *bdev, unsigned int key)
-+{
-+      struct mb_cache *cache = prev->e_cache;
-+      unsigned int bucket = hash_long(key, cache->c_bucket_bits);
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      mb_assert(index < mb_cache_indexes(cache));
-+      spin_lock(&mb_cache_spinlock);
-+      l = prev->e_indexes[index].o_list.next;
-+      ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
-+                                 index, bdev, key);
-+      __mb_cache_entry_release_unlock(prev);
-+      return ce;
-+}
-+
-+#endif  /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */
-diff -Nru a/fs/namei.c b/fs/namei.c
---- a/fs/namei.c       Sat Jan  4 18:24:12 2003
-+++ b/fs/namei.c       Sat Jan  4 18:24:12 2003
-@@ -108,6 +108,14 @@
-  * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
-  * PATH_MAX includes the nul terminator --RR.
-  */
-+
-+void intent_release(struct dentry *de, struct lookup_intent *it)
-+{
-+        if (it && de->d_op && de->d_op->d_intent_release)
-+                de->d_op->d_intent_release(de, it);
-+
-+}
-+
- static inline int do_getname(const char *filename, char *page)
- {
-       int retval;
-@@ -265,6 +273,9 @@
- void path_release(struct nameidata *nd)
- {
-+        if (&nd->it && nd->dentry && nd->dentry->d_op && 
-+            nd->dentry->d_op->d_intent_release)
-+                nd->dentry->d_op->d_intent_release(nd->dentry, &nd->it);
-       dput(nd->dentry);
-       mntput(nd->mnt);
- }
-@@ -273,10 +284,18 @@
-  * Internal lookup() using the new generic dcache.
-  * SMP-safe
-  */
--static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
- {
-       struct dentry * dentry = d_lookup(parent, name);
-       
-+      if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+              if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
-+                  !d_invalidate(dentry)) {
-+                      dput(dentry);
-+                      dentry = NULL;
-+              }
-+              return dentry;
-+      } else
-       if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-               if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
-                       dput(dentry);
-@@ -351,7 +370,7 @@
-  * make sure that nobody added the entry to the dcache in the meantime..
-  * SMP-safe
-  */
--static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
- {
-       struct dentry * result;
-       struct inode *dir = parent->d_inode;
-@@ -369,7 +388,10 @@
-               struct dentry * dentry = d_alloc(parent, name);
-               result = ERR_PTR(-ENOMEM);
-               if (dentry) {
--                      result = dir->i_op->lookup(dir, dentry);
-+                      if (dir->i_op->lookup2)
-+                              result = dir->i_op->lookup2(dir, dentry, it);
-+                      else
-+                                result = dir->i_op->lookup(dir, dentry);
-                       if (result)
-                               dput(dentry);
-                       else {
-@@ -391,6 +413,12 @@
-                       dput(result);
-                       result = ERR_PTR(-ENOENT);
-               }
-+      } else if (result->d_op && result->d_op->d_revalidate2) {
-+              if (!result->d_op->d_revalidate2(result, flags, it) &&
-+                  !d_invalidate(result)) {
-+                      dput(result);
-+                      result = ERR_PTR(-ENOENT);
-+              }
-       }
-       return result;
- }
-@@ -402,7 +430,7 @@
-  * Without that kind of total limit, nasty chains of consecutive
-  * symlinks can cause almost arbitrarily long lookups. 
-  */
--static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
-+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) 
- {
-       int err = -ELOOP;
-       if (current->link_count >= 5)
-@@ -419,10 +447,15 @@
-       current->link_count++;
-       current->total_link_count++;
-       UPDATE_ATIME(dentry->d_inode);
--      err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+        if (dentry->d_inode->i_op->follow_link2) {
-+                      err = dentry->d_inode->i_op->follow_link2(dentry, nd);
-+      }
-+        else 
-+                err = dentry->d_inode->i_op->follow_link(dentry, nd);
-       current->link_count--;
-       return err;
- loop:
-+      intent_release(dentry, &nd->it);
-       path_release(nd);
-       return err;
- }
-@@ -523,6 +556,8 @@
-       if (!dentry)
-               goto dcache_miss;
-+      if (dentry->d_op && dentry->d_op->d_revalidate2)
-+              goto need_revalidate2;
-       if (dentry->d_op && dentry->d_op->d_revalidate)
-               goto need_revalidate;
- done:
-@@ -534,7 +569,12 @@
-       unlock_nd(nd);
- need_lookup:
--      dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE);
-+      if (nd->it.it_op == 0){
-+              dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE, NULL);
-+      }
-+      else{
-+              dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE, &nd->it);
-+      }
-       if (IS_ERR(dentry))
-               goto fail;
-       mntget(mnt);
-@@ -546,6 +586,18 @@
-       lock_nd(nd);
-       goto done;
-+need_revalidate2:
-+      mntget(mnt);
-+      dget_locked(dentry);
-+      unlock_nd(nd);
-+      if (dentry->d_op->d_revalidate2(dentry, flags, &nd->it))
-+              goto relock;
-+      if (d_invalidate(dentry))
-+              goto relock;
-+      dput(dentry);
-+      mntput(mnt);
-+      goto need_lookup;
-+
- need_revalidate:
-       mntget(mnt);
-       dget_locked(dentry);
-@@ -577,6 +629,7 @@
-       struct inode *inode;
-       int err;
-       unsigned int lookup_flags = nd->flags;
-+      int save_it_op = nd->it.it_op;
-       
-       while (*name=='/')
-               name++;
-@@ -648,6 +701,7 @@
-                               break;
-               }
-               /* This does the actual lookups.. */
-+              nd->it.it_op = 0;
-               err = do_lookup(nd, &this, &next, &pinned, LOOKUP_CONTINUE);
-               if (err)
-                       break;
-@@ -662,7 +716,7 @@
-               if (!inode->i_op)
-                       break;
--              if (inode->i_op->follow_link) {
-+              if (inode->i_op->follow_link || inode->i_op->follow_link2) {
-                       mntget(next.mnt);
-                       dget_locked(next.dentry);
-                       unlock_nd(nd);
-@@ -684,7 +738,7 @@
-                       nd->dentry = next.dentry;
-               }
-               err = -ENOTDIR; 
--              if (!inode->i_op->lookup)
-+              if (!inode->i_op->lookup && !inode->i_op->lookup2)
-                       break;
-               continue;
-               /* here ends the main loop */
-@@ -692,6 +746,7 @@
- last_with_slashes:
-               lookup_flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
- last_component:
-+              nd->it.it_op = save_it_op;
-               if (lookup_flags & LOOKUP_PARENT)
-                       goto lookup_parent;
-               if (this.name[0] == '.') switch (this.len) {
-@@ -717,7 +772,8 @@
-               follow_mount(&next.mnt, &next.dentry);
-               inode = next.dentry->d_inode;
-               if ((lookup_flags & LOOKUP_FOLLOW)
--                  && inode && inode->i_op && inode->i_op->follow_link) {
-+                  && inode && inode->i_op && 
-+                  (inode->i_op->follow_link || inode->i_op->follow_link2)) {
-                       mntget(next.mnt);
-                       dget_locked(next.dentry);
-                       unlock_nd(nd);
-@@ -737,7 +793,8 @@
-                       break;
-               if (lookup_flags & LOOKUP_DIRECTORY) {
-                       err = -ENOTDIR; 
--                      if (!inode->i_op || !inode->i_op->lookup)
-+                      if (!inode->i_op || 
-+                            (!inode->i_op->lookup && !inode->i_op->lookup2))
-                               break;
-               }
-               goto return_base;
-@@ -886,7 +943,8 @@
-  * needs parent already locked. Doesn't follow mounts.
-  * SMP-safe.
-  */
--struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+struct dentry * lookup_hash(struct qstr *name, struct dentry * base, 
-+                            struct lookup_intent *it)
- {
-       struct dentry * dentry;
-       struct inode *inode;
-@@ -909,13 +967,16 @@
-                       goto out;
-       }
--      dentry = cached_lookup(base, name, 0);
-+      dentry = cached_lookup(base, name, 0, it);
-       if (!dentry) {
-               struct dentry *new = d_alloc(base, name);
-               dentry = ERR_PTR(-ENOMEM);
-               if (!new)
-                       goto out;
--              dentry = inode->i_op->lookup(inode, new);
-+                if (inode->i_op->lookup2) 
-+                        dentry = inode->i_op->lookup2(inode, new, it);
-+                else 
-+                        dentry = inode->i_op->lookup(inode, new);
-               if (!dentry) {
-                       dentry = new;
-                       security_ops->inode_post_lookup(inode, dentry);
-@@ -927,7 +988,7 @@
- }
- /* SMP-safe */
--struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
-+struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct lookup_intent *it)
- {
-       unsigned long hash;
-       struct qstr this;
-@@ -947,11 +1008,16 @@
-       }
-       this.hash = end_name_hash(hash);
--      return lookup_hash(&this, base);
-+      return lookup_hash(&this, base, it);
- access:
-       return ERR_PTR(-EACCES);
- }
-+struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
-+{
-+        return lookup_one_len_it(name, base, len, NULL);
-+}
-+
- /*
-  *    namei()
-  *
-@@ -1268,7 +1334,9 @@
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      nd->it.it_op |= IT_CREAT;
-+      nd->it.it_mode = mode;
-+      dentry = lookup_hash(&nd->last, nd->dentry, &nd->it);
- do_last:
-       error = PTR_ERR(dentry);
-@@ -1277,6 +1345,7 @@
-               goto exit;
-       }
-+      nd->it.it_mode = mode;
-       /* Negative dentry, just create the file */
-       if (!dentry->d_inode) {
-               error = vfs_create(dir->d_inode, dentry,
-@@ -1310,7 +1379,8 @@
-       error = -ENOENT;
-       if (!dentry->d_inode)
-               goto exit_dput;
--      if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
-+      if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
-+                                    dentry->d_inode->i_op->follow_link2))
-               goto do_link;
-       dput(nd->dentry);
-@@ -1325,8 +1395,10 @@
-       return 0;
- exit_dput:
-+      intent_release(dentry, &nd->it);
-       dput(dentry);
- exit:
-+      intent_release(nd->dentry, &nd->it);
-       path_release(nd);
-       return error;
-@@ -1348,7 +1420,12 @@
-       if (error)
-               goto exit_dput;
-       UPDATE_ATIME(dentry->d_inode);
--      error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if(dentry->d_inode->i_op->follow_link2)
-+              error = dentry->d_inode->i_op->follow_link2(dentry, nd);
-+      else
-+              error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (error)
-+              intent_release(dentry, &nd->it);
-       dput(dentry);
-       if (error)
-               return error;
-@@ -1370,7 +1447,7 @@
-       }
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash(&nd->last, nd->dentry, &nd->it);
-       putname(nd->last.name);
-       goto do_last;
- }
-@@ -1384,7 +1461,7 @@
-       dentry = ERR_PTR(-EEXIST);
-       if (nd->last_type != LAST_NORM)
-               goto fail;
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash(&nd->last, nd->dentry, &nd->it);
-       if (IS_ERR(dentry))
-               goto fail;
-       if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1429,6 +1506,7 @@
-       char * tmp;
-       struct dentry * dentry;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
-       if (S_ISDIR(mode))
-               return -EPERM;
-@@ -1436,9 +1514,14 @@
-       if (IS_ERR(tmp))
-               return PTR_ERR(tmp);
-+      nd.it = it;
-+      nd.it.it_mode = 0;
-+      nd.it.it_op = IT_LOOKUP;
-       error = path_lookup(tmp, LOOKUP_PARENT, &nd);
-       if (error)
-               goto out;
-+
-+      nd.it = it;
-       dentry = lookup_create(&nd, 0);
-       error = PTR_ERR(dentry);
-@@ -1457,6 +1540,7 @@
-               default:
-                       error = -EINVAL;
-               }
-+              intent_release(dentry, &nd.it); 
-               dput(dentry);
-       }
-       up(&nd.dentry->d_inode->i_sem);
-@@ -1495,6 +1579,7 @@
- {
-       int error = 0;
-       char * tmp;
-+      struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
-       tmp = getname(pathname);
-       error = PTR_ERR(tmp);
-@@ -1502,14 +1587,19 @@
-               struct dentry *dentry;
-               struct nameidata nd;
-+              nd.it = it;
-+              nd.it.it_mode = 0;
-+              nd.it.it_op = IT_LOOKUP;
-               error = path_lookup(tmp, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
-+              nd.it = it;
-               dentry = lookup_create(&nd, 1);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_mkdir(nd.dentry->d_inode, dentry,
-                                         mode & ~current->fs->umask);
-+                      intent_release(dentry, &nd.it);
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-@@ -1593,11 +1683,14 @@
-       char * name;
-       struct dentry *dentry;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_RMDIR };
-       name = getname(pathname);
-       if(IS_ERR(name))
-               return PTR_ERR(name);
--
-+              
-+      nd.it = it;
-+      nd.it.it_op = IT_LOOKUP;
-       error = path_lookup(name, LOOKUP_PARENT, &nd);
-       if (error)
-               goto exit;
-@@ -1614,10 +1707,12 @@
-                       goto exit1;
-       }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      nd.it = it;
-+      dentry = lookup_hash(&nd.last, nd.dentry, &nd.it);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               error = vfs_rmdir(nd.dentry->d_inode, dentry);
-+              intent_release(dentry, &nd.it);
-               dput(dentry);
-       }
-       up(&nd.dentry->d_inode->i_sem);
-@@ -1663,11 +1758,14 @@
-       char * name;
-       struct dentry *dentry;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_UNLINK };
-       name = getname(pathname);
-       if(IS_ERR(name))
-               return PTR_ERR(name);
-+      nd.it = it; 
-+      nd.it.it_op = IT_LOOKUP;
-       error = path_lookup(name, LOOKUP_PARENT, &nd);
-       if (error)
-               goto exit;
-@@ -1675,7 +1773,9 @@
-       if (nd.last_type != LAST_NORM)
-               goto exit1;
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+
-+      nd.it = it;
-+      dentry = lookup_hash(&nd.last, nd.dentry, &nd.it);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               /* Why not before? Because we want correct error value */
-@@ -1683,6 +1783,7 @@
-                       goto slashes;
-               error = vfs_unlink(nd.dentry->d_inode, dentry);
-       exit2:
-+              intent_release(dentry, &nd.it);
-               dput(dentry);
-       }
-       up(&nd.dentry->d_inode->i_sem);
-@@ -1727,6 +1828,7 @@
-       int error = 0;
-       char * from;
-       char * to;
-+      struct lookup_intent it = { .it_op = IT_SYMLINK };
-       from = getname(oldname);
-       if(IS_ERR(from))
-@@ -1737,13 +1839,18 @@
-               struct dentry *dentry;
-               struct nameidata nd;
-+              nd.it = it; 
-+              nd.it.it_op = IT_LOOKUP;
-               error = path_lookup(to, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
-+              nd.it = it;
-+              nd.it.it_data = from;
-               dentry = lookup_create(&nd, 0);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_symlink(nd.dentry->d_inode, dentry, from);
-+                      intent_release(dentry, &nd.it);
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-@@ -1810,24 +1917,32 @@
-       struct nameidata nd, old_nd;
-       int error;
-       char * to;
-+      struct lookup_intent it = { .it_op = IT_LINK };
-+
-       to = getname(newname);
-       if (IS_ERR(to))
-               return PTR_ERR(to);
-+      old_nd.it = it;
-       error = __user_walk(oldname, 0, &old_nd);
-       if (error)
-               goto exit;
-+      nd.it = it;
-+      nd.it.it_op = IT_LOOKUP;
-       error = path_lookup(to, LOOKUP_PARENT, &nd);
-       if (error)
-               goto out;
-       error = -EXDEV;
-       if (old_nd.mnt != nd.mnt)
-               goto out_release;
-+      nd.it = old_nd.it;//if __user_walk() above didn't change old_nd.it, this step is not need.
-+              nd.it.it_op = IT_LINK2; 
-       new_dentry = lookup_create(&nd, 0);
-       error = PTR_ERR(new_dentry);
-       if (!IS_ERR(new_dentry)) {
-               error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-+              intent_release(new_dentry, &nd.it);
-               dput(new_dentry);
-       }
-       up(&nd.dentry->d_inode->i_sem);
-@@ -1874,7 +1989,8 @@
-  *       locking].
-  */
- int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+             struct inode *new_dir, struct dentry *new_dentry,
-+             struct lookup_intent *it)
- {
-       int error = 0;
-       struct inode *target;
-@@ -1902,6 +2018,7 @@
-               error = -EBUSY;
-       else 
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       if (target) {
-               if (!error)
-                       target->i_flags |= S_DEAD;
-@@ -1919,7 +2036,8 @@
- }
- int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+             struct inode *new_dir, struct dentry *new_dentry,
-+             struct lookup_intent *it)
- {
-       struct inode *target;
-       int error;
-@@ -1944,12 +2062,14 @@
-       }
-       if (target)
-               up(&target->i_sem);
-+      intent_release(new_dentry, it);
-       dput(new_dentry);
-       return error;
- }
- int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+             struct inode *new_dir, struct dentry *new_dentry, 
-+               struct lookup_intent *it)
- {
-       int error;
-       int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
-@@ -1975,9 +2095,9 @@
-       DQUOT_INIT(new_dir);
-       if (is_dir)
--              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
-       else
--              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
-       if (!error) {
-               if (old_dir == new_dir)
-                       inode_dir_notify(old_dir, DN_RENAME);
-@@ -1996,11 +2116,16 @@
-       struct dentry * old_dentry, *new_dentry;
-       struct dentry * trap;
-       struct nameidata oldnd, newnd;
-+      struct lookup_intent it = { .it_op = IT_RENAME };
-+      oldnd.it = it;
-+      oldnd.it.it_op = IT_LOOKUP;
-       error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
-       if (error)
-               goto exit;
-+      newnd.it = it;
-+      newnd.it.it_op = IT_LOOKUP;
-       error = path_lookup(newname, LOOKUP_PARENT, &newnd);
-       if (error)
-               goto exit1;
-@@ -2020,7 +2145,8 @@
-       trap = lock_rename(new_dir, old_dir);
--      old_dentry = lookup_hash(&oldnd.last, old_dir);
-+      oldnd.it = it; 
-+      old_dentry = lookup_hash(&oldnd.last, old_dir, &oldnd.it);
-       error = PTR_ERR(old_dentry);
-       if (IS_ERR(old_dentry))
-               goto exit3;
-@@ -2040,7 +2166,9 @@
-       error = -EINVAL;
-       if (old_dentry == trap)
-               goto exit4;
--      new_dentry = lookup_hash(&newnd.last, new_dir);
-+      newnd.it = oldnd.it;
-+      newnd.it.it_op = IT_RENAME2;
-+      new_dentry = lookup_hash(&newnd.last, new_dir, &newnd.it);
-       error = PTR_ERR(new_dentry);
-       if (IS_ERR(new_dentry))
-               goto exit4;
-@@ -2050,10 +2178,12 @@
-               goto exit5;
-       error = vfs_rename(old_dir->d_inode, old_dentry,
--                                 new_dir->d_inode, new_dentry);
-+                                 new_dir->d_inode, new_dentry, NULL);
- exit5:
-+      intent_release(new_dentry, &newnd.it);
-       dput(new_dentry);
- exit4:
-+      intent_release(old_dentry, &oldnd.it);
-       dput(old_dentry);
- exit3:
-       unlock_rename(new_dir, old_dir);
-@@ -2135,12 +2265,17 @@
-       path_release(nd);
-       return PTR_ERR(link);
- }
-+/* if call vfs_follow_link, then equal set nd->it.it_op = 0;then call __vfs_follow_link
-+ * if call vfs_follow_link_it, now equal call __vfs_follow_link directly
-+*/
- int vfs_follow_link(struct nameidata *nd, const char *link)
- {
-+      nd->it.it_op = 0;
-       return __vfs_follow_link(nd, link);
- }
-+
- /* get the link contents into pagecache */
- static char *page_getlink(struct dentry * dentry, struct page **ppage)
- {
-@@ -2180,7 +2315,9 @@
- {
-       struct page *page = NULL;
-       char *s = page_getlink(dentry, &page);
--      int res = __vfs_follow_link(nd, s);
-+      int res;
-+      nd->it.it_op = 0;
-+      res = __vfs_follow_link(nd, s);
-       if (page) {
-               kunmap(page);
-               page_cache_release(page);
-diff -Nru a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
---- a/fs/nfsd/vfs.c    Sat Jan  4 18:24:12 2003
-+++ b/fs/nfsd/vfs.c    Sat Jan  4 18:24:12 2003
-@@ -1292,7 +1292,7 @@
-                       err = nfserr_perm;
-       } else
- #endif
--      err = vfs_rename(fdir, odentry, tdir, ndentry);
-+      err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
-       if (!err && EX_ISSYNC(tfhp->fh_export)) {
-               nfsd_sync_dir(tdentry);
-               nfsd_sync_dir(fdentry);
-diff -Nru a/fs/open.c b/fs/open.c
---- a/fs/open.c        Sat Jan  4 18:24:12 2003
-+++ b/fs/open.c        Sat Jan  4 18:24:12 2003
-@@ -22,6 +22,8 @@
- #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
-+extern void intent_release(struct dentry *de, struct lookup_intent *it);
-+
- int vfs_statfs(struct super_block *sb, struct statfs *buf)
- {
-       int retval = -ENODEV;
-@@ -96,7 +98,9 @@
-       struct nameidata nd;
-       struct inode * inode;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
-+      nd.it = it;
-       error = -EINVAL;
-       if (length < 0) /* sorry, but loff_t says... */
-               goto out;
-@@ -237,7 +241,9 @@
-       struct nameidata nd;
-       struct inode * inode;
-       struct iattr newattrs;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
-+      nd.it = it;
-       error = user_path_walk(filename, &nd);
-       if (error)
-               goto out;
-@@ -283,9 +289,10 @@
-       struct nameidata nd;
-       struct inode * inode;
-       struct iattr newattrs;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
-+      nd.it = it;
-       error = user_path_walk(filename, &nd);
--
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-@@ -329,7 +336,9 @@
-       int old_fsuid, old_fsgid;
-       kernel_cap_t old_cap;
-       int res;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-+      nd.it = it;
-       if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
-               return -EINVAL;
-@@ -374,7 +383,9 @@
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-+      nd.it = it;
-       error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
-       if (error)
-               goto out;
-@@ -425,7 +436,9 @@
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-+      nd.it = it;
-       error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
-       if (error)
-               goto out;
-@@ -488,7 +501,9 @@
-       struct inode * inode;
-       int error;
-       struct iattr newattrs;
-+      struct lookup_intent it= { .it_op = IT_SETATTR };
-+      nd.it = it;
-       error = user_path_walk(filename, &nd);
-       if (error)
-               goto out;
-@@ -555,7 +570,9 @@
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
-+      nd.it = it;
-       error = user_path_walk(filename, &nd);
-       if (!error) {
-               error = chown_common(nd.dentry, user, group);
-@@ -568,7 +585,9 @@
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
-+      nd.it = it;
-       error = user_path_walk_link(filename, &nd);
-       if (!error) {
-               error = chown_common(nd.dentry, user, group);
-@@ -605,11 +624,16 @@
-  * for the internal routines (ie open_namei()/follow_link() etc). 00 is
-  * used by symlinks.
-  */
-+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                            int flags, struct lookup_intent *it);
-+
- struct file *filp_open(const char * filename, int flags, int mode)
- {
-       int namei_flags, error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_OPEN };
-+      nd.it = it;
-       namei_flags = flags;
-       if ((namei_flags+1) & O_ACCMODE)
-               namei_flags++;
-@@ -618,12 +642,13 @@
-       error = open_namei(filename, namei_flags, mode, &nd);
-       if (!error)
--              return dentry_open(nd.dentry, nd.mnt, flags);
-+              return dentry_open_it(nd.dentry, nd.mnt, flags, &nd.it);
-       return ERR_PTR(error);
- }
--struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                          int flags, struct lookup_intent *it)
- {
-       struct file * f;
-       struct inode *inode;
-@@ -666,6 +691,7 @@
-               }
-       }
-+      intent_release(dentry, it);
-       return f;
- cleanup_all:
-@@ -678,10 +704,17 @@
- cleanup_file:
-       put_filp(f);
- cleanup_dentry:
-+      intent_release(dentry, it);
-       dput(dentry);
-       mntput(mnt);
-       return ERR_PTR(error);
- }
-+
-+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+{
-+              return dentry_open_it(dentry, mnt, flags, NULL);
-+}
-+
- /*
-  * Find an empty file descriptor entry, and mark it busy.
-diff -Nru a/fs/stat.c b/fs/stat.c
---- a/fs/stat.c        Sat Jan  4 18:24:12 2003
-+++ b/fs/stat.c        Sat Jan  4 18:24:12 2003
-@@ -61,7 +61,9 @@
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-+      nd.it = it;
-       error = user_path_walk(name, &nd);
-       if (!error) {
-               error = vfs_getattr(nd.mnt, nd.dentry, stat);
-@@ -74,7 +76,9 @@
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-+      nd.it = it;
-       error = user_path_walk_link(name, &nd);
-       if (!error) {
-               error = vfs_getattr(nd.mnt, nd.dentry, stat);
-diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c
---- a/fs/sysfs/inode.c Sat Jan  4 18:24:12 2003
-+++ b/fs/sysfs/inode.c Sat Jan  4 18:24:12 2003
-@@ -471,7 +471,7 @@
-       qstr.name = name;
-       qstr.len = strlen(name);
-       qstr.hash = full_name_hash(name,qstr.len);
--      return lookup_hash(&qstr,parent);
-+      return lookup_hash(&qstr,parent,NULL);
- }
- /**
-diff -Nru a/include/linux/dcache.h b/include/linux/dcache.h
---- a/include/linux/dcache.h   Sat Jan  4 18:24:12 2003
-+++ b/include/linux/dcache.h   Sat Jan  4 18:24:12 2003
-@@ -9,6 +9,24 @@
- #include <linux/spinlock.h>
- #include <asm/page.h>                 /* for BUG() */
-+#define IT_OPEN  (1)
-+#define IT_CREAT  (1<<1)
-+#define IT_MKDIR  (1<<2)
-+#define IT_LINK  (1<<3)
-+#define IT_LINK2  (1<<4)
-+#define IT_SYMLINK  (1<<5)
-+#define IT_UNLINK  (1<<6)
-+#define IT_RMDIR  (1<<7)
-+#define IT_RENAME  (1<<8)
-+#define IT_RENAME2  (1<<9)
-+#define IT_READDIR  (1<<10)
-+#define IT_GETATTR  (1<<11)
-+#define IT_SETATTR  (1<<12)
-+#define IT_READLINK  (1<<13)
-+#define IT_MKNOD  (1<<14)
-+#define IT_LOOKUP  (1<<15)
-+
-+
- /*
-  * linux/include/linux/dcache.h
-  *
-@@ -30,6 +48,8 @@
-       unsigned int hash;
- };
-+#include <linux/namei.h>
-+
- struct dentry_stat_t {
-       int nr_dentry;
-       int nr_unused;
-@@ -79,6 +99,7 @@
-       struct list_head d_subdirs;     /* our children */
-       struct list_head d_alias;       /* inode alias list */
-       int d_mounted;
-+        struct lookup_intent *d_it;
-       struct qstr d_name;
-       unsigned long d_time;           /* used by d_revalidate */
-       struct dentry_operations  *d_op;
-@@ -96,6 +117,8 @@
-       int (*d_delete)(struct dentry *);
-       void (*d_release)(struct dentry *);
-       void (*d_iput)(struct dentry *, struct inode *);
-+      int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
-+      void (*d_intent_release)(struct  dentry *, struct lookup_intent *);
- };
- /* the dentry parameter passed to d_hash and d_compare is the parent
-diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
---- a/include/linux/ext3_fs.h  Sat Jan  4 18:24:12 2003
-+++ b/include/linux/ext3_fs.h  Sat Jan  4 18:24:12 2003
-@@ -64,8 +64,6 @@
-  */
- #define       EXT3_BAD_INO             1      /* Bad blocks inode */
- #define EXT3_ROOT_INO          2      /* Root inode */
--#define EXT3_ACL_IDX_INO       3      /* ACL inode */
--#define EXT3_ACL_DATA_INO      4      /* ACL inode */
- #define EXT3_BOOT_LOADER_INO   5      /* Boot loader inode */
- #define EXT3_UNDEL_DIR_INO     6      /* Undelete directory inode */
- #define EXT3_RESIZE_INO                7      /* Reserved group descriptors inode */
-@@ -95,7 +93,6 @@
- #else
- # define EXT3_BLOCK_SIZE(s)           (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
- #endif
--#define EXT3_ACLE_PER_BLOCK(s)                (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
- #define       EXT3_ADDR_PER_BLOCK(s)          (EXT3_BLOCK_SIZE(s) / sizeof (__u32))
- #ifdef __KERNEL__
- # define EXT3_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
-@@ -130,28 +127,6 @@
- #endif
- /*
-- * ACL structures
-- */
--struct ext3_acl_header        /* Header of Access Control Lists */
--{
--      __u32   aclh_size;
--      __u32   aclh_file_count;
--      __u32   aclh_acle_count;
--      __u32   aclh_first_acle;
--};
--
--struct ext3_acl_entry /* Access Control List Entry */
--{
--      __u32   acle_size;
--      __u16   acle_perms;     /* Access permissions */
--      __u16   acle_type;      /* Type of entry */
--      __u16   acle_tag;       /* User or group identity */
--      __u16   acle_pad1;
--      __u32   acle_next;      /* Pointer on next entry for the */
--                                      /* same inode or on next free entry */
--};
--
--/*
-  * Structure of a blocks group descriptor
-  */
- struct ext3_group_desc
-@@ -347,6 +322,7 @@
-   #define EXT3_MOUNT_WRITEBACK_DATA   0x0C00  /* No data ordering */
- #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
-@@ -529,7 +505,7 @@
- #define EXT3_FEATURE_INCOMPAT_RECOVER         0x0004 /* Needs recovery */
- #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008 /* Journal device */
--#define EXT3_FEATURE_COMPAT_SUPP      0
-+#define EXT3_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
- #define EXT3_FEATURE_INCOMPAT_SUPP    (EXT3_FEATURE_INCOMPAT_FILETYPE| \
-                                        EXT3_FEATURE_INCOMPAT_RECOVER)
- #define EXT3_FEATURE_RO_COMPAT_SUPP   (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-@@ -713,6 +689,7 @@
- /* inode.c */
-+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
-@@ -781,8 +758,10 @@
- /* namei.c */
- extern struct inode_operations ext3_dir_inode_operations;
-+extern struct inode_operations ext3_special_inode_operations;
- /* symlink.c */
-+extern struct inode_operations ext3_symlink_inode_operations;
- extern struct inode_operations ext3_fast_symlink_inode_operations;
-diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
---- a/include/linux/ext3_jbd.h Sat Jan  4 18:24:12 2003
-+++ b/include/linux/ext3_jbd.h Sat Jan  4 18:24:12 2003
-@@ -30,13 +30,19 @@
- #define EXT3_SINGLEDATA_TRANS_BLOCKS  8
-+/* Extended attributes may touch two data buffers, two bitmap buffers,
-+ * and two group and summaries. */
-+
-+#define EXT3_XATTR_TRANS_BLOCKS               8
-+
- /* Define the minimum size for a transaction which modifies data.  This
-  * needs to take into account the fact that we may end up modifying two
-  * quota files too (one for the group, one for the user quota).  The
-  * superblock only gets updated once, of course, so don't bother
-  * counting that again for the quota updates. */
--#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
-+#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
-+                                       EXT3_XATTR_TRANS_BLOCKS - 2)
- extern int ext3_writepage_trans_blocks(struct inode *inode);
-diff -Nru a/include/linux/fs.h b/include/linux/fs.h
---- a/include/linux/fs.h       Sat Jan  4 18:24:12 2003
-+++ b/include/linux/fs.h       Sat Jan  4 18:24:12 2003
-@@ -700,7 +700,7 @@
- extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
- extern int vfs_rmdir(struct inode *, struct dentry *);
- extern int vfs_unlink(struct inode *, struct dentry *);
--extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
-+extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct lookup_intent *it);
- /*
-  * File types
-@@ -769,6 +769,8 @@
- struct inode_operations {
-       int (*create) (struct inode *,struct dentry *,int);
-       struct dentry * (*lookup) (struct inode *,struct dentry *);
-+      struct dentry * (*lookup2) (struct inode *,struct dentry *, 
-+                                    struct lookup_intent *);
-       int (*link) (struct dentry *,struct inode *,struct dentry *);
-       int (*unlink) (struct inode *,struct dentry *);
-       int (*symlink) (struct inode *,struct dentry *,const char *);
-@@ -779,6 +781,7 @@
-                       struct inode *, struct dentry *);
-       int (*readlink) (struct dentry *, char *,int);
-       int (*follow_link) (struct dentry *, struct nameidata *);
-+      int (*follow_link2) (struct dentry *, struct nameidata *);
-       void (*truncate) (struct inode *);
-       int (*permission) (struct inode *, int);
-       int (*setattr) (struct dentry *, struct iattr *);
-@@ -995,6 +998,7 @@
- extern int unregister_filesystem(struct file_system_type *);
- extern struct vfsmount *kern_mount(struct file_system_type *);
- extern int may_umount(struct vfsmount *);
-+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
- extern long do_mount(char *, char *, char *, unsigned long, void *);
- #define kern_umount mntput
-diff -Nru a/include/linux/lustre_version.h b/include/linux/lustre_version.h
---- /dev/null  Wed Dec 31 16:00:00 1969
-+++ b/include/linux/lustre_version.h   Sat Jan  4 18:24:12 2003
-@@ -0,0 +1 @@
-+#define LUSTRE_KERNEL_VERSION 4
-diff -Nru a/include/linux/mbcache.h b/include/linux/mbcache.h
---- /dev/null  Wed Dec 31 16:00:00 1969
-+++ b/include/linux/mbcache.h  Sat Jan  4 18:24:12 2003
-@@ -0,0 +1,72 @@
-+/*
-+  File: linux/mbcache.h
-+
-+  (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+/* Hardwire the number of additional indexes */
-+#define MB_CACHE_INDEXES_COUNT 1
-+
-+struct mb_cache_entry;
-+
-+struct mb_cache_op {
-+      void (*free)(struct mb_cache_entry *);
-+};
-+
-+struct mb_cache {
-+      struct list_head                c_cache_list;
-+      const char                      *c_name;
-+      struct mb_cache_op              c_op;
-+      atomic_t                        c_entry_count;
-+      int                             c_bucket_bits;
-+#ifndef MB_CACHE_INDEXES_COUNT
-+      int                             c_indexes_count;
-+#endif
-+      kmem_cache_t                    *c_entry_cache;
-+      struct list_head                *c_block_hash;
-+      struct list_head                *c_indexes_hash[0];
-+};
-+
-+struct mb_cache_entry_index {
-+      struct list_head                o_list;
-+      unsigned int                    o_key;
-+};
-+
-+struct mb_cache_entry {
-+      struct list_head                e_lru_list;
-+      struct mb_cache                 *e_cache;
-+      atomic_t                        e_used;
-+      struct block_device             *e_bdev;
-+      sector_t                        e_block;
-+      struct list_head                e_block_list;
-+      struct mb_cache_entry_index     e_indexes[0];
-+};
-+
-+/* Functions on caches */
-+
-+struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t,
-+                                int, int);
-+void mb_cache_shrink(struct mb_cache *, struct block_device *);
-+void mb_cache_destroy(struct mb_cache *);
-+
-+/* Functions on cache entries */
-+
-+struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
-+int mb_cache_entry_insert(struct mb_cache_entry *, struct block_device *,
-+                        sector_t, unsigned int[]);
-+void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
-+void mb_cache_entry_release(struct mb_cache_entry *);
-+void mb_cache_entry_takeout(struct mb_cache_entry *);
-+void mb_cache_entry_free(struct mb_cache_entry *);
-+struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *);
-+struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *,
-+                                        struct block_device *,
-+                                        sector_t);
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int,
-+                                               struct block_device *, 
-+                                               unsigned int);
-+struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int,
-+                                              struct block_device *, 
-+                                              unsigned int);
-+#endif
-diff -Nru a/include/linux/namei.h b/include/linux/namei.h
---- a/include/linux/namei.h    Sat Jan  4 18:24:12 2003
-+++ b/include/linux/namei.h    Sat Jan  4 18:24:12 2003
-@@ -5,6 +5,17 @@
- struct vfsmount;
-+struct lookup_intent {
-+      int it_op;
-+      int it_mode;
-+      int it_disposition;
-+      int it_status;
-+      struct iattr *it_iattr;
-+      __u64 it_lock_handle[2];
-+      int it_lock_mode;
-+      void *it_data;
-+};
-+
- struct nameidata {
-       struct dentry   *dentry;
-       struct vfsmount *mnt;
-@@ -13,6 +24,7 @@
-       int             last_type;
-       struct dentry   *old_dentry;
-       struct vfsmount *old_mnt;
-+        struct lookup_intent it;
- };
- /*
-@@ -46,7 +58,7 @@
- extern void path_release(struct nameidata *);
- extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
--extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
-+extern struct dentry * lookup_hash(struct qstr *, struct dentry *, struct lookup_intent *);
- extern int follow_down(struct vfsmount **, struct dentry **);
- extern int follow_up(struct vfsmount **, struct dentry **);
-diff -Nru a/include/linux/slab.h b/include/linux/slab.h
---- a/include/linux/slab.h     Sat Jan  4 18:24:12 2003
-+++ b/include/linux/slab.h     Sat Jan  4 18:24:12 2003
-@@ -56,6 +56,7 @@
- extern int kmem_cache_shrink(kmem_cache_t *);
- extern void *kmem_cache_alloc(kmem_cache_t *, int);
- extern void kmem_cache_free(kmem_cache_t *, void *);
-+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
- extern unsigned int kmem_cache_size(kmem_cache_t *);
- extern void *kmalloc(size_t, int);
-diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
---- a/kernel/ksyms.c   Sat Jan  4 18:24:12 2003
-+++ b/kernel/ksyms.c   Sat Jan  4 18:24:12 2003
-@@ -365,6 +365,13 @@
- EXPORT_SYMBOL(tty_get_baud_rate);
- EXPORT_SYMBOL(do_SAK);
-+/* lustre */
-+EXPORT_SYMBOL(panic_notifier_list);
-+//EXPORT_SYMBOL(pagecache_lock_cacheline);
-+EXPORT_SYMBOL(do_kern_mount);
-+EXPORT_SYMBOL(exit_files);
-+EXPORT_SYMBOL(kmem_cache_validate);
-+
- /* filesystem registration */
- EXPORT_SYMBOL(register_filesystem);
- EXPORT_SYMBOL(unregister_filesystem);
-@@ -529,6 +536,7 @@
- EXPORT_SYMBOL(seq_lseek);
- EXPORT_SYMBOL(single_open);
- EXPORT_SYMBOL(single_release);
-+EXPORT_SYMBOL(reparent_to_init);
- /* Program loader interfaces */
- EXPORT_SYMBOL(setup_arg_pages);
-diff -Nru a/mm/slab.c b/mm/slab.c
---- a/mm/slab.c        Sat Jan  4 18:24:12 2003
-+++ b/mm/slab.c        Sat Jan  4 18:24:12 2003
-@@ -1236,6 +1236,59 @@
-  * Called with the cache-lock held.
-  */
-+extern struct page *check_get_page(unsigned long kaddr);
-+struct page *page_mem_map(struct page *page);
-+static int kmem_check_cache_obj (kmem_cache_t * cachep,
-+                               slab_t *slabp, void * objp)
-+{
-+      int i;
-+      unsigned int objnr;
-+
-+#if DEBUG
-+      if (cachep->flags & SLAB_RED_ZONE) {
-+              objp -= BYTES_PER_WORD;
-+              if ( *(unsigned long *)objp != RED_MAGIC2)
-+                      /* Either write before start, or a double free. */
-+                      return 0;
-+              if (*(unsigned long *)(objp+cachep->objsize -
-+                              BYTES_PER_WORD) != RED_MAGIC2)
-+                      /* Either write past end, or a double free. */
-+                      return 0;
-+      }
-+#endif
-+
-+      objnr = (objp-slabp->s_mem)/cachep->objsize;
-+      if (objnr >= cachep->num)
-+              return 0;
-+      if (objp != slabp->s_mem + objnr*cachep->objsize)
-+              return 0;
-+
-+      /* Check slab's freelist to see if this obj is there. */
-+      for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
-+              if (i == objnr)
-+                      return 0;
-+      }
-+      return 1;
-+}
-+
-+
-+int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
-+{
-+      struct page *page = check_get_page((unsigned long)objp);
-+
-+      if (!page_mem_map(page))
-+              return 0;
-+
-+      if (!PageSlab(page))
-+              return 0;
-+
-+      /* XXX check for freed slab objects ? */
-+      if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
-+              return 0;
-+
-+      return (cachep == GET_PAGE_CACHE(page));
-+}
-+
- #if DEBUG
- static int kmem_extra_free_checks (kmem_cache_t * cachep,
-                       slab_t *slabp, void * objp)
-diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c
---- a/net/unix/af_unix.c       Sat Jan  4 18:24:12 2003
-+++ b/net/unix/af_unix.c       Sat Jan  4 18:24:12 2003
-@@ -715,7 +715,7 @@
-               /*
-                * Do the final lookup.
-                */
--              dentry = lookup_hash(&nd.last, nd.dentry);
-+              dentry = lookup_hash(&nd.last, nd.dentry, NULL);
-               err = PTR_ERR(dentry);
-               if (IS_ERR(dentry))
-                       goto out_mknod_unlock;
diff --git a/lustre/kernel_patches/patches/linux-2.4.18ea-0.8.26.patch b/lustre/kernel_patches/patches/linux-2.4.18ea-0.8.26.patch
deleted file mode 100644 (file)
index 75ebcd0..0000000
+++ /dev/null
@@ -1,1759 +0,0 @@
- 0 files changed
-
---- linux-2.4.18-18/fs/ext3/ialloc.c~linux-2.4.18ea-0.8.26     2003-04-20 16:14:31.000000000 +0800
-+++ linux-2.4.18-18-root/fs/ext3/ialloc.c      2003-04-20 16:14:31.000000000 +0800
-@@ -17,6 +17,7 @@
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/stat.h>
- #include <linux/string.h>
- #include <linux/locks.h>
-@@ -216,6 +217,7 @@ void ext3_free_inode (handle_t *handle, 
-        * as writing the quota to disk may need the lock as well.
-        */
-       DQUOT_INIT(inode);
-+      ext3_xattr_drop_inode(handle, inode);
-       DQUOT_FREE_INODE(inode);
-       DQUOT_DROP(inode);
---- linux-2.4.18-18/fs/ext3/inode.c~linux-2.4.18ea-0.8.26      2003-04-20 16:14:31.000000000 +0800
-+++ linux-2.4.18-18-root/fs/ext3/inode.c       2003-04-20 16:14:31.000000000 +0800
-@@ -39,6 +39,18 @@
-  */
- #undef SEARCH_FROM_ZERO
-+/*
-+ * Test whether an inode is a fast symlink.
-+ */
-+static inline int ext3_inode_is_fast_symlink(struct inode *inode)
-+{
-+      int ea_blocks = EXT3_I(inode)->i_file_acl ?
-+              (inode->i_sb->s_blocksize >> 9) : 0;
-+
-+      return (S_ISLNK(inode->i_mode) &&
-+              inode->i_blocks - ea_blocks == 0);
-+}
-+
- /* The ext3 forget function must perform a revoke if we are freeing data
-  * which has been journaled.  Metadata (eg. indirect blocks) must be
-  * revoked in all cases. 
-@@ -48,7 +60,7 @@
-  * still needs to be revoked.
-  */
--static int ext3_forget(handle_t *handle, int is_metadata,
-+int ext3_forget(handle_t *handle, int is_metadata,
-                      struct inode *inode, struct buffer_head *bh,
-                      int blocknr)
- {
-@@ -164,9 +176,7 @@ void ext3_delete_inode (struct inode * i
- {
-       handle_t *handle;
-       
--      if (is_bad_inode(inode) ||
--          inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
-+      if (is_bad_inode(inode))
-               goto no_delete;
-       lock_kernel();
-@@ -1861,6 +1871,8 @@ void ext3_truncate(struct inode * inode)
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-+      if (ext3_inode_is_fast_symlink(inode))
-+              return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-@@ -2008,8 +2020,6 @@ int ext3_get_inode_loc (struct inode *in
-       struct ext3_group_desc * gdp;
-               
-       if ((inode->i_ino != EXT3_ROOT_INO &&
--              inode->i_ino != EXT3_ACL_IDX_INO &&
--              inode->i_ino != EXT3_ACL_DATA_INO &&
-               inode->i_ino != EXT3_JOURNAL_INO &&
-               inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
-               inode->i_ino > le32_to_cpu(
-@@ -2136,10 +2146,7 @@ void ext3_read_inode(struct inode * inod
-       brelse (iloc.bh);
--      if (inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
--              /* Nothing to do */ ;
--      else if (S_ISREG(inode->i_mode)) {
-+      if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &ext3_file_inode_operations;
-               inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-@@ -2147,7 +2154,7 @@ void ext3_read_inode(struct inode * inod
-               inode->i_op = &ext3_dir_inode_operations;
-               inode->i_fop = &ext3_dir_operations;
-       } else if (S_ISLNK(inode->i_mode)) {
--              if (!inode->i_blocks)
-+              if (ext3_inode_is_fast_symlink(inode))
-                       inode->i_op = &ext3_fast_symlink_inode_operations;
-               else {
-                       inode->i_op = &page_symlink_inode_operations;
---- linux-2.4.18-18/fs/ext3/namei.c~linux-2.4.18ea-0.8.26      2003-04-20 16:14:31.000000000 +0800
-+++ linux-2.4.18-18-root/fs/ext3/namei.c       2003-04-20 16:14:31.000000000 +0800
-@@ -27,6 +27,7 @@
- #include <linux/sched.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/fcntl.h>
- #include <linux/stat.h>
- #include <linux/string.h>
-@@ -1183,6 +1184,7 @@ static int ext3_add_nondir(handle_t *han
-               d_instantiate(dentry, inode);
-               return 0;
-       }
-+      ext3_xattr_drop_inode(handle, inode);
-       ext3_dec_count(handle, inode);
-       iput(inode);
-       return err;
-@@ -1268,15 +1270,14 @@ static int ext3_mkdir(struct inode * dir
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
--      inode = ext3_new_inode (handle, dir, S_IFDIR);
-+      inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
-       err = PTR_ERR(inode);
-       if (IS_ERR(inode))
-               goto out_stop;
-       inode->i_op = &ext3_dir_inode_operations;
-       inode->i_fop = &ext3_dir_operations;
--      inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize;
--      inode->i_blocks = 0;    
-+      inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
-       dir_block = ext3_bread (handle, inode, 0, 1, &err);
-       if (!dir_block) {
-               inode->i_nlink--; /* is this nlink == 0? */
-@@ -1303,9 +1304,6 @@ static int ext3_mkdir(struct inode * dir
-       BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
-       ext3_journal_dirty_metadata(handle, dir_block);
-       brelse (dir_block);
--      inode->i_mode = S_IFDIR | mode;
--      if (dir->i_mode & S_ISGID)
--              inode->i_mode |= S_ISGID;
-       ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_entry (handle, dentry, inode);
-       if (err)
-@@ -1671,7 +1669,7 @@ static int ext3_symlink (struct inode * 
-       if (IS_ERR(inode))
-               goto out_stop;
--      if (l > sizeof (inode->u.ext3_i.i_data)) {
-+      if (l > sizeof(EXT3_I(inode)->i_data)) {
-               inode->i_op = &page_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-               /*
---- linux-2.4.18-18/fs/ext3/super.c~linux-2.4.18ea-0.8.26      2003-04-20 16:14:31.000000000 +0800
-+++ linux-2.4.18-18-root/fs/ext3/super.c       2003-04-20 16:14:31.000000000 +0800
-@@ -24,6 +24,7 @@
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/locks.h>
-@@ -404,6 +405,7 @@ void ext3_put_super (struct super_block 
-       kdev_t j_dev = sbi->s_journal->j_dev;
-       int i;
-+      ext3_xattr_put_super(sb);
-       journal_destroy(sbi->s_journal);
-       if (!(sb->s_flags & MS_RDONLY)) {
-               EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
-@@ -1748,14 +1750,25 @@ int ext3_statfs (struct super_block * sb
- static DECLARE_FSTYPE_DEV(ext3_fs_type, "ext3", ext3_read_super);
--static int __init init_ext3_fs(void)
-+static void exit_ext3_fs(void)
- {
--        return register_filesystem(&ext3_fs_type);
-+      unregister_filesystem(&ext3_fs_type);
-+      exit_ext3_xattr_user();
-+      exit_ext3_xattr();
- }
--static void __exit exit_ext3_fs(void)
-+static int __init init_ext3_fs(void)
- {
--      unregister_filesystem(&ext3_fs_type);
-+      int error = init_ext3_xattr();
-+      if (!error)
-+              error = init_ext3_xattr_user();
-+      if (!error)
-+              error = register_filesystem(&ext3_fs_type);
-+      if (!error)
-+              return 0;
-+
-+      exit_ext3_fs();
-+      return error;
- }
- EXPORT_SYMBOL(ext3_bread);
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.18-18-root/fs/ext3/xattr.c       2003-04-20 16:14:31.000000000 +0800
-@@ -0,0 +1,1247 @@
-+/*
-+ * linux/fs/ext3/xattr.c
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
-+ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
-+ * Extended attributes for symlinks and special files added per
-+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
-+ */
-+
-+/*
-+ * Extended attributes are stored on disk blocks allocated outside of
-+ * any inode. The i_file_acl field is then made to point to this allocated
-+ * block. If all extended attributes of an inode are identical, these
-+ * inodes may share the same extended attribute block. Such situations
-+ * are automatically detected by keeping a cache of recent attribute block
-+ * numbers and hashes over the block's contents in memory.
-+ *
-+ *
-+ * Extended attribute block layout:
-+ *
-+ *   +------------------+
-+ *   | header           |
-+ *   Â¦ entry 1          | |
-+ *   | entry 2          | | growing downwards
-+ *   | entry 3          | v
-+ *   | four null bytes  |
-+ *   | . . .            |
-+ *   | value 1          | ^
-+ *   | value 3          | | growing upwards
-+ *   | value 2          | |
-+ *   +------------------+
-+ *
-+ * The block header is followed by multiple entry descriptors. These entry
-+ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
-+ * byte boundaries. The entry descriptors are sorted by attribute name,
-+ * so that two extended attribute blocks can be compared efficiently.
-+ *
-+ * Attribute values are aligned to the end of the block, stored in
-+ * no specific order. They are also padded to EXT3_XATTR_PAD byte
-+ * boundaries. No additional gaps are left between them.
-+ *
-+ * Locking strategy
-+ * ----------------
-+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
-+ * the xattr inode operations are called, so we are guaranteed that only one
-+ * processes accesses extended attributes of an inode at any time.
-+ *
-+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
-+ * only a single process is modifying an extended attribute block, even
-+ * if the block is shared among inodes.
-+ *
-+ * Note for porting to 2.5
-+ * -----------------------
-+ * The BKL will no longer be held in the xattr inode operations.
-+ */
-+
-+#include <linux/fs.h>
-+#include <linux/locks.h>
-+#include <linux/slab.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+#include <linux/mbcache.h>
-+#endif
-+#include <linux/quotaops.h>
-+#include <asm/semaphore.h>
-+#include <linux/compatmac.h>
-+#include <linux/module.h>
-+
-+/* These symbols may be needed by a module. */
-+EXPORT_SYMBOL(ext3_xattr_register);
-+EXPORT_SYMBOL(ext3_xattr_unregister);
-+EXPORT_SYMBOL(ext3_xattr_get);
-+EXPORT_SYMBOL(ext3_xattr_list);
-+EXPORT_SYMBOL(ext3_xattr_set);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
-+#endif
-+
-+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
-+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
-+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
-+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
-+
-+#ifdef EXT3_XATTR_DEBUG
-+# define ea_idebug(inode, f...) do { \
-+              printk(KERN_DEBUG "inode %s:%ld: ", \
-+                      kdevname(inode->i_dev), inode->i_ino); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+# define ea_bdebug(bh, f...) do { \
-+              printk(KERN_DEBUG "block %s:%ld: ", \
-+                      kdevname(bh->b_dev), bh->b_blocknr); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+#else
-+# define ea_idebug(f...)
-+# define ea_bdebug(f...)
-+#endif
-+
-+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
-+                         struct ext3_xattr_header *);
-+
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+
-+static int ext3_xattr_cache_insert(struct buffer_head *);
-+static struct buffer_head *ext3_xattr_cache_find(struct inode *,
-+                                               struct ext3_xattr_header *);
-+static void ext3_xattr_cache_remove(struct buffer_head *);
-+static void ext3_xattr_rehash(struct ext3_xattr_header *,
-+                            struct ext3_xattr_entry *);
-+
-+static struct mb_cache *ext3_xattr_cache;
-+
-+#else
-+# define ext3_xattr_cache_insert(bh) 0
-+# define ext3_xattr_cache_find(inode, header) NULL
-+# define ext3_xattr_cache_remove(bh) do {} while(0)
-+# define ext3_xattr_rehash(header, entry) do {} while(0)
-+#endif
-+
-+/*
-+ * If a file system does not share extended attributes among inodes,
-+ * we should not need the ext3_xattr_sem semaphore. However, the
-+ * filesystem may still contain shared blocks, so we always take
-+ * the lock.
-+ */
-+
-+DECLARE_MUTEX(ext3_xattr_sem);
-+
-+static inline void
-+ext3_xattr_lock(void)
-+{
-+      down(&ext3_xattr_sem);
-+}
-+
-+static inline void
-+ext3_xattr_unlock(void)
-+{
-+      up(&ext3_xattr_sem);
-+}
-+
-+static inline int
-+ext3_xattr_new_block(handle_t *handle, struct inode *inode,
-+                   int * errp, int force)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
-+              EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb);
-+
-+      /* How can we enforce the allocation? */
-+      int block = ext3_new_block(handle, inode, goal, 0, 0, errp);
-+#ifdef OLD_QUOTAS
-+      if (!*errp)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#endif
-+      return block;
-+}
-+
-+static inline int
-+ext3_xattr_quota_alloc(struct inode *inode, int force)
-+{
-+      /* How can we enforce the allocation? */
-+#ifdef OLD_QUOTAS
-+      int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
-+      if (!error)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#else
-+      int error = DQUOT_ALLOC_BLOCK(inode, 1);
-+#endif
-+      return error;
-+}
-+
-+#ifdef OLD_QUOTAS
-+
-+static inline void
-+ext3_xattr_quota_free(struct inode *inode)
-+{
-+      DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+static inline void
-+ext3_xattr_free_block(handle_t *handle, struct inode * inode,
-+                    unsigned long block)
-+{
-+      ext3_free_blocks(handle, inode, block, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+#else
-+# define ext3_xattr_quota_free(inode) \
-+      DQUOT_FREE_BLOCK(inode, 1)
-+# define ext3_xattr_free_block(handle, inode, block) \
-+      ext3_free_blocks(handle, inode, block, 1)
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
-+
-+static inline struct buffer_head *
-+sb_bread(struct super_block *sb, int block)
-+{
-+      return bread(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+static inline struct buffer_head *
-+sb_getblk(struct super_block *sb, int block)
-+{
-+      return getblk(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+#endif
-+
-+struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
-+rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
-+
-+int
-+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      int error = -EINVAL;
-+
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              if (!ext3_xattr_handlers[name_index-1]) {
-+                      ext3_xattr_handlers[name_index-1] = handler;
-+                      error = 0;
-+              }
-+              write_unlock(&ext3_handler_lock);
-+      }
-+      return error;
-+}
-+
-+void
-+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              ext3_xattr_handlers[name_index-1] = NULL;
-+              write_unlock(&ext3_handler_lock);
-+      }
-+}
-+
-+static inline const char *
-+strcmp_prefix(const char *a, const char *a_prefix)
-+{
-+      while (*a_prefix && *a == *a_prefix) {
-+              a++;
-+              a_prefix++;
-+      }
-+      return *a_prefix ? NULL : a;
-+}
-+
-+/*
-+ * Decode the extended attribute name, and translate it into
-+ * the name_index and name suffix.
-+ */
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_resolve_name(const char **name)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      int i;
-+
-+      if (!*name)
-+              return NULL;
-+      read_lock(&ext3_handler_lock);
-+      for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
-+              if (ext3_xattr_handlers[i]) {
-+                      const char *n = strcmp_prefix(*name,
-+                              ext3_xattr_handlers[i]->prefix);
-+                      if (n) {
-+                              handler = ext3_xattr_handlers[i];
-+                              *name = n;
-+                              break;
-+                      }
-+              }
-+      }
-+      read_unlock(&ext3_handler_lock);
-+      return handler;
-+}
-+
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_handler(int name_index)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              read_lock(&ext3_handler_lock);
-+              handler = ext3_xattr_handlers[name_index-1];
-+              read_unlock(&ext3_handler_lock);
-+      }
-+      return handler;
-+}
-+
-+/*
-+ * Inode operation getxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext3_getxattr(struct dentry *dentry, const char *name,
-+            void *buffer, size_t size)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->get(inode, name, buffer, size);
-+}
-+
-+/*
-+ * Inode operation listxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
-+{
-+      return ext3_xattr_list(dentry->d_inode, buffer, size);
-+}
-+
-+/*
-+ * Inode operation setxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext3_setxattr(struct dentry *dentry, const char *name,
-+            void *value, size_t size, int flags)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      if (size == 0)
-+              value = "";  /* empty EA, do not remove */
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, value, size, flags);
-+}
-+
-+/*
-+ * Inode operation removexattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext3_removexattr(struct dentry *dentry, const char *name)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
-+}
-+
-+/*
-+ * ext3_xattr_get()
-+ *
-+ * Copy an extended attribute into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size;
-+      char *end;
-+      int name_len, error;
-+
-+      ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
-+                name_index, name, buffer, (long)buffer_size);
-+
-+      if (name == NULL)
-+              return -EINVAL;
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return -ENOATTR;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_get",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* find named attribute */
-+      name_len = strlen(name);
-+
-+      error = -ERANGE;
-+      if (name_len > 255)
-+              goto cleanup;
-+      entry = FIRST_ENTRY(bh);
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              if (name_index == entry->e_name_index &&
-+                  name_len == entry->e_name_len &&
-+                  memcmp(name, entry->e_name, name_len) == 0)
-+                      goto found;
-+              entry = next;
-+      }
-+      /* Check the remaining name entries */
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              entry = next;
-+      }
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      error = -ENOATTR;
-+      goto cleanup;
-+found:
-+      /* check the buffer size */
-+      if (entry->e_value_block != 0)
-+              goto bad_block;
-+      size = le32_to_cpu(entry->e_value_size);
-+      if (size > inode->i_sb->s_blocksize ||
-+          le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-+              goto bad_block;
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (buffer) {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+              /* return value of attribute */
-+              memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-+                      size);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_list()
-+ *
-+ * Copy a list of attribute names into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size = 0;
-+      char *buf, *end;
-+      int error;
-+
-+      ea_idebug(inode, "buffer=%p, buffer_size=%ld",
-+                buffer, (long)buffer_size);
-+
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return 0;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_list",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* compute the size required for the list of attribute names */
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler) {
-+                      size += handler->list(NULL, inode, entry->e_name,
-+                                            entry->e_name_len) + 1;
-+              }
-+      }
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (!buffer) {
-+              error = size;
-+              goto cleanup;
-+      } else {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+      }
-+
-+      /* list the attribute names */
-+      buf = buffer;
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler) {
-+                      buf += handler->list(buf, inode, entry->e_name,
-+                                           entry->e_name_len);
-+                      *buf++ = '\0';
-+              }
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
-+ * not set, set it.
-+ */
-+static void ext3_xattr_update_super_block(handle_t *handle,
-+                                        struct super_block *sb)
-+{
-+      if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
-+              return;
-+
-+      lock_super(sb);
-+      ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+      EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR;
-+#endif
-+      EXT3_SB(sb)->s_es->s_feature_compat |=
-+              cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
-+      sb->s_dirt = 1;
-+      ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-+      unlock_super(sb);
-+}
-+
-+/*
-+ * ext3_xattr_set()
-+ *
-+ * Create, replace or remove an extended attribute for this inode. Buffer
-+ * is NULL to remove an existing extended attribute, and non-NULL to
-+ * either replace an existing extended attribute, or create a new extended
-+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
-+ * specify that an extended attribute must exist and must not exist
-+ * previous to the call, respectively.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, void *value, size_t value_len, int flags)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_header *header = NULL;
-+      struct ext3_xattr_entry *here, *last;
-+      unsigned int name_len;
-+      int min_offs = sb->s_blocksize, not_found = 1, free, error;
-+      char *end;
-+      
-+      /*
-+       * header -- Points either into bh, or to a temporarily
-+       *           allocated buffer.
-+       * here -- The named entry found, or the place for inserting, within
-+       *         the block pointed to by header.
-+       * last -- Points right after the last named entry within the block
-+       *         pointed to by header.
-+       * min_offs -- The offset of the first value (values are aligned
-+       *             towards the end of the block).
-+       * end -- Points right after the block pointed to by header.
-+       */
-+      
-+      ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-+                name_index, name, value, (long)value_len);
-+
-+      if (IS_RDONLY(inode))
-+              return -EROFS;
-+      if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-+              return -EPERM;
-+      if (value == NULL)
-+              value_len = 0;
-+      if (name == NULL)
-+              return -EINVAL;
-+      name_len = strlen(name);
-+      if (name_len > 255 || value_len > sb->s_blocksize)
-+              return -ERANGE;
-+      ext3_xattr_lock();
-+
-+      if (EXT3_I(inode)->i_file_acl) {
-+              /* The inode already has an extended attribute block. */
-+              int block = EXT3_I(inode)->i_file_acl;
-+
-+              bh = sb_bread(sb, block);
-+              error = -EIO;
-+              if (!bh)
-+                      goto cleanup;
-+              ea_bdebug(bh, "b_count=%d, refcount=%d",
-+                      atomic_read(&(bh->b_count)),
-+                      le32_to_cpu(HDR(bh)->h_refcount));
-+              header = HDR(bh);
-+              end = bh->b_data + bh->b_size;
-+              if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+                  header->h_blocks != cpu_to_le32(1)) {
-+bad_block:            ext3_error(sb, "ext3_xattr_set",
-+                              "inode %ld: bad block %d", inode->i_ino, block);
-+                      error = -EIO;
-+                      goto cleanup;
-+              }
-+              /* Find the named attribute. */
-+              here = FIRST_ENTRY(bh);
-+              while (!IS_LAST_ENTRY(here)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!here->e_value_block && here->e_value_size) {
-+                              int offs = le16_to_cpu(here->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      not_found = name_index - here->e_name_index;
-+                      if (!not_found)
-+                              not_found = name_len - here->e_name_len;
-+                      if (!not_found)
-+                              not_found = memcmp(name, here->e_name,name_len);
-+                      if (not_found <= 0)
-+                              break;
-+                      here = next;
-+              }
-+              last = here;
-+              /* We still need to compute min_offs and last. */
-+              while (!IS_LAST_ENTRY(last)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!last->e_value_block && last->e_value_size) {
-+                              int offs = le16_to_cpu(last->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      last = next;
-+              }
-+
-+              /* Check whether we have enough space left. */
-+              free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-+      } else {
-+              /* We will use a new extended attribute block. */
-+              free = sb->s_blocksize -
-+                      sizeof(struct ext3_xattr_header) - sizeof(__u32);
-+              here = last = NULL;  /* avoid gcc uninitialized warning. */
-+      }
-+
-+      if (not_found) {
-+              /* Request to remove a nonexistent attribute? */
-+              error = -ENOATTR;
-+              if (flags & XATTR_REPLACE)
-+                      goto cleanup;
-+              error = 0;
-+              if (value == NULL)
-+                      goto cleanup;
-+              else
-+                      free -= EXT3_XATTR_LEN(name_len);
-+      } else {
-+              /* Request to create an existing attribute? */
-+              error = -EEXIST;
-+              if (flags & XATTR_CREATE)
-+                      goto cleanup;
-+              if (!here->e_value_block && here->e_value_size) {
-+                      unsigned int size = le32_to_cpu(here->e_value_size);
-+
-+                      if (le16_to_cpu(here->e_value_offs) + size > 
-+                          sb->s_blocksize || size > sb->s_blocksize)
-+                              goto bad_block;
-+                      free += EXT3_XATTR_SIZE(size);
-+              }
-+      }
-+      free -= EXT3_XATTR_SIZE(value_len);
-+      error = -ENOSPC;
-+      if (free < 0)
-+              goto cleanup;
-+
-+      /* Here we know that we can set the new attribute. */
-+
-+      if (header) {
-+              if (header->h_refcount == cpu_to_le32(1)) {
-+                      ea_bdebug(bh, "modifying in-place");
-+                      ext3_xattr_cache_remove(bh);
-+                      error = ext3_journal_get_write_access(handle, bh);
-+                      if (error)
-+                              goto cleanup;
-+              } else {
-+                      int offset;
-+
-+                      ea_bdebug(bh, "cloning");
-+                      header = kmalloc(bh->b_size, GFP_KERNEL);
-+                      error = -ENOMEM;
-+                      if (header == NULL)
-+                              goto cleanup;
-+                      memcpy(header, HDR(bh), bh->b_size);
-+                      header->h_refcount = cpu_to_le32(1);
-+                      offset = (char *)header - bh->b_data;
-+                      here = ENTRY((char *)here + offset);
-+                      last = ENTRY((char *)last + offset);
-+              }
-+      } else {
-+              /* Allocate a buffer where we construct the new block. */
-+              header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-+              error = -ENOMEM;
-+              if (header == NULL)
-+                      goto cleanup;
-+              memset(header, 0, sb->s_blocksize);
-+              end = (char *)header + sb->s_blocksize;
-+              header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
-+              header->h_blocks = header->h_refcount = cpu_to_le32(1);
-+              last = here = ENTRY(header+1);
-+      }
-+
-+      if (not_found) {
-+              /* Insert the new name. */
-+              int size = EXT3_XATTR_LEN(name_len);
-+              int rest = (char *)last - (char *)here;
-+              memmove((char *)here + size, here, rest);
-+              memset(here, 0, size);
-+              here->e_name_index = name_index;
-+              here->e_name_len = name_len;
-+              memcpy(here->e_name, name, name_len);
-+      } else {
-+              /* Remove the old value. */
-+              if (!here->e_value_block && here->e_value_size) {
-+                      char *first_val = (char *)header + min_offs;
-+                      int offs = le16_to_cpu(here->e_value_offs);
-+                      char *val = (char *)header + offs;
-+                      size_t size = EXT3_XATTR_SIZE(
-+                              le32_to_cpu(here->e_value_size));
-+                      memmove(first_val + size, first_val, val - first_val);
-+                      memset(first_val, 0, size);
-+                      here->e_value_offs = 0;
-+                      min_offs += size;
-+
-+                      /* Adjust all value offsets. */
-+                      last = ENTRY(header+1);
-+                      while (!IS_LAST_ENTRY(last)) {
-+                              int o = le16_to_cpu(last->e_value_offs);
-+                              if (!last->e_value_block && o < offs)
-+                                      last->e_value_offs =
-+                                              cpu_to_le16(o + size);
-+                              last = EXT3_XATTR_NEXT(last);
-+                      }
-+              }
-+              if (value == NULL) {
-+                      /* Remove this attribute. */
-+                      if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
-+                              /* This block is now empty. */
-+                              error = ext3_xattr_set2(handle, inode, bh,NULL);
-+                              goto cleanup;
-+                      } else {
-+                              /* Remove the old name. */
-+                              int size = EXT3_XATTR_LEN(name_len);
-+                              last = ENTRY((char *)last - size);
-+                              memmove(here, (char*)here + size,
-+                                      (char*)last - (char*)here);
-+                              memset(last, 0, size);
-+                      }
-+              }
-+      }
-+
-+      if (value != NULL) {
-+              /* Insert the new value. */
-+              here->e_value_size = cpu_to_le32(value_len);
-+              if (value_len) {
-+                      size_t size = EXT3_XATTR_SIZE(value_len);
-+                      char *val = (char *)header + min_offs - size;
-+                      here->e_value_offs =
-+                              cpu_to_le16((char *)val - (char *)header);
-+                      memset(val + size - EXT3_XATTR_PAD, 0,
-+                             EXT3_XATTR_PAD); /* Clear the pad bytes. */
-+                      memcpy(val, value, value_len);
-+              }
-+      }
-+      ext3_xattr_rehash(header, here);
-+
-+      error = ext3_xattr_set2(handle, inode, bh, header);
-+
-+cleanup:
-+      brelse(bh);
-+      if (!(bh && header == HDR(bh)))
-+              kfree(header);
-+      ext3_xattr_unlock();
-+
-+      return error;
-+}
-+
-+/*
-+ * Second half of ext3_xattr_set(): Update the file system.
-+ */
-+static int
-+ext3_xattr_set2(handle_t *handle, struct inode *inode,
-+              struct buffer_head *old_bh, struct ext3_xattr_header *header)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *new_bh = NULL;
-+      int error;
-+
-+      if (header) {
-+              new_bh = ext3_xattr_cache_find(inode, header);
-+              if (new_bh) {
-+                      /*
-+                       * We found an identical block in the cache.
-+                       * The old block will be released after updating
-+                       * the inode.
-+                       */
-+                      ea_bdebug(old_bh, "reusing block %ld",
-+                              new_bh->b_blocknr);
-+                      
-+                      error = -EDQUOT;
-+                      if (ext3_xattr_quota_alloc(inode, 1))
-+                              goto cleanup;
-+                      
-+                      error = ext3_journal_get_write_access(handle, new_bh);
-+                      if (error)
-+                              goto cleanup;
-+                      HDR(new_bh)->h_refcount = cpu_to_le32(
-+                              le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
-+                      ea_bdebug(new_bh, "refcount now=%d",
-+                              le32_to_cpu(HDR(new_bh)->h_refcount));
-+              } else if (old_bh && header == HDR(old_bh)) {
-+                      /* Keep this block. */
-+                      new_bh = old_bh;
-+                      (void)ext3_xattr_cache_insert(new_bh);
-+              } else {
-+                      /* We need to allocate a new block */
-+                      int force = EXT3_I(inode)->i_file_acl != 0;
-+                      int block = ext3_xattr_new_block(handle, inode,
-+                                                       &error, force);
-+                      if (error)
-+                              goto cleanup;
-+                      ea_idebug(inode, "creating block %d", block);
-+
-+                      new_bh = sb_getblk(sb, block);
-+                      if (!new_bh) {
-+getblk_failed:                        ext3_xattr_free_block(handle, inode, block);
-+                              error = -EIO;
-+                              goto cleanup;
-+                      }
-+                      lock_buffer(new_bh);
-+                      error = ext3_journal_get_create_access(handle, new_bh);
-+                      if (error) {
-+                              unlock_buffer(new_bh);
-+                              goto getblk_failed;
-+                      }
-+                      memcpy(new_bh->b_data, header, new_bh->b_size);
-+                      mark_buffer_uptodate(new_bh, 1);
-+                      unlock_buffer(new_bh);
-+                      (void)ext3_xattr_cache_insert(new_bh);
-+                      ext3_xattr_update_super_block(handle, sb);
-+              }
-+              error = ext3_journal_dirty_metadata(handle, new_bh);
-+              if (error)
-+                      goto cleanup;
-+      }
-+
-+      /* Update the inode. */
-+      EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-+      inode->i_ctime = CURRENT_TIME;
-+      ext3_mark_inode_dirty(handle, inode);
-+      if (IS_SYNC(inode))
-+              handle->h_sync = 1;
-+
-+      error = 0;
-+      if (old_bh && old_bh != new_bh) {
-+              /*
-+               * If there was an old block, and we are not still using it,
-+               * we now release the old block.
-+              */
-+              unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
-+
-+              error = ext3_journal_get_write_access(handle, old_bh);
-+              if (error)
-+                      goto cleanup;
-+              if (refcount == 1) {
-+                      /* Free the old block. */
-+                      ea_bdebug(old_bh, "freeing");
-+                      ext3_xattr_free_block(handle, inode, old_bh->b_blocknr);
-+
-+                      /* ext3_forget() calls bforget() for us, but we
-+                         let our caller release old_bh, so we need to
-+                         duplicate the handle before. */
-+                      get_bh(old_bh);
-+                      ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
-+              } else {
-+                      /* Decrement the refcount only. */
-+                      refcount--;
-+                      HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
-+                      ext3_xattr_quota_free(inode);
-+                      ext3_journal_dirty_metadata(handle, old_bh);
-+                      ea_bdebug(old_bh, "refcount now=%d", refcount);
-+              }
-+      }
-+
-+cleanup:
-+      if (old_bh != new_bh)
-+              brelse(new_bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_drop_inode()
-+ *
-+ * Free extended attribute resources associated with this inode. This
-+ * is called immediately before an inode is freed.
-+ */
-+void
-+ext3_xattr_drop_inode(handle_t *handle, struct inode *inode)
-+{
-+      struct buffer_head *bh;
-+      unsigned int block = EXT3_I(inode)->i_file_acl;
-+
-+      if (!block)
-+              return;
-+      ext3_xattr_lock();
-+
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh) {
-+              ext3_error(inode->i_sb, "ext3_xattr_drop_inode",
-+                      "inode %ld: block %d read error", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+              ext3_error(inode->i_sb, "ext3_xattr_drop_inode",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ext3_journal_get_write_access(handle, bh);
-+      ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+      if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-+              ext3_xattr_cache_remove(bh);
-+              ext3_xattr_free_block(handle, inode, block);
-+              ext3_forget(handle, 1, inode, bh, block);
-+              bh = NULL;
-+      } else {
-+              HDR(bh)->h_refcount = cpu_to_le32(
-+                      le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+              ext3_journal_dirty_metadata(handle, bh);
-+              if (IS_SYNC(inode))
-+                      handle->h_sync = 1;
-+              ext3_xattr_quota_free(inode);
-+      }
-+      EXT3_I(inode)->i_file_acl = 0;
-+
-+cleanup:
-+      brelse(bh);
-+      ext3_xattr_unlock();
-+}
-+
-+/*
-+ * ext3_xattr_put_super()
-+ *
-+ * This is called when a file system is unmounted.
-+ */
-+void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+      mb_cache_shrink(ext3_xattr_cache, sb->s_dev);
-+#endif
-+}
-+
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+
-+/*
-+ * ext3_xattr_cache_insert()
-+ *
-+ * Create a new entry in the extended attribute cache, and insert
-+ * it unless such an entry is already in the cache.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+static int
-+ext3_xattr_cache_insert(struct buffer_head *bh)
-+{
-+      __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
-+      struct mb_cache_entry *ce;
-+      int error;
-+
-+      ce = mb_cache_entry_alloc(ext3_xattr_cache);
-+      if (!ce)
-+              return -ENOMEM;
-+      error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
-+      if (error) {
-+              mb_cache_entry_free(ce);
-+              if (error == -EBUSY) {
-+                      ea_bdebug(bh, "already in cache (%d cache entries)",
-+                              atomic_read(&ext3_xattr_cache->c_entry_count));
-+                      error = 0;
-+              }
-+      } else {
-+              ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-+                        atomic_read(&ext3_xattr_cache->c_entry_count));
-+              mb_cache_entry_release(ce);
-+      }
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_cmp()
-+ *
-+ * Compare two extended attribute blocks for equality.
-+ *
-+ * Returns 0 if the blocks are equal, 1 if they differ, and
-+ * a negative error number on errors.
-+ */
-+static int
-+ext3_xattr_cmp(struct ext3_xattr_header *header1,
-+             struct ext3_xattr_header *header2)
-+{
-+      struct ext3_xattr_entry *entry1, *entry2;
-+
-+      entry1 = ENTRY(header1+1);
-+      entry2 = ENTRY(header2+1);
-+      while (!IS_LAST_ENTRY(entry1)) {
-+              if (IS_LAST_ENTRY(entry2))
-+                      return 1;
-+              if (entry1->e_hash != entry2->e_hash ||
-+                  entry1->e_name_len != entry2->e_name_len ||
-+                  entry1->e_value_size != entry2->e_value_size ||
-+                  memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
-+                      return 1;
-+              if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
-+                      return -EIO;
-+              if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
-+                         (char *)header2 + le16_to_cpu(entry2->e_value_offs),
-+                         le32_to_cpu(entry1->e_value_size)))
-+                      return 1;
-+
-+              entry1 = EXT3_XATTR_NEXT(entry1);
-+              entry2 = EXT3_XATTR_NEXT(entry2);
-+      }
-+      if (!IS_LAST_ENTRY(entry2))
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * ext3_xattr_cache_find()
-+ *
-+ * Find an identical extended attribute block.
-+ *
-+ * Returns a pointer to the block found, or NULL if such a block was
-+ * not found or an error occurred.
-+ */
-+static struct buffer_head *
-+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
-+{
-+      __u32 hash = le32_to_cpu(header->h_hash);
-+      struct mb_cache_entry *ce;
-+
-+      if (!header->h_hash)
-+              return NULL;  /* never share */
-+      ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
-+      ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash);
-+      while (ce) {
-+              struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
-+
-+              if (!bh) {
-+                      ext3_error(inode->i_sb, "ext3_xattr_cache_find",
-+                              "inode %ld: block %ld read error",
-+                              inode->i_ino, ce->e_block);
-+              } else if (le32_to_cpu(HDR(bh)->h_refcount) >
-+                         EXT3_XATTR_REFCOUNT_MAX) {
-+                      ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
-+                              le32_to_cpu(HDR(bh)->h_refcount),
-+                              EXT3_XATTR_REFCOUNT_MAX);
-+              } else if (!ext3_xattr_cmp(header, HDR(bh))) {
-+                      ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
-+                      mb_cache_entry_release(ce);
-+                      return bh;
-+              }
-+              brelse(bh);
-+              ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * ext3_xattr_cache_remove()
-+ *
-+ * Remove the cache entry of a block from the cache. Called when a
-+ * block becomes invalid.
-+ */
-+static void
-+ext3_xattr_cache_remove(struct buffer_head *bh)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr);
-+      if (ce) {
-+              ea_bdebug(bh, "removing (%d cache entries remaining)",
-+                        atomic_read(&ext3_xattr_cache->c_entry_count)-1);
-+              mb_cache_entry_free(ce);
-+      } else 
-+              ea_bdebug(bh, "no cache entry");
-+}
-+
-+#define NAME_HASH_SHIFT 5
-+#define VALUE_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_hash_entry()
-+ *
-+ * Compute the hash of an extended attribute.
-+ */
-+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
-+                                       struct ext3_xattr_entry *entry)
-+{
-+      __u32 hash = 0;
-+      char *name = entry->e_name;
-+      int n;
-+
-+      for (n=0; n < entry->e_name_len; n++) {
-+              hash = (hash << NAME_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
-+                     *name++;
-+      }
-+
-+      if (entry->e_value_block == 0 && entry->e_value_size != 0) {
-+              __u32 *value = (__u32 *)((char *)header +
-+                      le16_to_cpu(entry->e_value_offs));
-+              for (n = (le32_to_cpu(entry->e_value_size) +
-+                   EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
-+                      hash = (hash << VALUE_HASH_SHIFT) ^
-+                             (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
-+                             le32_to_cpu(*value++);
-+              }
-+      }
-+      entry->e_hash = cpu_to_le32(hash);
-+}
-+
-+#undef NAME_HASH_SHIFT
-+#undef VALUE_HASH_SHIFT
-+
-+#define BLOCK_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_rehash()
-+ *
-+ * Re-compute the extended attribute hash value after an entry has changed.
-+ */
-+static void ext3_xattr_rehash(struct ext3_xattr_header *header,
-+                            struct ext3_xattr_entry *entry)
-+{
-+      struct ext3_xattr_entry *here;
-+      __u32 hash = 0;
-+      
-+      ext3_xattr_hash_entry(header, entry);
-+      here = ENTRY(header+1);
-+      while (!IS_LAST_ENTRY(here)) {
-+              if (!here->e_hash) {
-+                      /* Block is not shared if an entry's hash value == 0 */
-+                      hash = 0;
-+                      break;
-+              }
-+              hash = (hash << BLOCK_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
-+                     le32_to_cpu(here->e_hash);
-+              here = EXT3_XATTR_NEXT(here);
-+      }
-+      header->h_hash = cpu_to_le32(hash);
-+}
-+
-+#undef BLOCK_HASH_SHIFT
-+
-+int __init
-+init_ext3_xattr(void)
-+{
-+      ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
-+              sizeof(struct mb_cache_entry) +
-+              sizeof(struct mb_cache_entry_index), 1, 61);
-+      if (!ext3_xattr_cache)
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+void
-+exit_ext3_xattr(void)
-+{
-+      if (ext3_xattr_cache)
-+              mb_cache_destroy(ext3_xattr_cache);
-+      ext3_xattr_cache = NULL;
-+}
-+
-+#else  /* CONFIG_EXT3_FS_XATTR_SHARING */
-+
-+int __init
-+init_ext3_xattr(void)
-+{
-+      return 0;
-+}
-+
-+void
-+exit_ext3_xattr(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
---- linux-2.4.18-18/include/linux/ext3_fs.h~linux-2.4.18ea-0.8.26      2003-04-20 16:14:31.000000000 +0800
-+++ linux-2.4.18-18-root/include/linux/ext3_fs.h       2003-04-20 16:14:31.000000000 +0800
-@@ -58,8 +58,6 @@
-  */
- #define       EXT3_BAD_INO             1      /* Bad blocks inode */
- #define EXT3_ROOT_INO          2      /* Root inode */
--#define EXT3_ACL_IDX_INO       3      /* ACL inode */
--#define EXT3_ACL_DATA_INO      4      /* ACL inode */
- #define EXT3_BOOT_LOADER_INO   5      /* Boot loader inode */
- #define EXT3_UNDEL_DIR_INO     6      /* Undelete directory inode */
- #define EXT3_RESIZE_INO                7      /* Reserved group descriptors inode */
-@@ -89,7 +87,6 @@
- #else
- # define EXT3_BLOCK_SIZE(s)           (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
- #endif
--#define EXT3_ACLE_PER_BLOCK(s)                (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
- #define       EXT3_ADDR_PER_BLOCK(s)          (EXT3_BLOCK_SIZE(s) / sizeof (__u32))
- #ifdef __KERNEL__
- # define EXT3_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
-@@ -124,28 +121,6 @@
- #endif
- /*
-- * ACL structures
-- */
--struct ext3_acl_header        /* Header of Access Control Lists */
--{
--      __u32   aclh_size;
--      __u32   aclh_file_count;
--      __u32   aclh_acle_count;
--      __u32   aclh_first_acle;
--};
--
--struct ext3_acl_entry /* Access Control List Entry */
--{
--      __u32   acle_size;
--      __u16   acle_perms;     /* Access permissions */
--      __u16   acle_type;      /* Type of entry */
--      __u16   acle_tag;       /* User or group identity */
--      __u16   acle_pad1;
--      __u32   acle_next;      /* Pointer on next entry for the */
--                                      /* same inode or on next free entry */
--};
--
--/*
-  * Structure of a blocks group descriptor
-  */
- struct ext3_group_desc
-@@ -513,7 +488,7 @@ struct ext3_super_block {
- #define EXT3_FEATURE_INCOMPAT_RECOVER         0x0004 /* Needs recovery */
- #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008 /* Journal device */
--#define EXT3_FEATURE_COMPAT_SUPP      0
-+#define EXT3_FEATURE_COMPAT_SUPP      EXT3_FEATURE_COMPAT_EXT_ATTR
- #define EXT3_FEATURE_INCOMPAT_SUPP    (EXT3_FEATURE_INCOMPAT_FILETYPE| \
-                                        EXT3_FEATURE_INCOMPAT_RECOVER)
- #define EXT3_FEATURE_RO_COMPAT_SUPP   (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-@@ -606,6 +581,24 @@ struct ext3_iloc
-       unsigned long block_group;
- };
-+/* Defined for extended attributes */
-+#define CONFIG_EXT3_FS_XATTR y
-+#ifndef ENOATTR
-+#define ENOATTR ENODATA               /* No such attribute */
-+#endif
-+#ifndef ENOTSUP
-+#define ENOTSUP EOPNOTSUPP    /* Operation not supported */
-+#endif
-+#ifndef XATTR_NAME_MAX
-+#define XATTR_NAME_MAX   255  /* # chars in an extended attribute name */
-+#define XATTR_SIZE_MAX 65536  /* size of an extended attribute value (64k) */
-+#define XATTR_LIST_MAX 65536  /* size of extended attribute namelist (64k) */
-+#endif
-+#ifndef XATTR_CREATE
-+#define XATTR_CREATE  1       /* set value, fail if attr already exists */
-+#define XATTR_REPLACE 2       /* set value, fail if attr does not exist */
-+#endif
-+
- /*
-  * Function prototypes
-  */
-@@ -647,6 +640,7 @@ extern void ext3_check_inodes_bitmap (st
- extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
- /* inode.c */
-+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
---- linux-2.4.18-18/include/linux/ext3_jbd.h~linux-2.4.18ea-0.8.26     2003-04-20 16:14:31.000000000 +0800
-+++ linux-2.4.18-18-root/include/linux/ext3_jbd.h      2003-04-20 16:14:31.000000000 +0800
-@@ -30,13 +30,19 @@
- #define EXT3_SINGLEDATA_TRANS_BLOCKS  8
-+/* Extended attributes may touch two data buffers, two bitmap buffers,
-+ * and two group and summaries. */
-+
-+#define EXT3_XATTR_TRANS_BLOCKS               8
-+
- /* Define the minimum size for a transaction which modifies data.  This
-  * needs to take into account the fact that we may end up modifying two
-  * quota files too (one for the group, one for the user quota).  The
-  * superblock only gets updated once, of course, so don't bother
-  * counting that again for the quota updates. */
--#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
-+#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
-+                                       EXT3_XATTR_TRANS_BLOCKS - 2)
- extern int ext3_writepage_trans_blocks(struct inode *inode);
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.18-18-root/include/linux/ext3_xattr.h    2003-04-20 16:14:31.000000000 +0800
-@@ -0,0 +1,155 @@
-+/*
-+  File: linux/ext3_xattr.h
-+
-+  On-disk format of extended attributes for the ext3 filesystem.
-+
-+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/xattr.h>
-+
-+/* Magic value in attribute blocks */
-+#define EXT3_XATTR_MAGIC              0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT3_XATTR_REFCOUNT_MAX               1024
-+
-+/* Name indexes */
-+#define EXT3_XATTR_INDEX_MAX                  10
-+#define EXT3_XATTR_INDEX_USER                 1
-+
-+struct ext3_xattr_header {
-+      __u32   h_magic;        /* magic number for identification */
-+      __u32   h_refcount;     /* reference count */
-+      __u32   h_blocks;       /* number of disk blocks used */
-+      __u32   h_hash;         /* hash value of all attributes */
-+      __u32   h_reserved[4];  /* zero right now */
-+};
-+
-+struct ext3_xattr_entry {
-+      __u8    e_name_len;     /* length of name */
-+      __u8    e_name_index;   /* attribute name index */
-+      __u16   e_value_offs;   /* offset in disk block of value */
-+      __u32   e_value_block;  /* disk block attribute is stored on (n/i) */
-+      __u32   e_value_size;   /* size of attribute value */
-+      __u32   e_hash;         /* hash value of name and value */
-+      char    e_name[0];      /* attribute name */
-+};
-+
-+#define EXT3_XATTR_PAD_BITS           2
-+#define EXT3_XATTR_PAD                (1<<EXT3_XATTR_PAD_BITS)
-+#define EXT3_XATTR_ROUND              (EXT3_XATTR_PAD-1)
-+#define EXT3_XATTR_LEN(name_len) \
-+      (((name_len) + EXT3_XATTR_ROUND + \
-+      sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
-+#define EXT3_XATTR_NEXT(entry) \
-+      ( (struct ext3_xattr_entry *)( \
-+        (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
-+#define EXT3_XATTR_SIZE(size) \
-+      (((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
-+
-+#ifdef __KERNEL__
-+
-+# ifdef CONFIG_EXT3_FS_XATTR
-+
-+struct ext3_xattr_handler {
-+      char *prefix;
-+      size_t (*list)(char *list, struct inode *inode, const char *name,
-+                     int name_len);
-+      int (*get)(struct inode *inode, const char *name, void *buffer,
-+                 size_t size);
-+      int (*set)(struct inode *inode, const char *name, void *buffer,
-+                 size_t size, int flags);
-+};
-+
-+extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
-+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
-+
-+extern int ext3_setxattr(struct dentry *, const char *, void *, size_t, int);
-+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
-+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
-+extern int ext3_removexattr(struct dentry *, const char *);
-+
-+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
-+extern int ext3_xattr_list(struct inode *, char *, size_t);
-+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, void *, size_t, int);
-+
-+extern void ext3_xattr_drop_inode(handle_t *, struct inode *);
-+extern void ext3_xattr_put_super(struct super_block *);
-+
-+extern int init_ext3_xattr(void) __init;
-+extern void exit_ext3_xattr(void);
-+
-+# else  /* CONFIG_EXT3_FS_XATTR */
-+#  define ext3_setxattr               NULL
-+#  define ext3_getxattr               NULL
-+#  define ext3_listxattr      NULL
-+#  define ext3_removexattr    NULL
-+
-+static inline int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t size, int flags)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext3_xattr_list(struct inode *inode, void *buffer, size_t size, int flags)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, void *value, size_t size, int flags)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline void
-+ext3_xattr_drop_inode(handle_t *handle, struct inode *inode)
-+{
-+}
-+
-+static inline void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+}
-+
-+static inline int
-+init_ext3_xattr(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext3_xattr(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT3_FS_XATTR */
-+
-+# ifdef CONFIG_EXT3_FS_XATTR_USER
-+
-+extern int init_ext3_xattr_user(void) __init;
-+extern void exit_ext3_xattr_user(void);
-+
-+# else  /* CONFIG_EXT3_FS_XATTR_USER */
-+
-+static inline int
-+init_ext3_xattr_user(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext3_xattr_user(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT3_FS_XATTR_USER */
-+
-+#endif  /* __KERNEL__ */
-+
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.18-18-root/include/linux/xattr.h 2003-04-20 16:14:31.000000000 +0800
-@@ -0,0 +1,15 @@
-+/*
-+  File: linux/xattr.h
-+
-+  Extended attributes handling.
-+
-+  Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
-+  Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
-+*/
-+#ifndef _LINUX_XATTR_H
-+#define _LINUX_XATTR_H
-+
-+#define XATTR_CREATE  1       /* set value, fail if attr already exists */
-+#define XATTR_REPLACE 2       /* set value, fail if attr does not exist */
-+
-+#endif        /* _LINUX_XATTR_H */
---- linux-2.4.18-18/fs/ext3/Makefile~linux-2.4.18ea-0.8.26     2003-04-20 16:14:54.000000000 +0800
-+++ linux-2.4.18-18-root/fs/ext3/Makefile      2003-04-20 16:15:15.000000000 +0800
-@@ -9,10 +9,10 @@
- O_TARGET := ext3.o
--export-objs :=        super.o inode.o
-+export-objs :=        super.o inode.o xattr.o
- obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
--              ioctl.o namei.o super.o symlink.o
-+              ioctl.o namei.o super.o symlink.o xattr.o
- obj-m    := $(O_TARGET)
- include $(TOPDIR)/Rules.make
-
-_
diff --git a/lustre/kernel_patches/patches/linux-2.4.19-xattr-0.8.54-hp.patch b/lustre/kernel_patches/patches/linux-2.4.19-xattr-0.8.54-hp.patch
deleted file mode 100644 (file)
index f33e802..0000000
+++ /dev/null
@@ -1,5321 +0,0 @@
- Documentation/Configure.help  |   66 ++
- arch/alpha/defconfig          |    7 
- arch/alpha/kernel/entry.S     |   12 
- arch/arm/defconfig            |    7 
- arch/arm/kernel/calls.S       |   24 
- arch/i386/defconfig           |    7 
- arch/ia64/defconfig           |    7 
- arch/m68k/defconfig           |    7 
- arch/mips/defconfig           |    7 
- arch/mips64/defconfig         |    7 
- arch/ppc/defconfig            |   14 
- arch/ppc64/kernel/misc.S      |    2 
- arch/s390/defconfig           |    7 
- arch/s390/kernel/entry.S      |   24 
- arch/s390x/defconfig          |    7 
- arch/s390x/kernel/entry.S     |   24 
- arch/s390x/kernel/wrapper32.S |   92 +++
- arch/sparc/defconfig          |    7 
- arch/sparc/kernel/systbls.S   |   10 
- arch/sparc64/defconfig        |    7 
- arch/sparc64/kernel/systbls.S |   20 
- fs/Config.in                  |   14 
- fs/Makefile                   |    3 
- fs/ext2/Makefile              |    4 
- fs/ext2/file.c                |    5 
- fs/ext2/ialloc.c              |    2 
- fs/ext2/inode.c               |   34 -
- fs/ext2/namei.c               |   14 
- fs/ext2/super.c               |   29 
- fs/ext2/symlink.c             |   14 
- fs/ext2/xattr.c               | 1212 +++++++++++++++++++++++++++++++++++++++++
- fs/ext2/xattr_user.c          |  103 +++
- fs/ext3/ialloc.c              |    2 
- fs/ext3/inode.c               |   35 -
- fs/ext3/namei.c               |   21 
- fs/ext3/symlink.c             |   14 
- fs/ext3/xattr.c               | 1232 ++++++++++++++++++++++++++++++++++++++++++
- fs/ext3/xattr_user.c          |  111 +++
- fs/mbcache.c                  |  648 ++++++++++++++++++++++
- include/asm-arm/unistd.h      |    2 
- include/asm-ppc64/unistd.h    |    2 
- include/asm-s390/unistd.h     |   15 
- include/asm-s390x/unistd.h    |   15 
- include/asm-sparc/unistd.h    |   24 
- include/asm-sparc64/unistd.h  |   24 
- include/linux/cache_def.h     |   15 
- include/linux/errno.h         |    4 
- include/linux/ext2_fs.h       |   31 -
- include/linux/ext2_xattr.h    |  157 +++++
- include/linux/ext3_fs.h       |   31 -
- include/linux/ext3_xattr.h    |  157 +++++
- include/linux/fs.h            |    2 
- include/linux/mbcache.h       |   69 ++
- kernel/ksyms.c                |    4 
- mm/vmscan.c                   |   35 +
- 55 files changed, 4280 insertions(+), 169 deletions(-)
-
---- linux-2.4.19-hppl/Documentation/Configure.help~linux-2.4.20-xattr-0.8.54-hp_chaos  2003-04-11 16:36:28.000000000 +0800
-+++ linux-2.4.19-hppl-root/Documentation/Configure.help        2003-04-11 16:52:15.000000000 +0800
-@@ -14601,6 +14601,39 @@ CONFIG_EXT2_FS
-   be compiled as a module, and so this could be dangerous.  Most
-   everyone wants to say Y here.
-+Ext2 extended attributes
-+CONFIG_EXT2_FS_XATTR
-+  Extended attributes are name:value pairs associated with inodes by
-+  the kernel or by users (see the attr(5) manual page, or visit
-+  <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext2 extended attribute block sharing
-+CONFIG_EXT2_FS_XATTR_SHARING
-+  This options enables code for sharing identical extended attribute
-+  blocks among multiple inodes.
-+
-+  Usually, say Y.
-+
-+Ext2 extended user attributes
-+CONFIG_EXT2_FS_XATTR_USER
-+  This option enables extended user attributes on ext2. Processes can
-+  associate extended user attributes with inodes to store additional
-+  information such as the character encoding of files, etc. (see the
-+  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext2 trusted extended attributes
-+CONFIG_EXT2_FS_XATTR_TRUSTED
-+  This option enables extended attributes on ext2 that are accessible
-+  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
-+  is only the super user. Trusted extended attributes are meant for
-+  implementing system/security services.
-+
-+  If unsure, say N.
-+
- Ext3 journalling file system support (EXPERIMENTAL)
- CONFIG_EXT3_FS
-   This is the journalling version of the Second extended file system
-@@ -14633,6 +14666,39 @@ CONFIG_EXT3_FS
-   of your root partition (the one containing the directory /) cannot
-   be compiled as a module, and so this may be dangerous.
-+Ext3 extended attributes
-+CONFIG_EXT3_FS_XATTR
-+  Extended attributes are name:value pairs associated with inodes by
-+  the kernel or by users (see the attr(5) manual page, or visit
-+  <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext3 extended attribute block sharing
-+CONFIG_EXT3_FS_XATTR_SHARING
-+  This options enables code for sharing identical extended attribute
-+  blocks among multiple inodes.
-+
-+  Usually, say Y.
-+
-+Ext3 extended user attributes
-+CONFIG_EXT3_FS_XATTR_USER
-+  This option enables extended user attributes on ext3. Processes can
-+  associate extended user attributes with inodes to store additional
-+  information such as the character encoding of files, etc. (see the
-+  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext3 trusted extended attributes
-+CONFIG_EXT3_FS_XATTR_TRUSTED
-+  This option enables extended attributes on ext3 that are accessible
-+  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
-+  is only the super user. Trusted extended attributes are meant for
-+  implementing system/security services.
-+
-+  If unsure, say N.
-+
- Journal Block Device support (JBD for ext3) (EXPERIMENTAL)
- CONFIG_JBD
-   This is a generic journalling layer for block devices.  It is
---- linux-2.4.19-hppl/arch/alpha/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos  2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/alpha/defconfig        2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_ALPHA=y
- # CONFIG_UID16 is not set
- # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
---- linux-2.4.19-hppl/arch/alpha/kernel/entry.S~linux-2.4.20-xattr-0.8.54-hp_chaos     2002-08-03 08:39:42.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/alpha/kernel/entry.S   2003-04-11 16:52:16.000000000 +0800
-@@ -1154,6 +1154,18 @@ sys_call_table:
-       .quad sys_readahead
-       .quad sys_ni_syscall                    /* 380, sys_security */
-       .quad sys_tkill
-+      .quad sys_setxattr
-+      .quad sys_lsetxattr
-+      .quad sys_fsetxattr
-+      .quad sys_getxattr                      /* 385 */
-+      .quad sys_lgetxattr
-+      .quad sys_fgetxattr
-+      .quad sys_listxattr
-+      .quad sys_llistxattr
-+      .quad sys_flistxattr                    /* 390 */
-+      .quad sys_removexattr
-+      .quad sys_lremovexattr
-+      .quad sys_fremovexattr
- /* Remember to update everything, kids.  */
- .ifne (. - sys_call_table) - (NR_SYSCALLS * 8)
---- linux-2.4.19-hppl/arch/arm/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos    2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/arm/defconfig  2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_ARM=y
- # CONFIG_EISA is not set
- # CONFIG_SBUS is not set
---- linux-2.4.19-hppl/arch/arm/kernel/calls.S~linux-2.4.20-xattr-0.8.54-hp_chaos       2002-08-03 08:39:42.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/arm/kernel/calls.S     2003-04-11 16:52:16.000000000 +0800
-@@ -240,18 +240,18 @@ __syscall_start:
-               .long   SYMBOL_NAME(sys_ni_syscall) /* Security */
-               .long   SYMBOL_NAME(sys_gettid)
- /* 225 */     .long   SYMBOL_NAME(sys_readahead)
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_setxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lsetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fsetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_getxattr */
--/* 230 */     .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lgetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fgetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_listxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_llistxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_flistxattr */
--/* 235 */     .long   SYMBOL_NAME(sys_ni_syscall) /* sys_removexattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lremovexattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fremovexattr */
-+              .long   SYMBOL_NAME(sys_setxattr)
-+              .long   SYMBOL_NAME(sys_lsetxattr)
-+              .long   SYMBOL_NAME(sys_fsetxattr)
-+              .long   SYMBOL_NAME(sys_getxattr)
-+/* 230 */     .long   SYMBOL_NAME(sys_lgetxattr)
-+              .long   SYMBOL_NAME(sys_fgetxattr)
-+              .long   SYMBOL_NAME(sys_listxattr)
-+              .long   SYMBOL_NAME(sys_llistxattr)
-+              .long   SYMBOL_NAME(sys_flistxattr)
-+/* 235 */     .long   SYMBOL_NAME(sys_removexattr)
-+              .long   SYMBOL_NAME(sys_lremovexattr)
-+              .long   SYMBOL_NAME(sys_fremovexattr)
-               .long   SYMBOL_NAME(sys_tkill)
-               /*
-                * Please check 2.5 _before_ adding calls here,
---- linux-2.4.19-hppl/arch/i386/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos   2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/i386/defconfig 2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_X86=y
- CONFIG_ISA=y
- # CONFIG_SBUS is not set
---- linux-2.4.19-hppl/arch/ia64/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos   2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/ia64/defconfig 2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- #
- # Code maturity level options
---- linux-2.4.19-hppl/arch/m68k/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos   2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/m68k/defconfig 2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_UID16=y
- #
---- linux-2.4.19-hppl/arch/mips/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos   2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/mips/defconfig 2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_MIPS=y
- CONFIG_MIPS32=y
---- linux-2.4.19-hppl/arch/mips64/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos 2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/mips64/defconfig       2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_MIPS=y
- CONFIG_MIPS64=y
---- linux-2.4.19-hppl/arch/ppc/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos    2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/ppc/defconfig  2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,20 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_UID16 is not set
- # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
- CONFIG_RWSEM_XCHGADD_ALGORITHM=y
---- linux-2.4.19-hppl/arch/ppc64/kernel/misc.S~linux-2.4.20-xattr-0.8.54-hp_chaos      2002-08-03 08:39:43.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/ppc64/kernel/misc.S    2003-04-11 16:52:16.000000000 +0800
-@@ -731,6 +731,7 @@ _GLOBAL(sys_call_table32)
-       .llong .sys_gettid              /* 207 */
- #if 0 /* Reserved syscalls */
-       .llong .sys_tkill               /* 208 */
-+#endif
-       .llong .sys_setxattr
-       .llong .sys_lsetxattr   /* 210 */
-       .llong .sys_fsetxattr
-@@ -743,6 +744,7 @@ _GLOBAL(sys_call_table32)
-       .llong .sys_removexattr
-       .llong .sys_lremovexattr
-       .llong .sys_fremovexattr        /* 220 */
-+#if 0 /* Reserved syscalls */
-       .llong .sys_futex
- #endif
-       .rept NR_syscalls-221
---- linux-2.4.19-hppl/arch/s390/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos   2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/s390/defconfig 2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_ISA is not set
- # CONFIG_EISA is not set
- # CONFIG_MCA is not set
---- linux-2.4.19-hppl/arch/s390/kernel/entry.S~linux-2.4.20-xattr-0.8.54-hp_chaos      2002-08-03 08:39:43.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/s390/kernel/entry.S    2003-04-11 16:52:16.000000000 +0800
-@@ -558,18 +558,18 @@ sys_call_table:
-         .long  sys_fcntl64 
-       .long  sys_ni_syscall
-       .long  sys_ni_syscall
--      .long  sys_ni_syscall            /* 224 - reserved for setxattr  */
--      .long  sys_ni_syscall            /* 225 - reserved for lsetxattr */
--      .long  sys_ni_syscall            /* 226 - reserved for fsetxattr */
--      .long  sys_ni_syscall            /* 227 - reserved for getxattr  */
--      .long  sys_ni_syscall            /* 228 - reserved for lgetxattr */
--      .long  sys_ni_syscall            /* 229 - reserved for fgetxattr */
--      .long  sys_ni_syscall            /* 230 - reserved for listxattr */
--      .long  sys_ni_syscall            /* 231 - reserved for llistxattr */
--      .long  sys_ni_syscall            /* 232 - reserved for flistxattr */
--      .long  sys_ni_syscall            /* 233 - reserved for removexattr */
--      .long  sys_ni_syscall            /* 234 - reserved for lremovexattr */
--      .long  sys_ni_syscall            /* 235 - reserved for fremovexattr */
-+      .long  sys_setxattr
-+      .long  sys_lsetxattr            /* 225 */
-+      .long  sys_fsetxattr
-+      .long  sys_getxattr
-+      .long  sys_lgetxattr
-+      .long  sys_fgetxattr
-+      .long  sys_listxattr            /* 230 */
-+      .long  sys_llistxattr
-+      .long  sys_flistxattr
-+      .long  sys_removexattr
-+      .long  sys_lremovexattr
-+      .long  sys_fremovexattr         /* 235 */
-       .long  sys_gettid
-       .long  sys_tkill
-       .rept  255-237
---- linux-2.4.19-hppl/arch/s390x/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos  2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/s390x/defconfig        2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_ISA is not set
- # CONFIG_EISA is not set
- # CONFIG_MCA is not set
---- linux-2.4.19-hppl/arch/s390x/kernel/entry.S~linux-2.4.20-xattr-0.8.54-hp_chaos     2002-08-03 08:39:43.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/s390x/kernel/entry.S   2003-04-11 16:52:16.000000000 +0800
-@@ -591,18 +591,18 @@ sys_call_table:
-       .long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
-       .long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
-       .long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr  */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 226 - reserved for fsetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 227 - reserved for getxattr  */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 228 - reserved for lgetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 229 - reserved for fgetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 230 - reserved for listxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 231 - reserved for llistxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 232 - reserved for flistxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 233 - reserved for removexattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 234 - reserved for lremovexattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 235 - reserved for fremovexattr */
-+      .long  SYSCALL(sys_setxattr,sys32_setxattr_wrapper)
-+      .long  SYSCALL(sys_lsetxattr,sys32_lsetxattr_wrapper)   /* 225 */
-+      .long  SYSCALL(sys_fsetxattr,sys32_fsetxattr_wrapper)
-+      .long  SYSCALL(sys_getxattr,sys32_getxattr_wrapper)
-+      .long  SYSCALL(sys_lgetxattr,sys32_lgetxattr_wrapper)
-+      .long  SYSCALL(sys_fgetxattr,sys32_fgetxattr_wrapper)
-+      .long  SYSCALL(sys_listxattr,sys32_listxattr_wrapper)   /* 230 */
-+      .long  SYSCALL(sys_llistxattr,sys32_llistxattr_wrapper)
-+      .long  SYSCALL(sys_flistxattr,sys32_flistxattr_wrapper)
-+      .long  SYSCALL(sys_removexattr,sys32_removexattr_wrapper)
-+      .long  SYSCALL(sys_lremovexattr,sys32_lremovexattr_wrapper)
-+      .long  SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper)/* 235 */
-       .long  SYSCALL(sys_gettid,sys_gettid)
-       .long  SYSCALL(sys_tkill,sys_tkill)
-       .rept  255-237
---- linux-2.4.19-hppl/arch/s390x/kernel/wrapper32.S~linux-2.4.20-xattr-0.8.54-hp_chaos 2002-02-26 03:37:56.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/s390x/kernel/wrapper32.S       2003-04-11 16:52:16.000000000 +0800
-@@ -1091,3 +1091,95 @@ sys32_fstat64_wrapper:
-       llgtr   %r3,%r3                 # struct stat64 *
-       llgfr   %r4,%r4                 # long
-       jg      sys32_fstat64           # branch to system call
-+
-+      .globl  sys32_setxattr_wrapper
-+sys32_setxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_setxattr
-+
-+      .globl  sys32_lsetxattr_wrapper
-+sys32_lsetxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_lsetxattr
-+
-+      .globl  sys32_fsetxattr_wrapper
-+sys32_fsetxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_fsetxattr
-+
-+      .globl  sys32_getxattr_wrapper
-+sys32_getxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_getxattr
-+
-+      .globl  sys32_lgetxattr_wrapper
-+sys32_lgetxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_lgetxattr
-+
-+      .globl  sys32_fgetxattr_wrapper
-+sys32_fgetxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_fgetxattr
-+
-+      .globl  sys32_listxattr_wrapper
-+sys32_listxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_listxattr
-+
-+      .globl  sys32_llistxattr_wrapper
-+sys32_llistxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_llistxattr
-+
-+      .globl  sys32_flistxattr_wrapper
-+sys32_flistxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_flistxattr
-+
-+      .globl  sys32_removexattr_wrapper
-+sys32_removexattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_removexattr
-+
-+      .globl  sys32_lremovexattr_wrapper
-+sys32_lremovexattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_lremovexattr
-+
-+      .globl  sys32_fremovexattr_wrapper
-+sys32_fremovexattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_fremovexattr
-+
-+
---- linux-2.4.19-hppl/arch/sparc/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos  2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/sparc/defconfig        2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_UID16=y
- CONFIG_HIGHMEM=y
---- linux-2.4.19-hppl/arch/sparc/kernel/systbls.S~linux-2.4.20-xattr-0.8.54-hp_chaos   2002-08-03 08:39:43.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/sparc/kernel/systbls.S 2003-04-11 16:52:16.000000000 +0800
-@@ -51,11 +51,11 @@ sys_call_table:
- /*150*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
- /*155*/       .long sys_fcntl64, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
- /*160*/       .long sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
--/*165*/       .long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
--/*170*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
--/*175*/       .long sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_sigpending, sys_query_module
--/*185*/       .long sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sys_newuname
-+/*165*/       .long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
-+/*170*/       .long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
-+/*175*/       .long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module
-+/*185*/       .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sys_newuname
- /*190*/       .long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
- /*195*/       .long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
- /*200*/       .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
---- linux-2.4.19-hppl/arch/sparc64/defconfig~linux-2.4.20-xattr-0.8.54-hp_chaos        2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/sparc64/defconfig      2003-04-11 16:52:16.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- #
- # Code maturity level options
---- linux-2.4.19-hppl/arch/sparc64/kernel/systbls.S~linux-2.4.20-xattr-0.8.54-hp_chaos 2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/arch/sparc64/kernel/systbls.S       2003-04-11 16:52:16.000000000 +0800
-@@ -52,11 +52,11 @@ sys_call_table32:
- /*150*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
-       .word sys32_fcntl64, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
- /*160*/       .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
--      .word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_nis_syscall
--/*170*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents
--      .word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_sigpending, sys32_query_module
--      .word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
-+      .word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_setxattr
-+/*170*/       .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
-+      .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module
-+      .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
- /*190*/       .word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
-       .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
- /*200*/       .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
-@@ -111,11 +111,11 @@ sys_call_table:
- /*150*/       .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
-       .word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
- /*160*/       .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_utrap_install
--      .word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
--/*170*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
--      .word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_query_module
--      .word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
-+      .word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
-+/*170*/       .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
-+      .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module
-+      .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
- /*190*/       .word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
-       .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
- /*200*/       .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
---- linux-2.4.19-hppl/fs/Config.in~linux-2.4.20-xattr-0.8.54-hp_chaos  2003-04-11 16:36:25.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/Config.in        2003-04-11 16:52:16.000000000 +0800
-@@ -32,6 +32,11 @@ dep_tristate 'Apple Macintosh file syste
- dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
- tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS
-+dep_mbool '  Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS
-+dep_bool '    Ext3 extended attribute block sharing' \
-+    CONFIG_EXT3_FS_XATTR_SHARING $CONFIG_EXT3_FS_XATTR
-+dep_bool '    Ext3 extended user attributes' \
-+    CONFIG_EXT3_FS_XATTR_USER $CONFIG_EXT3_FS_XATTR
- # CONFIG_JBD could be its own option (even modular), but until there are
- # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
- # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
-@@ -91,6 +96,11 @@ dep_mbool '  QNX4FS write support (DANGE
- tristate 'ROM file system support' CONFIG_ROMFS_FS
- tristate 'Second extended fs support' CONFIG_EXT2_FS
-+dep_mbool '  Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS
-+dep_bool '    Ext2 extended attribute block sharing' \
-+    CONFIG_EXT2_FS_XATTR_SHARING $CONFIG_EXT2_FS_XATTR
-+dep_bool '    Ext2 extended user attributes' \
-+    CONFIG_EXT2_FS_XATTR_USER $CONFIG_EXT2_FS_XATTR
- tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS
-@@ -177,6 +187,10 @@ else
-   fi
- fi
-+# Meta block cache for Extended Attributes (ext2/ext3)
-+#tristate 'Meta block cache' CONFIG_FS_MBCACHE
-+define_tristate CONFIG_FS_MBCACHE y
-+
- mainmenu_option next_comment
- comment 'Partition Types'
- source fs/partitions/Config.in
---- linux-2.4.19-hppl/fs/Makefile~linux-2.4.20-xattr-0.8.54-hp_chaos   2003-04-11 16:50:56.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/Makefile 2003-04-11 16:52:16.000000000 +0800
-@@ -78,6 +78,9 @@ obj-y                                += binfmt_script.o
- obj-$(CONFIG_BINFMT_ELF)      += binfmt_elf.o
-+export-objs += mbcache.o
-+obj-$(CONFIG_FS_MBCACHE)      += mbcache.o
-+
- # persistent filesystems
- obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
---- linux-2.4.19-hppl/fs/ext2/Makefile~linux-2.4.20-xattr-0.8.54-hp_chaos      2001-10-11 23:05:18.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext2/Makefile    2003-04-11 16:52:16.000000000 +0800
-@@ -13,4 +13,8 @@ obj-y    := balloc.o bitmap.o dir.o file
-               ioctl.o namei.o super.o symlink.o
- obj-m    := $(O_TARGET)
-+export-objs += xattr.o
-+obj-$(CONFIG_EXT2_FS_XATTR) += xattr.o
-+obj-$(CONFIG_EXT2_FS_XATTR_USER) += xattr_user.o
-+
- include $(TOPDIR)/Rules.make
---- linux-2.4.19-hppl/fs/ext2/file.c~linux-2.4.20-xattr-0.8.54-hp_chaos        2001-10-11 23:05:18.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext2/file.c      2003-04-11 16:52:16.000000000 +0800
-@@ -20,6 +20,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/sched.h>
- /*
-@@ -51,4 +52,8 @@ struct file_operations ext2_file_operati
- struct inode_operations ext2_file_inode_operations = {
-       truncate:       ext2_truncate,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- linux-2.4.19-hppl/fs/ext2/ialloc.c~linux-2.4.20-xattr-0.8.54-hp_chaos      2002-02-26 03:38:08.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext2/ialloc.c    2003-04-11 16:52:17.000000000 +0800
-@@ -15,6 +15,7 @@
- #include <linux/config.h>
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/locks.h>
- #include <linux/quotaops.h>
-@@ -167,6 +168,7 @@ void ext2_free_inode (struct inode * ino
-        */
-       if (!is_bad_inode(inode)) {
-               /* Quota is already initialized in iput() */
-+              ext2_xattr_delete_inode(inode);
-               DQUOT_FREE_INODE(inode);
-               DQUOT_DROP(inode);
-       }
---- linux-2.4.19-hppl/fs/ext2/inode.c~linux-2.4.20-xattr-0.8.54-hp_chaos       2002-08-03 08:39:45.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext2/inode.c     2003-04-11 16:52:17.000000000 +0800
-@@ -39,6 +39,18 @@ MODULE_LICENSE("GPL");
- static int ext2_update_inode(struct inode * inode, int do_sync);
- /*
-+ * Test whether an inode is a fast symlink.
-+ */
-+static inline int ext2_inode_is_fast_symlink(struct inode *inode)
-+{
-+      int ea_blocks = inode->u.ext2_i.i_file_acl ?
-+              (inode->i_sb->s_blocksize >> 9) : 0;
-+
-+      return (S_ISLNK(inode->i_mode) &&
-+              inode->i_blocks - ea_blocks == 0);
-+}
-+
-+/*
-  * Called at each iput()
-  */
- void ext2_put_inode (struct inode * inode)
-@@ -53,9 +65,7 @@ void ext2_delete_inode (struct inode * i
- {
-       lock_kernel();
--      if (is_bad_inode(inode) ||
--          inode->i_ino == EXT2_ACL_IDX_INO ||
--          inode->i_ino == EXT2_ACL_DATA_INO)
-+      if (is_bad_inode(inode))
-               goto no_delete;
-       inode->u.ext2_i.i_dtime = CURRENT_TIME;
-       mark_inode_dirty(inode);
-@@ -792,6 +802,8 @@ void ext2_truncate (struct inode * inode
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-+      if (ext2_inode_is_fast_symlink(inode))
-+              return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-@@ -879,8 +891,7 @@ void ext2_read_inode (struct inode * ino
-       unsigned long offset;
-       struct ext2_group_desc * gdp;
--      if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
--           inode->i_ino != EXT2_ACL_DATA_INO &&
-+      if ((inode->i_ino != EXT2_ROOT_INO &&
-            inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||
-           inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {
-               ext2_error (inode->i_sb, "ext2_read_inode",
-@@ -965,10 +976,7 @@ void ext2_read_inode (struct inode * ino
-       for (block = 0; block < EXT2_N_BLOCKS; block++)
-               inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
--      if (inode->i_ino == EXT2_ACL_IDX_INO ||
--          inode->i_ino == EXT2_ACL_DATA_INO)
--              /* Nothing to do */ ;
--      else if (S_ISREG(inode->i_mode)) {
-+      if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &ext2_file_inode_operations;
-               inode->i_fop = &ext2_file_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-@@ -977,15 +985,17 @@ void ext2_read_inode (struct inode * ino
-               inode->i_fop = &ext2_dir_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-       } else if (S_ISLNK(inode->i_mode)) {
--              if (!inode->i_blocks)
-+              if (ext2_inode_is_fast_symlink(inode))
-                       inode->i_op = &ext2_fast_symlink_inode_operations;
-               else {
--                      inode->i_op = &page_symlink_inode_operations;
-+                      inode->i_op = &ext2_symlink_inode_operations;
-                       inode->i_mapping->a_ops = &ext2_aops;
-               }
--      } else 
-+      } else {
-+              inode->i_op = &ext2_special_inode_operations;
-               init_special_inode(inode, inode->i_mode,
-                                  le32_to_cpu(raw_inode->i_block[0]));
-+      }
-       brelse (bh);
-       inode->i_attr_flags = 0;
-       if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) {
---- linux-2.4.19-hppl/fs/ext2/namei.c~linux-2.4.20-xattr-0.8.54-hp_chaos       2001-10-04 13:57:36.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext2/namei.c     2003-04-11 16:52:17.000000000 +0800
-@@ -31,6 +31,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/pagemap.h>
- /*
-@@ -136,7 +137,7 @@ static int ext2_symlink (struct inode * 
-       if (l > sizeof (inode->u.ext2_i.i_data)) {
-               /* slow symlink */
--              inode->i_op = &page_symlink_inode_operations;
-+              inode->i_op = &ext2_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-               err = block_symlink(inode, symname, l);
-               if (err)
-@@ -345,4 +346,15 @@ struct inode_operations ext2_dir_inode_o
-       rmdir:          ext2_rmdir,
-       mknod:          ext2_mknod,
-       rename:         ext2_rename,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
-+};
-+
-+struct inode_operations ext2_special_inode_operations = {
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- linux-2.4.19-hppl/fs/ext2/super.c~linux-2.4.20-xattr-0.8.54-hp_chaos       2002-02-26 03:38:08.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext2/super.c     2003-04-11 16:52:17.000000000 +0800
-@@ -21,6 +21,7 @@
- #include <linux/string.h>
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/locks.h>
-@@ -125,6 +126,7 @@ void ext2_put_super (struct super_block 
-       int db_count;
-       int i;
-+      ext2_xattr_put_super(sb);
-       if (!(sb->s_flags & MS_RDONLY)) {
-               struct ext2_super_block *es = EXT2_SB(sb)->s_es;
-@@ -175,6 +177,13 @@ static int parse_options (char * options
-            this_char = strtok (NULL, ",")) {
-               if ((value = strchr (this_char, '=')) != NULL)
-                       *value++ = 0;
-+#ifdef CONFIG_EXT2_FS_XATTR_USER
-+              if (!strcmp (this_char, "user_xattr"))
-+                      set_opt (*mount_options, XATTR_USER);
-+              else if (!strcmp (this_char, "nouser_xattr"))
-+                      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")) {
-@@ -424,6 +433,9 @@ struct super_block * ext2_read_super (st
-           blocksize = BLOCK_SIZE;
-       sb->u.ext2_sb.s_mount_opt = 0;
-+#ifdef CONFIG_EXT2_FS_XATTR_USER
-+      /* set_opt (sb->u.ext2_sb.s_mount_opt, XATTR_USER); */
-+#endif
-       if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
-           &sb->u.ext2_sb.s_mount_opt)) {
-               return NULL;
-@@ -810,12 +822,27 @@ static DECLARE_FSTYPE_DEV(ext2_fs_type, 
- static int __init init_ext2_fs(void)
- {
--        return register_filesystem(&ext2_fs_type);
-+      int error = init_ext2_xattr();
-+      if (error)
-+              return error;
-+      error = init_ext2_xattr_user();
-+      if (error)
-+              goto fail;
-+      error = register_filesystem(&ext2_fs_type);
-+      if (!error)
-+              return 0;
-+
-+      exit_ext2_xattr_user();
-+fail:
-+      exit_ext2_xattr();
-+      return error;
- }
- static void __exit exit_ext2_fs(void)
- {
-       unregister_filesystem(&ext2_fs_type);
-+      exit_ext2_xattr_user();
-+      exit_ext2_xattr();
- }
- EXPORT_NO_SYMBOLS;
---- linux-2.4.19-hppl/fs/ext2/symlink.c~linux-2.4.20-xattr-0.8.54-hp_chaos     2000-09-28 04:41:33.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext2/symlink.c   2003-04-11 16:52:17.000000000 +0800
-@@ -19,6 +19,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
-@@ -32,7 +33,20 @@ static int ext2_follow_link(struct dentr
-       return vfs_follow_link(nd, s);
- }
-+struct inode_operations ext2_symlink_inode_operations = {
-+      readlink:       page_readlink,
-+      follow_link:    page_follow_link,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
-+};
-+
- struct inode_operations ext2_fast_symlink_inode_operations = {
-       readlink:       ext2_readlink,
-       follow_link:    ext2_follow_link,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- /dev/null  2003-01-30 18:24:37.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext2/xattr.c     2003-04-11 16:52:17.000000000 +0800
-@@ -0,0 +1,1212 @@
-+/*
-+ * linux/fs/ext2/xattr.c
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
-+ * Extended attributes for symlinks and special files added per
-+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
-+ */
-+
-+/*
-+ * Extended attributes are stored on disk blocks allocated outside of
-+ * any inode. The i_file_acl field is then made to point to this allocated
-+ * block. If all extended attributes of an inode are identical, these
-+ * inodes may share the same extended attribute block. Such situations
-+ * are automatically detected by keeping a cache of recent attribute block
-+ * numbers and hashes over the block's contents in memory.
-+ *
-+ *
-+ * Extended attribute block layout:
-+ *
-+ *   +------------------+
-+ *   | header           |
-+ *   | entry 1          | |
-+ *   | entry 2          | | growing downwards
-+ *   | entry 3          | v
-+ *   | four null bytes  |
-+ *   | . . .            |
-+ *   | value 1          | ^
-+ *   | value 3          | | growing upwards
-+ *   | value 2          | |
-+ *   +------------------+
-+ *
-+ * The block header is followed by multiple entry descriptors. These entry
-+ * descriptors are variable in size, and alligned to EXT2_XATTR_PAD
-+ * byte boundaries. The entry descriptors are sorted by attribute name,
-+ * so that two extended attribute blocks can be compared efficiently.
-+ *
-+ * Attribute values are aligned to the end of the block, stored in
-+ * no specific order. They are also padded to EXT2_XATTR_PAD byte
-+ * boundaries. No additional gaps are left between them.
-+ *
-+ * Locking strategy
-+ * ----------------
-+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
-+ * the xattr inode operations are called, so we are guaranteed that only one
-+ * processes accesses extended attributes of an inode at any time.
-+ *
-+ * For writing we also grab the ext2_xattr_sem semaphore. This ensures that
-+ * only a single process is modifying an extended attribute block, even
-+ * if the block is shared among inodes.
-+ *
-+ * Note for porting to 2.5
-+ * -----------------------
-+ * The BKL will no longer be held in the xattr inode operations.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/locks.h>
-+#include <linux/slab.h>
-+#include <linux/fs.h>
-+#include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
-+#include <linux/mbcache.h>
-+#include <linux/quotaops.h>
-+#include <asm/semaphore.h>
-+#include <linux/compatmac.h>
-+
-+/* These symbols may be needed by a module. */
-+EXPORT_SYMBOL(ext2_xattr_register);
-+EXPORT_SYMBOL(ext2_xattr_unregister);
-+EXPORT_SYMBOL(ext2_xattr_get);
-+EXPORT_SYMBOL(ext2_xattr_list);
-+EXPORT_SYMBOL(ext2_xattr_set);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
-+#endif
-+
-+#define HDR(bh) ((struct ext2_xattr_header *)((bh)->b_data))
-+#define ENTRY(ptr) ((struct ext2_xattr_entry *)(ptr))
-+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
-+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
-+
-+#ifdef EXT2_XATTR_DEBUG
-+# define ea_idebug(inode, f...) do { \
-+              printk(KERN_DEBUG "inode %s:%ld: ", \
-+                      kdevname(inode->i_dev), inode->i_ino); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+# define ea_bdebug(bh, f...) do { \
-+              printk(KERN_DEBUG "block %s:%ld: ", \
-+                      kdevname(bh->b_dev), bh->b_blocknr); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+#else
-+# define ea_idebug(f...)
-+# define ea_bdebug(f...)
-+#endif
-+
-+static int ext2_xattr_set2(struct inode *, struct buffer_head *,
-+                         struct ext2_xattr_header *);
-+
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+
-+static int ext2_xattr_cache_insert(struct buffer_head *);
-+static struct buffer_head *ext2_xattr_cache_find(struct inode *,
-+                                               struct ext2_xattr_header *);
-+static void ext2_xattr_cache_remove(struct buffer_head *);
-+static void ext2_xattr_rehash(struct ext2_xattr_header *,
-+                            struct ext2_xattr_entry *);
-+
-+static struct mb_cache *ext2_xattr_cache;
-+
-+#else
-+# define ext2_xattr_cache_insert(bh) 0
-+# define ext2_xattr_cache_find(inode, header) NULL
-+# define ext2_xattr_cache_remove(bh) while(0) {}
-+# define ext2_xattr_rehash(header, entry) while(0) {}
-+#endif
-+
-+/*
-+ * If a file system does not share extended attributes among inodes,
-+ * we should not need the ext2_xattr_sem semaphore. However, the
-+ * filesystem may still contain shared blocks, so we always take
-+ * the lock.
-+ */
-+
-+DECLARE_MUTEX(ext2_xattr_sem);
-+
-+static inline int
-+ext2_xattr_new_block(struct inode *inode, int * errp, int force)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      int goal = le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) +
-+              EXT2_I(inode)->i_block_group * EXT2_BLOCKS_PER_GROUP(sb);
-+
-+      /* How can we enforce the allocation? */
-+      int block = ext2_new_block(inode, goal, 0, 0, errp);
-+#ifdef OLD_QUOTAS
-+      if (!*errp)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#endif
-+      return block;
-+}
-+
-+static inline int
-+ext2_xattr_quota_alloc(struct inode *inode, int force)
-+{
-+      /* How can we enforce the allocation? */
-+#ifdef OLD_QUOTAS
-+      int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
-+      if (!error)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#else
-+      int error = DQUOT_ALLOC_BLOCK(inode, 1);
-+#endif
-+      return error;
-+}
-+
-+#ifdef OLD_QUOTAS
-+
-+static inline void
-+ext2_xattr_quota_free(struct inode *inode)
-+{
-+      DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+static inline void
-+ext2_xattr_free_block(struct inode * inode, unsigned long block)
-+{
-+      ext2_free_blocks(inode, block, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+#else
-+# define ext2_xattr_quota_free(inode) \
-+      DQUOT_FREE_BLOCK(inode, 1)
-+# define ext2_xattr_free_block(inode, block) \
-+      ext2_free_blocks(inode, block, 1)
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
-+
-+static inline struct buffer_head *
-+sb_bread(struct super_block *sb, int block)
-+{
-+      return bread(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+static inline struct buffer_head *
-+sb_getblk(struct super_block *sb, int block)
-+{
-+      return getblk(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+#endif
-+
-+struct ext2_xattr_handler *ext2_xattr_handlers[EXT2_XATTR_INDEX_MAX];
-+rwlock_t ext2_handler_lock = RW_LOCK_UNLOCKED;
-+
-+int
-+ext2_xattr_register(int name_index, struct ext2_xattr_handler *handler)
-+{
-+      int error = -EINVAL;
-+
-+      if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
-+              write_lock(&ext2_handler_lock);
-+              if (!ext2_xattr_handlers[name_index-1]) {
-+                      ext2_xattr_handlers[name_index-1] = handler;
-+                      error = 0;
-+              }
-+              write_unlock(&ext2_handler_lock);
-+      }
-+      return error;
-+}
-+
-+void
-+ext2_xattr_unregister(int name_index, struct ext2_xattr_handler *handler)
-+{
-+      if (name_index > 0 || name_index <= EXT2_XATTR_INDEX_MAX) {
-+              write_lock(&ext2_handler_lock);
-+              ext2_xattr_handlers[name_index-1] = NULL;
-+              write_unlock(&ext2_handler_lock);
-+      }
-+}
-+
-+static inline const char *
-+strcmp_prefix(const char *a, const char *a_prefix)
-+{
-+      while (*a_prefix && *a == *a_prefix) {
-+              a++;
-+              a_prefix++;
-+      }
-+      return *a_prefix ? NULL : a;
-+}
-+
-+/*
-+ * Decode the extended attribute name, and translate it into
-+ * the name_index and name suffix.
-+ */
-+static struct ext2_xattr_handler *
-+ext2_xattr_resolve_name(const char **name)
-+{
-+      struct ext2_xattr_handler *handler = NULL;
-+      int i;
-+
-+      if (!*name)
-+              return NULL;
-+      read_lock(&ext2_handler_lock);
-+      for (i=0; i<EXT2_XATTR_INDEX_MAX; i++) {
-+              if (ext2_xattr_handlers[i]) {
-+                      const char *n = strcmp_prefix(*name,
-+                              ext2_xattr_handlers[i]->prefix);
-+                      if (n) {
-+                              handler = ext2_xattr_handlers[i];
-+                              *name = n;
-+                              break;
-+                      }
-+              }
-+      }
-+      read_unlock(&ext2_handler_lock);
-+      return handler;
-+}
-+
-+static inline struct ext2_xattr_handler *
-+ext2_xattr_handler(int name_index)
-+{
-+      struct ext2_xattr_handler *handler = NULL;
-+      if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
-+              read_lock(&ext2_handler_lock);
-+              handler = ext2_xattr_handlers[name_index-1];
-+              read_unlock(&ext2_handler_lock);
-+      }
-+      return handler;
-+}
-+
-+/*
-+ * Inode operation getxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext2_getxattr(struct dentry *dentry, const char *name,
-+            void *buffer, size_t size)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->get(inode, name, buffer, size);
-+}
-+
-+/*
-+ * Inode operation listxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
-+{
-+      return ext2_xattr_list(dentry->d_inode, buffer, size);
-+}
-+
-+/*
-+ * Inode operation setxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext2_setxattr(struct dentry *dentry, const char *name,
-+            const void *value, size_t size, int flags)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      if (size == 0)
-+              value = "";  /* empty EA, do not remove */
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, value, size, flags);
-+}
-+
-+/*
-+ * Inode operation removexattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext2_removexattr(struct dentry *dentry, const char *name)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
-+}
-+
-+/*
-+ * ext2_xattr_get()
-+ *
-+ * Copy an extended attribute into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext2_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_entry *entry;
-+      unsigned int block, size;
-+      char *end;
-+      int name_len, error;
-+
-+      ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
-+                name_index, name, buffer, (long)buffer_size);
-+
-+      if (name == NULL)
-+              return -EINVAL;
-+      if (!EXT2_I(inode)->i_file_acl)
-+              return -ENOATTR;
-+      block = EXT2_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext2_error(inode->i_sb, "ext2_xattr_get",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* find named attribute */
-+      name_len = strlen(name);
-+
-+      error = -ERANGE;
-+      if (name_len > 255)
-+              goto cleanup;
-+      entry = FIRST_ENTRY(bh);
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              if (name_index == entry->e_name_index &&
-+                  name_len == entry->e_name_len &&
-+                  memcmp(name, entry->e_name, name_len) == 0)
-+                      goto found;
-+              entry = next;
-+      }
-+      /* Check the remaining name entries */
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              entry = next;
-+      }
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      error = -ENOATTR;
-+      goto cleanup;
-+found:
-+      /* check the buffer size */
-+      if (entry->e_value_block != 0)
-+              goto bad_block;
-+      size = le32_to_cpu(entry->e_value_size);
-+      if (size > inode->i_sb->s_blocksize ||
-+          le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-+              goto bad_block;
-+
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (buffer) {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+              /* return value of attribute */
-+              memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-+                      size);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_list()
-+ *
-+ * Copy a list of attribute names into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_entry *entry;
-+      unsigned int block, size = 0;
-+      char *buf, *end;
-+      int error;
-+
-+      ea_idebug(inode, "buffer=%p, buffer_size=%ld",
-+                buffer, (long)buffer_size);
-+
-+      if (!EXT2_I(inode)->i_file_acl)
-+              return 0;
-+      block = EXT2_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext2_error(inode->i_sb, "ext2_xattr_list",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* compute the size required for the list of attribute names */
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT2_XATTR_NEXT(entry)) {
-+              struct ext2_xattr_handler *handler;
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+
-+              handler = ext2_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      size += handler->list(NULL, inode, entry->e_name,
-+                                            entry->e_name_len);
-+      }
-+
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (!buffer) {
-+              error = size;
-+              goto cleanup;
-+      } else {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+      }
-+
-+      /* list the attribute names */
-+      buf = buffer;
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT2_XATTR_NEXT(entry)) {
-+              struct ext2_xattr_handler *handler;
-+              
-+              handler = ext2_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      buf += handler->list(buf, inode, entry->e_name,
-+                                           entry->e_name_len);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * If the EXT2_FEATURE_COMPAT_EXT_ATTR feature of this file system is
-+ * not set, set it.
-+ */
-+static void ext2_xattr_update_super_block(struct super_block *sb)
-+{
-+      if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR))
-+              return;
-+
-+      lock_super(sb);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+      EXT2_SB(sb)->s_feature_compat |= EXT2_FEATURE_COMPAT_EXT_ATTR;
-+#endif
-+      EXT2_SB(sb)->s_es->s_feature_compat |=
-+              cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR);
-+      sb->s_dirt = 1;
-+      mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
-+      unlock_super(sb);
-+}
-+
-+/*
-+ * ext2_xattr_set()
-+ *
-+ * Create, replace or remove an extended attribute for this inode. Buffer
-+ * is NULL to remove an existing extended attribute, and non-NULL to
-+ * either replace an existing extended attribute, or create a new extended
-+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
-+ * specify that an extended attribute must exist and must not exist
-+ * previous to the call, respectively.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+int
-+ext2_xattr_set(struct inode *inode, int name_index, const char *name,
-+             const void *value, size_t value_len, int flags)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_header *header = NULL;
-+      struct ext2_xattr_entry *here, *last;
-+      unsigned int name_len;
-+      int block = EXT2_I(inode)->i_file_acl;
-+      int min_offs = sb->s_blocksize, not_found = 1, free, error;
-+      char *end;
-+      
-+      /*
-+       * header -- Points either into bh, or to a temporarily
-+       *           allocated buffer.
-+       * here -- The named entry found, or the place for inserting, within
-+       *         the block pointed to by header.
-+       * last -- Points right after the last named entry within the block
-+       *         pointed to by header.
-+       * min_offs -- The offset of the first value (values are aligned
-+       *             towards the end of the block).
-+       * end -- Points right after the block pointed to by header.
-+       */
-+      
-+      ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-+                name_index, name, value, (long)value_len);
-+
-+      if (IS_RDONLY(inode))
-+              return -EROFS;
-+      if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-+              return -EPERM;
-+      if (value == NULL)
-+              value_len = 0;
-+      if (name == NULL)
-+              return -EINVAL;
-+      name_len = strlen(name);
-+      if (name_len > 255 || value_len > sb->s_blocksize)
-+              return -ERANGE;
-+      down(&ext2_xattr_sem);
-+
-+      if (block) {
-+              /* The inode already has an extended attribute block. */
-+
-+              bh = sb_bread(sb, block);
-+              error = -EIO;
-+              if (!bh)
-+                      goto cleanup;
-+              ea_bdebug(bh, "b_count=%d, refcount=%d",
-+                      atomic_read(&(bh->b_count)),
-+                      le32_to_cpu(HDR(bh)->h_refcount));
-+              header = HDR(bh);
-+              end = bh->b_data + bh->b_size;
-+              if (header->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+                  header->h_blocks != cpu_to_le32(1)) {
-+bad_block:            ext2_error(sb, "ext2_xattr_set",
-+                              "inode %ld: bad block %d", inode->i_ino, block);
-+                      error = -EIO;
-+                      goto cleanup;
-+              }
-+              /* Find the named attribute. */
-+              here = FIRST_ENTRY(bh);
-+              while (!IS_LAST_ENTRY(here)) {
-+                      struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(here);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!here->e_value_block && here->e_value_size) {
-+                              int offs = le16_to_cpu(here->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      not_found = name_index - here->e_name_index;
-+                      if (!not_found)
-+                              not_found = name_len - here->e_name_len;
-+                      if (!not_found)
-+                              not_found = memcmp(name, here->e_name,name_len);
-+                      if (not_found <= 0)
-+                              break;
-+                      here = next;
-+              }
-+              last = here;
-+              /* We still need to compute min_offs and last. */
-+              while (!IS_LAST_ENTRY(last)) {
-+                      struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(last);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!last->e_value_block && last->e_value_size) {
-+                              int offs = le16_to_cpu(last->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      last = next;
-+              }
-+
-+              /* Check whether we have enough space left. */
-+              free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-+      } else {
-+              /* We will use a new extended attribute block. */
-+              free = sb->s_blocksize -
-+                      sizeof(struct ext2_xattr_header) - sizeof(__u32);
-+              here = last = NULL;  /* avoid gcc uninitialized warning. */
-+      }
-+
-+      if (not_found) {
-+              /* Request to remove a nonexistent attribute? */
-+              error = -ENOATTR;
-+              if (flags & XATTR_REPLACE)
-+                      goto cleanup;
-+              error = 0;
-+              if (value == NULL)
-+                      goto cleanup;
-+              else
-+                      free -= EXT2_XATTR_LEN(name_len);
-+      } else {
-+              /* Request to create an existing attribute? */
-+              error = -EEXIST;
-+              if (flags & XATTR_CREATE)
-+                      goto cleanup;
-+              if (!here->e_value_block && here->e_value_size) {
-+                      unsigned int size = le32_to_cpu(here->e_value_size);
-+
-+                      if (le16_to_cpu(here->e_value_offs) + size > 
-+                          sb->s_blocksize || size > sb->s_blocksize)
-+                              goto bad_block;
-+                      free += EXT2_XATTR_SIZE(size);
-+              }
-+      }
-+      free -= EXT2_XATTR_SIZE(value_len);
-+      error = -ENOSPC;
-+      if (free < 0)
-+              goto cleanup;
-+
-+      /* Here we know that we can set the new attribute. */
-+
-+      if (header) {
-+              if (header->h_refcount == cpu_to_le32(1)) {
-+                      ea_bdebug(bh, "modifying in-place");
-+                      ext2_xattr_cache_remove(bh);
-+              } else {
-+                      int offset;
-+
-+                      ea_bdebug(bh, "cloning");
-+                      header = kmalloc(bh->b_size, GFP_KERNEL);
-+                      error = -ENOMEM;
-+                      if (header == NULL)
-+                              goto cleanup;
-+                      memcpy(header, HDR(bh), bh->b_size);
-+                      header->h_refcount = cpu_to_le32(1);
-+                      offset = (char *)header - bh->b_data;
-+                      here = ENTRY((char *)here + offset);
-+                      last = ENTRY((char *)last + offset);
-+              }
-+      } else {
-+              /* Allocate a buffer where we construct the new block. */
-+              header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-+              error = -ENOMEM;
-+              if (header == NULL)
-+                      goto cleanup;
-+              memset(header, 0, sb->s_blocksize);
-+              end = (char *)header + sb->s_blocksize;
-+              header->h_magic = cpu_to_le32(EXT2_XATTR_MAGIC);
-+              header->h_blocks = header->h_refcount = cpu_to_le32(1);
-+              last = here = ENTRY(header+1);
-+      }
-+
-+      if (not_found) {
-+              /* Insert the new name. */
-+              int size = EXT2_XATTR_LEN(name_len);
-+              int rest = (char *)last - (char *)here;
-+              memmove((char *)here + size, here, rest);
-+              memset(here, 0, size);
-+              here->e_name_index = name_index;
-+              here->e_name_len = name_len;
-+              memcpy(here->e_name, name, name_len);
-+      } else {
-+              /* Remove the old value. */
-+              if (!here->e_value_block && here->e_value_size) {
-+                      char *first_val = (char *)header + min_offs;
-+                      int offs = le16_to_cpu(here->e_value_offs);
-+                      char *val = (char *)header + offs;
-+                      size_t size = EXT2_XATTR_SIZE(
-+                              le32_to_cpu(here->e_value_size));
-+                      memmove(first_val + size, first_val, val - first_val);
-+                      memset(first_val, 0, size);
-+                      here->e_value_offs = 0;
-+                      min_offs += size;
-+
-+                      /* Adjust all value offsets. */
-+                      last = ENTRY(header+1);
-+                      while (!IS_LAST_ENTRY(last)) {
-+                              int o = le16_to_cpu(last->e_value_offs);
-+                              if (!last->e_value_block && o < offs)
-+                                      last->e_value_offs =
-+                                              cpu_to_le16(o + size);
-+                              last = EXT2_XATTR_NEXT(last);
-+                      }
-+              }
-+              if (value == NULL) {
-+                      /* Remove this attribute. */
-+                      if (EXT2_XATTR_NEXT(ENTRY(header+1)) == last) {
-+                              /* This block is now empty. */
-+                              error = ext2_xattr_set2(inode, bh, NULL);
-+                              goto cleanup;
-+                      } else {
-+                              /* Remove the old name. */
-+                              int size = EXT2_XATTR_LEN(name_len);
-+                              last = ENTRY((char *)last - size);
-+                              memmove(here, (char*)here + size,
-+                                      (char*)last - (char*)here);
-+                              memset(last, 0, size);
-+                      }
-+              }
-+      }
-+
-+      if (value != NULL) {
-+              /* Insert the new value. */
-+              here->e_value_size = cpu_to_le32(value_len);
-+              if (value_len) {
-+                      size_t size = EXT2_XATTR_SIZE(value_len);
-+                      char *val = (char *)header + min_offs - size;
-+                      here->e_value_offs =
-+                              cpu_to_le16((char *)val - (char *)header);
-+                      memset(val + size - EXT2_XATTR_PAD, 0,
-+                             EXT2_XATTR_PAD); /* Clear the pad bytes. */
-+                      memcpy(val, value, value_len);
-+              }
-+      }
-+      ext2_xattr_rehash(header, here);
-+
-+      error = ext2_xattr_set2(inode, bh, header);
-+
-+cleanup:
-+      brelse(bh);
-+      if (!(bh && header == HDR(bh)))
-+              kfree(header);
-+      up(&ext2_xattr_sem);
-+
-+      return error;
-+}
-+
-+/*
-+ * Second half of ext2_xattr_set(): Update the file system.
-+ */
-+static int
-+ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
-+              struct ext2_xattr_header *header)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *new_bh = NULL;
-+      int error;
-+
-+      if (header) {
-+              new_bh = ext2_xattr_cache_find(inode, header);
-+              if (new_bh) {
-+                      /*
-+                       * We found an identical block in the cache.
-+                       * The old block will be released after updating
-+                       * the inode.
-+                       */
-+                      ea_bdebug(old_bh, "reusing block %ld",
-+                              new_bh->b_blocknr);
-+                      
-+                      error = -EDQUOT;
-+                      if (ext2_xattr_quota_alloc(inode, 1))
-+                              goto cleanup;
-+                      
-+                      HDR(new_bh)->h_refcount = cpu_to_le32(
-+                              le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
-+                      ea_bdebug(new_bh, "refcount now=%d",
-+                              le32_to_cpu(HDR(new_bh)->h_refcount));
-+              } else if (old_bh && header == HDR(old_bh)) {
-+                      /* Keep this block. */
-+                      new_bh = old_bh;
-+                      ext2_xattr_cache_insert(new_bh);
-+              } else {
-+                      /* We need to allocate a new block */
-+                      int force = EXT2_I(inode)->i_file_acl != 0;
-+                      int block = ext2_xattr_new_block(inode, &error, force);
-+                      if (error)
-+                              goto cleanup;
-+                      ea_idebug(inode, "creating block %d", block);
-+
-+                      new_bh = sb_getblk(sb, block);
-+                      if (!new_bh) {
-+                              ext2_xattr_free_block(inode, block);
-+                              error = -EIO;
-+                              goto cleanup;
-+                      }
-+                      lock_buffer(new_bh);
-+                      memcpy(new_bh->b_data, header, new_bh->b_size);
-+                      mark_buffer_uptodate(new_bh, 1);
-+                      unlock_buffer(new_bh);
-+                      ext2_xattr_cache_insert(new_bh);
-+                      
-+                      ext2_xattr_update_super_block(sb);
-+              }
-+              mark_buffer_dirty(new_bh);
-+              if (IS_SYNC(inode)) {
-+                      ll_rw_block(WRITE, 1, &new_bh);
-+                      wait_on_buffer(new_bh); 
-+                      error = -EIO;
-+                      if (buffer_req(new_bh) && !buffer_uptodate(new_bh))
-+                              goto cleanup;
-+              }
-+      }
-+
-+      /* Update the inode. */
-+      EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-+      inode->i_ctime = CURRENT_TIME;
-+      if (IS_SYNC(inode)) {
-+              error = ext2_sync_inode (inode);
-+              if (error)
-+                      goto cleanup;
-+      } else
-+              mark_inode_dirty(inode);
-+
-+      error = 0;
-+      if (old_bh && old_bh != new_bh) {
-+              /*
-+               * If there was an old block, and we are not still using it,
-+               * we now release the old block.
-+              */
-+              unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
-+
-+              if (refcount == 1) {
-+                      /* Free the old block. */
-+                      ea_bdebug(old_bh, "freeing");
-+                      ext2_xattr_free_block(inode, old_bh->b_blocknr);
-+                      mark_buffer_clean(old_bh);
-+              } else {
-+                      /* Decrement the refcount only. */
-+                      refcount--;
-+                      HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
-+                      ext2_xattr_quota_free(inode);
-+                      mark_buffer_dirty(old_bh);
-+                      ea_bdebug(old_bh, "refcount now=%d", refcount);
-+              }
-+      }
-+
-+cleanup:
-+      if (old_bh != new_bh)
-+              brelse(new_bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_delete_inode()
-+ *
-+ * Free extended attribute resources associated with this inode. This
-+ * is called immediately before an inode is freed.
-+ */
-+void
-+ext2_xattr_delete_inode(struct inode *inode)
-+{
-+      struct buffer_head *bh;
-+      unsigned int block = EXT2_I(inode)->i_file_acl;
-+
-+      if (!block)
-+              return;
-+      down(&ext2_xattr_sem);
-+
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh) {
-+              ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
-+                      "inode %ld: block %d read error", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+              ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+      if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-+              ext2_xattr_cache_remove(bh);
-+              ext2_xattr_free_block(inode, block);
-+              bforget(bh);
-+              bh = NULL;
-+      } else {
-+              HDR(bh)->h_refcount = cpu_to_le32(
-+                      le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+              mark_buffer_dirty(bh);
-+              if (IS_SYNC(inode)) {
-+                      ll_rw_block(WRITE, 1, &bh);
-+                      wait_on_buffer(bh);
-+              }
-+              ext2_xattr_quota_free(inode);
-+      }
-+      EXT2_I(inode)->i_file_acl = 0;
-+
-+cleanup:
-+      brelse(bh);
-+      up(&ext2_xattr_sem);
-+}
-+
-+/*
-+ * ext2_xattr_put_super()
-+ *
-+ * This is called when a file system is unmounted.
-+ */
-+void
-+ext2_xattr_put_super(struct super_block *sb)
-+{
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+      mb_cache_shrink(ext2_xattr_cache, sb->s_dev);
-+#endif
-+}
-+
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+
-+/*
-+ * ext2_xattr_cache_insert()
-+ *
-+ * Create a new entry in the extended attribute cache, and insert
-+ * it unless such an entry is already in the cache.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+static int
-+ext2_xattr_cache_insert(struct buffer_head *bh)
-+{
-+      __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
-+      struct mb_cache_entry *ce;
-+      int error;
-+
-+      ce = mb_cache_entry_alloc(ext2_xattr_cache);
-+      if (!ce)
-+              return -ENOMEM;
-+      error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
-+      if (error) {
-+              mb_cache_entry_free(ce);
-+              if (error == -EBUSY) {
-+                      ea_bdebug(bh, "already in cache (%d cache entries)",
-+                              atomic_read(&ext2_xattr_cache->c_entry_count));
-+                      error = 0;
-+              }
-+      } else {
-+              ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-+                        atomic_read(&ext2_xattr_cache->c_entry_count));
-+              mb_cache_entry_release(ce);
-+      }
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_cmp()
-+ *
-+ * Compare two extended attribute blocks for equality.
-+ *
-+ * Returns 0 if the blocks are equal, 1 if they differ, and
-+ * a negative error number on errors.
-+ */
-+static int
-+ext2_xattr_cmp(struct ext2_xattr_header *header1,
-+             struct ext2_xattr_header *header2)
-+{
-+      struct ext2_xattr_entry *entry1, *entry2;
-+
-+      entry1 = ENTRY(header1+1);
-+      entry2 = ENTRY(header2+1);
-+      while (!IS_LAST_ENTRY(entry1)) {
-+              if (IS_LAST_ENTRY(entry2))
-+                      return 1;
-+              if (entry1->e_hash != entry2->e_hash ||
-+                  entry1->e_name_len != entry2->e_name_len ||
-+                  entry1->e_value_size != entry2->e_value_size ||
-+                  memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
-+                      return 1;
-+              if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
-+                      return -EIO;
-+              if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
-+                         (char *)header2 + le16_to_cpu(entry2->e_value_offs),
-+                         le32_to_cpu(entry1->e_value_size)))
-+                      return 1;
-+
-+              entry1 = EXT2_XATTR_NEXT(entry1);
-+              entry2 = EXT2_XATTR_NEXT(entry2);
-+      }
-+      if (!IS_LAST_ENTRY(entry2))
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * ext2_xattr_cache_find()
-+ *
-+ * Find an identical extended attribute block.
-+ *
-+ * Returns a pointer to the block found, or NULL if such a block was
-+ * not found or an error occurred.
-+ */
-+static struct buffer_head *
-+ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header)
-+{
-+      __u32 hash = le32_to_cpu(header->h_hash);
-+      struct mb_cache_entry *ce;
-+
-+      if (!header->h_hash)
-+              return NULL;  /* never share */
-+      ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
-+      ce = mb_cache_entry_find_first(ext2_xattr_cache, 0, inode->i_dev, hash);
-+      while (ce) {
-+              struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
-+
-+              if (!bh) {
-+                      ext2_error(inode->i_sb, "ext2_xattr_cache_find",
-+                              "inode %ld: block %ld read error",
-+                              inode->i_ino, ce->e_block);
-+              } else if (le32_to_cpu(HDR(bh)->h_refcount) >
-+                         EXT2_XATTR_REFCOUNT_MAX) {
-+                      ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
-+                              le32_to_cpu(HDR(bh)->h_refcount),
-+                              EXT2_XATTR_REFCOUNT_MAX);
-+              } else if (!ext2_xattr_cmp(header, HDR(bh))) {
-+                      ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
-+                      mb_cache_entry_release(ce);
-+                      return bh;
-+              }
-+              brelse(bh);
-+              ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * ext2_xattr_cache_remove()
-+ *
-+ * Remove the cache entry of a block from the cache. Called when a
-+ * block becomes invalid.
-+ */
-+static void
-+ext2_xattr_cache_remove(struct buffer_head *bh)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_dev, bh->b_blocknr);
-+      if (ce) {
-+              ea_bdebug(bh, "removing (%d cache entries remaining)",
-+                        atomic_read(&ext2_xattr_cache->c_entry_count)-1);
-+              mb_cache_entry_free(ce);
-+      } else 
-+              ea_bdebug(bh, "no cache entry");
-+}
-+
-+#define NAME_HASH_SHIFT 5
-+#define VALUE_HASH_SHIFT 16
-+
-+/*
-+ * ext2_xattr_hash_entry()
-+ *
-+ * Compute the hash of an extended attribute.
-+ */
-+static inline void ext2_xattr_hash_entry(struct ext2_xattr_header *header,
-+                                       struct ext2_xattr_entry *entry)
-+{
-+      __u32 hash = 0;
-+      char *name = entry->e_name;
-+      int n;
-+
-+      for (n=0; n < entry->e_name_len; n++) {
-+              hash = (hash << NAME_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
-+                     *name++;
-+      }
-+
-+      if (entry->e_value_block == 0 && entry->e_value_size != 0) {
-+              __u32 *value = (__u32 *)((char *)header +
-+                      le16_to_cpu(entry->e_value_offs));
-+              for (n = (le32_to_cpu(entry->e_value_size) +
-+                   EXT2_XATTR_ROUND) >> EXT2_XATTR_PAD_BITS; n; n--) {
-+                      hash = (hash << VALUE_HASH_SHIFT) ^
-+                             (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
-+                             le32_to_cpu(*value++);
-+              }
-+      }
-+      entry->e_hash = cpu_to_le32(hash);
-+}
-+
-+#undef NAME_HASH_SHIFT
-+#undef VALUE_HASH_SHIFT
-+
-+#define BLOCK_HASH_SHIFT 16
-+
-+/*
-+ * ext2_xattr_rehash()
-+ *
-+ * Re-compute the extended attribute hash value after an entry has changed.
-+ */
-+static void ext2_xattr_rehash(struct ext2_xattr_header *header,
-+                            struct ext2_xattr_entry *entry)
-+{
-+      struct ext2_xattr_entry *here;
-+      __u32 hash = 0;
-+      
-+      ext2_xattr_hash_entry(header, entry);
-+      here = ENTRY(header+1);
-+      while (!IS_LAST_ENTRY(here)) {
-+              if (!here->e_hash) {
-+                      /* Block is not shared if an entry's hash value == 0 */
-+                      hash = 0;
-+                      break;
-+              }
-+              hash = (hash << BLOCK_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
-+                     le32_to_cpu(here->e_hash);
-+              here = EXT2_XATTR_NEXT(here);
-+      }
-+      header->h_hash = cpu_to_le32(hash);
-+}
-+
-+#undef BLOCK_HASH_SHIFT
-+
-+int __init
-+init_ext2_xattr(void)
-+{
-+      ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
-+              sizeof(struct mb_cache_entry) +
-+              sizeof(struct mb_cache_entry_index), 1, 61);
-+      if (!ext2_xattr_cache)
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+void
-+exit_ext2_xattr(void)
-+{
-+      mb_cache_destroy(ext2_xattr_cache);
-+}
-+
-+#else  /* CONFIG_EXT2_FS_XATTR_SHARING */
-+
-+int __init
-+init_ext2_xattr(void)
-+{
-+      return 0;
-+}
-+
-+void
-+exit_ext2_xattr(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT2_FS_XATTR_SHARING */
---- /dev/null  2003-01-30 18:24:37.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext2/xattr_user.c        2003-04-11 16:52:17.000000000 +0800
-@@ -0,0 +1,103 @@
-+/*
-+ * linux/fs/ext2/xattr_user.c
-+ * Handler for extended user attributes.
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/fs.h>
-+#include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
-+
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+# include <linux/ext2_acl.h>
-+#endif
-+
-+#define XATTR_USER_PREFIX "user."
-+
-+static size_t
-+ext2_xattr_user_list(char *list, struct inode *inode,
-+                   const char *name, int name_len)
-+{
-+      const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
-+
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return 0;
-+
-+      if (list) {
-+              memcpy(list, XATTR_USER_PREFIX, prefix_len);
-+              memcpy(list+prefix_len, name, name_len);
-+              list[prefix_len + name_len] = '\0';
-+      }
-+      return prefix_len + name_len + 1;
-+}
-+
-+static int
-+ext2_xattr_user_get(struct inode *inode, const char *name,
-+                  void *buffer, size_t size)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+      error = ext2_permission_locked(inode, MAY_READ);
-+#else
-+      error = permission(inode, MAY_READ);
-+#endif
-+      if (error)
-+              return error;
-+
-+      return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name,
-+                            buffer, size);
-+}
-+
-+static int
-+ext2_xattr_user_set(struct inode *inode, const char *name,
-+                  const void *value, size_t size, int flags)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+      if ( !S_ISREG(inode->i_mode) &&
-+          (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-+              return -EPERM;
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+      error = ext2_permission_locked(inode, MAY_WRITE);
-+#else
-+      error = permission(inode, MAY_WRITE);
-+#endif
-+      if (error)
-+              return error;
-+  
-+      return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
-+                            value, size, flags);
-+}
-+
-+struct ext2_xattr_handler ext2_xattr_user_handler = {
-+      prefix: XATTR_USER_PREFIX,
-+      list:   ext2_xattr_user_list,
-+      get:    ext2_xattr_user_get,
-+      set:    ext2_xattr_user_set,
-+};
-+
-+int __init
-+init_ext2_xattr_user(void)
-+{
-+      return ext2_xattr_register(EXT2_XATTR_INDEX_USER,
-+                                 &ext2_xattr_user_handler);
-+}
-+
-+void
-+exit_ext2_xattr_user(void)
-+{
-+      ext2_xattr_unregister(EXT2_XATTR_INDEX_USER,
-+                            &ext2_xattr_user_handler);
-+}
---- linux-2.4.19-hppl/fs/ext3/ialloc.c~linux-2.4.20-xattr-0.8.54-hp_chaos      2002-02-26 03:38:08.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext3/ialloc.c    2003-04-11 16:52:25.000000000 +0800
-@@ -17,6 +17,7 @@
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/stat.h>
- #include <linux/string.h>
- #include <linux/locks.h>
-@@ -216,6 +217,7 @@ void ext3_free_inode (handle_t *handle, 
-        * as writing the quota to disk may need the lock as well.
-        */
-       DQUOT_INIT(inode);
-+      ext3_xattr_delete_inode(handle, inode);
-       DQUOT_FREE_INODE(inode);
-       DQUOT_DROP(inode);
---- linux-2.4.19-hppl/fs/ext3/inode.c~linux-2.4.20-xattr-0.8.54-hp_chaos       2002-08-03 08:39:45.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext3/inode.c     2003-04-11 16:52:25.000000000 +0800
-@@ -39,6 +39,18 @@
-  */
- #undef SEARCH_FROM_ZERO
-+/*
-+ * Test whether an inode is a fast symlink.
-+ */
-+static inline int ext3_inode_is_fast_symlink(struct inode *inode)
-+{
-+      int ea_blocks = inode->u.ext3_i.i_file_acl ?
-+              (inode->i_sb->s_blocksize >> 9) : 0;
-+
-+      return (S_ISLNK(inode->i_mode) &&
-+              inode->i_blocks - ea_blocks == 0);
-+}
-+
- /* The ext3 forget function must perform a revoke if we are freeing data
-  * which has been journaled.  Metadata (eg. indirect blocks) must be
-  * revoked in all cases. 
-@@ -48,7 +60,7 @@
-  * still needs to be revoked.
-  */
--static int ext3_forget(handle_t *handle, int is_metadata,
-+int ext3_forget(handle_t *handle, int is_metadata,
-                      struct inode *inode, struct buffer_head *bh,
-                      int blocknr)
- {
-@@ -164,9 +176,7 @@ void ext3_delete_inode (struct inode * i
- {
-       handle_t *handle;
-       
--      if (is_bad_inode(inode) ||
--          inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
-+      if (is_bad_inode(inode))
-               goto no_delete;
-       lock_kernel();
-@@ -1843,6 +1853,8 @@ void ext3_truncate(struct inode * inode)
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-+      if (ext3_inode_is_fast_symlink(inode))
-+              return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-@@ -1990,8 +2002,6 @@ int ext3_get_inode_loc (struct inode *in
-       struct ext3_group_desc * gdp;
-               
-       if ((inode->i_ino != EXT3_ROOT_INO &&
--              inode->i_ino != EXT3_ACL_IDX_INO &&
--              inode->i_ino != EXT3_ACL_DATA_INO &&
-               inode->i_ino != EXT3_JOURNAL_INO &&
-               inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
-               inode->i_ino > le32_to_cpu(
-@@ -2118,10 +2128,7 @@ void ext3_read_inode(struct inode * inod
-       brelse (iloc.bh);
--      if (inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
--              /* Nothing to do */ ;
--      else if (S_ISREG(inode->i_mode)) {
-+      if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &ext3_file_inode_operations;
-               inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-@@ -2129,15 +2136,17 @@ void ext3_read_inode(struct inode * inod
-               inode->i_op = &ext3_dir_inode_operations;
-               inode->i_fop = &ext3_dir_operations;
-       } else if (S_ISLNK(inode->i_mode)) {
--              if (!inode->i_blocks)
-+              if (ext3_inode_is_fast_symlink(inode))
-                       inode->i_op = &ext3_fast_symlink_inode_operations;
-               else {
--                      inode->i_op = &page_symlink_inode_operations;
-+                      inode->i_op = &ext3_symlink_inode_operations;
-                       inode->i_mapping->a_ops = &ext3_aops;
-               }
--      } else 
-+      } else {
-+              inode->i_op = &ext3_special_inode_operations;
-               init_special_inode(inode, inode->i_mode,
-                                  le32_to_cpu(iloc.raw_inode->i_block[0]));
-+      }
-       /* inode->i_attr_flags = 0;                             unused */
-       if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) {
-               /* inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS; unused */
---- linux-2.4.19-hppl/fs/ext3/namei.c~linux-2.4.20-xattr-0.8.54-hp_chaos       2003-04-11 16:51:07.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext3/namei.c     2003-04-11 16:52:25.000000000 +0800
-@@ -29,6 +29,7 @@
- #include <linux/sched.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/fcntl.h>
- #include <linux/stat.h>
- #include <linux/string.h>
-@@ -1613,7 +1614,7 @@ static int ext3_mkdir(struct inode * dir
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
--      inode = ext3_new_inode (handle, dir, S_IFDIR);
-+      inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
-       err = PTR_ERR(inode);
-       if (IS_ERR(inode))
-               goto out_stop;
-@@ -1621,7 +1622,6 @@ static int ext3_mkdir(struct inode * dir
-       inode->i_op = &ext3_dir_inode_operations;
-       inode->i_fop = &ext3_dir_operations;
-       inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
--      inode->i_blocks = 0;    
-       dir_block = ext3_bread (handle, inode, 0, 1, &err);
-       if (!dir_block) {
-               inode->i_nlink--; /* is this nlink == 0? */
-@@ -1648,9 +1648,6 @@ static int ext3_mkdir(struct inode * dir
-       BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
-       ext3_journal_dirty_metadata(handle, dir_block);
-       brelse (dir_block);
--      inode->i_mode = S_IFDIR | mode;
--      if (dir->i_mode & S_ISGID)
--              inode->i_mode |= S_ISGID;
-       ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_entry (handle, dentry, inode);
-       if (err) {
-@@ -2019,7 +2016,7 @@ static int ext3_symlink (struct inode * 
-               goto out_stop;
-       if (l > sizeof (EXT3_I(inode)->i_data)) {
--              inode->i_op = &page_symlink_inode_operations;
-+              inode->i_op = &ext3_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-               /*
-                * block_symlink() calls back into ext3_prepare/commit_write.
-@@ -2247,4 +2244,16 @@ struct inode_operations ext3_dir_inode_o
-       rmdir:          ext3_rmdir,             /* BKL held */
-       mknod:          ext3_mknod,             /* BKL held */
-       rename:         ext3_rename,            /* BKL held */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
-+
-+struct inode_operations ext3_special_inode_operations = {
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
-+};
-+
---- linux-2.4.19-hppl/fs/ext3/symlink.c~linux-2.4.20-xattr-0.8.54-hp_chaos     2001-11-10 06:25:04.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext3/symlink.c   2003-04-11 16:52:28.000000000 +0800
-@@ -20,6 +20,7 @@
- #include <linux/fs.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
- static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
-@@ -33,7 +34,20 @@ static int ext3_follow_link(struct dentr
-       return vfs_follow_link(nd, s);
- }
-+struct inode_operations ext3_symlink_inode_operations = {
-+      readlink:       page_readlink,          /* BKL not held.  Don't need */
-+      follow_link:    page_follow_link,       /* BKL not held.  Don't need */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
-+};
-+
- struct inode_operations ext3_fast_symlink_inode_operations = {
-       readlink:       ext3_readlink,          /* BKL not held.  Don't need */
-       follow_link:    ext3_follow_link,       /* BKL not held.  Don't need */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
---- /dev/null  2003-01-30 18:24:37.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext3/xattr.c     2003-04-11 16:52:28.000000000 +0800
-@@ -0,0 +1,1232 @@
-+/*
-+ * linux/fs/ext3/xattr.c
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
-+ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
-+ * Extended attributes for symlinks and special files added per
-+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
-+ */
-+
-+/*
-+ * Extended attributes are stored on disk blocks allocated outside of
-+ * any inode. The i_file_acl field is then made to point to this allocated
-+ * block. If all extended attributes of an inode are identical, these
-+ * inodes may share the same extended attribute block. Such situations
-+ * are automatically detected by keeping a cache of recent attribute block
-+ * numbers and hashes over the block's contents in memory.
-+ *
-+ *
-+ * Extended attribute block layout:
-+ *
-+ *   +------------------+
-+ *   | header           |
-+ *   | entry 1          | |
-+ *   | entry 2          | | growing downwards
-+ *   | entry 3          | v
-+ *   | four null bytes  |
-+ *   | . . .            |
-+ *   | value 1          | ^
-+ *   | value 3          | | growing upwards
-+ *   | value 2          | |
-+ *   +------------------+
-+ *
-+ * The block header is followed by multiple entry descriptors. These entry
-+ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
-+ * byte boundaries. The entry descriptors are sorted by attribute name,
-+ * so that two extended attribute blocks can be compared efficiently.
-+ *
-+ * Attribute values are aligned to the end of the block, stored in
-+ * no specific order. They are also padded to EXT3_XATTR_PAD byte
-+ * boundaries. No additional gaps are left between them.
-+ *
-+ * Locking strategy
-+ * ----------------
-+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
-+ * the xattr inode operations are called, so we are guaranteed that only one
-+ * processes accesses extended attributes of an inode at any time.
-+ *
-+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
-+ * only a single process is modifying an extended attribute block, even
-+ * if the block is shared among inodes.
-+ *
-+ * Note for porting to 2.5
-+ * -----------------------
-+ * The BKL will no longer be held in the xattr inode operations.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/locks.h>
-+#include <linux/slab.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
-+#include <linux/mbcache.h>
-+#include <linux/quotaops.h>
-+#include <asm/semaphore.h>
-+#include <linux/compatmac.h>
-+
-+#define EXT3_EA_USER "user."
-+
-+/* These symbols may be needed by a module. */
-+EXPORT_SYMBOL(ext3_xattr_register);
-+EXPORT_SYMBOL(ext3_xattr_unregister);
-+EXPORT_SYMBOL(ext3_xattr_get);
-+EXPORT_SYMBOL(ext3_xattr_list);
-+EXPORT_SYMBOL(ext3_xattr_set);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
-+#endif
-+
-+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
-+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
-+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
-+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
-+
-+#ifdef EXT3_XATTR_DEBUG
-+# define ea_idebug(inode, f...) do { \
-+              printk(KERN_DEBUG "inode %s:%ld: ", \
-+                      kdevname(inode->i_dev), inode->i_ino); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+# define ea_bdebug(bh, f...) do { \
-+              printk(KERN_DEBUG "block %s:%ld: ", \
-+                      kdevname(bh->b_dev), bh->b_blocknr); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+#else
-+# define ea_idebug(f...)
-+# define ea_bdebug(f...)
-+#endif
-+
-+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
-+                         struct ext3_xattr_header *);
-+
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+
-+static int ext3_xattr_cache_insert(struct buffer_head *);
-+static struct buffer_head *ext3_xattr_cache_find(struct inode *,
-+                                               struct ext3_xattr_header *);
-+static void ext3_xattr_cache_remove(struct buffer_head *);
-+static void ext3_xattr_rehash(struct ext3_xattr_header *,
-+                            struct ext3_xattr_entry *);
-+
-+static struct mb_cache *ext3_xattr_cache;
-+
-+#else
-+# define ext3_xattr_cache_insert(bh) 0
-+# define ext3_xattr_cache_find(inode, header) NULL
-+# define ext3_xattr_cache_remove(bh) while(0) {}
-+# define ext3_xattr_rehash(header, entry) while(0) {}
-+#endif
-+
-+/*
-+ * If a file system does not share extended attributes among inodes,
-+ * we should not need the ext3_xattr_sem semaphore. However, the
-+ * filesystem may still contain shared blocks, so we always take
-+ * the lock.
-+ */
-+
-+DECLARE_MUTEX(ext3_xattr_sem);
-+
-+static inline int
-+ext3_xattr_new_block(handle_t *handle, struct inode *inode,
-+                   int * errp, int force)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
-+              EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb);
-+
-+      /* How can we enforce the allocation? */
-+      int block = ext3_new_block(handle, inode, goal, 0, 0, errp);
-+#ifdef OLD_QUOTAS
-+      if (!*errp)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#endif
-+      return block;
-+}
-+
-+static inline int
-+ext3_xattr_quota_alloc(struct inode *inode, int force)
-+{
-+      /* How can we enforce the allocation? */
-+#ifdef OLD_QUOTAS
-+      int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
-+      if (!error)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#else
-+      int error = DQUOT_ALLOC_BLOCK(inode, 1);
-+#endif
-+      return error;
-+}
-+
-+#ifdef OLD_QUOTAS
-+
-+static inline void
-+ext3_xattr_quota_free(struct inode *inode)
-+{
-+      DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+static inline void
-+ext3_xattr_free_block(handle_t *handle, struct inode * inode,
-+                    unsigned long block)
-+{
-+      ext3_free_blocks(handle, inode, block, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+#else
-+# define ext3_xattr_quota_free(inode) \
-+      DQUOT_FREE_BLOCK(inode, 1)
-+# define ext3_xattr_free_block(handle, inode, block) \
-+      ext3_free_blocks(handle, inode, block, 1)
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
-+
-+static inline struct buffer_head *
-+sb_bread(struct super_block *sb, int block)
-+{
-+      return bread(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+static inline struct buffer_head *
-+sb_getblk(struct super_block *sb, int block)
-+{
-+      return getblk(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+#endif
-+
-+struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
-+rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
-+
-+int
-+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      int error = -EINVAL;
-+
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              if (!ext3_xattr_handlers[name_index-1]) {
-+                      ext3_xattr_handlers[name_index-1] = handler;
-+                      error = 0;
-+              }
-+              write_unlock(&ext3_handler_lock);
-+      }
-+      return error;
-+}
-+
-+void
-+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              ext3_xattr_handlers[name_index-1] = NULL;
-+              write_unlock(&ext3_handler_lock);
-+      }
-+}
-+
-+static inline const char *
-+strcmp_prefix(const char *a, const char *a_prefix)
-+{
-+      while (*a_prefix && *a == *a_prefix) {
-+              a++;
-+              a_prefix++;
-+      }
-+      return *a_prefix ? NULL : a;
-+}
-+
-+/*
-+ * Decode the extended attribute name, and translate it into
-+ * the name_index and name suffix.
-+ */
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_resolve_name(const char **name)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      int i;
-+
-+      if (!*name)
-+              return NULL;
-+      read_lock(&ext3_handler_lock);
-+      for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
-+              if (ext3_xattr_handlers[i]) {
-+                      const char *n = strcmp_prefix(*name,
-+                              ext3_xattr_handlers[i]->prefix);
-+                      if (n) {
-+                              handler = ext3_xattr_handlers[i];
-+                              *name = n;
-+                              break;
-+                      }
-+              }
-+      }
-+      read_unlock(&ext3_handler_lock);
-+      return handler;
-+}
-+
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_handler(int name_index)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              read_lock(&ext3_handler_lock);
-+              handler = ext3_xattr_handlers[name_index-1];
-+              read_unlock(&ext3_handler_lock);
-+      }
-+      return handler;
-+}
-+
-+/*
-+ * Inode operation getxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext3_getxattr(struct dentry *dentry, const char *name,
-+            void *buffer, size_t size)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->get(inode, name, buffer, size);
-+}
-+
-+/*
-+ * Inode operation listxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
-+{
-+      return ext3_xattr_list(dentry->d_inode, buffer, size);
-+}
-+
-+/*
-+ * Inode operation setxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext3_setxattr(struct dentry *dentry, const char *name,
-+            const void *value, size_t size, int flags)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      if (size == 0)
-+              value = "";  /* empty EA, do not remove */
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, value, size, flags);
-+}
-+
-+/*
-+ * Inode operation removexattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext3_removexattr(struct dentry *dentry, const char *name)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
-+}
-+
-+/*
-+ * ext3_xattr_get()
-+ *
-+ * Copy an extended attribute into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size;
-+      char *end;
-+      int name_len, error;
-+
-+      ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
-+                name_index, name, buffer, (long)buffer_size);
-+
-+      if (name == NULL)
-+              return -EINVAL;
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return -ENOATTR;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_get",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* find named attribute */
-+      name_len = strlen(name);
-+
-+      error = -ERANGE;
-+      if (name_len > 255)
-+              goto cleanup;
-+      entry = FIRST_ENTRY(bh);
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              if (name_index == entry->e_name_index &&
-+                  name_len == entry->e_name_len &&
-+                  memcmp(name, entry->e_name, name_len) == 0)
-+                      goto found;
-+              entry = next;
-+      }
-+      /* Check the remaining name entries */
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              entry = next;
-+      }
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      error = -ENOATTR;
-+      goto cleanup;
-+found:
-+      /* check the buffer size */
-+      if (entry->e_value_block != 0)
-+              goto bad_block;
-+      size = le32_to_cpu(entry->e_value_size);
-+      if (size > inode->i_sb->s_blocksize ||
-+          le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-+              goto bad_block;
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (buffer) {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+              /* return value of attribute */
-+              memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-+                      size);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_list()
-+ *
-+ * Copy a list of attribute names into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size = 0;
-+      char *buf, *end;
-+      int error;
-+
-+      ea_idebug(inode, "buffer=%p, buffer_size=%ld",
-+                buffer, (long)buffer_size);
-+
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return 0;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_list",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* compute the size required for the list of attribute names */
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      size += handler->list(NULL, inode, entry->e_name,
-+                                            entry->e_name_len);
-+      }
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (!buffer) {
-+              error = size;
-+              goto cleanup;
-+      } else {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+      }
-+
-+      /* list the attribute names */
-+      buf = buffer;
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      buf += handler->list(buf, inode, entry->e_name,
-+                                           entry->e_name_len);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
-+ * not set, set it.
-+ */
-+static void ext3_xattr_update_super_block(handle_t *handle,
-+                                        struct super_block *sb)
-+{
-+      if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
-+              return;
-+
-+      lock_super(sb);
-+      ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+      EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR;
-+#endif
-+      EXT3_SB(sb)->s_es->s_feature_compat |=
-+              cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
-+      sb->s_dirt = 1;
-+      ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-+      unlock_super(sb);
-+}
-+
-+/*
-+ * ext3_xattr_set()
-+ *
-+ * Create, replace or remove an extended attribute for this inode. Buffer
-+ * is NULL to remove an existing extended attribute, and non-NULL to
-+ * either replace an existing extended attribute, or create a new extended
-+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
-+ * specify that an extended attribute must exist and must not exist
-+ * previous to the call, respectively.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, const void *value, size_t value_len, int flags)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_header *header = NULL;
-+      struct ext3_xattr_entry *here, *last;
-+      unsigned int name_len;
-+      int block = EXT3_I(inode)->i_file_acl;
-+      int min_offs = sb->s_blocksize, not_found = 1, free, error;
-+      char *end;
-+      
-+      /*
-+       * header -- Points either into bh, or to a temporarily
-+       *           allocated buffer.
-+       * here -- The named entry found, or the place for inserting, within
-+       *         the block pointed to by header.
-+       * last -- Points right after the last named entry within the block
-+       *         pointed to by header.
-+       * min_offs -- The offset of the first value (values are aligned
-+       *             towards the end of the block).
-+       * end -- Points right after the block pointed to by header.
-+       */
-+      
-+      ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-+                name_index, name, value, (long)value_len);
-+
-+      if (IS_RDONLY(inode))
-+              return -EROFS;
-+      if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-+              return -EPERM;
-+      if (value == NULL)
-+              value_len = 0;
-+      if (name == NULL)
-+              return -EINVAL;
-+      name_len = strlen(name);
-+      if (name_len > 255 || value_len > sb->s_blocksize)
-+              return -ERANGE;
-+      down(&ext3_xattr_sem);
-+
-+      if (block) {
-+              /* The inode already has an extended attribute block. */
-+              bh = sb_bread(sb, block);
-+              error = -EIO;
-+              if (!bh)
-+                      goto cleanup;
-+              ea_bdebug(bh, "b_count=%d, refcount=%d",
-+                      atomic_read(&(bh->b_count)),
-+                      le32_to_cpu(HDR(bh)->h_refcount));
-+              header = HDR(bh);
-+              end = bh->b_data + bh->b_size;
-+              if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+                  header->h_blocks != cpu_to_le32(1)) {
-+bad_block:            ext3_error(sb, "ext3_xattr_set",
-+                              "inode %ld: bad block %d", inode->i_ino, block);
-+                      error = -EIO;
-+                      goto cleanup;
-+              }
-+              /* Find the named attribute. */
-+              here = FIRST_ENTRY(bh);
-+              while (!IS_LAST_ENTRY(here)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!here->e_value_block && here->e_value_size) {
-+                              int offs = le16_to_cpu(here->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      not_found = name_index - here->e_name_index;
-+                      if (!not_found)
-+                              not_found = name_len - here->e_name_len;
-+                      if (!not_found)
-+                              not_found = memcmp(name, here->e_name,name_len);
-+                      if (not_found <= 0)
-+                              break;
-+                      here = next;
-+              }
-+              last = here;
-+              /* We still need to compute min_offs and last. */
-+              while (!IS_LAST_ENTRY(last)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!last->e_value_block && last->e_value_size) {
-+                              int offs = le16_to_cpu(last->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      last = next;
-+              }
-+
-+              /* Check whether we have enough space left. */
-+              free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-+      } else {
-+              /* We will use a new extended attribute block. */
-+              free = sb->s_blocksize -
-+                      sizeof(struct ext3_xattr_header) - sizeof(__u32);
-+              here = last = NULL;  /* avoid gcc uninitialized warning. */
-+      }
-+
-+      if (not_found) {
-+              /* Request to remove a nonexistent attribute? */
-+              error = -ENOATTR;
-+              if (flags & XATTR_REPLACE)
-+                      goto cleanup;
-+              error = 0;
-+              if (value == NULL)
-+                      goto cleanup;
-+              else
-+                      free -= EXT3_XATTR_LEN(name_len);
-+      } else {
-+              /* Request to create an existing attribute? */
-+              error = -EEXIST;
-+              if (flags & XATTR_CREATE)
-+                      goto cleanup;
-+              if (!here->e_value_block && here->e_value_size) {
-+                      unsigned int size = le32_to_cpu(here->e_value_size);
-+
-+                      if (le16_to_cpu(here->e_value_offs) + size > 
-+                          sb->s_blocksize || size > sb->s_blocksize)
-+                              goto bad_block;
-+                      free += EXT3_XATTR_SIZE(size);
-+              }
-+      }
-+      free -= EXT3_XATTR_SIZE(value_len);
-+      error = -ENOSPC;
-+      if (free < 0)
-+              goto cleanup;
-+
-+      /* Here we know that we can set the new attribute. */
-+
-+      if (header) {
-+              if (header->h_refcount == cpu_to_le32(1)) {
-+                      ea_bdebug(bh, "modifying in-place");
-+                      ext3_xattr_cache_remove(bh);
-+                      error = ext3_journal_get_write_access(handle, bh);
-+                      if (error)
-+                              goto cleanup;
-+              } else {
-+                      int offset;
-+
-+                      ea_bdebug(bh, "cloning");
-+                      header = kmalloc(bh->b_size, GFP_KERNEL);
-+                      error = -ENOMEM;
-+                      if (header == NULL)
-+                              goto cleanup;
-+                      memcpy(header, HDR(bh), bh->b_size);
-+                      header->h_refcount = cpu_to_le32(1);
-+                      offset = (char *)header - bh->b_data;
-+                      here = ENTRY((char *)here + offset);
-+                      last = ENTRY((char *)last + offset);
-+              }
-+      } else {
-+              /* Allocate a buffer where we construct the new block. */
-+              header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-+              error = -ENOMEM;
-+              if (header == NULL)
-+                      goto cleanup;
-+              memset(header, 0, sb->s_blocksize);
-+              end = (char *)header + sb->s_blocksize;
-+              header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
-+              header->h_blocks = header->h_refcount = cpu_to_le32(1);
-+              last = here = ENTRY(header+1);
-+      }
-+
-+      if (not_found) {
-+              /* Insert the new name. */
-+              int size = EXT3_XATTR_LEN(name_len);
-+              int rest = (char *)last - (char *)here;
-+              memmove((char *)here + size, here, rest);
-+              memset(here, 0, size);
-+              here->e_name_index = name_index;
-+              here->e_name_len = name_len;
-+              memcpy(here->e_name, name, name_len);
-+      } else {
-+              /* Remove the old value. */
-+              if (!here->e_value_block && here->e_value_size) {
-+                      char *first_val = (char *)header + min_offs;
-+                      int offs = le16_to_cpu(here->e_value_offs);
-+                      char *val = (char *)header + offs;
-+                      size_t size = EXT3_XATTR_SIZE(
-+                              le32_to_cpu(here->e_value_size));
-+                      memmove(first_val + size, first_val, val - first_val);
-+                      memset(first_val, 0, size);
-+                      here->e_value_offs = 0;
-+                      min_offs += size;
-+
-+                      /* Adjust all value offsets. */
-+                      last = ENTRY(header+1);
-+                      while (!IS_LAST_ENTRY(last)) {
-+                              int o = le16_to_cpu(last->e_value_offs);
-+                              if (!last->e_value_block && o < offs)
-+                                      last->e_value_offs =
-+                                              cpu_to_le16(o + size);
-+                              last = EXT3_XATTR_NEXT(last);
-+                      }
-+              }
-+              if (value == NULL) {
-+                      /* Remove this attribute. */
-+                      if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
-+                              /* This block is now empty. */
-+                              error = ext3_xattr_set2(handle, inode, bh,NULL);
-+                              goto cleanup;
-+                      } else {
-+                              /* Remove the old name. */
-+                              int size = EXT3_XATTR_LEN(name_len);
-+                              last = ENTRY((char *)last - size);
-+                              memmove(here, (char*)here + size,
-+                                      (char*)last - (char*)here);
-+                              memset(last, 0, size);
-+                      }
-+              }
-+      }
-+
-+      if (value != NULL) {
-+              /* Insert the new value. */
-+              here->e_value_size = cpu_to_le32(value_len);
-+              if (value_len) {
-+                      size_t size = EXT3_XATTR_SIZE(value_len);
-+                      char *val = (char *)header + min_offs - size;
-+                      here->e_value_offs =
-+                              cpu_to_le16((char *)val - (char *)header);
-+                      memset(val + size - EXT3_XATTR_PAD, 0,
-+                             EXT3_XATTR_PAD); /* Clear the pad bytes. */
-+                      memcpy(val, value, value_len);
-+              }
-+      }
-+      ext3_xattr_rehash(header, here);
-+
-+      error = ext3_xattr_set2(handle, inode, bh, header);
-+
-+cleanup:
-+      brelse(bh);
-+      if (!(bh && header == HDR(bh)))
-+              kfree(header);
-+      up(&ext3_xattr_sem);
-+
-+      return error;
-+}
-+
-+/*
-+ * Second half of ext3_xattr_set(): Update the file system.
-+ */
-+static int
-+ext3_xattr_set2(handle_t *handle, struct inode *inode,
-+              struct buffer_head *old_bh, struct ext3_xattr_header *header)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *new_bh = NULL;
-+      int error;
-+
-+      if (header) {
-+              new_bh = ext3_xattr_cache_find(inode, header);
-+              if (new_bh) {
-+                      /*
-+                       * We found an identical block in the cache.
-+                       * The old block will be released after updating
-+                       * the inode.
-+                       */
-+                      ea_bdebug(old_bh, "reusing block %ld",
-+                              new_bh->b_blocknr);
-+                      
-+                      error = -EDQUOT;
-+                      if (ext3_xattr_quota_alloc(inode, 1))
-+                              goto cleanup;
-+                      
-+                      error = ext3_journal_get_write_access(handle, new_bh);
-+                      if (error)
-+                              goto cleanup;
-+                      HDR(new_bh)->h_refcount = cpu_to_le32(
-+                              le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
-+                      ea_bdebug(new_bh, "refcount now=%d",
-+                              le32_to_cpu(HDR(new_bh)->h_refcount));
-+              } else if (old_bh && header == HDR(old_bh)) {
-+                      /* Keep this block. */
-+                      new_bh = old_bh;
-+                      ext3_xattr_cache_insert(new_bh);
-+              } else {
-+                      /* We need to allocate a new block */
-+                      int force = EXT3_I(inode)->i_file_acl != 0;
-+                      int block = ext3_xattr_new_block(handle, inode,
-+                                                       &error, force);
-+                      if (error)
-+                              goto cleanup;
-+                      ea_idebug(inode, "creating block %d", block);
-+
-+                      new_bh = sb_getblk(sb, block);
-+                      if (!new_bh) {
-+getblk_failed:                        ext3_xattr_free_block(handle, inode, block);
-+                              error = -EIO;
-+                              goto cleanup;
-+                      }
-+                      lock_buffer(new_bh);
-+                      error = ext3_journal_get_create_access(handle, new_bh);
-+                      if (error) {
-+                              unlock_buffer(new_bh);
-+                              goto getblk_failed;
-+                      }
-+                      memcpy(new_bh->b_data, header, new_bh->b_size);
-+                      mark_buffer_uptodate(new_bh, 1);
-+                      unlock_buffer(new_bh);
-+                      ext3_xattr_cache_insert(new_bh);
-+                      
-+                      ext3_xattr_update_super_block(handle, sb);
-+              }
-+              error = ext3_journal_dirty_metadata(handle, new_bh);
-+              if (error)
-+                      goto cleanup;
-+      }
-+
-+      /* Update the inode. */
-+      EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-+      inode->i_ctime = CURRENT_TIME;
-+      ext3_mark_inode_dirty(handle, inode);
-+      if (IS_SYNC(inode))
-+              handle->h_sync = 1;
-+
-+      error = 0;
-+      if (old_bh && old_bh != new_bh) {
-+              /*
-+               * If there was an old block, and we are not still using it,
-+               * we now release the old block.
-+              */
-+              unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
-+
-+              error = ext3_journal_get_write_access(handle, old_bh);
-+              if (error)
-+                      goto cleanup;
-+              if (refcount == 1) {
-+                      /* Free the old block. */
-+                      ea_bdebug(old_bh, "freeing");
-+                      ext3_xattr_free_block(handle, inode, old_bh->b_blocknr);
-+
-+                      /* ext3_forget() calls bforget() for us, but we
-+                         let our caller release old_bh, so we need to
-+                         duplicate the handle before. */
-+                      get_bh(old_bh);
-+                      ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
-+              } else {
-+                      /* Decrement the refcount only. */
-+                      refcount--;
-+                      HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
-+                      ext3_xattr_quota_free(inode);
-+                      ext3_journal_dirty_metadata(handle, old_bh);
-+                      ea_bdebug(old_bh, "refcount now=%d", refcount);
-+              }
-+      }
-+
-+cleanup:
-+      if (old_bh != new_bh)
-+              brelse(new_bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_delete_inode()
-+ *
-+ * Free extended attribute resources associated with this inode. This
-+ * is called immediately before an inode is freed.
-+ */
-+void
-+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
-+{
-+      struct buffer_head *bh;
-+      unsigned int block = EXT3_I(inode)->i_file_acl;
-+
-+      if (!block)
-+              return;
-+      down(&ext3_xattr_sem);
-+
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh) {
-+              ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
-+                      "inode %ld: block %d read error", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+              ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ext3_journal_get_write_access(handle, bh);
-+      ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+      if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-+              ext3_xattr_cache_remove(bh);
-+              ext3_xattr_free_block(handle, inode, block);
-+              ext3_forget(handle, 1, inode, bh, block);
-+              bh = NULL;
-+      } else {
-+              HDR(bh)->h_refcount = cpu_to_le32(
-+                      le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+              ext3_journal_dirty_metadata(handle, bh);
-+              if (IS_SYNC(inode))
-+                      handle->h_sync = 1;
-+              ext3_xattr_quota_free(inode);
-+      }
-+      EXT3_I(inode)->i_file_acl = 0;
-+
-+cleanup:
-+      brelse(bh);
-+      up(&ext3_xattr_sem);
-+}
-+
-+/*
-+ * ext3_xattr_put_super()
-+ *
-+ * This is called when a file system is unmounted.
-+ */
-+void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+      mb_cache_shrink(ext3_xattr_cache, sb->s_dev);
-+#endif
-+}
-+
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+
-+/*
-+ * ext3_xattr_cache_insert()
-+ *
-+ * Create a new entry in the extended attribute cache, and insert
-+ * it unless such an entry is already in the cache.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+static int
-+ext3_xattr_cache_insert(struct buffer_head *bh)
-+{
-+      __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
-+      struct mb_cache_entry *ce;
-+      int error;
-+
-+      ce = mb_cache_entry_alloc(ext3_xattr_cache);
-+      if (!ce)
-+              return -ENOMEM;
-+      error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
-+      if (error) {
-+              mb_cache_entry_free(ce);
-+              if (error == -EBUSY) {
-+                      ea_bdebug(bh, "already in cache (%d cache entries)",
-+                              atomic_read(&ext3_xattr_cache->c_entry_count));
-+                      error = 0;
-+              }
-+      } else {
-+              ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-+                        atomic_read(&ext3_xattr_cache->c_entry_count));
-+              mb_cache_entry_release(ce);
-+      }
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_cmp()
-+ *
-+ * Compare two extended attribute blocks for equality.
-+ *
-+ * Returns 0 if the blocks are equal, 1 if they differ, and
-+ * a negative error number on errors.
-+ */
-+static int
-+ext3_xattr_cmp(struct ext3_xattr_header *header1,
-+             struct ext3_xattr_header *header2)
-+{
-+      struct ext3_xattr_entry *entry1, *entry2;
-+
-+      entry1 = ENTRY(header1+1);
-+      entry2 = ENTRY(header2+1);
-+      while (!IS_LAST_ENTRY(entry1)) {
-+              if (IS_LAST_ENTRY(entry2))
-+                      return 1;
-+              if (entry1->e_hash != entry2->e_hash ||
-+                  entry1->e_name_len != entry2->e_name_len ||
-+                  entry1->e_value_size != entry2->e_value_size ||
-+                  memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
-+                      return 1;
-+              if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
-+                      return -EIO;
-+              if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
-+                         (char *)header2 + le16_to_cpu(entry2->e_value_offs),
-+                         le32_to_cpu(entry1->e_value_size)))
-+                      return 1;
-+
-+              entry1 = EXT3_XATTR_NEXT(entry1);
-+              entry2 = EXT3_XATTR_NEXT(entry2);
-+      }
-+      if (!IS_LAST_ENTRY(entry2))
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * ext3_xattr_cache_find()
-+ *
-+ * Find an identical extended attribute block.
-+ *
-+ * Returns a pointer to the block found, or NULL if such a block was
-+ * not found or an error occurred.
-+ */
-+static struct buffer_head *
-+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
-+{
-+      __u32 hash = le32_to_cpu(header->h_hash);
-+      struct mb_cache_entry *ce;
-+
-+      if (!header->h_hash)
-+              return NULL;  /* never share */
-+      ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
-+      ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash);
-+      while (ce) {
-+              struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
-+
-+              if (!bh) {
-+                      ext3_error(inode->i_sb, "ext3_xattr_cache_find",
-+                              "inode %ld: block %ld read error",
-+                              inode->i_ino, ce->e_block);
-+              } else if (le32_to_cpu(HDR(bh)->h_refcount) >
-+                         EXT3_XATTR_REFCOUNT_MAX) {
-+                      ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
-+                              le32_to_cpu(HDR(bh)->h_refcount),
-+                              EXT3_XATTR_REFCOUNT_MAX);
-+              } else if (!ext3_xattr_cmp(header, HDR(bh))) {
-+                      ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
-+                      mb_cache_entry_release(ce);
-+                      return bh;
-+              }
-+              brelse(bh);
-+              ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * ext3_xattr_cache_remove()
-+ *
-+ * Remove the cache entry of a block from the cache. Called when a
-+ * block becomes invalid.
-+ */
-+static void
-+ext3_xattr_cache_remove(struct buffer_head *bh)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr);
-+      if (ce) {
-+              ea_bdebug(bh, "removing (%d cache entries remaining)",
-+                        atomic_read(&ext3_xattr_cache->c_entry_count)-1);
-+              mb_cache_entry_free(ce);
-+      } else 
-+              ea_bdebug(bh, "no cache entry");
-+}
-+
-+#define NAME_HASH_SHIFT 5
-+#define VALUE_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_hash_entry()
-+ *
-+ * Compute the hash of an extended attribute.
-+ */
-+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
-+                                       struct ext3_xattr_entry *entry)
-+{
-+      __u32 hash = 0;
-+      char *name = entry->e_name;
-+      int n;
-+
-+      for (n=0; n < entry->e_name_len; n++) {
-+              hash = (hash << NAME_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
-+                     *name++;
-+      }
-+
-+      if (entry->e_value_block == 0 && entry->e_value_size != 0) {
-+              __u32 *value = (__u32 *)((char *)header +
-+                      le16_to_cpu(entry->e_value_offs));
-+              for (n = (le32_to_cpu(entry->e_value_size) +
-+                   EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
-+                      hash = (hash << VALUE_HASH_SHIFT) ^
-+                             (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
-+                             le32_to_cpu(*value++);
-+              }
-+      }
-+      entry->e_hash = cpu_to_le32(hash);
-+}
-+
-+#undef NAME_HASH_SHIFT
-+#undef VALUE_HASH_SHIFT
-+
-+#define BLOCK_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_rehash()
-+ *
-+ * Re-compute the extended attribute hash value after an entry has changed.
-+ */
-+static void ext3_xattr_rehash(struct ext3_xattr_header *header,
-+                            struct ext3_xattr_entry *entry)
-+{
-+      struct ext3_xattr_entry *here;
-+      __u32 hash = 0;
-+      
-+      ext3_xattr_hash_entry(header, entry);
-+      here = ENTRY(header+1);
-+      while (!IS_LAST_ENTRY(here)) {
-+              if (!here->e_hash) {
-+                      /* Block is not shared if an entry's hash value == 0 */
-+                      hash = 0;
-+                      break;
-+              }
-+              hash = (hash << BLOCK_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
-+                     le32_to_cpu(here->e_hash);
-+              here = EXT3_XATTR_NEXT(here);
-+      }
-+      header->h_hash = cpu_to_le32(hash);
-+}
-+
-+#undef BLOCK_HASH_SHIFT
-+
-+int __init
-+init_ext3_xattr(void)
-+{
-+      ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
-+              sizeof(struct mb_cache_entry) +
-+              sizeof(struct mb_cache_entry_index), 1, 61);
-+      if (!ext3_xattr_cache)
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+void
-+exit_ext3_xattr(void)
-+{
-+      if (ext3_xattr_cache)
-+              mb_cache_destroy(ext3_xattr_cache);
-+      ext3_xattr_cache = NULL;
-+}
-+
-+#else  /* CONFIG_EXT3_FS_XATTR_SHARING */
-+
-+int __init
-+init_ext3_xattr(void)
-+{
-+      return 0;
-+}
-+
-+void
-+exit_ext3_xattr(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
---- /dev/null  2003-01-30 18:24:37.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/ext3/xattr_user.c        2003-04-11 16:52:28.000000000 +0800
-@@ -0,0 +1,111 @@
-+/*
-+ * linux/fs/ext3/xattr_user.c
-+ * Handler for extended user attributes.
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/fs.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
-+
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+# include <linux/ext3_acl.h>
-+#endif
-+
-+#define XATTR_USER_PREFIX "user."
-+
-+static size_t
-+ext3_xattr_user_list(char *list, struct inode *inode,
-+                   const char *name, int name_len)
-+{
-+      const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
-+
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return 0;
-+
-+      if (list) {
-+              memcpy(list, XATTR_USER_PREFIX, prefix_len);
-+              memcpy(list+prefix_len, name, name_len);
-+              list[prefix_len + name_len] = '\0';
-+      }
-+      return prefix_len + name_len + 1;
-+}
-+
-+static int
-+ext3_xattr_user_get(struct inode *inode, const char *name,
-+                  void *buffer, size_t size)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+      error = ext3_permission_locked(inode, MAY_READ);
-+#else
-+      error = permission(inode, MAY_READ);
-+#endif
-+      if (error)
-+              return error;
-+
-+      return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name,
-+                            buffer, size);
-+}
-+
-+static int
-+ext3_xattr_user_set(struct inode *inode, const char *name,
-+                  const void *value, size_t size, int flags)
-+{
-+      handle_t *handle;
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+      if ( !S_ISREG(inode->i_mode) &&
-+          (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-+              return -EPERM;
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+      error = ext3_permission_locked(inode, MAY_WRITE);
-+#else
-+      error = permission(inode, MAY_WRITE);
-+#endif
-+      if (error)
-+              return error;
-+  
-+      handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
-+      if (IS_ERR(handle))
-+              return PTR_ERR(handle);
-+      error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name,
-+                             value, size, flags);
-+      ext3_journal_stop(handle, inode);
-+
-+      return error;
-+}
-+
-+struct ext3_xattr_handler ext3_xattr_user_handler = {
-+      prefix: XATTR_USER_PREFIX,
-+      list:   ext3_xattr_user_list,
-+      get:    ext3_xattr_user_get,
-+      set:    ext3_xattr_user_set,
-+};
-+
-+int __init
-+init_ext3_xattr_user(void)
-+{
-+      return ext3_xattr_register(EXT3_XATTR_INDEX_USER,
-+                                 &ext3_xattr_user_handler);
-+}
-+
-+void
-+exit_ext3_xattr_user(void)
-+{
-+      ext3_xattr_unregister(EXT3_XATTR_INDEX_USER,
-+                            &ext3_xattr_user_handler);
-+}
---- /dev/null  2003-01-30 18:24:37.000000000 +0800
-+++ linux-2.4.19-hppl-root/fs/mbcache.c        2003-04-11 16:52:33.000000000 +0800
-@@ -0,0 +1,648 @@
-+/*
-+ * linux/fs/mbcache.c
-+ * (C) 2001-2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+/*
-+ * Filesystem Meta Information Block Cache (mbcache)
-+ *
-+ * The mbcache caches blocks of block devices that need to be located
-+ * by their device/block number, as well as by other criteria (such
-+ * as the block's contents).
-+ *
-+ * There can only be one cache entry in a cache per device and block number.
-+ * Additional indexes need not be unique in this sense. The number of
-+ * additional indexes (=other criteria) can be hardwired at compile time
-+ * or specified at cache create time.
-+ *
-+ * Each cache entry is of fixed size. An entry may be `valid' or `invalid'
-+ * in the cache. A valid entry is in the main hash tables of the cache,
-+ * and may also be in the lru list. An invalid entry is not in any hashes
-+ * or lists.
-+ *
-+ * A valid cache entry is only in the lru list if no handles refer to it.
-+ * Invalid cache entries will be freed when the last handle to the cache
-+ * entry is released. Entries that cannot be freed immediately are put
-+ * back on the lru list.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+
-+#include <linux/fs.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/cache_def.h>
-+#include <linux/version.h>
-+#include <linux/init.h>
-+#include <linux/mbcache.h>
-+
-+
-+#ifdef MB_CACHE_DEBUG
-+# define mb_debug(f...) do { \
-+              printk(KERN_DEBUG f); \
-+              printk("\n"); \
-+      } while (0)
-+#define mb_assert(c) do { if (!(c)) \
-+              printk(KERN_ERR "assertion " #c " failed\n"); \
-+      } while(0)
-+#else
-+# define mb_debug(f...) do { } while(0)
-+# define mb_assert(c) do { } while(0)
-+#endif
-+#define mb_error(f...) do { \
-+              printk(KERN_ERR f); \
-+              printk("\n"); \
-+      } while(0)
-+              
-+MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
-+MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+EXPORT_SYMBOL(mb_cache_create);
-+EXPORT_SYMBOL(mb_cache_shrink);
-+EXPORT_SYMBOL(mb_cache_destroy);
-+EXPORT_SYMBOL(mb_cache_entry_alloc);
-+EXPORT_SYMBOL(mb_cache_entry_insert);
-+EXPORT_SYMBOL(mb_cache_entry_release);
-+EXPORT_SYMBOL(mb_cache_entry_takeout);
-+EXPORT_SYMBOL(mb_cache_entry_free);
-+EXPORT_SYMBOL(mb_cache_entry_dup);
-+EXPORT_SYMBOL(mb_cache_entry_get);
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+EXPORT_SYMBOL(mb_cache_entry_find_first);
-+EXPORT_SYMBOL(mb_cache_entry_find_next);
-+#endif
-+
-+
-+/*
-+ * Global data: list of all mbcache's, lru list, and a spinlock for
-+ * accessing cache data structures on SMP machines. The lru list is
-+ * global across all mbcaches.
-+ */
-+
-+static LIST_HEAD(mb_cache_list);
-+static LIST_HEAD(mb_cache_lru_list);
-+static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED;
-+
-+static inline int
-+mb_cache_indexes(struct mb_cache *cache)
-+{
-+#ifdef MB_CACHE_INDEXES_COUNT
-+      return MB_CACHE_INDEXES_COUNT;
-+#else
-+      return cache->c_indexes_count;
-+#endif
-+}
-+
-+/*
-+ * What the mbcache registers as to get shrunk dynamically.
-+ */
-+
-+static void
-+mb_cache_memory_pressure(int priority, unsigned int gfp_mask);
-+
-+static struct cache_definition mb_cache_definition = {
-+      "mb_cache",
-+      mb_cache_memory_pressure
-+};
-+
-+
-+static inline int
-+__mb_cache_entry_is_hashed(struct mb_cache_entry *ce)
-+{
-+      return !list_empty(&ce->e_block_list);
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_unhash(struct mb_cache_entry *ce)
-+{
-+      int n;
-+
-+      if (__mb_cache_entry_is_hashed(ce)) {
-+              list_del_init(&ce->e_block_list);
-+              for (n=0; n<mb_cache_indexes(ce->e_cache); n++)
-+                      list_del(&ce->e_indexes[n].o_list);
-+      }
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask)
-+{
-+      struct mb_cache *cache = ce->e_cache;
-+
-+      mb_assert(atomic_read(&ce->e_used) == 0);
-+      if (cache->c_op.free && cache->c_op.free(ce, gfp_mask)) {
-+              /* free failed -- put back on the lru list
-+                 for freeing later. */
-+              spin_lock(&mb_cache_spinlock);
-+              list_add(&ce->e_lru_list, &mb_cache_lru_list);
-+              spin_unlock(&mb_cache_spinlock);
-+      } else {
-+              kmem_cache_free(cache->c_entry_cache, ce);
-+              atomic_dec(&cache->c_entry_count);
-+      }
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
-+{
-+      if (atomic_dec_and_test(&ce->e_used)) {
-+              if (__mb_cache_entry_is_hashed(ce))
-+                      list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
-+              else {
-+                      spin_unlock(&mb_cache_spinlock);
-+                      __mb_cache_entry_forget(ce, GFP_KERNEL);
-+                      return;
-+              }
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+}
-+
-+
-+/*
-+ * mb_cache_memory_pressure()  memory pressure callback
-+ *
-+ * This function is called by the kernel memory management when memory
-+ * gets low.
-+ *
-+ * @priority: Amount by which to shrink the cache (0 = highes priority)
-+ * @gfp_mask: (ignored)
-+ */
-+static void
-+mb_cache_memory_pressure(int priority, unsigned int gfp_mask)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+      int count = 0;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &mb_cache_list) {
-+              struct mb_cache *cache =
-+                      list_entry(l, struct mb_cache, c_cache_list);
-+              mb_debug("cache %s (%d)", cache->c_name,
-+                        atomic_read(&cache->c_entry_count));
-+              count += atomic_read(&cache->c_entry_count);
-+      }
-+      mb_debug("trying to free %d of %d entries",
-+                count / (priority ? priority : 1), count);
-+      if (priority)
-+              count /= priority;
-+      while (count-- && !list_empty(&mb_cache_lru_list)) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(mb_cache_lru_list.next,
-+                                 struct mb_cache_entry, e_lru_list);
-+              list_del(&ce->e_lru_list);
-+              __mb_cache_entry_unhash(ce);
-+              list_add_tail(&ce->e_lru_list, &free_list);
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), gfp_mask);
-+      }
-+}
-+
-+
-+/*
-+ * mb_cache_create()  create a new cache
-+ *
-+ * All entries in one cache are equal size. Cache entries may be from
-+ * multiple devices. If this is the first mbcache created, registers
-+ * the cache with kernel memory management. Returns NULL if no more
-+ * memory was available.
-+ *
-+ * @name: name of the cache (informal)
-+ * @cache_op: contains the callback called when freeing a cache entry
-+ * @entry_size: The size of a cache entry, including
-+ *              struct mb_cache_entry
-+ * @indexes_count: number of additional indexes in the cache. Must equal
-+ *                 MB_CACHE_INDEXES_COUNT if the number of indexes is
-+ *                 hardwired.
-+ * @bucket_count: number of hash buckets
-+ */
-+struct mb_cache *
-+mb_cache_create(const char *name, struct mb_cache_op *cache_op,
-+              size_t entry_size, int indexes_count, int bucket_count)
-+{
-+      int m=0, n;
-+      struct mb_cache *cache = NULL;
-+
-+      if(entry_size < sizeof(struct mb_cache_entry) +
-+         indexes_count * sizeof(struct mb_cache_entry_index))
-+              return NULL;
-+
-+      MOD_INC_USE_COUNT;
-+      cache = kmalloc(sizeof(struct mb_cache) +
-+                      indexes_count * sizeof(struct list_head), GFP_KERNEL);
-+      if (!cache)
-+              goto fail;
-+      cache->c_name = name;
-+      cache->c_op.free = NULL;
-+      if (cache_op)
-+              cache->c_op.free = cache_op->free;
-+      atomic_set(&cache->c_entry_count, 0);
-+      cache->c_bucket_count = bucket_count;
-+#ifdef MB_CACHE_INDEXES_COUNT
-+      mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT);
-+#else
-+      cache->c_indexes_count = indexes_count;
-+#endif
-+      cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
-+                                    GFP_KERNEL);
-+      if (!cache->c_block_hash)
-+              goto fail;
-+      for (n=0; n<bucket_count; n++)
-+              INIT_LIST_HEAD(&cache->c_block_hash[n]);
-+      for (m=0; m<indexes_count; m++) {
-+              cache->c_indexes_hash[m] = kmalloc(bucket_count *
-+                                               sizeof(struct list_head),
-+                                               GFP_KERNEL);
-+              if (!cache->c_indexes_hash[m])
-+                      goto fail;
-+              for (n=0; n<bucket_count; n++)
-+                      INIT_LIST_HEAD(&cache->c_indexes_hash[m][n]);
-+      }
-+      cache->c_entry_cache = kmem_cache_create(name, entry_size, 0,
-+              0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL);
-+      if (!cache->c_entry_cache)
-+              goto fail;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_add(&cache->c_cache_list, &mb_cache_list);
-+      spin_unlock(&mb_cache_spinlock);
-+      return cache;
-+
-+fail:
-+      if (cache) {
-+              while (--m >= 0)
-+                      kfree(cache->c_indexes_hash[m]);
-+              if (cache->c_block_hash)
-+                      kfree(cache->c_block_hash);
-+              kfree(cache);
-+      }
-+      MOD_DEC_USE_COUNT;
-+      return NULL;
-+}
-+
-+
-+/*
-+ * mb_cache_shrink()
-+ *
-+ * Removes all cache entires of a device from the cache. All cache entries
-+ * currently in use cannot be freed, and thus remain in the cache.
-+ *
-+ * @cache: which cache to shrink
-+ * @dev: which device's cache entries to shrink
-+ */
-+void
-+mb_cache_shrink(struct mb_cache *cache, kdev_t dev)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              if (ce->e_dev == dev) {
-+                      list_del(&ce->e_lru_list);
-+                      list_add_tail(&ce->e_lru_list, &free_list);
-+                      __mb_cache_entry_unhash(ce);
-+              }
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), GFP_KERNEL);
-+      }
-+}
-+
-+
-+/*
-+ * mb_cache_destroy()
-+ *
-+ * Shrinks the cache to its minimum possible size (hopefully 0 entries),
-+ * and then destroys it. If this was the last mbcache, un-registers the
-+ * mbcache from kernel memory management.
-+ */
-+void
-+mb_cache_destroy(struct mb_cache *cache)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+      int n;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              if (ce->e_cache == cache) {
-+                      list_del(&ce->e_lru_list);
-+                      list_add_tail(&ce->e_lru_list, &free_list);
-+                      __mb_cache_entry_unhash(ce);
-+              }
-+      }
-+      list_del(&cache->c_cache_list);
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), GFP_KERNEL);
-+      }
-+
-+      if (atomic_read(&cache->c_entry_count) > 0) {
-+              mb_error("cache %s: %d orphaned entries",
-+                        cache->c_name,
-+                        atomic_read(&cache->c_entry_count));
-+      }
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-+      /* We don't have kmem_cache_destroy() in 2.2.x */
-+      kmem_cache_shrink(cache->c_entry_cache);
-+#else
-+      kmem_cache_destroy(cache->c_entry_cache);
-+#endif
-+      for (n=0; n < mb_cache_indexes(cache); n++)
-+              kfree(cache->c_indexes_hash[n]);
-+      kfree(cache->c_block_hash);
-+      kfree(cache);
-+
-+      MOD_DEC_USE_COUNT;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_alloc()
-+ *
-+ * Allocates a new cache entry. The new entry will not be valid initially,
-+ * and thus cannot be looked up yet. It should be filled with data, and
-+ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL
-+ * if no more memory was available.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_alloc(struct mb_cache *cache)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      atomic_inc(&cache->c_entry_count);
-+      ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
-+      if (ce) {
-+              INIT_LIST_HEAD(&ce->e_lru_list);
-+              INIT_LIST_HEAD(&ce->e_block_list);
-+              ce->e_cache = cache;
-+              atomic_set(&ce->e_used, 1);
-+      }
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_insert()
-+ *
-+ * Inserts an entry that was allocated using mb_cache_entry_alloc() into
-+ * the cache. After this, the cache entry can be looked up, but is not yet
-+ * in the lru list as the caller still holds a handle to it. Returns 0 on
-+ * success, or -EBUSY if a cache entry for that device + inode exists
-+ * already (this may happen after a failed lookup, if another process has
-+ * inserted the same cache entry in the meantime).
-+ *
-+ * @dev: device the cache entry belongs to
-+ * @block: block number
-+ * @keys: array of additional keys. There must be indexes_count entries
-+ *        in the array (as specified when creating the cache).
-+ */
-+int
-+mb_cache_entry_insert(struct mb_cache_entry *ce, kdev_t dev,
-+                    unsigned long block, unsigned int keys[])
-+{
-+      struct mb_cache *cache = ce->e_cache;
-+      unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
-+      struct list_head *l;
-+      int error = -EBUSY, n;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &cache->c_block_hash[bucket]) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_block_list);
-+              if (ce->e_dev == dev && ce->e_block == block)
-+                      goto out;
-+      }
-+      __mb_cache_entry_unhash(ce);
-+      ce->e_dev = dev;
-+      ce->e_block = block;
-+      list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
-+      for (n=0; n<mb_cache_indexes(cache); n++) {
-+              ce->e_indexes[n].o_key = keys[n];
-+              bucket = keys[n] % cache->c_bucket_count;
-+              list_add(&ce->e_indexes[n].o_list,
-+                       &cache->c_indexes_hash[n][bucket]);
-+      }
-+out:
-+      spin_unlock(&mb_cache_spinlock);
-+      return error;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_release()
-+ *
-+ * Release a handle to a cache entry. When the last handle to a cache entry
-+ * is released it is either freed (if it is invalid) or otherwise inserted
-+ * in to the lru list.
-+ */
-+void
-+mb_cache_entry_release(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      __mb_cache_entry_release_unlock(ce);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_takeout()
-+ *
-+ * Take a cache entry out of the cache, making it invalid. The entry can later
-+ * be re-inserted using mb_cache_entry_insert(), or released using
-+ * mb_cache_entry_release().
-+ */
-+void
-+mb_cache_entry_takeout(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      mb_assert(list_empty(&ce->e_lru_list));
-+      __mb_cache_entry_unhash(ce);
-+      spin_unlock(&mb_cache_spinlock);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_free()
-+ *
-+ * This is equivalent to the sequence mb_cache_entry_takeout() --
-+ * mb_cache_entry_release().
-+ */
-+void
-+mb_cache_entry_free(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      mb_assert(list_empty(&ce->e_lru_list));
-+      __mb_cache_entry_unhash(ce);
-+      __mb_cache_entry_release_unlock(ce);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_dup()
-+ *
-+ * Duplicate a handle to a cache entry (does not duplicate the cache entry
-+ * itself). After the call, both the old and the new handle must be released.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_dup(struct mb_cache_entry *ce)
-+{
-+      atomic_inc(&ce->e_used);
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_get()
-+ *
-+ * Get a cache entry  by device / block number. (There can only be one entry
-+ * in the cache per device and block.) Returns NULL if no such cache entry
-+ * exists.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_get(struct mb_cache *cache, kdev_t dev, unsigned long block)
-+{
-+      unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &cache->c_block_hash[bucket]) {
-+              ce = list_entry(l, struct mb_cache_entry, e_block_list);
-+              if (ce->e_dev == dev && ce->e_block == block) {
-+                      if (!list_empty(&ce->e_lru_list))
-+                              list_del_init(&ce->e_lru_list);
-+                      atomic_inc(&ce->e_used);
-+                      goto cleanup;
-+              }
-+      }
-+      ce = NULL;
-+
-+cleanup:
-+      spin_unlock(&mb_cache_spinlock);
-+      return ce;
-+}
-+
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+
-+static struct mb_cache_entry *
-+__mb_cache_entry_find(struct list_head *l, struct list_head *head,
-+                    int index, kdev_t dev, unsigned int key)
-+{
-+      while (l != head) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry,
-+                                 e_indexes[index].o_list);
-+              if (ce->e_dev == dev && ce->e_indexes[index].o_key == key) {
-+                      if (!list_empty(&ce->e_lru_list))
-+                              list_del_init(&ce->e_lru_list);
-+                      atomic_inc(&ce->e_used);
-+                      return ce;
-+              }
-+              l = l->next;
-+      }
-+      return NULL;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_find_first()
-+ *
-+ * Find the first cache entry on a given device with a certain key in
-+ * an additional index. Additonal matches can be found with
-+ * mb_cache_entry_find_next(). Returns NULL if no match was found.
-+ *
-+ * @cache: the cache to search
-+ * @index: the number of the additonal index to search (0<=index<indexes_count)
-+ * @dev: the device the cache entry should belong to
-+ * @key: the key in the index
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_find_first(struct mb_cache *cache, int index, kdev_t dev,
-+                        unsigned int key)
-+{
-+      unsigned int bucket = key % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      mb_assert(index < mb_cache_indexes(cache));
-+      spin_lock(&mb_cache_spinlock);
-+      l = cache->c_indexes_hash[index][bucket].next;
-+      ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
-+                                 index, dev, key);
-+      spin_unlock(&mb_cache_spinlock);
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_find_next()
-+ *
-+ * Find the next cache entry on a given device with a certain key in an
-+ * additional index. Returns NULL if no match could be found. The previous
-+ * entry is atomatically released, so that mb_cache_entry_find_next() can
-+ * be called like this:
-+ *
-+ * entry = mb_cache_entry_find_first();
-+ * while (entry) {
-+ *    ...
-+ *    entry = mb_cache_entry_find_next(entry, ...);
-+ * }
-+ *
-+ * @prev: The previous match
-+ * @index: the number of the additonal index to search (0<=index<indexes_count)
-+ * @dev: the device the cache entry should belong to
-+ * @key: the key in the index
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_find_next(struct mb_cache_entry *prev, int index, kdev_t dev,
-+                       unsigned int key)
-+{
-+      struct mb_cache *cache = prev->e_cache;
-+      unsigned int bucket = key % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      mb_assert(index < mb_cache_indexes(cache));
-+      spin_lock(&mb_cache_spinlock);
-+      l = prev->e_indexes[index].o_list.next;
-+      ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
-+                                 index, dev, key);
-+      __mb_cache_entry_release_unlock(prev);
-+      return ce;
-+}
-+
-+#endif  /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */
-+
-+static int __init init_mbcache(void)
-+{
-+      register_cache(&mb_cache_definition);
-+      return 0;
-+}
-+
-+static void __exit exit_mbcache(void)
-+{
-+      unregister_cache(&mb_cache_definition);
-+}
-+
-+module_init(init_mbcache)
-+module_exit(exit_mbcache)
-+
---- linux-2.4.19-hppl/include/asm-arm/unistd.h~linux-2.4.20-xattr-0.8.54-hp_chaos      2002-08-03 08:39:45.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/asm-arm/unistd.h    2003-04-11 16:52:33.000000000 +0800
-@@ -244,7 +244,6 @@
- #define __NR_security                 (__NR_SYSCALL_BASE+223)
- #define __NR_gettid                   (__NR_SYSCALL_BASE+224)
- #define __NR_readahead                        (__NR_SYSCALL_BASE+225)
--#if 0 /* allocated in 2.5 */
- #define __NR_setxattr                 (__NR_SYSCALL_BASE+226)
- #define __NR_lsetxattr                        (__NR_SYSCALL_BASE+227)
- #define __NR_fsetxattr                        (__NR_SYSCALL_BASE+228)
-@@ -257,7 +256,6 @@
- #define __NR_removexattr              (__NR_SYSCALL_BASE+235)
- #define __NR_lremovexattr             (__NR_SYSCALL_BASE+236)
- #define __NR_fremovexattr             (__NR_SYSCALL_BASE+237)
--#endif
- #define __NR_tkill                    (__NR_SYSCALL_BASE+238)
- /*
-  * Please check 2.5 _before_ adding calls here,
---- linux-2.4.19-hppl/include/asm-ppc64/unistd.h~linux-2.4.20-xattr-0.8.54-hp_chaos    2002-08-03 08:39:45.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/asm-ppc64/unistd.h  2003-04-11 16:52:33.000000000 +0800
-@@ -218,6 +218,7 @@
- #define __NR_gettid           207
- #if 0 /* Reserved syscalls */
- #define __NR_tkill            208
-+#endif
- #define __NR_setxattr         209
- #define __NR_lsetxattr                210
- #define __NR_fsetxattr                211
-@@ -230,6 +231,7 @@
- #define __NR_removexattr      218
- #define __NR_lremovexattr     219
- #define __NR_fremovexattr     220
-+#if 0 /* Reserved syscalls */
- #define __NR_futex            221
- #endif
---- linux-2.4.19-hppl/include/asm-s390/unistd.h~linux-2.4.20-xattr-0.8.54-hp_chaos     2002-08-03 08:39:45.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/asm-s390/unistd.h   2003-04-11 16:52:33.000000000 +0800
-@@ -212,9 +212,18 @@
- #define __NR_madvise            219
- #define __NR_getdents64               220
- #define __NR_fcntl64          221
--/*
-- * Numbers 224-235 are reserved for posix acl
-- */
-+#define __NR_setxattr         224
-+#define __NR_lsetxattr                225
-+#define __NR_fsetxattr                226
-+#define __NR_getxattr         227
-+#define __NR_lgetxattr                228
-+#define __NR_fgetxattr                229
-+#define __NR_listxattr                230
-+#define __NR_llistxattr               231
-+#define __NR_flistxattr               232
-+#define __NR_removexattr      233
-+#define __NR_lremovexattr     234
-+#define __NR_fremovexattr     235
- #define __NR_gettid           236
- #define __NR_tkill            237
---- linux-2.4.19-hppl/include/asm-s390x/unistd.h~linux-2.4.20-xattr-0.8.54-hp_chaos    2002-08-03 08:39:45.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/asm-s390x/unistd.h  2003-04-11 16:52:33.000000000 +0800
-@@ -180,9 +180,18 @@
- #define __NR_pivot_root         217
- #define __NR_mincore            218
- #define __NR_madvise            219
--/*
-- * Numbers 224-235 are reserved for posix acl
-- */
-+#define __NR_setxattr         224
-+#define __NR_lsetxattr                225
-+#define __NR_fsetxattr                226
-+#define __NR_getxattr         227
-+#define __NR_lgetxattr                228
-+#define __NR_fgetxattr                229
-+#define __NR_listxattr                230
-+#define __NR_llistxattr               231
-+#define __NR_flistxattr               232
-+#define __NR_removexattr      233
-+#define __NR_lremovexattr     234
-+#define __NR_fremovexattr     235
- #define __NR_gettid           236
- #define __NR_tkill            237
---- linux-2.4.19-hppl/include/asm-sparc/unistd.h~linux-2.4.20-xattr-0.8.54-hp_chaos    2002-08-03 08:39:45.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/asm-sparc/unistd.h  2003-04-11 16:52:33.000000000 +0800
-@@ -184,24 +184,24 @@
- /* #define __NR_exportfs        166    SunOS Specific                              */
- #define __NR_mount              167 /* Common                                      */
- #define __NR_ustat              168 /* Common                                      */
--/* #define __NR_semsys          169    SunOS Specific                              */
--/* #define __NR_msgsys          170    SunOS Specific                              */
--/* #define __NR_shmsys          171    SunOS Specific                              */
--/* #define __NR_auditsys        172    SunOS Specific                              */
--/* #define __NR_rfssys          173    SunOS Specific                              */
-+#define __NR_setxattr           169 /* SunOS: semsys                               */
-+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-+#define __NR_getxattr           172 /* SunOS: auditsys                             */
-+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
- #define __NR_getdents           174 /* Common                                      */
- #define __NR_setsid             175 /* Common                                      */
- #define __NR_fchdir             176 /* Common                                      */
--/* #define __NR_fchroot         177    SunOS Specific                              */
--/* #define __NR_vpixsys         178    SunOS Specific                              */
--/* #define __NR_aioread         179    SunOS Specific                              */
--/* #define __NR_aiowrite        180    SunOS Specific                              */
--/* #define __NR_aiowait         181    SunOS Specific                              */
--/* #define __NR_aiocancel       182    SunOS Specific                              */
-+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-+#define __NR_llistxattr         179 /* SunOS: aioread                              */
-+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-+#define __NR_removexattr        181 /* SunOS: aiowait                              */
-+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
- #define __NR_sigpending         183 /* Common                                      */
- #define __NR_query_module     184 /* Linux Specific                              */
- #define __NR_setpgid            185 /* Common                                      */
--/* #define __NR_pathconf        186    SunOS Specific                              */
-+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
- #define __NR_tkill              187 /* SunOS: fpathconf                            */
- /* #define __NR_sysconf         188    SunOS Specific                              */
- #define __NR_uname              189 /* Linux Specific                              */
---- linux-2.4.19-hppl/include/asm-sparc64/unistd.h~linux-2.4.20-xattr-0.8.54-hp_chaos  2002-08-03 08:39:45.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/asm-sparc64/unistd.h        2003-04-11 16:52:33.000000000 +0800
-@@ -184,24 +184,24 @@
- /* #define __NR_exportfs        166    SunOS Specific                              */
- #define __NR_mount              167 /* Common                                      */
- #define __NR_ustat              168 /* Common                                      */
--/* #define __NR_semsys          169    SunOS Specific                              */
--/* #define __NR_msgsys          170    SunOS Specific                              */
--/* #define __NR_shmsys          171    SunOS Specific                              */
--/* #define __NR_auditsys        172    SunOS Specific                              */
--/* #define __NR_rfssys          173    SunOS Specific                              */
-+#define __NR_setxattr           169 /* SunOS: semsys                               */
-+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-+#define __NR_getxattr           172 /* SunOS: auditsys                             */
-+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
- #define __NR_getdents           174 /* Common                                      */
- #define __NR_setsid             175 /* Common                                      */
- #define __NR_fchdir             176 /* Common                                      */
--/* #define __NR_fchroot         177    SunOS Specific                              */
--/* #define __NR_vpixsys         178    SunOS Specific                              */
--/* #define __NR_aioread         179    SunOS Specific                              */
--/* #define __NR_aiowrite        180    SunOS Specific                              */
--/* #define __NR_aiowait         181    SunOS Specific                              */
--/* #define __NR_aiocancel       182    SunOS Specific                              */
-+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-+#define __NR_llistxattr         179 /* SunOS: aioread                              */
-+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-+#define __NR_removexattr        181 /* SunOS: aiowait                              */
-+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
- #define __NR_sigpending         183 /* Common                                      */
- #define __NR_query_module     184 /* Linux Specific                              */
- #define __NR_setpgid            185 /* Common                                      */
--/* #define __NR_pathconf        186    SunOS Specific                              */
-+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
- #define __NR_tkill              187 /* SunOS: fpathconf                            */
- /* #define __NR_sysconf         188    SunOS Specific                              */
- #define __NR_uname              189 /* Linux Specific                              */
---- /dev/null  2003-01-30 18:24:37.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/linux/cache_def.h   2003-04-11 16:52:33.000000000 +0800
-@@ -0,0 +1,15 @@
-+/*
-+ * linux/cache_def.h
-+ * Handling of caches defined in drivers, filesystems, ...
-+ *
-+ * Copyright (C) 2002 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+struct cache_definition {
-+      const char *name;
-+      void (*shrink)(int, unsigned int);
-+      struct list_head link;
-+};
-+
-+extern void register_cache(struct cache_definition *);
-+extern void unregister_cache(struct cache_definition *);
---- linux-2.4.19-hppl/include/linux/errno.h~linux-2.4.20-xattr-0.8.54-hp_chaos 2001-02-10 06:46:13.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/linux/errno.h       2003-04-11 16:52:33.000000000 +0800
-@@ -23,4 +23,8 @@
- #endif
-+/* Defined for extended attributes */
-+#define ENOATTR ENODATA               /* No such attribute */
-+#define ENOTSUP EOPNOTSUPP    /* Operation not supported */
-+
- #endif
---- linux-2.4.19-hppl/include/linux/ext2_fs.h~linux-2.4.20-xattr-0.8.54-hp_chaos       2001-11-23 03:46:52.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/linux/ext2_fs.h     2003-04-11 16:52:33.000000000 +0800
-@@ -57,8 +57,6 @@
-  */
- #define       EXT2_BAD_INO             1      /* Bad blocks inode */
- #define EXT2_ROOT_INO          2      /* Root inode */
--#define EXT2_ACL_IDX_INO       3      /* ACL inode */
--#define EXT2_ACL_DATA_INO      4      /* ACL inode */
- #define EXT2_BOOT_LOADER_INO   5      /* Boot loader inode */
- #define EXT2_UNDEL_DIR_INO     6      /* Undelete directory inode */
-@@ -86,7 +84,6 @@
- #else
- # define EXT2_BLOCK_SIZE(s)           (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
- #endif
--#define EXT2_ACLE_PER_BLOCK(s)                (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
- #define       EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
- #ifdef __KERNEL__
- # define EXT2_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
-@@ -121,28 +118,6 @@
- #endif
- /*
-- * ACL structures
-- */
--struct ext2_acl_header        /* Header of Access Control Lists */
--{
--      __u32   aclh_size;
--      __u32   aclh_file_count;
--      __u32   aclh_acle_count;
--      __u32   aclh_first_acle;
--};
--
--struct ext2_acl_entry /* Access Control List Entry */
--{
--      __u32   acle_size;
--      __u16   acle_perms;     /* Access permissions */
--      __u16   acle_type;      /* Type of entry */
--      __u16   acle_tag;       /* User or group identity */
--      __u16   acle_pad1;
--      __u32   acle_next;      /* Pointer on next entry for the */
--                                      /* same inode or on next free entry */
--};
--
--/*
-  * Structure of a blocks group descriptor
-  */
- struct ext2_group_desc
-@@ -314,6 +289,7 @@ struct ext2_inode {
- #define EXT2_MOUNT_ERRORS_PANIC               0x0040  /* Panic on errors */
- #define EXT2_MOUNT_MINIX_DF           0x0080  /* Mimics the Minix statfs */
- #define EXT2_MOUNT_NO_UID32           0x0200  /* Disable 32-bit UIDs */
-+#define EXT2_MOUNT_XATTR_USER         0x4000  /* Extended user attributes */
- #define clear_opt(o, opt)             o &= ~EXT2_MOUNT_##opt
- #define set_opt(o, opt)                       o |= EXT2_MOUNT_##opt
-@@ -397,6 +373,7 @@ struct ext2_super_block {
- #ifdef __KERNEL__
- #define EXT2_SB(sb)   (&((sb)->u.ext2_sb))
-+#define EXT2_I(inode) (&((inode)->u.ext2_i))
- #else
- /* Assume that user mode programs are passing in an ext2fs superblock, not
-  * a kernel struct super_block.  This will allow us to call the feature-test
-@@ -466,7 +443,7 @@ struct ext2_super_block {
- #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008
- #define EXT2_FEATURE_INCOMPAT_ANY             0xffffffff
--#define EXT2_FEATURE_COMPAT_SUPP      0
-+#define EXT2_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
- #define EXT2_FEATURE_INCOMPAT_SUPP    EXT2_FEATURE_INCOMPAT_FILETYPE
- #define EXT2_FEATURE_RO_COMPAT_SUPP   (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-                                        EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
-@@ -623,8 +600,10 @@ extern struct address_space_operations e
- /* namei.c */
- extern struct inode_operations ext2_dir_inode_operations;
-+extern struct inode_operations ext2_special_inode_operations;
- /* symlink.c */
-+extern struct inode_operations ext2_symlink_inode_operations;
- extern struct inode_operations ext2_fast_symlink_inode_operations;
- #endif        /* __KERNEL__ */
---- /dev/null  2003-01-30 18:24:37.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/linux/ext2_xattr.h  2003-04-11 16:52:33.000000000 +0800
-@@ -0,0 +1,157 @@
-+/*
-+  File: linux/ext2_xattr.h
-+
-+  On-disk format of extended attributes for the ext2 filesystem.
-+
-+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/xattr.h>
-+
-+/* Magic value in attribute blocks */
-+#define EXT2_XATTR_MAGIC              0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT2_XATTR_REFCOUNT_MAX               1024
-+
-+/* Name indexes */
-+#define EXT2_XATTR_INDEX_MAX                  10
-+#define EXT2_XATTR_INDEX_USER                 1
-+#define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS     2
-+#define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT    3
-+
-+struct ext2_xattr_header {
-+      __u32   h_magic;        /* magic number for identification */
-+      __u32   h_refcount;     /* reference count */
-+      __u32   h_blocks;       /* number of disk blocks used */
-+      __u32   h_hash;         /* hash value of all attributes */
-+      __u32   h_reserved[4];  /* zero right now */
-+};
-+
-+struct ext2_xattr_entry {
-+      __u8    e_name_len;     /* length of name */
-+      __u8    e_name_index;   /* attribute name index */
-+      __u16   e_value_offs;   /* offset in disk block of value */
-+      __u32   e_value_block;  /* disk block attribute is stored on (n/i) */
-+      __u32   e_value_size;   /* size of attribute value */
-+      __u32   e_hash;         /* hash value of name and value */
-+      char    e_name[0];      /* attribute name */
-+};
-+
-+#define EXT2_XATTR_PAD_BITS           2
-+#define EXT2_XATTR_PAD                (1<<EXT2_XATTR_PAD_BITS)
-+#define EXT2_XATTR_ROUND              (EXT2_XATTR_PAD-1)
-+#define EXT2_XATTR_LEN(name_len) \
-+      (((name_len) + EXT2_XATTR_ROUND + \
-+      sizeof(struct ext2_xattr_entry)) & ~EXT2_XATTR_ROUND)
-+#define EXT2_XATTR_NEXT(entry) \
-+      ( (struct ext2_xattr_entry *)( \
-+        (char *)(entry) + EXT2_XATTR_LEN((entry)->e_name_len)) )
-+#define EXT2_XATTR_SIZE(size) \
-+      (((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)
-+
-+#ifdef __KERNEL__
-+
-+# ifdef CONFIG_EXT2_FS_XATTR
-+
-+struct ext2_xattr_handler {
-+      char *prefix;
-+      size_t (*list)(char *list, struct inode *inode, const char *name,
-+                     int name_len);
-+      int (*get)(struct inode *inode, const char *name, void *buffer,
-+                 size_t size);
-+      int (*set)(struct inode *inode, const char *name, const void *buffer,
-+                 size_t size, int flags);
-+};
-+
-+extern int ext2_xattr_register(int, struct ext2_xattr_handler *);
-+extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *);
-+
-+extern int ext2_setxattr(struct dentry *, const char *, const void *, size_t, int);
-+extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t);
-+extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
-+extern int ext2_removexattr(struct dentry *, const char *);
-+
-+extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
-+extern int ext2_xattr_list(struct inode *, char *, size_t);
-+extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
-+
-+extern void ext2_xattr_delete_inode(struct inode *);
-+extern void ext2_xattr_put_super(struct super_block *);
-+
-+extern int init_ext2_xattr(void) __init;
-+extern void exit_ext2_xattr(void);
-+
-+# else  /* CONFIG_EXT2_FS_XATTR */
-+#  define ext2_setxattr               NULL
-+#  define ext2_getxattr               NULL
-+#  define ext2_listxattr      NULL
-+#  define ext2_removexattr    NULL
-+
-+static inline int
-+ext2_xattr_get(struct inode *inode, int name_index,
-+             const char *name, void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext2_xattr_list(struct inode *inode, char *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext2_xattr_set(struct inode *inode, int name_index, const char *name,
-+             const void *value, size_t size, int flags)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline void
-+ext2_xattr_delete_inode(struct inode *inode)
-+{
-+}
-+
-+static inline void
-+ext2_xattr_put_super(struct super_block *sb)
-+{
-+}
-+
-+static inline int
-+init_ext2_xattr(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext2_xattr(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT2_FS_XATTR */
-+
-+# ifdef CONFIG_EXT2_FS_XATTR_USER
-+
-+extern int init_ext2_xattr_user(void) __init;
-+extern void exit_ext2_xattr_user(void);
-+
-+# else  /* CONFIG_EXT2_FS_XATTR_USER */
-+
-+static inline int
-+init_ext2_xattr_user(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext2_xattr_user(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT2_FS_XATTR_USER */
-+
-+#endif  /* __KERNEL__ */
-+
---- linux-2.4.19-hppl/include/linux/ext3_fs.h~linux-2.4.20-xattr-0.8.54-hp_chaos       2003-04-11 16:51:05.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/linux/ext3_fs.h     2003-04-11 16:52:33.000000000 +0800
-@@ -63,8 +63,6 @@
-  */
- #define       EXT3_BAD_INO             1      /* Bad blocks inode */
- #define EXT3_ROOT_INO          2      /* Root inode */
--#define EXT3_ACL_IDX_INO       3      /* ACL inode */
--#define EXT3_ACL_DATA_INO      4      /* ACL inode */
- #define EXT3_BOOT_LOADER_INO   5      /* Boot loader inode */
- #define EXT3_UNDEL_DIR_INO     6      /* Undelete directory inode */
- #define EXT3_RESIZE_INO                7      /* Reserved group descriptors inode */
-@@ -94,7 +92,6 @@
- #else
- # define EXT3_BLOCK_SIZE(s)           (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
- #endif
--#define EXT3_ACLE_PER_BLOCK(s)                (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
- #define       EXT3_ADDR_PER_BLOCK(s)          (EXT3_BLOCK_SIZE(s) / sizeof (__u32))
- #ifdef __KERNEL__
- # define EXT3_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
-@@ -129,28 +126,6 @@
- #endif
- /*
-- * ACL structures
-- */
--struct ext3_acl_header        /* Header of Access Control Lists */
--{
--      __u32   aclh_size;
--      __u32   aclh_file_count;
--      __u32   aclh_acle_count;
--      __u32   aclh_first_acle;
--};
--
--struct ext3_acl_entry /* Access Control List Entry */
--{
--      __u32   acle_size;
--      __u16   acle_perms;     /* Access permissions */
--      __u16   acle_type;      /* Type of entry */
--      __u16   acle_tag;       /* User or group identity */
--      __u16   acle_pad1;
--      __u32   acle_next;      /* Pointer on next entry for the */
--                                      /* same inode or on next free entry */
--};
--
--/*
-  * Structure of a blocks group descriptor
-  */
- struct ext3_group_desc
-@@ -344,6 +319,7 @@ struct ext3_inode {
-   #define EXT3_MOUNT_WRITEBACK_DATA   0x0C00  /* No data ordering */
- #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
-@@ -520,7 +496,7 @@ struct ext3_super_block {
- #define EXT3_FEATURE_INCOMPAT_RECOVER         0x0004 /* Needs recovery */
- #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008 /* Journal device */
--#define EXT3_FEATURE_COMPAT_SUPP      0
-+#define EXT3_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
- #define EXT3_FEATURE_INCOMPAT_SUPP    (EXT3_FEATURE_INCOMPAT_FILETYPE| \
-                                        EXT3_FEATURE_INCOMPAT_RECOVER)
- #define EXT3_FEATURE_RO_COMPAT_SUPP   (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-@@ -703,6 +679,7 @@ extern void ext3_check_inodes_bitmap (st
- extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
- /* inode.c */
-+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
-@@ -771,8 +748,10 @@ extern struct address_space_operations e
- /* namei.c */
- extern struct inode_operations ext3_dir_inode_operations;
-+extern struct inode_operations ext3_special_inode_operations;
- /* symlink.c */
-+extern struct inode_operations ext3_symlink_inode_operations;
- extern struct inode_operations ext3_fast_symlink_inode_operations;
---- /dev/null  2003-01-30 18:24:37.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/linux/ext3_xattr.h  2003-04-11 16:52:36.000000000 +0800
-@@ -0,0 +1,157 @@
-+/*
-+  File: linux/ext3_xattr.h
-+
-+  On-disk format of extended attributes for the ext3 filesystem.
-+
-+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/xattr.h>
-+
-+/* Magic value in attribute blocks */
-+#define EXT3_XATTR_MAGIC              0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT3_XATTR_REFCOUNT_MAX               1024
-+
-+/* Name indexes */
-+#define EXT3_XATTR_INDEX_MAX                  10
-+#define EXT3_XATTR_INDEX_USER                 1
-+#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS     2
-+#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT    3
-+
-+struct ext3_xattr_header {
-+      __u32   h_magic;        /* magic number for identification */
-+      __u32   h_refcount;     /* reference count */
-+      __u32   h_blocks;       /* number of disk blocks used */
-+      __u32   h_hash;         /* hash value of all attributes */
-+      __u32   h_reserved[4];  /* zero right now */
-+};
-+
-+struct ext3_xattr_entry {
-+      __u8    e_name_len;     /* length of name */
-+      __u8    e_name_index;   /* attribute name index */
-+      __u16   e_value_offs;   /* offset in disk block of value */
-+      __u32   e_value_block;  /* disk block attribute is stored on (n/i) */
-+      __u32   e_value_size;   /* size of attribute value */
-+      __u32   e_hash;         /* hash value of name and value */
-+      char    e_name[0];      /* attribute name */
-+};
-+
-+#define EXT3_XATTR_PAD_BITS           2
-+#define EXT3_XATTR_PAD                (1<<EXT3_XATTR_PAD_BITS)
-+#define EXT3_XATTR_ROUND              (EXT3_XATTR_PAD-1)
-+#define EXT3_XATTR_LEN(name_len) \
-+      (((name_len) + EXT3_XATTR_ROUND + \
-+      sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
-+#define EXT3_XATTR_NEXT(entry) \
-+      ( (struct ext3_xattr_entry *)( \
-+        (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
-+#define EXT3_XATTR_SIZE(size) \
-+      (((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
-+
-+#ifdef __KERNEL__
-+
-+# ifdef CONFIG_EXT3_FS_XATTR
-+
-+struct ext3_xattr_handler {
-+      char *prefix;
-+      size_t (*list)(char *list, struct inode *inode, const char *name,
-+                     int name_len);
-+      int (*get)(struct inode *inode, const char *name, void *buffer,
-+                 size_t size);
-+      int (*set)(struct inode *inode, const char *name, const void *buffer,
-+                 size_t size, int flags);
-+};
-+
-+extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
-+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
-+
-+extern int ext3_setxattr(struct dentry *, const char *, const void *, size_t, int);
-+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
-+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
-+extern int ext3_removexattr(struct dentry *, const char *);
-+
-+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
-+extern int ext3_xattr_list(struct inode *, char *, size_t);
-+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
-+
-+extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
-+extern void ext3_xattr_put_super(struct super_block *);
-+
-+extern int init_ext3_xattr(void) __init;
-+extern void exit_ext3_xattr(void);
-+
-+# else  /* CONFIG_EXT3_FS_XATTR */
-+#  define ext3_setxattr               NULL
-+#  define ext3_getxattr               NULL
-+#  define ext3_listxattr      NULL
-+#  define ext3_removexattr    NULL
-+
-+static inline int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, const void *value, size_t size, int flags)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline void
-+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
-+{
-+}
-+
-+static inline void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+}
-+
-+static inline int
-+init_ext3_xattr(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext3_xattr(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT3_FS_XATTR */
-+
-+# ifdef CONFIG_EXT3_FS_XATTR_USER
-+
-+extern int init_ext3_xattr_user(void) __init;
-+extern void exit_ext3_xattr_user(void);
-+
-+# else  /* CONFIG_EXT3_FS_XATTR_USER */
-+
-+static inline int
-+init_ext3_xattr_user(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext3_xattr_user(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT3_FS_XATTR_USER */
-+
-+#endif  /* __KERNEL__ */
-+
---- linux-2.4.19-hppl/include/linux/fs.h~linux-2.4.20-xattr-0.8.54-hp_chaos    2003-04-11 16:49:47.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/linux/fs.h  2003-04-11 16:52:36.000000000 +0800
-@@ -909,7 +909,7 @@ struct inode_operations {
-       int (*setattr) (struct dentry *, struct iattr *);
-       int (*setattr_raw) (struct inode *, struct iattr *);
-       int (*getattr) (struct dentry *, struct iattr *);
--      int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
-+      int (*setxattr) (struct dentry *, const char *, const void *, size_t, int);
-       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-       ssize_t (*listxattr) (struct dentry *, char *, size_t);
-       int (*removexattr) (struct dentry *, const char *);
---- /dev/null  2003-01-30 18:24:37.000000000 +0800
-+++ linux-2.4.19-hppl-root/include/linux/mbcache.h     2003-04-11 16:52:36.000000000 +0800
-@@ -0,0 +1,69 @@
-+/*
-+  File: linux/mbcache.h
-+
-+  (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+/* Hardwire the number of additional indexes */
-+#define MB_CACHE_INDEXES_COUNT 1
-+
-+struct mb_cache_entry;
-+
-+struct mb_cache_op {
-+      int (*free)(struct mb_cache_entry *, int);
-+};
-+
-+struct mb_cache {
-+      struct list_head                c_cache_list;
-+      const char                      *c_name;
-+      struct mb_cache_op              c_op;
-+      atomic_t                        c_entry_count;
-+      int                             c_bucket_count;
-+#ifndef MB_CACHE_INDEXES_COUNT
-+      int                             c_indexes_count;
-+#endif
-+      kmem_cache_t                    *c_entry_cache;
-+      struct list_head                *c_block_hash;
-+      struct list_head                *c_indexes_hash[0];
-+};
-+
-+struct mb_cache_entry_index {
-+      struct list_head                o_list;
-+      unsigned int                    o_key;
-+};
-+
-+struct mb_cache_entry {
-+      struct list_head                e_lru_list;
-+      struct mb_cache                 *e_cache;
-+      atomic_t                        e_used;
-+      kdev_t                          e_dev;
-+      unsigned long                   e_block;
-+      struct list_head                e_block_list;
-+      struct mb_cache_entry_index     e_indexes[0];
-+};
-+
-+/* Functions on caches */
-+
-+struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t,
-+                                int, int);
-+void mb_cache_shrink(struct mb_cache *, kdev_t);
-+void mb_cache_destroy(struct mb_cache *);
-+
-+/* Functions on cache entries */
-+
-+struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
-+int mb_cache_entry_insert(struct mb_cache_entry *, kdev_t, unsigned long,
-+                        unsigned int[]);
-+void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
-+void mb_cache_entry_release(struct mb_cache_entry *);
-+void mb_cache_entry_takeout(struct mb_cache_entry *);
-+void mb_cache_entry_free(struct mb_cache_entry *);
-+struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *);
-+struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, kdev_t,
-+                                        unsigned long);
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int,
-+                                               kdev_t, unsigned int);
-+struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int,
-+                                              kdev_t, unsigned int);
-+#endif
---- linux-2.4.19-hppl/kernel/ksyms.c~linux-2.4.20-xattr-0.8.54-hp_chaos        2003-04-11 16:49:43.000000000 +0800
-+++ linux-2.4.19-hppl-root/kernel/ksyms.c      2003-04-11 16:52:36.000000000 +0800
-@@ -11,6 +11,7 @@
- #include <linux/config.h>
- #include <linux/slab.h>
-+#include <linux/cache_def.h>
- #include <linux/module.h>
- #include <linux/blkdev.h>
- #include <linux/cdrom.h>
-@@ -102,6 +103,7 @@ EXPORT_SYMBOL(exit_mm);
- EXPORT_SYMBOL(exit_files);
- EXPORT_SYMBOL(exit_fs);
- EXPORT_SYMBOL(exit_sighand);
-+EXPORT_SYMBOL(copy_fs_struct);
- EXPORT_SYMBOL(make_pages_present);
- /* internal kernel memory management */
-@@ -122,6 +124,8 @@ EXPORT_SYMBOL(kmem_cache_validate);
- EXPORT_SYMBOL(kmem_cache_alloc);
- EXPORT_SYMBOL(kmem_cache_free);
- EXPORT_SYMBOL(kmem_cache_size);
-+EXPORT_SYMBOL(register_cache);
-+EXPORT_SYMBOL(unregister_cache);
- EXPORT_SYMBOL(kmalloc);
- EXPORT_SYMBOL(kfree);
- EXPORT_SYMBOL(vfree);
---- linux-2.4.19-hppl/mm/vmscan.c~linux-2.4.20-xattr-0.8.54-hp_chaos   2003-04-11 16:36:27.000000000 +0800
-+++ linux-2.4.19-hppl-root/mm/vmscan.c 2003-04-11 16:52:36.000000000 +0800
-@@ -15,6 +15,7 @@
- #include <linux/kernel_stat.h>
- #include <linux/swap.h>
- #include <linux/swapctl.h>
-+#include <linux/cache_def.h>
- #include <linux/smp_lock.h>
- #include <linux/pagemap.h>
- #include <linux/init.h>
-@@ -32,6 +33,39 @@
-  */
- #define DEF_PRIORITY (6)
-+static DECLARE_MUTEX(other_caches_sem);
-+static LIST_HEAD(cache_definitions);
-+
-+void register_cache(struct cache_definition *cache)
-+{
-+      down(&other_caches_sem);
-+      list_add(&cache->link, &cache_definitions);
-+      up(&other_caches_sem);
-+}
-+
-+void unregister_cache(struct cache_definition *cache)
-+{
-+      down(&other_caches_sem);
-+      list_del(&cache->link);
-+      up(&other_caches_sem);
-+}
-+
-+static void shrink_other_caches(unsigned int priority, int gfp_mask)
-+{
-+      struct list_head *p;
-+
-+      if (down_trylock(&other_caches_sem))
-+              return;
-+
-+      list_for_each_prev(p, &cache_definitions) {
-+              struct cache_definition *cache =
-+                      list_entry(p, struct cache_definition, link);
-+
-+              cache->shrink(priority, gfp_mask);
-+      }
-+      up(&other_caches_sem);
-+}
-+
- /*
-  * The swap-out function returns 1 if it successfully
-  * scanned all the pages it was asked to (`count').
-@@ -576,6 +610,7 @@ static int shrink_caches(zone_t * classz
-       shrink_dcache_memory(priority, gfp_mask);
-       shrink_icache_memory(priority, gfp_mask);
-+      shrink_other_caches(priority, gfp_mask);
- #ifdef CONFIG_QUOTA
-       shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
- #endif
-
-_
diff --git a/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-chaos.patch b/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-chaos.patch
deleted file mode 100644 (file)
index ce2c9ce..0000000
+++ /dev/null
@@ -1,5515 +0,0 @@
- Documentation/Configure.help  |   66 ++
- arch/alpha/defconfig          |    7 
- arch/alpha/kernel/entry.S     |   12 
- arch/arm/defconfig            |    7 
- arch/arm/kernel/calls.S       |   24 
- arch/i386/defconfig           |    7 
- arch/ia64/defconfig           |    7 
- arch/m68k/defconfig           |    7 
- arch/mips/defconfig           |    7 
- arch/mips64/defconfig         |    7 
- arch/ppc/defconfig            |   14 
- arch/ppc64/kernel/misc.S      |    2 
- arch/s390/defconfig           |    7 
- arch/s390/kernel/entry.S      |   24 
- arch/s390x/defconfig          |    7 
- arch/s390x/kernel/entry.S     |   24 
- arch/s390x/kernel/wrapper32.S |   92 +++
- arch/sparc/defconfig          |    7 
- arch/sparc/kernel/systbls.S   |   10 
- arch/sparc64/defconfig        |    7 
- arch/sparc64/kernel/systbls.S |   20 
- fs/Config.in                  |   14 
- fs/Makefile                   |    3 
- fs/ext2/Makefile              |    4 
- fs/ext2/file.c                |    5 
- fs/ext2/ialloc.c              |    2 
- fs/ext2/inode.c               |   34 -
- fs/ext2/namei.c               |   14 
- fs/ext2/super.c               |   29 
- fs/ext2/symlink.c             |   14 
- fs/ext2/xattr.c               | 1212 +++++++++++++++++++++++++++++++++++++++++
- fs/ext2/xattr_user.c          |  103 +++
- fs/ext3/Makefile              |    6 
- fs/ext3/file.c                |    5 
- fs/ext3/ialloc.c              |    2 
- fs/ext3/inode.c               |   35 -
- fs/ext3/namei.c               |   21 
- fs/ext3/super.c               |   33 +
- fs/ext3/symlink.c             |   14 
- fs/ext3/xattr.c               | 1232 ++++++++++++++++++++++++++++++++++++++++++
- fs/ext3/xattr_user.c          |  111 +++
- fs/jfs/jfs_xattr.h            |    6 
- fs/jfs/xattr.c                |    6 
- fs/mbcache.c                  |  648 ++++++++++++++++++++++
- include/asm-arm/unistd.h      |    2 
- include/asm-ppc64/unistd.h    |    2 
- include/asm-s390/unistd.h     |   15 
- include/asm-s390x/unistd.h    |   15 
- include/asm-sparc/unistd.h    |   24 
- include/asm-sparc64/unistd.h  |   24 
- include/linux/cache_def.h     |   15 
- include/linux/errno.h         |    4 
- include/linux/ext2_fs.h       |   31 -
- include/linux/ext2_xattr.h    |  157 +++++
- include/linux/ext3_fs.h       |   31 -
- include/linux/ext3_jbd.h      |    8 
- include/linux/ext3_xattr.h    |  157 +++++
- include/linux/fs.h            |    2 
- include/linux/mbcache.h       |   69 ++
- kernel/ksyms.c                |    4 
- mm/vmscan.c                   |   36 +
- 61 files changed, 4336 insertions(+), 178 deletions(-)
-
---- linux-chaos-2.4.20-6/Documentation/Configure.help~linux-2.4.20-xattr-0.8.54-chaos  2003-03-12 12:48:52.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/Documentation/Configure.help    2003-04-09 16:30:45.000000000 -0600
-@@ -15226,6 +15226,39 @@ CONFIG_EXT2_FS
-   be compiled as a module, and so this could be dangerous.  Most
-   everyone wants to say Y here.
-+Ext2 extended attributes
-+CONFIG_EXT2_FS_XATTR
-+  Extended attributes are name:value pairs associated with inodes by
-+  the kernel or by users (see the attr(5) manual page, or visit
-+  <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext2 extended attribute block sharing
-+CONFIG_EXT2_FS_XATTR_SHARING
-+  This options enables code for sharing identical extended attribute
-+  blocks among multiple inodes.
-+
-+  Usually, say Y.
-+
-+Ext2 extended user attributes
-+CONFIG_EXT2_FS_XATTR_USER
-+  This option enables extended user attributes on ext2. Processes can
-+  associate extended user attributes with inodes to store additional
-+  information such as the character encoding of files, etc. (see the
-+  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext2 trusted extended attributes
-+CONFIG_EXT2_FS_XATTR_TRUSTED
-+  This option enables extended attributes on ext2 that are accessible
-+  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
-+  is only the super user. Trusted extended attributes are meant for
-+  implementing system/security services.
-+
-+  If unsure, say N.
-+
- Ext3 journalling file system support (EXPERIMENTAL)
- CONFIG_EXT3_FS
-   This is the journalling version of the Second extended file system
-@@ -15258,6 +15291,39 @@ CONFIG_EXT3_FS
-   of your root partition (the one containing the directory /) cannot
-   be compiled as a module, and so this may be dangerous.
-+Ext3 extended attributes
-+CONFIG_EXT3_FS_XATTR
-+  Extended attributes are name:value pairs associated with inodes by
-+  the kernel or by users (see the attr(5) manual page, or visit
-+  <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext3 extended attribute block sharing
-+CONFIG_EXT3_FS_XATTR_SHARING
-+  This options enables code for sharing identical extended attribute
-+  blocks among multiple inodes.
-+
-+  Usually, say Y.
-+
-+Ext3 extended user attributes
-+CONFIG_EXT3_FS_XATTR_USER
-+  This option enables extended user attributes on ext3. Processes can
-+  associate extended user attributes with inodes to store additional
-+  information such as the character encoding of files, etc. (see the
-+  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext3 trusted extended attributes
-+CONFIG_EXT3_FS_XATTR_TRUSTED
-+  This option enables extended attributes on ext3 that are accessible
-+  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
-+  is only the super user. Trusted extended attributes are meant for
-+  implementing system/security services.
-+
-+  If unsure, say N.
-+
- Journal Block Device support (JBD for ext3) (EXPERIMENTAL)
- CONFIG_JBD
-   This is a generic journalling layer for block devices.  It is
---- linux-chaos-2.4.20-6/arch/alpha/defconfig~linux-2.4.20-xattr-0.8.54-chaos  2002-05-07 15:53:54.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/arch/alpha/defconfig    2003-04-09 16:30:45.000000000 -0600
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_ALPHA=y
- # CONFIG_UID16 is not set
- # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
---- linux-chaos-2.4.20-6/arch/alpha/kernel/entry.S~linux-2.4.20-xattr-0.8.54-chaos     2003-03-12 12:48:57.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/alpha/kernel/entry.S       2003-04-09 16:30:45.000000000 -0600
-@@ -1162,6 +1162,18 @@ sys_call_table:
-       .quad sys_readahead
-       .quad sys_ni_syscall                    /* 380, sys_security */
-       .quad sys_tkill
-+      .quad sys_setxattr
-+      .quad sys_lsetxattr
-+      .quad sys_fsetxattr
-+      .quad sys_getxattr                      /* 385 */
-+      .quad sys_lgetxattr
-+      .quad sys_fgetxattr
-+      .quad sys_listxattr
-+      .quad sys_llistxattr
-+      .quad sys_flistxattr                    /* 390 */
-+      .quad sys_removexattr
-+      .quad sys_lremovexattr
-+      .quad sys_fremovexattr
- /* Remember to update everything, kids.  */
- .ifne (. - sys_call_table) - (NR_SYSCALLS * 8)
---- linux-chaos-2.4.20-6/arch/arm/defconfig~linux-2.4.20-xattr-0.8.54-chaos    2002-05-07 15:53:56.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/arch/arm/defconfig      2003-04-09 16:30:45.000000000 -0600
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_ARM=y
- # CONFIG_EISA is not set
- # CONFIG_SBUS is not set
---- linux-chaos-2.4.20-6/arch/arm/kernel/calls.S~linux-2.4.20-xattr-0.8.54-chaos       2002-09-25 11:09:16.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/arch/arm/kernel/calls.S 2003-04-09 16:30:45.000000000 -0600
-@@ -240,18 +240,18 @@ __syscall_start:
-               .long   SYMBOL_NAME(sys_ni_syscall) /* Security */
-               .long   SYMBOL_NAME(sys_gettid)
- /* 225 */     .long   SYMBOL_NAME(sys_readahead)
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_setxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lsetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fsetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_getxattr */
--/* 230 */     .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lgetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fgetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_listxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_llistxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_flistxattr */
--/* 235 */     .long   SYMBOL_NAME(sys_ni_syscall) /* sys_removexattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lremovexattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fremovexattr */
-+              .long   SYMBOL_NAME(sys_setxattr)
-+              .long   SYMBOL_NAME(sys_lsetxattr)
-+              .long   SYMBOL_NAME(sys_fsetxattr)
-+              .long   SYMBOL_NAME(sys_getxattr)
-+/* 230 */     .long   SYMBOL_NAME(sys_lgetxattr)
-+              .long   SYMBOL_NAME(sys_fgetxattr)
-+              .long   SYMBOL_NAME(sys_listxattr)
-+              .long   SYMBOL_NAME(sys_llistxattr)
-+              .long   SYMBOL_NAME(sys_flistxattr)
-+/* 235 */     .long   SYMBOL_NAME(sys_removexattr)
-+              .long   SYMBOL_NAME(sys_lremovexattr)
-+              .long   SYMBOL_NAME(sys_fremovexattr)
-               .long   SYMBOL_NAME(sys_tkill)
-               /*
-                * Please check 2.5 _before_ adding calls here,
---- linux-chaos-2.4.20-6/arch/i386/defconfig~linux-2.4.20-xattr-0.8.54-chaos   2003-03-12 12:49:05.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/i386/defconfig     2003-04-09 16:30:45.000000000 -0600
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_X86=y
- CONFIG_ISA=y
- # CONFIG_SBUS is not set
---- linux-chaos-2.4.20-6/arch/ia64/defconfig~linux-2.4.20-xattr-0.8.54-chaos   2003-03-12 12:49:10.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/ia64/defconfig     2003-04-09 16:30:45.000000000 -0600
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- #
- # Code maturity level options
---- linux-chaos-2.4.20-6/arch/m68k/defconfig~linux-2.4.20-xattr-0.8.54-chaos   2002-05-07 15:53:55.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/arch/m68k/defconfig     2003-04-09 16:30:59.000000000 -0600
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_UID16=y
- #
---- linux-chaos-2.4.20-6/arch/mips/defconfig~linux-2.4.20-xattr-0.8.54-chaos   2003-02-14 15:58:06.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/mips/defconfig     2003-04-09 16:30:59.000000000 -0600
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_MIPS=y
- CONFIG_MIPS32=y
- # CONFIG_MIPS64 is not set
---- linux-chaos-2.4.20-6/arch/mips64/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:58:11.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/mips64/defconfig   2003-04-09 16:30:59.000000000 -0600
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_MIPS=y
- # CONFIG_MIPS32 is not set
- CONFIG_MIPS64=y
---- linux-chaos-2.4.20-6/arch/ppc/defconfig~linux-2.4.20-xattr-0.8.54-chaos    2003-03-12 12:49:21.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/ppc/defconfig      2003-04-09 16:30:59.000000000 -0600
-@@ -1,6 +1,20 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_UID16 is not set
- # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
- CONFIG_RWSEM_XCHGADD_ALGORITHM=y
---- linux-chaos-2.4.20-6/arch/ppc64/kernel/misc.S~linux-2.4.20-xattr-0.8.54-chaos      2003-02-14 15:58:20.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/ppc64/kernel/misc.S        2003-04-09 16:30:59.000000000 -0600
-@@ -731,6 +731,7 @@ _GLOBAL(sys_call_table32)
-       .llong .sys_gettid              /* 207 */
- #if 0 /* Reserved syscalls */
-       .llong .sys_tkill               /* 208 */
-+#endif
-       .llong .sys_setxattr
-       .llong .sys_lsetxattr   /* 210 */
-       .llong .sys_fsetxattr
-@@ -743,6 +744,7 @@ _GLOBAL(sys_call_table32)
-       .llong .sys_removexattr
-       .llong .sys_lremovexattr
-       .llong .sys_fremovexattr        /* 220 */
-+#if 0 /* Reserved syscalls */
-       .llong .sys_futex
- #endif
-       .llong .sys_perfmonctl   /* Put this here for now ... */
---- linux-chaos-2.4.20-6/arch/s390/defconfig~linux-2.4.20-xattr-0.8.54-chaos   2003-02-14 15:58:20.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/s390/defconfig     2003-04-09 16:30:59.000000000 -0600
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_ISA is not set
- # CONFIG_EISA is not set
- # CONFIG_MCA is not set
---- linux-chaos-2.4.20-6/arch/s390/kernel/entry.S~linux-2.4.20-xattr-0.8.54-chaos      2003-02-14 15:58:20.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/s390/kernel/entry.S        2003-04-09 16:30:59.000000000 -0600
-@@ -558,18 +558,18 @@ sys_call_table:
-         .long  sys_fcntl64 
-       .long  sys_ni_syscall
-       .long  sys_ni_syscall
--      .long  sys_ni_syscall            /* 224 - reserved for setxattr  */
--      .long  sys_ni_syscall            /* 225 - reserved for lsetxattr */
--      .long  sys_ni_syscall            /* 226 - reserved for fsetxattr */
--      .long  sys_ni_syscall            /* 227 - reserved for getxattr  */
--      .long  sys_ni_syscall            /* 228 - reserved for lgetxattr */
--      .long  sys_ni_syscall            /* 229 - reserved for fgetxattr */
--      .long  sys_ni_syscall            /* 230 - reserved for listxattr */
--      .long  sys_ni_syscall            /* 231 - reserved for llistxattr */
--      .long  sys_ni_syscall            /* 232 - reserved for flistxattr */
--      .long  sys_ni_syscall            /* 233 - reserved for removexattr */
--      .long  sys_ni_syscall            /* 234 - reserved for lremovexattr */
--      .long  sys_ni_syscall            /* 235 - reserved for fremovexattr */
-+      .long  sys_setxattr
-+      .long  sys_lsetxattr            /* 225 */
-+      .long  sys_fsetxattr
-+      .long  sys_getxattr
-+      .long  sys_lgetxattr
-+      .long  sys_fgetxattr
-+      .long  sys_listxattr            /* 230 */
-+      .long  sys_llistxattr
-+      .long  sys_flistxattr
-+      .long  sys_removexattr
-+      .long  sys_lremovexattr
-+      .long  sys_fremovexattr         /* 235 */
-       .long  sys_gettid
-       .long  sys_tkill
-       .rept  255-237
---- linux-chaos-2.4.20-6/arch/s390x/defconfig~linux-2.4.20-xattr-0.8.54-chaos  2003-02-14 15:58:21.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/s390x/defconfig    2003-04-09 16:30:59.000000000 -0600
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_ISA is not set
- # CONFIG_EISA is not set
- # CONFIG_MCA is not set
---- linux-chaos-2.4.20-6/arch/s390x/kernel/entry.S~linux-2.4.20-xattr-0.8.54-chaos     2003-02-14 15:58:21.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/s390x/kernel/entry.S       2003-04-09 16:30:59.000000000 -0600
-@@ -591,18 +591,18 @@ sys_call_table:
-       .long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
-       .long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
-       .long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr  */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 226 - reserved for fsetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 227 - reserved for getxattr  */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 228 - reserved for lgetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 229 - reserved for fgetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 230 - reserved for listxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 231 - reserved for llistxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 232 - reserved for flistxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 233 - reserved for removexattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 234 - reserved for lremovexattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 235 - reserved for fremovexattr */
-+      .long  SYSCALL(sys_setxattr,sys32_setxattr_wrapper)
-+      .long  SYSCALL(sys_lsetxattr,sys32_lsetxattr_wrapper)   /* 225 */
-+      .long  SYSCALL(sys_fsetxattr,sys32_fsetxattr_wrapper)
-+      .long  SYSCALL(sys_getxattr,sys32_getxattr_wrapper)
-+      .long  SYSCALL(sys_lgetxattr,sys32_lgetxattr_wrapper)
-+      .long  SYSCALL(sys_fgetxattr,sys32_fgetxattr_wrapper)
-+      .long  SYSCALL(sys_listxattr,sys32_listxattr_wrapper)   /* 230 */
-+      .long  SYSCALL(sys_llistxattr,sys32_llistxattr_wrapper)
-+      .long  SYSCALL(sys_flistxattr,sys32_flistxattr_wrapper)
-+      .long  SYSCALL(sys_removexattr,sys32_removexattr_wrapper)
-+      .long  SYSCALL(sys_lremovexattr,sys32_lremovexattr_wrapper)
-+      .long  SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper)/* 235 */
-       .long  SYSCALL(sys_gettid,sys_gettid)
-       .long  SYSCALL(sys_tkill,sys_tkill)
-       .rept  255-237
---- linux-chaos-2.4.20-6/arch/s390x/kernel/wrapper32.S~linux-2.4.20-xattr-0.8.54-chaos 2002-05-07 15:53:59.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/arch/s390x/kernel/wrapper32.S   2003-04-09 16:30:59.000000000 -0600
-@@ -1091,3 +1091,95 @@ sys32_fstat64_wrapper:
-       llgtr   %r3,%r3                 # struct stat64 *
-       llgfr   %r4,%r4                 # long
-       jg      sys32_fstat64           # branch to system call
-+
-+      .globl  sys32_setxattr_wrapper
-+sys32_setxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_setxattr
-+
-+      .globl  sys32_lsetxattr_wrapper
-+sys32_lsetxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_lsetxattr
-+
-+      .globl  sys32_fsetxattr_wrapper
-+sys32_fsetxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_fsetxattr
-+
-+      .globl  sys32_getxattr_wrapper
-+sys32_getxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_getxattr
-+
-+      .globl  sys32_lgetxattr_wrapper
-+sys32_lgetxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_lgetxattr
-+
-+      .globl  sys32_fgetxattr_wrapper
-+sys32_fgetxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_fgetxattr
-+
-+      .globl  sys32_listxattr_wrapper
-+sys32_listxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_listxattr
-+
-+      .globl  sys32_llistxattr_wrapper
-+sys32_llistxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_llistxattr
-+
-+      .globl  sys32_flistxattr_wrapper
-+sys32_flistxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_flistxattr
-+
-+      .globl  sys32_removexattr_wrapper
-+sys32_removexattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_removexattr
-+
-+      .globl  sys32_lremovexattr_wrapper
-+sys32_lremovexattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_lremovexattr
-+
-+      .globl  sys32_fremovexattr_wrapper
-+sys32_fremovexattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_fremovexattr
-+
-+
---- linux-chaos-2.4.20-6/arch/sparc/defconfig~linux-2.4.20-xattr-0.8.54-chaos  2002-09-25 11:10:50.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/arch/sparc/defconfig    2003-04-09 16:30:59.000000000 -0600
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_UID16=y
- CONFIG_HIGHMEM=y
---- linux-chaos-2.4.20-6/arch/sparc/kernel/systbls.S~linux-2.4.20-xattr-0.8.54-chaos   2002-09-25 11:10:52.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/arch/sparc/kernel/systbls.S     2003-04-09 16:30:59.000000000 -0600
-@@ -51,11 +51,11 @@ sys_call_table:
- /*150*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
- /*155*/       .long sys_fcntl64, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
- /*160*/       .long sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
--/*165*/       .long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
--/*170*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
--/*175*/       .long sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_sigpending, sys_query_module
--/*185*/       .long sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sys_newuname
-+/*165*/       .long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
-+/*170*/       .long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
-+/*175*/       .long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module
-+/*185*/       .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sys_newuname
- /*190*/       .long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
- /*195*/       .long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
- /*200*/       .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
---- linux-chaos-2.4.20-6/arch/sparc64/defconfig~linux-2.4.20-xattr-0.8.54-chaos        2003-03-12 12:49:27.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/arch/sparc64/defconfig  2003-04-09 16:30:59.000000000 -0600
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- #
- # Code maturity level options
---- linux-chaos-2.4.20-6/arch/sparc64/kernel/systbls.S~linux-2.4.20-xattr-0.8.54-chaos 2002-09-25 11:10:55.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/arch/sparc64/kernel/systbls.S   2003-04-09 16:30:59.000000000 -0600
-@@ -52,11 +52,11 @@ sys_call_table32:
- /*150*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
-       .word sys32_fcntl64, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
- /*160*/       .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
--      .word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_nis_syscall
--/*170*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents
--      .word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_sigpending, sys32_query_module
--      .word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
-+      .word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_setxattr
-+/*170*/       .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
-+      .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module
-+      .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
- /*190*/       .word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
-       .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
- /*200*/       .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
-@@ -111,11 +111,11 @@ sys_call_table:
- /*150*/       .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
-       .word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
- /*160*/       .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_utrap_install
--      .word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
--/*170*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
--      .word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_query_module
--      .word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
-+      .word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
-+/*170*/       .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
-+      .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module
-+      .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
- /*190*/       .word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
-       .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
- /*200*/       .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
---- linux-chaos-2.4.20-6/fs/Config.in~linux-2.4.20-xattr-0.8.54-chaos  2003-03-12 12:50:56.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/Config.in    2003-04-09 16:30:59.000000000 -0600
-@@ -34,6 +34,11 @@ dep_mbool '  Debug Befs' CONFIG_BEFS_DEB
- dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
- tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS
-+dep_mbool '  Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS
-+dep_bool '    Ext3 extended attribute block sharing' \
-+    CONFIG_EXT3_FS_XATTR_SHARING $CONFIG_EXT3_FS_XATTR
-+dep_bool '    Ext3 extended user attributes' \
-+    CONFIG_EXT3_FS_XATTR_USER $CONFIG_EXT3_FS_XATTR
- # CONFIG_JBD could be its own option (even modular), but until there are
- # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
- # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
-@@ -93,6 +98,11 @@ dep_mbool '  QNX4FS write support (DANGE
- tristate 'ROM file system support' CONFIG_ROMFS_FS
- tristate 'Second extended fs support' CONFIG_EXT2_FS
-+dep_mbool '  Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS
-+dep_bool '    Ext2 extended attribute block sharing' \
-+    CONFIG_EXT2_FS_XATTR_SHARING $CONFIG_EXT2_FS_XATTR
-+dep_bool '    Ext2 extended user attributes' \
-+    CONFIG_EXT2_FS_XATTR_USER $CONFIG_EXT2_FS_XATTR
- tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS
-@@ -164,6 +174,10 @@ else
-    define_tristate CONFIG_ZISOFS_FS n
- fi
-+# Meta block cache for Extended Attributes (ext2/ext3)
-+#tristate 'Meta block cache' CONFIG_FS_MBCACHE
-+define_tristate CONFIG_FS_MBCACHE y
-+
- mainmenu_option next_comment
- comment 'Partition Types'
- source fs/partitions/Config.in
---- linux-chaos-2.4.20-6/fs/Makefile~linux-2.4.20-xattr-0.8.54-chaos   2003-04-09 16:11:02.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/Makefile     2003-04-09 16:30:59.000000000 -0600
-@@ -84,6 +84,9 @@ obj-y                                += binfmt_script.o
- obj-$(CONFIG_BINFMT_ELF)      += binfmt_elf.o
-+export-objs += mbcache.o
-+obj-$(CONFIG_FS_MBCACHE)      += mbcache.o
-+
- # persistent filesystems
- obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
---- linux-chaos-2.4.20-6/fs/ext2/Makefile~linux-2.4.20-xattr-0.8.54-chaos      2002-05-07 15:53:46.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext2/Makefile        2003-04-09 16:30:59.000000000 -0600
-@@ -13,4 +13,8 @@ obj-y    := balloc.o bitmap.o dir.o file
-               ioctl.o namei.o super.o symlink.o
- obj-m    := $(O_TARGET)
-+export-objs += xattr.o
-+obj-$(CONFIG_EXT2_FS_XATTR) += xattr.o
-+obj-$(CONFIG_EXT2_FS_XATTR_USER) += xattr_user.o
-+
- include $(TOPDIR)/Rules.make
---- linux-chaos-2.4.20-6/fs/ext2/file.c~linux-2.4.20-xattr-0.8.54-chaos        2002-05-07 15:53:46.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext2/file.c  2003-04-09 16:30:59.000000000 -0600
-@@ -20,6 +20,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/sched.h>
- /*
-@@ -51,4 +52,8 @@ struct file_operations ext2_file_operati
- struct inode_operations ext2_file_inode_operations = {
-       truncate:       ext2_truncate,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- linux-chaos-2.4.20-6/fs/ext2/ialloc.c~linux-2.4.20-xattr-0.8.54-chaos      2003-02-14 15:59:09.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext2/ialloc.c        2003-04-09 16:30:59.000000000 -0600
-@@ -15,6 +15,7 @@
- #include <linux/config.h>
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/locks.h>
- #include <linux/quotaops.h>
-@@ -167,6 +168,7 @@ void ext2_free_inode (struct inode * ino
-        */
-       if (!is_bad_inode(inode)) {
-               /* Quota is already initialized in iput() */
-+              ext2_xattr_delete_inode(inode);
-               DQUOT_FREE_INODE(inode);
-               DQUOT_DROP(inode);
-       }
---- linux-chaos-2.4.20-6/fs/ext2/inode.c~linux-2.4.20-xattr-0.8.54-chaos       2003-02-14 15:59:09.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext2/inode.c 2003-04-09 16:30:59.000000000 -0600
-@@ -39,6 +39,18 @@ MODULE_LICENSE("GPL");
- static int ext2_update_inode(struct inode * inode, int do_sync);
- /*
-+ * Test whether an inode is a fast symlink.
-+ */
-+static inline int ext2_inode_is_fast_symlink(struct inode *inode)
-+{
-+      int ea_blocks = inode->u.ext2_i.i_file_acl ?
-+              (inode->i_sb->s_blocksize >> 9) : 0;
-+
-+      return (S_ISLNK(inode->i_mode) &&
-+              inode->i_blocks - ea_blocks == 0);
-+}
-+
-+/*
-  * Called at each iput()
-  */
- void ext2_put_inode (struct inode * inode)
-@@ -53,9 +65,7 @@ void ext2_delete_inode (struct inode * i
- {
-       lock_kernel();
--      if (is_bad_inode(inode) ||
--          inode->i_ino == EXT2_ACL_IDX_INO ||
--          inode->i_ino == EXT2_ACL_DATA_INO)
-+      if (is_bad_inode(inode))
-               goto no_delete;
-       inode->u.ext2_i.i_dtime = CURRENT_TIME;
-       mark_inode_dirty(inode);
-@@ -801,6 +811,8 @@ void ext2_truncate (struct inode * inode
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-+      if (ext2_inode_is_fast_symlink(inode))
-+              return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-@@ -888,8 +900,7 @@ void ext2_read_inode (struct inode * ino
-       unsigned long offset;
-       struct ext2_group_desc * gdp;
--      if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
--           inode->i_ino != EXT2_ACL_DATA_INO &&
-+      if ((inode->i_ino != EXT2_ROOT_INO &&
-            inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||
-           inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {
-               ext2_error (inode->i_sb, "ext2_read_inode",
-@@ -974,10 +985,7 @@ void ext2_read_inode (struct inode * ino
-       for (block = 0; block < EXT2_N_BLOCKS; block++)
-               inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
--      if (inode->i_ino == EXT2_ACL_IDX_INO ||
--          inode->i_ino == EXT2_ACL_DATA_INO)
--              /* Nothing to do */ ;
--      else if (S_ISREG(inode->i_mode)) {
-+      if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &ext2_file_inode_operations;
-               inode->i_fop = &ext2_file_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-@@ -986,15 +994,17 @@ void ext2_read_inode (struct inode * ino
-               inode->i_fop = &ext2_dir_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-       } else if (S_ISLNK(inode->i_mode)) {
--              if (!inode->i_blocks)
-+              if (ext2_inode_is_fast_symlink(inode))
-                       inode->i_op = &ext2_fast_symlink_inode_operations;
-               else {
--                      inode->i_op = &page_symlink_inode_operations;
-+                      inode->i_op = &ext2_symlink_inode_operations;
-                       inode->i_mapping->a_ops = &ext2_aops;
-               }
--      } else 
-+      } else {
-+              inode->i_op = &ext2_special_inode_operations;
-               init_special_inode(inode, inode->i_mode,
-                                  le32_to_cpu(raw_inode->i_block[0]));
-+      }
-       brelse (bh);
-       inode->i_attr_flags = 0;
-       if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) {
---- linux-chaos-2.4.20-6/fs/ext2/namei.c~linux-2.4.20-xattr-0.8.54-chaos       2002-05-07 15:53:46.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext2/namei.c 2003-04-09 16:30:59.000000000 -0600
-@@ -31,6 +31,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/pagemap.h>
- /*
-@@ -136,7 +137,7 @@ static int ext2_symlink (struct inode * 
-       if (l > sizeof (inode->u.ext2_i.i_data)) {
-               /* slow symlink */
--              inode->i_op = &page_symlink_inode_operations;
-+              inode->i_op = &ext2_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-               err = block_symlink(inode, symname, l);
-               if (err)
-@@ -345,4 +346,15 @@ struct inode_operations ext2_dir_inode_o
-       rmdir:          ext2_rmdir,
-       mknod:          ext2_mknod,
-       rename:         ext2_rename,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
-+};
-+
-+struct inode_operations ext2_special_inode_operations = {
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- linux-chaos-2.4.20-6/fs/ext2/super.c~linux-2.4.20-xattr-0.8.54-chaos       2003-02-14 15:59:09.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext2/super.c 2003-04-09 16:30:59.000000000 -0600
-@@ -21,6 +21,7 @@
- #include <linux/string.h>
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/locks.h>
-@@ -125,6 +126,7 @@ void ext2_put_super (struct super_block 
-       int db_count;
-       int i;
-+      ext2_xattr_put_super(sb);
-       if (!(sb->s_flags & MS_RDONLY)) {
-               struct ext2_super_block *es = EXT2_SB(sb)->s_es;
-@@ -175,6 +177,13 @@ static int parse_options (char * options
-            this_char = strtok (NULL, ",")) {
-               if ((value = strchr (this_char, '=')) != NULL)
-                       *value++ = 0;
-+#ifdef CONFIG_EXT2_FS_XATTR_USER
-+              if (!strcmp (this_char, "user_xattr"))
-+                      set_opt (*mount_options, XATTR_USER);
-+              else if (!strcmp (this_char, "nouser_xattr"))
-+                      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")) {
-@@ -424,6 +433,9 @@ struct super_block * ext2_read_super (st
-           blocksize = BLOCK_SIZE;
-       sb->u.ext2_sb.s_mount_opt = 0;
-+#ifdef CONFIG_EXT2_FS_XATTR_USER
-+      /* set_opt (sb->u.ext2_sb.s_mount_opt, XATTR_USER); */
-+#endif
-       if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
-           &sb->u.ext2_sb.s_mount_opt)) {
-               return NULL;
-@@ -813,12 +825,27 @@ static DECLARE_FSTYPE_DEV(ext2_fs_type, 
- static int __init init_ext2_fs(void)
- {
--        return register_filesystem(&ext2_fs_type);
-+      int error = init_ext2_xattr();
-+      if (error)
-+              return error;
-+      error = init_ext2_xattr_user();
-+      if (error)
-+              goto fail;
-+      error = register_filesystem(&ext2_fs_type);
-+      if (!error)
-+              return 0;
-+
-+      exit_ext2_xattr_user();
-+fail:
-+      exit_ext2_xattr();
-+      return error;
- }
- static void __exit exit_ext2_fs(void)
- {
-       unregister_filesystem(&ext2_fs_type);
-+      exit_ext2_xattr_user();
-+      exit_ext2_xattr();
- }
- EXPORT_NO_SYMBOLS;
---- linux-chaos-2.4.20-6/fs/ext2/symlink.c~linux-2.4.20-xattr-0.8.54-chaos     2002-05-07 15:53:46.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext2/symlink.c       2003-04-09 16:30:59.000000000 -0600
-@@ -19,6 +19,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
-@@ -32,7 +33,20 @@ static int ext2_follow_link(struct dentr
-       return vfs_follow_link(nd, s);
- }
-+struct inode_operations ext2_symlink_inode_operations = {
-+      readlink:       page_readlink,
-+      follow_link:    page_follow_link,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
-+};
-+
- struct inode_operations ext2_fast_symlink_inode_operations = {
-       readlink:       ext2_readlink,
-       follow_link:    ext2_follow_link,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- /dev/null  2003-01-30 03:24:37.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext2/xattr.c 2003-04-09 16:30:59.000000000 -0600
-@@ -0,0 +1,1212 @@
-+/*
-+ * linux/fs/ext2/xattr.c
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
-+ * Extended attributes for symlinks and special files added per
-+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
-+ */
-+
-+/*
-+ * Extended attributes are stored on disk blocks allocated outside of
-+ * any inode. The i_file_acl field is then made to point to this allocated
-+ * block. If all extended attributes of an inode are identical, these
-+ * inodes may share the same extended attribute block. Such situations
-+ * are automatically detected by keeping a cache of recent attribute block
-+ * numbers and hashes over the block's contents in memory.
-+ *
-+ *
-+ * Extended attribute block layout:
-+ *
-+ *   +------------------+
-+ *   | header           |
-+ *   | entry 1          | |
-+ *   | entry 2          | | growing downwards
-+ *   | entry 3          | v
-+ *   | four null bytes  |
-+ *   | . . .            |
-+ *   | value 1          | ^
-+ *   | value 3          | | growing upwards
-+ *   | value 2          | |
-+ *   +------------------+
-+ *
-+ * The block header is followed by multiple entry descriptors. These entry
-+ * descriptors are variable in size, and alligned to EXT2_XATTR_PAD
-+ * byte boundaries. The entry descriptors are sorted by attribute name,
-+ * so that two extended attribute blocks can be compared efficiently.
-+ *
-+ * Attribute values are aligned to the end of the block, stored in
-+ * no specific order. They are also padded to EXT2_XATTR_PAD byte
-+ * boundaries. No additional gaps are left between them.
-+ *
-+ * Locking strategy
-+ * ----------------
-+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
-+ * the xattr inode operations are called, so we are guaranteed that only one
-+ * processes accesses extended attributes of an inode at any time.
-+ *
-+ * For writing we also grab the ext2_xattr_sem semaphore. This ensures that
-+ * only a single process is modifying an extended attribute block, even
-+ * if the block is shared among inodes.
-+ *
-+ * Note for porting to 2.5
-+ * -----------------------
-+ * The BKL will no longer be held in the xattr inode operations.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/locks.h>
-+#include <linux/slab.h>
-+#include <linux/fs.h>
-+#include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
-+#include <linux/mbcache.h>
-+#include <linux/quotaops.h>
-+#include <asm/semaphore.h>
-+#include <linux/compatmac.h>
-+
-+/* These symbols may be needed by a module. */
-+EXPORT_SYMBOL(ext2_xattr_register);
-+EXPORT_SYMBOL(ext2_xattr_unregister);
-+EXPORT_SYMBOL(ext2_xattr_get);
-+EXPORT_SYMBOL(ext2_xattr_list);
-+EXPORT_SYMBOL(ext2_xattr_set);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
-+#endif
-+
-+#define HDR(bh) ((struct ext2_xattr_header *)((bh)->b_data))
-+#define ENTRY(ptr) ((struct ext2_xattr_entry *)(ptr))
-+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
-+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
-+
-+#ifdef EXT2_XATTR_DEBUG
-+# define ea_idebug(inode, f...) do { \
-+              printk(KERN_DEBUG "inode %s:%ld: ", \
-+                      kdevname(inode->i_dev), inode->i_ino); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+# define ea_bdebug(bh, f...) do { \
-+              printk(KERN_DEBUG "block %s:%ld: ", \
-+                      kdevname(bh->b_dev), bh->b_blocknr); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+#else
-+# define ea_idebug(f...)
-+# define ea_bdebug(f...)
-+#endif
-+
-+static int ext2_xattr_set2(struct inode *, struct buffer_head *,
-+                         struct ext2_xattr_header *);
-+
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+
-+static int ext2_xattr_cache_insert(struct buffer_head *);
-+static struct buffer_head *ext2_xattr_cache_find(struct inode *,
-+                                               struct ext2_xattr_header *);
-+static void ext2_xattr_cache_remove(struct buffer_head *);
-+static void ext2_xattr_rehash(struct ext2_xattr_header *,
-+                            struct ext2_xattr_entry *);
-+
-+static struct mb_cache *ext2_xattr_cache;
-+
-+#else
-+# define ext2_xattr_cache_insert(bh) 0
-+# define ext2_xattr_cache_find(inode, header) NULL
-+# define ext2_xattr_cache_remove(bh) while(0) {}
-+# define ext2_xattr_rehash(header, entry) while(0) {}
-+#endif
-+
-+/*
-+ * If a file system does not share extended attributes among inodes,
-+ * we should not need the ext2_xattr_sem semaphore. However, the
-+ * filesystem may still contain shared blocks, so we always take
-+ * the lock.
-+ */
-+
-+DECLARE_MUTEX(ext2_xattr_sem);
-+
-+static inline int
-+ext2_xattr_new_block(struct inode *inode, int * errp, int force)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      int goal = le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) +
-+              EXT2_I(inode)->i_block_group * EXT2_BLOCKS_PER_GROUP(sb);
-+
-+      /* How can we enforce the allocation? */
-+      int block = ext2_new_block(inode, goal, 0, 0, errp);
-+#ifdef OLD_QUOTAS
-+      if (!*errp)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#endif
-+      return block;
-+}
-+
-+static inline int
-+ext2_xattr_quota_alloc(struct inode *inode, int force)
-+{
-+      /* How can we enforce the allocation? */
-+#ifdef OLD_QUOTAS
-+      int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
-+      if (!error)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#else
-+      int error = DQUOT_ALLOC_BLOCK(inode, 1);
-+#endif
-+      return error;
-+}
-+
-+#ifdef OLD_QUOTAS
-+
-+static inline void
-+ext2_xattr_quota_free(struct inode *inode)
-+{
-+      DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+static inline void
-+ext2_xattr_free_block(struct inode * inode, unsigned long block)
-+{
-+      ext2_free_blocks(inode, block, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+#else
-+# define ext2_xattr_quota_free(inode) \
-+      DQUOT_FREE_BLOCK(inode, 1)
-+# define ext2_xattr_free_block(inode, block) \
-+      ext2_free_blocks(inode, block, 1)
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
-+
-+static inline struct buffer_head *
-+sb_bread(struct super_block *sb, int block)
-+{
-+      return bread(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+static inline struct buffer_head *
-+sb_getblk(struct super_block *sb, int block)
-+{
-+      return getblk(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+#endif
-+
-+struct ext2_xattr_handler *ext2_xattr_handlers[EXT2_XATTR_INDEX_MAX];
-+rwlock_t ext2_handler_lock = RW_LOCK_UNLOCKED;
-+
-+int
-+ext2_xattr_register(int name_index, struct ext2_xattr_handler *handler)
-+{
-+      int error = -EINVAL;
-+
-+      if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
-+              write_lock(&ext2_handler_lock);
-+              if (!ext2_xattr_handlers[name_index-1]) {
-+                      ext2_xattr_handlers[name_index-1] = handler;
-+                      error = 0;
-+              }
-+              write_unlock(&ext2_handler_lock);
-+      }
-+      return error;
-+}
-+
-+void
-+ext2_xattr_unregister(int name_index, struct ext2_xattr_handler *handler)
-+{
-+      if (name_index > 0 || name_index <= EXT2_XATTR_INDEX_MAX) {
-+              write_lock(&ext2_handler_lock);
-+              ext2_xattr_handlers[name_index-1] = NULL;
-+              write_unlock(&ext2_handler_lock);
-+      }
-+}
-+
-+static inline const char *
-+strcmp_prefix(const char *a, const char *a_prefix)
-+{
-+      while (*a_prefix && *a == *a_prefix) {
-+              a++;
-+              a_prefix++;
-+      }
-+      return *a_prefix ? NULL : a;
-+}
-+
-+/*
-+ * Decode the extended attribute name, and translate it into
-+ * the name_index and name suffix.
-+ */
-+static struct ext2_xattr_handler *
-+ext2_xattr_resolve_name(const char **name)
-+{
-+      struct ext2_xattr_handler *handler = NULL;
-+      int i;
-+
-+      if (!*name)
-+              return NULL;
-+      read_lock(&ext2_handler_lock);
-+      for (i=0; i<EXT2_XATTR_INDEX_MAX; i++) {
-+              if (ext2_xattr_handlers[i]) {
-+                      const char *n = strcmp_prefix(*name,
-+                              ext2_xattr_handlers[i]->prefix);
-+                      if (n) {
-+                              handler = ext2_xattr_handlers[i];
-+                              *name = n;
-+                              break;
-+                      }
-+              }
-+      }
-+      read_unlock(&ext2_handler_lock);
-+      return handler;
-+}
-+
-+static inline struct ext2_xattr_handler *
-+ext2_xattr_handler(int name_index)
-+{
-+      struct ext2_xattr_handler *handler = NULL;
-+      if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
-+              read_lock(&ext2_handler_lock);
-+              handler = ext2_xattr_handlers[name_index-1];
-+              read_unlock(&ext2_handler_lock);
-+      }
-+      return handler;
-+}
-+
-+/*
-+ * Inode operation getxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext2_getxattr(struct dentry *dentry, const char *name,
-+            void *buffer, size_t size)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->get(inode, name, buffer, size);
-+}
-+
-+/*
-+ * Inode operation listxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
-+{
-+      return ext2_xattr_list(dentry->d_inode, buffer, size);
-+}
-+
-+/*
-+ * Inode operation setxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext2_setxattr(struct dentry *dentry, const char *name,
-+            const void *value, size_t size, int flags)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      if (size == 0)
-+              value = "";  /* empty EA, do not remove */
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, value, size, flags);
-+}
-+
-+/*
-+ * Inode operation removexattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext2_removexattr(struct dentry *dentry, const char *name)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
-+}
-+
-+/*
-+ * ext2_xattr_get()
-+ *
-+ * Copy an extended attribute into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext2_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_entry *entry;
-+      unsigned int block, size;
-+      char *end;
-+      int name_len, error;
-+
-+      ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
-+                name_index, name, buffer, (long)buffer_size);
-+
-+      if (name == NULL)
-+              return -EINVAL;
-+      if (!EXT2_I(inode)->i_file_acl)
-+              return -ENOATTR;
-+      block = EXT2_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext2_error(inode->i_sb, "ext2_xattr_get",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* find named attribute */
-+      name_len = strlen(name);
-+
-+      error = -ERANGE;
-+      if (name_len > 255)
-+              goto cleanup;
-+      entry = FIRST_ENTRY(bh);
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              if (name_index == entry->e_name_index &&
-+                  name_len == entry->e_name_len &&
-+                  memcmp(name, entry->e_name, name_len) == 0)
-+                      goto found;
-+              entry = next;
-+      }
-+      /* Check the remaining name entries */
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              entry = next;
-+      }
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      error = -ENOATTR;
-+      goto cleanup;
-+found:
-+      /* check the buffer size */
-+      if (entry->e_value_block != 0)
-+              goto bad_block;
-+      size = le32_to_cpu(entry->e_value_size);
-+      if (size > inode->i_sb->s_blocksize ||
-+          le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-+              goto bad_block;
-+
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (buffer) {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+              /* return value of attribute */
-+              memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-+                      size);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_list()
-+ *
-+ * Copy a list of attribute names into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_entry *entry;
-+      unsigned int block, size = 0;
-+      char *buf, *end;
-+      int error;
-+
-+      ea_idebug(inode, "buffer=%p, buffer_size=%ld",
-+                buffer, (long)buffer_size);
-+
-+      if (!EXT2_I(inode)->i_file_acl)
-+              return 0;
-+      block = EXT2_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext2_error(inode->i_sb, "ext2_xattr_list",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* compute the size required for the list of attribute names */
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT2_XATTR_NEXT(entry)) {
-+              struct ext2_xattr_handler *handler;
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+
-+              handler = ext2_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      size += handler->list(NULL, inode, entry->e_name,
-+                                            entry->e_name_len);
-+      }
-+
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (!buffer) {
-+              error = size;
-+              goto cleanup;
-+      } else {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+      }
-+
-+      /* list the attribute names */
-+      buf = buffer;
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT2_XATTR_NEXT(entry)) {
-+              struct ext2_xattr_handler *handler;
-+              
-+              handler = ext2_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      buf += handler->list(buf, inode, entry->e_name,
-+                                           entry->e_name_len);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * If the EXT2_FEATURE_COMPAT_EXT_ATTR feature of this file system is
-+ * not set, set it.
-+ */
-+static void ext2_xattr_update_super_block(struct super_block *sb)
-+{
-+      if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR))
-+              return;
-+
-+      lock_super(sb);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+      EXT2_SB(sb)->s_feature_compat |= EXT2_FEATURE_COMPAT_EXT_ATTR;
-+#endif
-+      EXT2_SB(sb)->s_es->s_feature_compat |=
-+              cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR);
-+      sb->s_dirt = 1;
-+      mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
-+      unlock_super(sb);
-+}
-+
-+/*
-+ * ext2_xattr_set()
-+ *
-+ * Create, replace or remove an extended attribute for this inode. Buffer
-+ * is NULL to remove an existing extended attribute, and non-NULL to
-+ * either replace an existing extended attribute, or create a new extended
-+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
-+ * specify that an extended attribute must exist and must not exist
-+ * previous to the call, respectively.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+int
-+ext2_xattr_set(struct inode *inode, int name_index, const char *name,
-+             const void *value, size_t value_len, int flags)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_header *header = NULL;
-+      struct ext2_xattr_entry *here, *last;
-+      unsigned int name_len;
-+      int block = EXT2_I(inode)->i_file_acl;
-+      int min_offs = sb->s_blocksize, not_found = 1, free, error;
-+      char *end;
-+      
-+      /*
-+       * header -- Points either into bh, or to a temporarily
-+       *           allocated buffer.
-+       * here -- The named entry found, or the place for inserting, within
-+       *         the block pointed to by header.
-+       * last -- Points right after the last named entry within the block
-+       *         pointed to by header.
-+       * min_offs -- The offset of the first value (values are aligned
-+       *             towards the end of the block).
-+       * end -- Points right after the block pointed to by header.
-+       */
-+      
-+      ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-+                name_index, name, value, (long)value_len);
-+
-+      if (IS_RDONLY(inode))
-+              return -EROFS;
-+      if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-+              return -EPERM;
-+      if (value == NULL)
-+              value_len = 0;
-+      if (name == NULL)
-+              return -EINVAL;
-+      name_len = strlen(name);
-+      if (name_len > 255 || value_len > sb->s_blocksize)
-+              return -ERANGE;
-+      down(&ext2_xattr_sem);
-+
-+      if (block) {
-+              /* The inode already has an extended attribute block. */
-+
-+              bh = sb_bread(sb, block);
-+              error = -EIO;
-+              if (!bh)
-+                      goto cleanup;
-+              ea_bdebug(bh, "b_count=%d, refcount=%d",
-+                      atomic_read(&(bh->b_count)),
-+                      le32_to_cpu(HDR(bh)->h_refcount));
-+              header = HDR(bh);
-+              end = bh->b_data + bh->b_size;
-+              if (header->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+                  header->h_blocks != cpu_to_le32(1)) {
-+bad_block:            ext2_error(sb, "ext2_xattr_set",
-+                              "inode %ld: bad block %d", inode->i_ino, block);
-+                      error = -EIO;
-+                      goto cleanup;
-+              }
-+              /* Find the named attribute. */
-+              here = FIRST_ENTRY(bh);
-+              while (!IS_LAST_ENTRY(here)) {
-+                      struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(here);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!here->e_value_block && here->e_value_size) {
-+                              int offs = le16_to_cpu(here->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      not_found = name_index - here->e_name_index;
-+                      if (!not_found)
-+                              not_found = name_len - here->e_name_len;
-+                      if (!not_found)
-+                              not_found = memcmp(name, here->e_name,name_len);
-+                      if (not_found <= 0)
-+                              break;
-+                      here = next;
-+              }
-+              last = here;
-+              /* We still need to compute min_offs and last. */
-+              while (!IS_LAST_ENTRY(last)) {
-+                      struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(last);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!last->e_value_block && last->e_value_size) {
-+                              int offs = le16_to_cpu(last->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      last = next;
-+              }
-+
-+              /* Check whether we have enough space left. */
-+              free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-+      } else {
-+              /* We will use a new extended attribute block. */
-+              free = sb->s_blocksize -
-+                      sizeof(struct ext2_xattr_header) - sizeof(__u32);
-+              here = last = NULL;  /* avoid gcc uninitialized warning. */
-+      }
-+
-+      if (not_found) {
-+              /* Request to remove a nonexistent attribute? */
-+              error = -ENOATTR;
-+              if (flags & XATTR_REPLACE)
-+                      goto cleanup;
-+              error = 0;
-+              if (value == NULL)
-+                      goto cleanup;
-+              else
-+                      free -= EXT2_XATTR_LEN(name_len);
-+      } else {
-+              /* Request to create an existing attribute? */
-+              error = -EEXIST;
-+              if (flags & XATTR_CREATE)
-+                      goto cleanup;
-+              if (!here->e_value_block && here->e_value_size) {
-+                      unsigned int size = le32_to_cpu(here->e_value_size);
-+
-+                      if (le16_to_cpu(here->e_value_offs) + size > 
-+                          sb->s_blocksize || size > sb->s_blocksize)
-+                              goto bad_block;
-+                      free += EXT2_XATTR_SIZE(size);
-+              }
-+      }
-+      free -= EXT2_XATTR_SIZE(value_len);
-+      error = -ENOSPC;
-+      if (free < 0)
-+              goto cleanup;
-+
-+      /* Here we know that we can set the new attribute. */
-+
-+      if (header) {
-+              if (header->h_refcount == cpu_to_le32(1)) {
-+                      ea_bdebug(bh, "modifying in-place");
-+                      ext2_xattr_cache_remove(bh);
-+              } else {
-+                      int offset;
-+
-+                      ea_bdebug(bh, "cloning");
-+                      header = kmalloc(bh->b_size, GFP_KERNEL);
-+                      error = -ENOMEM;
-+                      if (header == NULL)
-+                              goto cleanup;
-+                      memcpy(header, HDR(bh), bh->b_size);
-+                      header->h_refcount = cpu_to_le32(1);
-+                      offset = (char *)header - bh->b_data;
-+                      here = ENTRY((char *)here + offset);
-+                      last = ENTRY((char *)last + offset);
-+              }
-+      } else {
-+              /* Allocate a buffer where we construct the new block. */
-+              header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-+              error = -ENOMEM;
-+              if (header == NULL)
-+                      goto cleanup;
-+              memset(header, 0, sb->s_blocksize);
-+              end = (char *)header + sb->s_blocksize;
-+              header->h_magic = cpu_to_le32(EXT2_XATTR_MAGIC);
-+              header->h_blocks = header->h_refcount = cpu_to_le32(1);
-+              last = here = ENTRY(header+1);
-+      }
-+
-+      if (not_found) {
-+              /* Insert the new name. */
-+              int size = EXT2_XATTR_LEN(name_len);
-+              int rest = (char *)last - (char *)here;
-+              memmove((char *)here + size, here, rest);
-+              memset(here, 0, size);
-+              here->e_name_index = name_index;
-+              here->e_name_len = name_len;
-+              memcpy(here->e_name, name, name_len);
-+      } else {
-+              /* Remove the old value. */
-+              if (!here->e_value_block && here->e_value_size) {
-+                      char *first_val = (char *)header + min_offs;
-+                      int offs = le16_to_cpu(here->e_value_offs);
-+                      char *val = (char *)header + offs;
-+                      size_t size = EXT2_XATTR_SIZE(
-+                              le32_to_cpu(here->e_value_size));
-+                      memmove(first_val + size, first_val, val - first_val);
-+                      memset(first_val, 0, size);
-+                      here->e_value_offs = 0;
-+                      min_offs += size;
-+
-+                      /* Adjust all value offsets. */
-+                      last = ENTRY(header+1);
-+                      while (!IS_LAST_ENTRY(last)) {
-+                              int o = le16_to_cpu(last->e_value_offs);
-+                              if (!last->e_value_block && o < offs)
-+                                      last->e_value_offs =
-+                                              cpu_to_le16(o + size);
-+                              last = EXT2_XATTR_NEXT(last);
-+                      }
-+              }
-+              if (value == NULL) {
-+                      /* Remove this attribute. */
-+                      if (EXT2_XATTR_NEXT(ENTRY(header+1)) == last) {
-+                              /* This block is now empty. */
-+                              error = ext2_xattr_set2(inode, bh, NULL);
-+                              goto cleanup;
-+                      } else {
-+                              /* Remove the old name. */
-+                              int size = EXT2_XATTR_LEN(name_len);
-+                              last = ENTRY((char *)last - size);
-+                              memmove(here, (char*)here + size,
-+                                      (char*)last - (char*)here);
-+                              memset(last, 0, size);
-+                      }
-+              }
-+      }
-+
-+      if (value != NULL) {
-+              /* Insert the new value. */
-+              here->e_value_size = cpu_to_le32(value_len);
-+              if (value_len) {
-+                      size_t size = EXT2_XATTR_SIZE(value_len);
-+                      char *val = (char *)header + min_offs - size;
-+                      here->e_value_offs =
-+                              cpu_to_le16((char *)val - (char *)header);
-+                      memset(val + size - EXT2_XATTR_PAD, 0,
-+                             EXT2_XATTR_PAD); /* Clear the pad bytes. */
-+                      memcpy(val, value, value_len);
-+              }
-+      }
-+      ext2_xattr_rehash(header, here);
-+
-+      error = ext2_xattr_set2(inode, bh, header);
-+
-+cleanup:
-+      brelse(bh);
-+      if (!(bh && header == HDR(bh)))
-+              kfree(header);
-+      up(&ext2_xattr_sem);
-+
-+      return error;
-+}
-+
-+/*
-+ * Second half of ext2_xattr_set(): Update the file system.
-+ */
-+static int
-+ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
-+              struct ext2_xattr_header *header)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *new_bh = NULL;
-+      int error;
-+
-+      if (header) {
-+              new_bh = ext2_xattr_cache_find(inode, header);
-+              if (new_bh) {
-+                      /*
-+                       * We found an identical block in the cache.
-+                       * The old block will be released after updating
-+                       * the inode.
-+                       */
-+                      ea_bdebug(old_bh, "reusing block %ld",
-+                              new_bh->b_blocknr);
-+                      
-+                      error = -EDQUOT;
-+                      if (ext2_xattr_quota_alloc(inode, 1))
-+                              goto cleanup;
-+                      
-+                      HDR(new_bh)->h_refcount = cpu_to_le32(
-+                              le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
-+                      ea_bdebug(new_bh, "refcount now=%d",
-+                              le32_to_cpu(HDR(new_bh)->h_refcount));
-+              } else if (old_bh && header == HDR(old_bh)) {
-+                      /* Keep this block. */
-+                      new_bh = old_bh;
-+                      ext2_xattr_cache_insert(new_bh);
-+              } else {
-+                      /* We need to allocate a new block */
-+                      int force = EXT2_I(inode)->i_file_acl != 0;
-+                      int block = ext2_xattr_new_block(inode, &error, force);
-+                      if (error)
-+                              goto cleanup;
-+                      ea_idebug(inode, "creating block %d", block);
-+
-+                      new_bh = sb_getblk(sb, block);
-+                      if (!new_bh) {
-+                              ext2_xattr_free_block(inode, block);
-+                              error = -EIO;
-+                              goto cleanup;
-+                      }
-+                      lock_buffer(new_bh);
-+                      memcpy(new_bh->b_data, header, new_bh->b_size);
-+                      mark_buffer_uptodate(new_bh, 1);
-+                      unlock_buffer(new_bh);
-+                      ext2_xattr_cache_insert(new_bh);
-+                      
-+                      ext2_xattr_update_super_block(sb);
-+              }
-+              mark_buffer_dirty(new_bh);
-+              if (IS_SYNC(inode)) {
-+                      ll_rw_block(WRITE, 1, &new_bh);
-+                      wait_on_buffer(new_bh); 
-+                      error = -EIO;
-+                      if (buffer_req(new_bh) && !buffer_uptodate(new_bh))
-+                              goto cleanup;
-+              }
-+      }
-+
-+      /* Update the inode. */
-+      EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-+      inode->i_ctime = CURRENT_TIME;
-+      if (IS_SYNC(inode)) {
-+              error = ext2_sync_inode (inode);
-+              if (error)
-+                      goto cleanup;
-+      } else
-+              mark_inode_dirty(inode);
-+
-+      error = 0;
-+      if (old_bh && old_bh != new_bh) {
-+              /*
-+               * If there was an old block, and we are not still using it,
-+               * we now release the old block.
-+              */
-+              unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
-+
-+              if (refcount == 1) {
-+                      /* Free the old block. */
-+                      ea_bdebug(old_bh, "freeing");
-+                      ext2_xattr_free_block(inode, old_bh->b_blocknr);
-+                      mark_buffer_clean(old_bh);
-+              } else {
-+                      /* Decrement the refcount only. */
-+                      refcount--;
-+                      HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
-+                      ext2_xattr_quota_free(inode);
-+                      mark_buffer_dirty(old_bh);
-+                      ea_bdebug(old_bh, "refcount now=%d", refcount);
-+              }
-+      }
-+
-+cleanup:
-+      if (old_bh != new_bh)
-+              brelse(new_bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_delete_inode()
-+ *
-+ * Free extended attribute resources associated with this inode. This
-+ * is called immediately before an inode is freed.
-+ */
-+void
-+ext2_xattr_delete_inode(struct inode *inode)
-+{
-+      struct buffer_head *bh;
-+      unsigned int block = EXT2_I(inode)->i_file_acl;
-+
-+      if (!block)
-+              return;
-+      down(&ext2_xattr_sem);
-+
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh) {
-+              ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
-+                      "inode %ld: block %d read error", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+              ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+      if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-+              ext2_xattr_cache_remove(bh);
-+              ext2_xattr_free_block(inode, block);
-+              bforget(bh);
-+              bh = NULL;
-+      } else {
-+              HDR(bh)->h_refcount = cpu_to_le32(
-+                      le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+              mark_buffer_dirty(bh);
-+              if (IS_SYNC(inode)) {
-+                      ll_rw_block(WRITE, 1, &bh);
-+                      wait_on_buffer(bh);
-+              }
-+              ext2_xattr_quota_free(inode);
-+      }
-+      EXT2_I(inode)->i_file_acl = 0;
-+
-+cleanup:
-+      brelse(bh);
-+      up(&ext2_xattr_sem);
-+}
-+
-+/*
-+ * ext2_xattr_put_super()
-+ *
-+ * This is called when a file system is unmounted.
-+ */
-+void
-+ext2_xattr_put_super(struct super_block *sb)
-+{
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+      mb_cache_shrink(ext2_xattr_cache, sb->s_dev);
-+#endif
-+}
-+
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+
-+/*
-+ * ext2_xattr_cache_insert()
-+ *
-+ * Create a new entry in the extended attribute cache, and insert
-+ * it unless such an entry is already in the cache.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+static int
-+ext2_xattr_cache_insert(struct buffer_head *bh)
-+{
-+      __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
-+      struct mb_cache_entry *ce;
-+      int error;
-+
-+      ce = mb_cache_entry_alloc(ext2_xattr_cache);
-+      if (!ce)
-+              return -ENOMEM;
-+      error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
-+      if (error) {
-+              mb_cache_entry_free(ce);
-+              if (error == -EBUSY) {
-+                      ea_bdebug(bh, "already in cache (%d cache entries)",
-+                              atomic_read(&ext2_xattr_cache->c_entry_count));
-+                      error = 0;
-+              }
-+      } else {
-+              ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-+                        atomic_read(&ext2_xattr_cache->c_entry_count));
-+              mb_cache_entry_release(ce);
-+      }
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_cmp()
-+ *
-+ * Compare two extended attribute blocks for equality.
-+ *
-+ * Returns 0 if the blocks are equal, 1 if they differ, and
-+ * a negative error number on errors.
-+ */
-+static int
-+ext2_xattr_cmp(struct ext2_xattr_header *header1,
-+             struct ext2_xattr_header *header2)
-+{
-+      struct ext2_xattr_entry *entry1, *entry2;
-+
-+      entry1 = ENTRY(header1+1);
-+      entry2 = ENTRY(header2+1);
-+      while (!IS_LAST_ENTRY(entry1)) {
-+              if (IS_LAST_ENTRY(entry2))
-+                      return 1;
-+              if (entry1->e_hash != entry2->e_hash ||
-+                  entry1->e_name_len != entry2->e_name_len ||
-+                  entry1->e_value_size != entry2->e_value_size ||
-+                  memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
-+                      return 1;
-+              if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
-+                      return -EIO;
-+              if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
-+                         (char *)header2 + le16_to_cpu(entry2->e_value_offs),
-+                         le32_to_cpu(entry1->e_value_size)))
-+                      return 1;
-+
-+              entry1 = EXT2_XATTR_NEXT(entry1);
-+              entry2 = EXT2_XATTR_NEXT(entry2);
-+      }
-+      if (!IS_LAST_ENTRY(entry2))
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * ext2_xattr_cache_find()
-+ *
-+ * Find an identical extended attribute block.
-+ *
-+ * Returns a pointer to the block found, or NULL if such a block was
-+ * not found or an error occurred.
-+ */
-+static struct buffer_head *
-+ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header)
-+{
-+      __u32 hash = le32_to_cpu(header->h_hash);
-+      struct mb_cache_entry *ce;
-+
-+      if (!header->h_hash)
-+              return NULL;  /* never share */
-+      ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
-+      ce = mb_cache_entry_find_first(ext2_xattr_cache, 0, inode->i_dev, hash);
-+      while (ce) {
-+              struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
-+
-+              if (!bh) {
-+                      ext2_error(inode->i_sb, "ext2_xattr_cache_find",
-+                              "inode %ld: block %ld read error",
-+                              inode->i_ino, ce->e_block);
-+              } else if (le32_to_cpu(HDR(bh)->h_refcount) >
-+                         EXT2_XATTR_REFCOUNT_MAX) {
-+                      ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
-+                              le32_to_cpu(HDR(bh)->h_refcount),
-+                              EXT2_XATTR_REFCOUNT_MAX);
-+              } else if (!ext2_xattr_cmp(header, HDR(bh))) {
-+                      ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
-+                      mb_cache_entry_release(ce);
-+                      return bh;
-+              }
-+              brelse(bh);
-+              ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * ext2_xattr_cache_remove()
-+ *
-+ * Remove the cache entry of a block from the cache. Called when a
-+ * block becomes invalid.
-+ */
-+static void
-+ext2_xattr_cache_remove(struct buffer_head *bh)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_dev, bh->b_blocknr);
-+      if (ce) {
-+              ea_bdebug(bh, "removing (%d cache entries remaining)",
-+                        atomic_read(&ext2_xattr_cache->c_entry_count)-1);
-+              mb_cache_entry_free(ce);
-+      } else 
-+              ea_bdebug(bh, "no cache entry");
-+}
-+
-+#define NAME_HASH_SHIFT 5
-+#define VALUE_HASH_SHIFT 16
-+
-+/*
-+ * ext2_xattr_hash_entry()
-+ *
-+ * Compute the hash of an extended attribute.
-+ */
-+static inline void ext2_xattr_hash_entry(struct ext2_xattr_header *header,
-+                                       struct ext2_xattr_entry *entry)
-+{
-+      __u32 hash = 0;
-+      char *name = entry->e_name;
-+      int n;
-+
-+      for (n=0; n < entry->e_name_len; n++) {
-+              hash = (hash << NAME_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
-+                     *name++;
-+      }
-+
-+      if (entry->e_value_block == 0 && entry->e_value_size != 0) {
-+              __u32 *value = (__u32 *)((char *)header +
-+                      le16_to_cpu(entry->e_value_offs));
-+              for (n = (le32_to_cpu(entry->e_value_size) +
-+                   EXT2_XATTR_ROUND) >> EXT2_XATTR_PAD_BITS; n; n--) {
-+                      hash = (hash << VALUE_HASH_SHIFT) ^
-+                             (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
-+                             le32_to_cpu(*value++);
-+              }
-+      }
-+      entry->e_hash = cpu_to_le32(hash);
-+}
-+
-+#undef NAME_HASH_SHIFT
-+#undef VALUE_HASH_SHIFT
-+
-+#define BLOCK_HASH_SHIFT 16
-+
-+/*
-+ * ext2_xattr_rehash()
-+ *
-+ * Re-compute the extended attribute hash value after an entry has changed.
-+ */
-+static void ext2_xattr_rehash(struct ext2_xattr_header *header,
-+                            struct ext2_xattr_entry *entry)
-+{
-+      struct ext2_xattr_entry *here;
-+      __u32 hash = 0;
-+      
-+      ext2_xattr_hash_entry(header, entry);
-+      here = ENTRY(header+1);
-+      while (!IS_LAST_ENTRY(here)) {
-+              if (!here->e_hash) {
-+                      /* Block is not shared if an entry's hash value == 0 */
-+                      hash = 0;
-+                      break;
-+              }
-+              hash = (hash << BLOCK_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
-+                     le32_to_cpu(here->e_hash);
-+              here = EXT2_XATTR_NEXT(here);
-+      }
-+      header->h_hash = cpu_to_le32(hash);
-+}
-+
-+#undef BLOCK_HASH_SHIFT
-+
-+int __init
-+init_ext2_xattr(void)
-+{
-+      ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
-+              sizeof(struct mb_cache_entry) +
-+              sizeof(struct mb_cache_entry_index), 1, 61);
-+      if (!ext2_xattr_cache)
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+void
-+exit_ext2_xattr(void)
-+{
-+      mb_cache_destroy(ext2_xattr_cache);
-+}
-+
-+#else  /* CONFIG_EXT2_FS_XATTR_SHARING */
-+
-+int __init
-+init_ext2_xattr(void)
-+{
-+      return 0;
-+}
-+
-+void
-+exit_ext2_xattr(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT2_FS_XATTR_SHARING */
---- /dev/null  2003-01-30 03:24:37.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext2/xattr_user.c    2003-04-09 16:30:59.000000000 -0600
-@@ -0,0 +1,103 @@
-+/*
-+ * linux/fs/ext2/xattr_user.c
-+ * Handler for extended user attributes.
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/fs.h>
-+#include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
-+
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+# include <linux/ext2_acl.h>
-+#endif
-+
-+#define XATTR_USER_PREFIX "user."
-+
-+static size_t
-+ext2_xattr_user_list(char *list, struct inode *inode,
-+                   const char *name, int name_len)
-+{
-+      const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
-+
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return 0;
-+
-+      if (list) {
-+              memcpy(list, XATTR_USER_PREFIX, prefix_len);
-+              memcpy(list+prefix_len, name, name_len);
-+              list[prefix_len + name_len] = '\0';
-+      }
-+      return prefix_len + name_len + 1;
-+}
-+
-+static int
-+ext2_xattr_user_get(struct inode *inode, const char *name,
-+                  void *buffer, size_t size)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+      error = ext2_permission_locked(inode, MAY_READ);
-+#else
-+      error = permission(inode, MAY_READ);
-+#endif
-+      if (error)
-+              return error;
-+
-+      return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name,
-+                            buffer, size);
-+}
-+
-+static int
-+ext2_xattr_user_set(struct inode *inode, const char *name,
-+                  const void *value, size_t size, int flags)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+      if ( !S_ISREG(inode->i_mode) &&
-+          (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-+              return -EPERM;
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+      error = ext2_permission_locked(inode, MAY_WRITE);
-+#else
-+      error = permission(inode, MAY_WRITE);
-+#endif
-+      if (error)
-+              return error;
-+  
-+      return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
-+                            value, size, flags);
-+}
-+
-+struct ext2_xattr_handler ext2_xattr_user_handler = {
-+      prefix: XATTR_USER_PREFIX,
-+      list:   ext2_xattr_user_list,
-+      get:    ext2_xattr_user_get,
-+      set:    ext2_xattr_user_set,
-+};
-+
-+int __init
-+init_ext2_xattr_user(void)
-+{
-+      return ext2_xattr_register(EXT2_XATTR_INDEX_USER,
-+                                 &ext2_xattr_user_handler);
-+}
-+
-+void
-+exit_ext2_xattr_user(void)
-+{
-+      ext2_xattr_unregister(EXT2_XATTR_INDEX_USER,
-+                            &ext2_xattr_user_handler);
-+}
---- linux-chaos-2.4.20-6/fs/ext3/Makefile~linux-2.4.20-xattr-0.8.54-chaos      2003-04-09 16:26:17.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/Makefile        2003-04-09 16:30:59.000000000 -0600
-@@ -1,5 +1,5 @@
- #
--# Makefile for the linux ext2-filesystem routines.
-+# Makefile for the linux ext3-filesystem routines.
- #
- # Note! Dependencies are done automagically by 'make dep', which also
- # removes any old dependencies. DON'T put your own dependencies here
-@@ -15,4 +15,8 @@ obj-y    := balloc.o bitmap.o dir.o file
-               ioctl.o namei.o super.o symlink.o hash.o
- obj-m    := $(O_TARGET)
-+export-objs += xattr.o
-+obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o
-+obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o
-+
- include $(TOPDIR)/Rules.make
---- linux-chaos-2.4.20-6/fs/ext3/file.c~linux-2.4.20-xattr-0.8.54-chaos        2003-04-09 16:26:17.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/file.c  2003-04-09 16:30:59.000000000 -0600
-@@ -23,6 +23,7 @@
- #include <linux/locks.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/ext3_jbd.h>
- #include <linux/smp_lock.h>
-@@ -126,5 +127,9 @@ struct file_operations ext3_file_operati
- struct inode_operations ext3_file_inode_operations = {
-       truncate:       ext3_truncate,          /* BKL held */
-       setattr:        ext3_setattr,           /* BKL held */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
---- linux-chaos-2.4.20-6/fs/ext3/ialloc.c~linux-2.4.20-xattr-0.8.54-chaos      2003-03-12 12:51:02.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/ialloc.c        2003-04-09 16:30:59.000000000 -0600
-@@ -17,6 +17,7 @@
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/stat.h>
- #include <linux/string.h>
- #include <linux/locks.h>
-@@ -216,6 +217,7 @@ void ext3_free_inode (handle_t *handle, 
-        * as writing the quota to disk may need the lock as well.
-        */
-       DQUOT_INIT(inode);
-+      ext3_xattr_delete_inode(handle, inode);
-       DQUOT_FREE_INODE(inode);
-       DQUOT_DROP(inode);
---- linux-chaos-2.4.20-6/fs/ext3/inode.c~linux-2.4.20-xattr-0.8.54-chaos       2003-03-12 12:51:02.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/inode.c 2003-04-09 16:30:59.000000000 -0600
-@@ -39,6 +39,18 @@
-  */
- #undef SEARCH_FROM_ZERO
-+/*
-+ * Test whether an inode is a fast symlink.
-+ */
-+static inline int ext3_inode_is_fast_symlink(struct inode *inode)
-+{
-+      int ea_blocks = inode->u.ext3_i.i_file_acl ?
-+              (inode->i_sb->s_blocksize >> 9) : 0;
-+
-+      return (S_ISLNK(inode->i_mode) &&
-+              inode->i_blocks - ea_blocks == 0);
-+}
-+
- /* The ext3 forget function must perform a revoke if we are freeing data
-  * which has been journaled.  Metadata (eg. indirect blocks) must be
-  * revoked in all cases. 
-@@ -48,7 +60,7 @@
-  * still needs to be revoked.
-  */
--static int ext3_forget(handle_t *handle, int is_metadata,
-+int ext3_forget(handle_t *handle, int is_metadata,
-                      struct inode *inode, struct buffer_head *bh,
-                      int blocknr)
- {
-@@ -179,9 +191,7 @@ void ext3_delete_inode (struct inode * i
- {
-       handle_t *handle;
-       
--      if (is_bad_inode(inode) ||
--          inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
-+      if (is_bad_inode(inode))
-               goto no_delete;
-       lock_kernel();
-@@ -1874,6 +1884,8 @@ void ext3_truncate(struct inode * inode)
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-+      if (ext3_inode_is_fast_symlink(inode))
-+              return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-@@ -2021,8 +2033,6 @@ int ext3_get_inode_loc (struct inode *in
-       struct ext3_group_desc * gdp;
-               
-       if ((inode->i_ino != EXT3_ROOT_INO &&
--              inode->i_ino != EXT3_ACL_IDX_INO &&
--              inode->i_ino != EXT3_ACL_DATA_INO &&
-               inode->i_ino != EXT3_JOURNAL_INO &&
-               inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
-               inode->i_ino > le32_to_cpu(
-@@ -2149,10 +2159,7 @@ void ext3_read_inode(struct inode * inod
-       brelse (iloc.bh);
--      if (inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
--              /* Nothing to do */ ;
--      else if (S_ISREG(inode->i_mode)) {
-+      if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &ext3_file_inode_operations;
-               inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-@@ -2160,15 +2167,17 @@ void ext3_read_inode(struct inode * inod
-               inode->i_op = &ext3_dir_inode_operations;
-               inode->i_fop = &ext3_dir_operations;
-       } else if (S_ISLNK(inode->i_mode)) {
--              if (!inode->i_blocks)
-+              if (ext3_inode_is_fast_symlink(inode))
-                       inode->i_op = &ext3_fast_symlink_inode_operations;
-               else {
--                      inode->i_op = &page_symlink_inode_operations;
-+                      inode->i_op = &ext3_symlink_inode_operations;
-                       inode->i_mapping->a_ops = &ext3_aops;
-               }
--      } else 
-+      } else {
-+              inode->i_op = &ext3_special_inode_operations;
-               init_special_inode(inode, inode->i_mode,
-                                  le32_to_cpu(iloc.raw_inode->i_block[0]));
-+      }
-       /* inode->i_attr_flags = 0;                             unused */
-       if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) {
-               /* inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS; unused */
---- linux-chaos-2.4.20-6/fs/ext3/namei.c~linux-2.4.20-xattr-0.8.54-chaos       2003-04-09 16:26:24.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/namei.c 2003-04-09 16:30:59.000000000 -0600
-@@ -29,6 +29,7 @@
- #include <linux/sched.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/fcntl.h>
- #include <linux/stat.h>
- #include <linux/string.h>
-@@ -1613,7 +1614,7 @@ static int ext3_mkdir(struct inode * dir
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
--      inode = ext3_new_inode (handle, dir, S_IFDIR);
-+      inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
-       err = PTR_ERR(inode);
-       if (IS_ERR(inode))
-               goto out_stop;
-@@ -1621,7 +1622,6 @@ static int ext3_mkdir(struct inode * dir
-       inode->i_op = &ext3_dir_inode_operations;
-       inode->i_fop = &ext3_dir_operations;
-       inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
--      inode->i_blocks = 0;    
-       dir_block = ext3_bread (handle, inode, 0, 1, &err);
-       if (!dir_block) {
-               inode->i_nlink--; /* is this nlink == 0? */
-@@ -1648,9 +1648,6 @@ static int ext3_mkdir(struct inode * dir
-       BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
-       ext3_journal_dirty_metadata(handle, dir_block);
-       brelse (dir_block);
--      inode->i_mode = S_IFDIR | mode;
--      if (dir->i_mode & S_ISGID)
--              inode->i_mode |= S_ISGID;
-       ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_entry (handle, dentry, inode);
-       if (err) {
-@@ -2019,7 +2016,7 @@ static int ext3_symlink (struct inode * 
-               goto out_stop;
-       if (l > sizeof (EXT3_I(inode)->i_data)) {
--              inode->i_op = &page_symlink_inode_operations;
-+              inode->i_op = &ext3_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-               /*
-                * block_symlink() calls back into ext3_prepare/commit_write.
-@@ -2245,4 +2242,16 @@ struct inode_operations ext3_dir_inode_o
-       rmdir:          ext3_rmdir,             /* BKL held */
-       mknod:          ext3_mknod,             /* BKL held */
-       rename:         ext3_rename,            /* BKL held */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
-+
-+struct inode_operations ext3_special_inode_operations = {
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
-+};
-+
---- linux-chaos-2.4.20-6/fs/ext3/super.c~linux-2.4.20-xattr-0.8.54-chaos       2003-04-09 16:26:17.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/super.c 2003-04-09 16:30:59.000000000 -0600
-@@ -24,6 +24,7 @@
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/locks.h>
-@@ -406,6 +407,7 @@ void ext3_put_super (struct super_block 
-       kdev_t j_dev = sbi->s_journal->j_dev;
-       int i;
-+      ext3_xattr_put_super(sb);
-       journal_destroy(sbi->s_journal);
-       if (!(sb->s_flags & MS_RDONLY)) {
-               EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
-@@ -502,6 +504,7 @@ static int parse_options (char * options
-                         int is_remount)
- {
-       unsigned long *mount_options = &sbi->s_mount_opt;
-+      
-       uid_t *resuid = &sbi->s_resuid;
-       gid_t *resgid = &sbi->s_resgid;
-       char * this_char;
-@@ -514,6 +517,13 @@ static int parse_options (char * options
-            this_char = strtok (NULL, ",")) {
-               if ((value = strchr (this_char, '=')) != NULL)
-                       *value++ = 0;
-+#ifdef CONFIG_EXT3_FS_XATTR_USER
-+              if (!strcmp (this_char, "user_xattr"))
-+                      set_opt (*mount_options, XATTR_USER);
-+              else if (!strcmp (this_char, "nouser_xattr"))
-+                      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")) {
-@@ -931,6 +941,12 @@ struct super_block * ext3_read_super (st
-       sbi->s_mount_opt = 0;
-       sbi->s_resuid = EXT3_DEF_RESUID;
-       sbi->s_resgid = EXT3_DEF_RESGID;
-+
-+      /* Default extended attribute flags */
-+#ifdef CONFIG_EXT3_FS_XATTR_USER
-+      /* set_opt(sbi->s_mount_opt, XATTR_USER); */
-+#endif
-+
-       if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) {
-               sb->s_dev = 0;
-               goto out_fail;
-@@ -1768,12 +1784,27 @@ static DECLARE_FSTYPE_DEV(ext3_fs_type, 
- static int __init init_ext3_fs(void)
- {
--        return register_filesystem(&ext3_fs_type);
-+      int error = init_ext3_xattr();
-+      if (error)
-+              return error;
-+      error = init_ext3_xattr_user();
-+      if (error)
-+              goto fail;
-+      error = register_filesystem(&ext3_fs_type);
-+      if (!error)
-+              return 0;
-+      
-+      exit_ext3_xattr_user();
-+fail:
-+      exit_ext3_xattr();
-+      return error;
- }
- static void __exit exit_ext3_fs(void)
- {
-       unregister_filesystem(&ext3_fs_type);
-+      exit_ext3_xattr_user();
-+      exit_ext3_xattr();
- }
- EXPORT_SYMBOL(ext3_force_commit);
---- linux-chaos-2.4.20-6/fs/ext3/symlink.c~linux-2.4.20-xattr-0.8.54-chaos     2002-05-07 15:53:46.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/symlink.c       2003-04-09 16:30:59.000000000 -0600
-@@ -20,6 +20,7 @@
- #include <linux/fs.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
- static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
-@@ -33,7 +34,20 @@ static int ext3_follow_link(struct dentr
-       return vfs_follow_link(nd, s);
- }
-+struct inode_operations ext3_symlink_inode_operations = {
-+      readlink:       page_readlink,          /* BKL not held.  Don't need */
-+      follow_link:    page_follow_link,       /* BKL not held.  Don't need */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
-+};
-+
- struct inode_operations ext3_fast_symlink_inode_operations = {
-       readlink:       ext3_readlink,          /* BKL not held.  Don't need */
-       follow_link:    ext3_follow_link,       /* BKL not held.  Don't need */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
---- /dev/null  2003-01-30 03:24:37.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/xattr.c 2003-04-09 16:30:59.000000000 -0600
-@@ -0,0 +1,1232 @@
-+/*
-+ * linux/fs/ext3/xattr.c
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
-+ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
-+ * Extended attributes for symlinks and special files added per
-+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
-+ */
-+
-+/*
-+ * Extended attributes are stored on disk blocks allocated outside of
-+ * any inode. The i_file_acl field is then made to point to this allocated
-+ * block. If all extended attributes of an inode are identical, these
-+ * inodes may share the same extended attribute block. Such situations
-+ * are automatically detected by keeping a cache of recent attribute block
-+ * numbers and hashes over the block's contents in memory.
-+ *
-+ *
-+ * Extended attribute block layout:
-+ *
-+ *   +------------------+
-+ *   | header           |
-+ *   | entry 1          | |
-+ *   | entry 2          | | growing downwards
-+ *   | entry 3          | v
-+ *   | four null bytes  |
-+ *   | . . .            |
-+ *   | value 1          | ^
-+ *   | value 3          | | growing upwards
-+ *   | value 2          | |
-+ *   +------------------+
-+ *
-+ * The block header is followed by multiple entry descriptors. These entry
-+ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
-+ * byte boundaries. The entry descriptors are sorted by attribute name,
-+ * so that two extended attribute blocks can be compared efficiently.
-+ *
-+ * Attribute values are aligned to the end of the block, stored in
-+ * no specific order. They are also padded to EXT3_XATTR_PAD byte
-+ * boundaries. No additional gaps are left between them.
-+ *
-+ * Locking strategy
-+ * ----------------
-+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
-+ * the xattr inode operations are called, so we are guaranteed that only one
-+ * processes accesses extended attributes of an inode at any time.
-+ *
-+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
-+ * only a single process is modifying an extended attribute block, even
-+ * if the block is shared among inodes.
-+ *
-+ * Note for porting to 2.5
-+ * -----------------------
-+ * The BKL will no longer be held in the xattr inode operations.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/locks.h>
-+#include <linux/slab.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
-+#include <linux/mbcache.h>
-+#include <linux/quotaops.h>
-+#include <asm/semaphore.h>
-+#include <linux/compatmac.h>
-+
-+#define EXT3_EA_USER "user."
-+
-+/* These symbols may be needed by a module. */
-+EXPORT_SYMBOL(ext3_xattr_register);
-+EXPORT_SYMBOL(ext3_xattr_unregister);
-+EXPORT_SYMBOL(ext3_xattr_get);
-+EXPORT_SYMBOL(ext3_xattr_list);
-+EXPORT_SYMBOL(ext3_xattr_set);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
-+#endif
-+
-+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
-+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
-+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
-+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
-+
-+#ifdef EXT3_XATTR_DEBUG
-+# define ea_idebug(inode, f...) do { \
-+              printk(KERN_DEBUG "inode %s:%ld: ", \
-+                      kdevname(inode->i_dev), inode->i_ino); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+# define ea_bdebug(bh, f...) do { \
-+              printk(KERN_DEBUG "block %s:%ld: ", \
-+                      kdevname(bh->b_dev), bh->b_blocknr); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+#else
-+# define ea_idebug(f...)
-+# define ea_bdebug(f...)
-+#endif
-+
-+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
-+                         struct ext3_xattr_header *);
-+
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+
-+static int ext3_xattr_cache_insert(struct buffer_head *);
-+static struct buffer_head *ext3_xattr_cache_find(struct inode *,
-+                                               struct ext3_xattr_header *);
-+static void ext3_xattr_cache_remove(struct buffer_head *);
-+static void ext3_xattr_rehash(struct ext3_xattr_header *,
-+                            struct ext3_xattr_entry *);
-+
-+static struct mb_cache *ext3_xattr_cache;
-+
-+#else
-+# define ext3_xattr_cache_insert(bh) 0
-+# define ext3_xattr_cache_find(inode, header) NULL
-+# define ext3_xattr_cache_remove(bh) while(0) {}
-+# define ext3_xattr_rehash(header, entry) while(0) {}
-+#endif
-+
-+/*
-+ * If a file system does not share extended attributes among inodes,
-+ * we should not need the ext3_xattr_sem semaphore. However, the
-+ * filesystem may still contain shared blocks, so we always take
-+ * the lock.
-+ */
-+
-+DECLARE_MUTEX(ext3_xattr_sem);
-+
-+static inline int
-+ext3_xattr_new_block(handle_t *handle, struct inode *inode,
-+                   int * errp, int force)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
-+              EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb);
-+
-+      /* How can we enforce the allocation? */
-+      int block = ext3_new_block(handle, inode, goal, 0, 0, errp);
-+#ifdef OLD_QUOTAS
-+      if (!*errp)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#endif
-+      return block;
-+}
-+
-+static inline int
-+ext3_xattr_quota_alloc(struct inode *inode, int force)
-+{
-+      /* How can we enforce the allocation? */
-+#ifdef OLD_QUOTAS
-+      int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
-+      if (!error)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#else
-+      int error = DQUOT_ALLOC_BLOCK(inode, 1);
-+#endif
-+      return error;
-+}
-+
-+#ifdef OLD_QUOTAS
-+
-+static inline void
-+ext3_xattr_quota_free(struct inode *inode)
-+{
-+      DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+static inline void
-+ext3_xattr_free_block(handle_t *handle, struct inode * inode,
-+                    unsigned long block)
-+{
-+      ext3_free_blocks(handle, inode, block, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+#else
-+# define ext3_xattr_quota_free(inode) \
-+      DQUOT_FREE_BLOCK(inode, 1)
-+# define ext3_xattr_free_block(handle, inode, block) \
-+      ext3_free_blocks(handle, inode, block, 1)
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
-+
-+static inline struct buffer_head *
-+sb_bread(struct super_block *sb, int block)
-+{
-+      return bread(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+static inline struct buffer_head *
-+sb_getblk(struct super_block *sb, int block)
-+{
-+      return getblk(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+#endif
-+
-+struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
-+rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
-+
-+int
-+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      int error = -EINVAL;
-+
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              if (!ext3_xattr_handlers[name_index-1]) {
-+                      ext3_xattr_handlers[name_index-1] = handler;
-+                      error = 0;
-+              }
-+              write_unlock(&ext3_handler_lock);
-+      }
-+      return error;
-+}
-+
-+void
-+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              ext3_xattr_handlers[name_index-1] = NULL;
-+              write_unlock(&ext3_handler_lock);
-+      }
-+}
-+
-+static inline const char *
-+strcmp_prefix(const char *a, const char *a_prefix)
-+{
-+      while (*a_prefix && *a == *a_prefix) {
-+              a++;
-+              a_prefix++;
-+      }
-+      return *a_prefix ? NULL : a;
-+}
-+
-+/*
-+ * Decode the extended attribute name, and translate it into
-+ * the name_index and name suffix.
-+ */
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_resolve_name(const char **name)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      int i;
-+
-+      if (!*name)
-+              return NULL;
-+      read_lock(&ext3_handler_lock);
-+      for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
-+              if (ext3_xattr_handlers[i]) {
-+                      const char *n = strcmp_prefix(*name,
-+                              ext3_xattr_handlers[i]->prefix);
-+                      if (n) {
-+                              handler = ext3_xattr_handlers[i];
-+                              *name = n;
-+                              break;
-+                      }
-+              }
-+      }
-+      read_unlock(&ext3_handler_lock);
-+      return handler;
-+}
-+
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_handler(int name_index)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              read_lock(&ext3_handler_lock);
-+              handler = ext3_xattr_handlers[name_index-1];
-+              read_unlock(&ext3_handler_lock);
-+      }
-+      return handler;
-+}
-+
-+/*
-+ * Inode operation getxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext3_getxattr(struct dentry *dentry, const char *name,
-+            void *buffer, size_t size)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->get(inode, name, buffer, size);
-+}
-+
-+/*
-+ * Inode operation listxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
-+{
-+      return ext3_xattr_list(dentry->d_inode, buffer, size);
-+}
-+
-+/*
-+ * Inode operation setxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext3_setxattr(struct dentry *dentry, const char *name,
-+            const void *value, size_t size, int flags)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      if (size == 0)
-+              value = "";  /* empty EA, do not remove */
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, value, size, flags);
-+}
-+
-+/*
-+ * Inode operation removexattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext3_removexattr(struct dentry *dentry, const char *name)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
-+}
-+
-+/*
-+ * ext3_xattr_get()
-+ *
-+ * Copy an extended attribute into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size;
-+      char *end;
-+      int name_len, error;
-+
-+      ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
-+                name_index, name, buffer, (long)buffer_size);
-+
-+      if (name == NULL)
-+              return -EINVAL;
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return -ENOATTR;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_get",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* find named attribute */
-+      name_len = strlen(name);
-+
-+      error = -ERANGE;
-+      if (name_len > 255)
-+              goto cleanup;
-+      entry = FIRST_ENTRY(bh);
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              if (name_index == entry->e_name_index &&
-+                  name_len == entry->e_name_len &&
-+                  memcmp(name, entry->e_name, name_len) == 0)
-+                      goto found;
-+              entry = next;
-+      }
-+      /* Check the remaining name entries */
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              entry = next;
-+      }
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      error = -ENOATTR;
-+      goto cleanup;
-+found:
-+      /* check the buffer size */
-+      if (entry->e_value_block != 0)
-+              goto bad_block;
-+      size = le32_to_cpu(entry->e_value_size);
-+      if (size > inode->i_sb->s_blocksize ||
-+          le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-+              goto bad_block;
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (buffer) {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+              /* return value of attribute */
-+              memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-+                      size);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_list()
-+ *
-+ * Copy a list of attribute names into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size = 0;
-+      char *buf, *end;
-+      int error;
-+
-+      ea_idebug(inode, "buffer=%p, buffer_size=%ld",
-+                buffer, (long)buffer_size);
-+
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return 0;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_list",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* compute the size required for the list of attribute names */
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      size += handler->list(NULL, inode, entry->e_name,
-+                                            entry->e_name_len);
-+      }
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (!buffer) {
-+              error = size;
-+              goto cleanup;
-+      } else {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+      }
-+
-+      /* list the attribute names */
-+      buf = buffer;
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      buf += handler->list(buf, inode, entry->e_name,
-+                                           entry->e_name_len);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
-+ * not set, set it.
-+ */
-+static void ext3_xattr_update_super_block(handle_t *handle,
-+                                        struct super_block *sb)
-+{
-+      if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
-+              return;
-+
-+      lock_super(sb);
-+      ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+      EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR;
-+#endif
-+      EXT3_SB(sb)->s_es->s_feature_compat |=
-+              cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
-+      sb->s_dirt = 1;
-+      ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-+      unlock_super(sb);
-+}
-+
-+/*
-+ * ext3_xattr_set()
-+ *
-+ * Create, replace or remove an extended attribute for this inode. Buffer
-+ * is NULL to remove an existing extended attribute, and non-NULL to
-+ * either replace an existing extended attribute, or create a new extended
-+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
-+ * specify that an extended attribute must exist and must not exist
-+ * previous to the call, respectively.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, const void *value, size_t value_len, int flags)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_header *header = NULL;
-+      struct ext3_xattr_entry *here, *last;
-+      unsigned int name_len;
-+      int block = EXT3_I(inode)->i_file_acl;
-+      int min_offs = sb->s_blocksize, not_found = 1, free, error;
-+      char *end;
-+      
-+      /*
-+       * header -- Points either into bh, or to a temporarily
-+       *           allocated buffer.
-+       * here -- The named entry found, or the place for inserting, within
-+       *         the block pointed to by header.
-+       * last -- Points right after the last named entry within the block
-+       *         pointed to by header.
-+       * min_offs -- The offset of the first value (values are aligned
-+       *             towards the end of the block).
-+       * end -- Points right after the block pointed to by header.
-+       */
-+      
-+      ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-+                name_index, name, value, (long)value_len);
-+
-+      if (IS_RDONLY(inode))
-+              return -EROFS;
-+      if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-+              return -EPERM;
-+      if (value == NULL)
-+              value_len = 0;
-+      if (name == NULL)
-+              return -EINVAL;
-+      name_len = strlen(name);
-+      if (name_len > 255 || value_len > sb->s_blocksize)
-+              return -ERANGE;
-+      down(&ext3_xattr_sem);
-+
-+      if (block) {
-+              /* The inode already has an extended attribute block. */
-+              bh = sb_bread(sb, block);
-+              error = -EIO;
-+              if (!bh)
-+                      goto cleanup;
-+              ea_bdebug(bh, "b_count=%d, refcount=%d",
-+                      atomic_read(&(bh->b_count)),
-+                      le32_to_cpu(HDR(bh)->h_refcount));
-+              header = HDR(bh);
-+              end = bh->b_data + bh->b_size;
-+              if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+                  header->h_blocks != cpu_to_le32(1)) {
-+bad_block:            ext3_error(sb, "ext3_xattr_set",
-+                              "inode %ld: bad block %d", inode->i_ino, block);
-+                      error = -EIO;
-+                      goto cleanup;
-+              }
-+              /* Find the named attribute. */
-+              here = FIRST_ENTRY(bh);
-+              while (!IS_LAST_ENTRY(here)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!here->e_value_block && here->e_value_size) {
-+                              int offs = le16_to_cpu(here->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      not_found = name_index - here->e_name_index;
-+                      if (!not_found)
-+                              not_found = name_len - here->e_name_len;
-+                      if (!not_found)
-+                              not_found = memcmp(name, here->e_name,name_len);
-+                      if (not_found <= 0)
-+                              break;
-+                      here = next;
-+              }
-+              last = here;
-+              /* We still need to compute min_offs and last. */
-+              while (!IS_LAST_ENTRY(last)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!last->e_value_block && last->e_value_size) {
-+                              int offs = le16_to_cpu(last->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      last = next;
-+              }
-+
-+              /* Check whether we have enough space left. */
-+              free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-+      } else {
-+              /* We will use a new extended attribute block. */
-+              free = sb->s_blocksize -
-+                      sizeof(struct ext3_xattr_header) - sizeof(__u32);
-+              here = last = NULL;  /* avoid gcc uninitialized warning. */
-+      }
-+
-+      if (not_found) {
-+              /* Request to remove a nonexistent attribute? */
-+              error = -ENOATTR;
-+              if (flags & XATTR_REPLACE)
-+                      goto cleanup;
-+              error = 0;
-+              if (value == NULL)
-+                      goto cleanup;
-+              else
-+                      free -= EXT3_XATTR_LEN(name_len);
-+      } else {
-+              /* Request to create an existing attribute? */
-+              error = -EEXIST;
-+              if (flags & XATTR_CREATE)
-+                      goto cleanup;
-+              if (!here->e_value_block && here->e_value_size) {
-+                      unsigned int size = le32_to_cpu(here->e_value_size);
-+
-+                      if (le16_to_cpu(here->e_value_offs) + size > 
-+                          sb->s_blocksize || size > sb->s_blocksize)
-+                              goto bad_block;
-+                      free += EXT3_XATTR_SIZE(size);
-+              }
-+      }
-+      free -= EXT3_XATTR_SIZE(value_len);
-+      error = -ENOSPC;
-+      if (free < 0)
-+              goto cleanup;
-+
-+      /* Here we know that we can set the new attribute. */
-+
-+      if (header) {
-+              if (header->h_refcount == cpu_to_le32(1)) {
-+                      ea_bdebug(bh, "modifying in-place");
-+                      ext3_xattr_cache_remove(bh);
-+                      error = ext3_journal_get_write_access(handle, bh);
-+                      if (error)
-+                              goto cleanup;
-+              } else {
-+                      int offset;
-+
-+                      ea_bdebug(bh, "cloning");
-+                      header = kmalloc(bh->b_size, GFP_KERNEL);
-+                      error = -ENOMEM;
-+                      if (header == NULL)
-+                              goto cleanup;
-+                      memcpy(header, HDR(bh), bh->b_size);
-+                      header->h_refcount = cpu_to_le32(1);
-+                      offset = (char *)header - bh->b_data;
-+                      here = ENTRY((char *)here + offset);
-+                      last = ENTRY((char *)last + offset);
-+              }
-+      } else {
-+              /* Allocate a buffer where we construct the new block. */
-+              header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-+              error = -ENOMEM;
-+              if (header == NULL)
-+                      goto cleanup;
-+              memset(header, 0, sb->s_blocksize);
-+              end = (char *)header + sb->s_blocksize;
-+              header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
-+              header->h_blocks = header->h_refcount = cpu_to_le32(1);
-+              last = here = ENTRY(header+1);
-+      }
-+
-+      if (not_found) {
-+              /* Insert the new name. */
-+              int size = EXT3_XATTR_LEN(name_len);
-+              int rest = (char *)last - (char *)here;
-+              memmove((char *)here + size, here, rest);
-+              memset(here, 0, size);
-+              here->e_name_index = name_index;
-+              here->e_name_len = name_len;
-+              memcpy(here->e_name, name, name_len);
-+      } else {
-+              /* Remove the old value. */
-+              if (!here->e_value_block && here->e_value_size) {
-+                      char *first_val = (char *)header + min_offs;
-+                      int offs = le16_to_cpu(here->e_value_offs);
-+                      char *val = (char *)header + offs;
-+                      size_t size = EXT3_XATTR_SIZE(
-+                              le32_to_cpu(here->e_value_size));
-+                      memmove(first_val + size, first_val, val - first_val);
-+                      memset(first_val, 0, size);
-+                      here->e_value_offs = 0;
-+                      min_offs += size;
-+
-+                      /* Adjust all value offsets. */
-+                      last = ENTRY(header+1);
-+                      while (!IS_LAST_ENTRY(last)) {
-+                              int o = le16_to_cpu(last->e_value_offs);
-+                              if (!last->e_value_block && o < offs)
-+                                      last->e_value_offs =
-+                                              cpu_to_le16(o + size);
-+                              last = EXT3_XATTR_NEXT(last);
-+                      }
-+              }
-+              if (value == NULL) {
-+                      /* Remove this attribute. */
-+                      if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
-+                              /* This block is now empty. */
-+                              error = ext3_xattr_set2(handle, inode, bh,NULL);
-+                              goto cleanup;
-+                      } else {
-+                              /* Remove the old name. */
-+                              int size = EXT3_XATTR_LEN(name_len);
-+                              last = ENTRY((char *)last - size);
-+                              memmove(here, (char*)here + size,
-+                                      (char*)last - (char*)here);
-+                              memset(last, 0, size);
-+                      }
-+              }
-+      }
-+
-+      if (value != NULL) {
-+              /* Insert the new value. */
-+              here->e_value_size = cpu_to_le32(value_len);
-+              if (value_len) {
-+                      size_t size = EXT3_XATTR_SIZE(value_len);
-+                      char *val = (char *)header + min_offs - size;
-+                      here->e_value_offs =
-+                              cpu_to_le16((char *)val - (char *)header);
-+                      memset(val + size - EXT3_XATTR_PAD, 0,
-+                             EXT3_XATTR_PAD); /* Clear the pad bytes. */
-+                      memcpy(val, value, value_len);
-+              }
-+      }
-+      ext3_xattr_rehash(header, here);
-+
-+      error = ext3_xattr_set2(handle, inode, bh, header);
-+
-+cleanup:
-+      brelse(bh);
-+      if (!(bh && header == HDR(bh)))
-+              kfree(header);
-+      up(&ext3_xattr_sem);
-+
-+      return error;
-+}
-+
-+/*
-+ * Second half of ext3_xattr_set(): Update the file system.
-+ */
-+static int
-+ext3_xattr_set2(handle_t *handle, struct inode *inode,
-+              struct buffer_head *old_bh, struct ext3_xattr_header *header)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *new_bh = NULL;
-+      int error;
-+
-+      if (header) {
-+              new_bh = ext3_xattr_cache_find(inode, header);
-+              if (new_bh) {
-+                      /*
-+                       * We found an identical block in the cache.
-+                       * The old block will be released after updating
-+                       * the inode.
-+                       */
-+                      ea_bdebug(old_bh, "reusing block %ld",
-+                              new_bh->b_blocknr);
-+                      
-+                      error = -EDQUOT;
-+                      if (ext3_xattr_quota_alloc(inode, 1))
-+                              goto cleanup;
-+                      
-+                      error = ext3_journal_get_write_access(handle, new_bh);
-+                      if (error)
-+                              goto cleanup;
-+                      HDR(new_bh)->h_refcount = cpu_to_le32(
-+                              le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
-+                      ea_bdebug(new_bh, "refcount now=%d",
-+                              le32_to_cpu(HDR(new_bh)->h_refcount));
-+              } else if (old_bh && header == HDR(old_bh)) {
-+                      /* Keep this block. */
-+                      new_bh = old_bh;
-+                      ext3_xattr_cache_insert(new_bh);
-+              } else {
-+                      /* We need to allocate a new block */
-+                      int force = EXT3_I(inode)->i_file_acl != 0;
-+                      int block = ext3_xattr_new_block(handle, inode,
-+                                                       &error, force);
-+                      if (error)
-+                              goto cleanup;
-+                      ea_idebug(inode, "creating block %d", block);
-+
-+                      new_bh = sb_getblk(sb, block);
-+                      if (!new_bh) {
-+getblk_failed:                        ext3_xattr_free_block(handle, inode, block);
-+                              error = -EIO;
-+                              goto cleanup;
-+                      }
-+                      lock_buffer(new_bh);
-+                      error = ext3_journal_get_create_access(handle, new_bh);
-+                      if (error) {
-+                              unlock_buffer(new_bh);
-+                              goto getblk_failed;
-+                      }
-+                      memcpy(new_bh->b_data, header, new_bh->b_size);
-+                      mark_buffer_uptodate(new_bh, 1);
-+                      unlock_buffer(new_bh);
-+                      ext3_xattr_cache_insert(new_bh);
-+                      
-+                      ext3_xattr_update_super_block(handle, sb);
-+              }
-+              error = ext3_journal_dirty_metadata(handle, new_bh);
-+              if (error)
-+                      goto cleanup;
-+      }
-+
-+      /* Update the inode. */
-+      EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-+      inode->i_ctime = CURRENT_TIME;
-+      ext3_mark_inode_dirty(handle, inode);
-+      if (IS_SYNC(inode))
-+              handle->h_sync = 1;
-+
-+      error = 0;
-+      if (old_bh && old_bh != new_bh) {
-+              /*
-+               * If there was an old block, and we are not still using it,
-+               * we now release the old block.
-+              */
-+              unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
-+
-+              error = ext3_journal_get_write_access(handle, old_bh);
-+              if (error)
-+                      goto cleanup;
-+              if (refcount == 1) {
-+                      /* Free the old block. */
-+                      ea_bdebug(old_bh, "freeing");
-+                      ext3_xattr_free_block(handle, inode, old_bh->b_blocknr);
-+
-+                      /* ext3_forget() calls bforget() for us, but we
-+                         let our caller release old_bh, so we need to
-+                         duplicate the handle before. */
-+                      get_bh(old_bh);
-+                      ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
-+              } else {
-+                      /* Decrement the refcount only. */
-+                      refcount--;
-+                      HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
-+                      ext3_xattr_quota_free(inode);
-+                      ext3_journal_dirty_metadata(handle, old_bh);
-+                      ea_bdebug(old_bh, "refcount now=%d", refcount);
-+              }
-+      }
-+
-+cleanup:
-+      if (old_bh != new_bh)
-+              brelse(new_bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_delete_inode()
-+ *
-+ * Free extended attribute resources associated with this inode. This
-+ * is called immediately before an inode is freed.
-+ */
-+void
-+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
-+{
-+      struct buffer_head *bh;
-+      unsigned int block = EXT3_I(inode)->i_file_acl;
-+
-+      if (!block)
-+              return;
-+      down(&ext3_xattr_sem);
-+
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh) {
-+              ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
-+                      "inode %ld: block %d read error", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+              ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ext3_journal_get_write_access(handle, bh);
-+      ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+      if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-+              ext3_xattr_cache_remove(bh);
-+              ext3_xattr_free_block(handle, inode, block);
-+              ext3_forget(handle, 1, inode, bh, block);
-+              bh = NULL;
-+      } else {
-+              HDR(bh)->h_refcount = cpu_to_le32(
-+                      le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+              ext3_journal_dirty_metadata(handle, bh);
-+              if (IS_SYNC(inode))
-+                      handle->h_sync = 1;
-+              ext3_xattr_quota_free(inode);
-+      }
-+      EXT3_I(inode)->i_file_acl = 0;
-+
-+cleanup:
-+      brelse(bh);
-+      up(&ext3_xattr_sem);
-+}
-+
-+/*
-+ * ext3_xattr_put_super()
-+ *
-+ * This is called when a file system is unmounted.
-+ */
-+void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+      mb_cache_shrink(ext3_xattr_cache, sb->s_dev);
-+#endif
-+}
-+
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+
-+/*
-+ * ext3_xattr_cache_insert()
-+ *
-+ * Create a new entry in the extended attribute cache, and insert
-+ * it unless such an entry is already in the cache.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+static int
-+ext3_xattr_cache_insert(struct buffer_head *bh)
-+{
-+      __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
-+      struct mb_cache_entry *ce;
-+      int error;
-+
-+      ce = mb_cache_entry_alloc(ext3_xattr_cache);
-+      if (!ce)
-+              return -ENOMEM;
-+      error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
-+      if (error) {
-+              mb_cache_entry_free(ce);
-+              if (error == -EBUSY) {
-+                      ea_bdebug(bh, "already in cache (%d cache entries)",
-+                              atomic_read(&ext3_xattr_cache->c_entry_count));
-+                      error = 0;
-+              }
-+      } else {
-+              ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-+                        atomic_read(&ext3_xattr_cache->c_entry_count));
-+              mb_cache_entry_release(ce);
-+      }
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_cmp()
-+ *
-+ * Compare two extended attribute blocks for equality.
-+ *
-+ * Returns 0 if the blocks are equal, 1 if they differ, and
-+ * a negative error number on errors.
-+ */
-+static int
-+ext3_xattr_cmp(struct ext3_xattr_header *header1,
-+             struct ext3_xattr_header *header2)
-+{
-+      struct ext3_xattr_entry *entry1, *entry2;
-+
-+      entry1 = ENTRY(header1+1);
-+      entry2 = ENTRY(header2+1);
-+      while (!IS_LAST_ENTRY(entry1)) {
-+              if (IS_LAST_ENTRY(entry2))
-+                      return 1;
-+              if (entry1->e_hash != entry2->e_hash ||
-+                  entry1->e_name_len != entry2->e_name_len ||
-+                  entry1->e_value_size != entry2->e_value_size ||
-+                  memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
-+                      return 1;
-+              if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
-+                      return -EIO;
-+              if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
-+                         (char *)header2 + le16_to_cpu(entry2->e_value_offs),
-+                         le32_to_cpu(entry1->e_value_size)))
-+                      return 1;
-+
-+              entry1 = EXT3_XATTR_NEXT(entry1);
-+              entry2 = EXT3_XATTR_NEXT(entry2);
-+      }
-+      if (!IS_LAST_ENTRY(entry2))
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * ext3_xattr_cache_find()
-+ *
-+ * Find an identical extended attribute block.
-+ *
-+ * Returns a pointer to the block found, or NULL if such a block was
-+ * not found or an error occurred.
-+ */
-+static struct buffer_head *
-+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
-+{
-+      __u32 hash = le32_to_cpu(header->h_hash);
-+      struct mb_cache_entry *ce;
-+
-+      if (!header->h_hash)
-+              return NULL;  /* never share */
-+      ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
-+      ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash);
-+      while (ce) {
-+              struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
-+
-+              if (!bh) {
-+                      ext3_error(inode->i_sb, "ext3_xattr_cache_find",
-+                              "inode %ld: block %ld read error",
-+                              inode->i_ino, ce->e_block);
-+              } else if (le32_to_cpu(HDR(bh)->h_refcount) >
-+                         EXT3_XATTR_REFCOUNT_MAX) {
-+                      ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
-+                              le32_to_cpu(HDR(bh)->h_refcount),
-+                              EXT3_XATTR_REFCOUNT_MAX);
-+              } else if (!ext3_xattr_cmp(header, HDR(bh))) {
-+                      ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
-+                      mb_cache_entry_release(ce);
-+                      return bh;
-+              }
-+              brelse(bh);
-+              ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * ext3_xattr_cache_remove()
-+ *
-+ * Remove the cache entry of a block from the cache. Called when a
-+ * block becomes invalid.
-+ */
-+static void
-+ext3_xattr_cache_remove(struct buffer_head *bh)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr);
-+      if (ce) {
-+              ea_bdebug(bh, "removing (%d cache entries remaining)",
-+                        atomic_read(&ext3_xattr_cache->c_entry_count)-1);
-+              mb_cache_entry_free(ce);
-+      } else 
-+              ea_bdebug(bh, "no cache entry");
-+}
-+
-+#define NAME_HASH_SHIFT 5
-+#define VALUE_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_hash_entry()
-+ *
-+ * Compute the hash of an extended attribute.
-+ */
-+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
-+                                       struct ext3_xattr_entry *entry)
-+{
-+      __u32 hash = 0;
-+      char *name = entry->e_name;
-+      int n;
-+
-+      for (n=0; n < entry->e_name_len; n++) {
-+              hash = (hash << NAME_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
-+                     *name++;
-+      }
-+
-+      if (entry->e_value_block == 0 && entry->e_value_size != 0) {
-+              __u32 *value = (__u32 *)((char *)header +
-+                      le16_to_cpu(entry->e_value_offs));
-+              for (n = (le32_to_cpu(entry->e_value_size) +
-+                   EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
-+                      hash = (hash << VALUE_HASH_SHIFT) ^
-+                             (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
-+                             le32_to_cpu(*value++);
-+              }
-+      }
-+      entry->e_hash = cpu_to_le32(hash);
-+}
-+
-+#undef NAME_HASH_SHIFT
-+#undef VALUE_HASH_SHIFT
-+
-+#define BLOCK_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_rehash()
-+ *
-+ * Re-compute the extended attribute hash value after an entry has changed.
-+ */
-+static void ext3_xattr_rehash(struct ext3_xattr_header *header,
-+                            struct ext3_xattr_entry *entry)
-+{
-+      struct ext3_xattr_entry *here;
-+      __u32 hash = 0;
-+      
-+      ext3_xattr_hash_entry(header, entry);
-+      here = ENTRY(header+1);
-+      while (!IS_LAST_ENTRY(here)) {
-+              if (!here->e_hash) {
-+                      /* Block is not shared if an entry's hash value == 0 */
-+                      hash = 0;
-+                      break;
-+              }
-+              hash = (hash << BLOCK_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
-+                     le32_to_cpu(here->e_hash);
-+              here = EXT3_XATTR_NEXT(here);
-+      }
-+      header->h_hash = cpu_to_le32(hash);
-+}
-+
-+#undef BLOCK_HASH_SHIFT
-+
-+int __init
-+init_ext3_xattr(void)
-+{
-+      ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
-+              sizeof(struct mb_cache_entry) +
-+              sizeof(struct mb_cache_entry_index), 1, 61);
-+      if (!ext3_xattr_cache)
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+void
-+exit_ext3_xattr(void)
-+{
-+      if (ext3_xattr_cache)
-+              mb_cache_destroy(ext3_xattr_cache);
-+      ext3_xattr_cache = NULL;
-+}
-+
-+#else  /* CONFIG_EXT3_FS_XATTR_SHARING */
-+
-+int __init
-+init_ext3_xattr(void)
-+{
-+      return 0;
-+}
-+
-+void
-+exit_ext3_xattr(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
---- /dev/null  2003-01-30 03:24:37.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/ext3/xattr_user.c    2003-04-09 16:30:59.000000000 -0600
-@@ -0,0 +1,111 @@
-+/*
-+ * linux/fs/ext3/xattr_user.c
-+ * Handler for extended user attributes.
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/fs.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
-+
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+# include <linux/ext3_acl.h>
-+#endif
-+
-+#define XATTR_USER_PREFIX "user."
-+
-+static size_t
-+ext3_xattr_user_list(char *list, struct inode *inode,
-+                   const char *name, int name_len)
-+{
-+      const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
-+
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return 0;
-+
-+      if (list) {
-+              memcpy(list, XATTR_USER_PREFIX, prefix_len);
-+              memcpy(list+prefix_len, name, name_len);
-+              list[prefix_len + name_len] = '\0';
-+      }
-+      return prefix_len + name_len + 1;
-+}
-+
-+static int
-+ext3_xattr_user_get(struct inode *inode, const char *name,
-+                  void *buffer, size_t size)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+      error = ext3_permission_locked(inode, MAY_READ);
-+#else
-+      error = permission(inode, MAY_READ);
-+#endif
-+      if (error)
-+              return error;
-+
-+      return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name,
-+                            buffer, size);
-+}
-+
-+static int
-+ext3_xattr_user_set(struct inode *inode, const char *name,
-+                  const void *value, size_t size, int flags)
-+{
-+      handle_t *handle;
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+      if ( !S_ISREG(inode->i_mode) &&
-+          (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-+              return -EPERM;
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+      error = ext3_permission_locked(inode, MAY_WRITE);
-+#else
-+      error = permission(inode, MAY_WRITE);
-+#endif
-+      if (error)
-+              return error;
-+  
-+      handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
-+      if (IS_ERR(handle))
-+              return PTR_ERR(handle);
-+      error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name,
-+                             value, size, flags);
-+      ext3_journal_stop(handle, inode);
-+
-+      return error;
-+}
-+
-+struct ext3_xattr_handler ext3_xattr_user_handler = {
-+      prefix: XATTR_USER_PREFIX,
-+      list:   ext3_xattr_user_list,
-+      get:    ext3_xattr_user_get,
-+      set:    ext3_xattr_user_set,
-+};
-+
-+int __init
-+init_ext3_xattr_user(void)
-+{
-+      return ext3_xattr_register(EXT3_XATTR_INDEX_USER,
-+                                 &ext3_xattr_user_handler);
-+}
-+
-+void
-+exit_ext3_xattr_user(void)
-+{
-+      ext3_xattr_unregister(EXT3_XATTR_INDEX_USER,
-+                            &ext3_xattr_user_handler);
-+}
---- linux-chaos-2.4.20-6/fs/jfs/jfs_xattr.h~linux-2.4.20-xattr-0.8.54-chaos    2003-02-14 15:59:11.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/jfs/jfs_xattr.h      2003-04-09 16:30:59.000000000 -0600
-@@ -52,8 +52,10 @@ struct jfs_ea_list {
- #define       END_EALIST(ealist) \
-       ((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist)))
--extern int __jfs_setxattr(struct inode *, const char *, void *, size_t, int);
--extern int jfs_setxattr(struct dentry *, const char *, void *, size_t, int);
-+extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t,
-+                        int);
-+extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
-+                      int);
- extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t);
- extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t);
- extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
---- linux-chaos-2.4.20-6/fs/jfs/xattr.c~linux-2.4.20-xattr-0.8.54-chaos        2003-02-14 15:59:11.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/jfs/xattr.c  2003-04-09 16:30:59.000000000 -0600
-@@ -641,7 +641,7 @@ static int ea_put(struct inode *inode, s
- }
- static int can_set_xattr(struct inode *inode, const char *name,
--                       void *value, size_t value_len)
-+                       const void *value, size_t value_len)
- {
-       if (IS_RDONLY(inode))
-               return -EROFS;
-@@ -660,7 +660,7 @@ static int can_set_xattr(struct inode *i
-       return permission(inode, MAY_WRITE);
- }
--int __jfs_setxattr(struct inode *inode, const char *name, void *value,
-+int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
-                  size_t value_len, int flags)
- {
-       struct jfs_ea_list *ealist;
-@@ -799,7 +799,7 @@ int __jfs_setxattr(struct inode *inode, 
-       return rc;
- }
--int jfs_setxattr(struct dentry *dentry, const char *name, void *value,
-+int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
-                size_t value_len, int flags)
- {
-       if (value == NULL) {    /* empty EA, do not remove */
---- /dev/null  2003-01-30 03:24:37.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/fs/mbcache.c    2003-04-09 16:30:59.000000000 -0600
-@@ -0,0 +1,648 @@
-+/*
-+ * linux/fs/mbcache.c
-+ * (C) 2001-2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+/*
-+ * Filesystem Meta Information Block Cache (mbcache)
-+ *
-+ * The mbcache caches blocks of block devices that need to be located
-+ * by their device/block number, as well as by other criteria (such
-+ * as the block's contents).
-+ *
-+ * There can only be one cache entry in a cache per device and block number.
-+ * Additional indexes need not be unique in this sense. The number of
-+ * additional indexes (=other criteria) can be hardwired at compile time
-+ * or specified at cache create time.
-+ *
-+ * Each cache entry is of fixed size. An entry may be `valid' or `invalid'
-+ * in the cache. A valid entry is in the main hash tables of the cache,
-+ * and may also be in the lru list. An invalid entry is not in any hashes
-+ * or lists.
-+ *
-+ * A valid cache entry is only in the lru list if no handles refer to it.
-+ * Invalid cache entries will be freed when the last handle to the cache
-+ * entry is released. Entries that cannot be freed immediately are put
-+ * back on the lru list.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+
-+#include <linux/fs.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/cache_def.h>
-+#include <linux/version.h>
-+#include <linux/init.h>
-+#include <linux/mbcache.h>
-+
-+
-+#ifdef MB_CACHE_DEBUG
-+# define mb_debug(f...) do { \
-+              printk(KERN_DEBUG f); \
-+              printk("\n"); \
-+      } while (0)
-+#define mb_assert(c) do { if (!(c)) \
-+              printk(KERN_ERR "assertion " #c " failed\n"); \
-+      } while(0)
-+#else
-+# define mb_debug(f...) do { } while(0)
-+# define mb_assert(c) do { } while(0)
-+#endif
-+#define mb_error(f...) do { \
-+              printk(KERN_ERR f); \
-+              printk("\n"); \
-+      } while(0)
-+              
-+MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
-+MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+EXPORT_SYMBOL(mb_cache_create);
-+EXPORT_SYMBOL(mb_cache_shrink);
-+EXPORT_SYMBOL(mb_cache_destroy);
-+EXPORT_SYMBOL(mb_cache_entry_alloc);
-+EXPORT_SYMBOL(mb_cache_entry_insert);
-+EXPORT_SYMBOL(mb_cache_entry_release);
-+EXPORT_SYMBOL(mb_cache_entry_takeout);
-+EXPORT_SYMBOL(mb_cache_entry_free);
-+EXPORT_SYMBOL(mb_cache_entry_dup);
-+EXPORT_SYMBOL(mb_cache_entry_get);
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+EXPORT_SYMBOL(mb_cache_entry_find_first);
-+EXPORT_SYMBOL(mb_cache_entry_find_next);
-+#endif
-+
-+
-+/*
-+ * Global data: list of all mbcache's, lru list, and a spinlock for
-+ * accessing cache data structures on SMP machines. The lru list is
-+ * global across all mbcaches.
-+ */
-+
-+static LIST_HEAD(mb_cache_list);
-+static LIST_HEAD(mb_cache_lru_list);
-+static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED;
-+
-+static inline int
-+mb_cache_indexes(struct mb_cache *cache)
-+{
-+#ifdef MB_CACHE_INDEXES_COUNT
-+      return MB_CACHE_INDEXES_COUNT;
-+#else
-+      return cache->c_indexes_count;
-+#endif
-+}
-+
-+/*
-+ * What the mbcache registers as to get shrunk dynamically.
-+ */
-+
-+static void
-+mb_cache_memory_pressure(int priority, unsigned int gfp_mask);
-+
-+static struct cache_definition mb_cache_definition = {
-+      "mb_cache",
-+      mb_cache_memory_pressure
-+};
-+
-+
-+static inline int
-+__mb_cache_entry_is_hashed(struct mb_cache_entry *ce)
-+{
-+      return !list_empty(&ce->e_block_list);
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_unhash(struct mb_cache_entry *ce)
-+{
-+      int n;
-+
-+      if (__mb_cache_entry_is_hashed(ce)) {
-+              list_del_init(&ce->e_block_list);
-+              for (n=0; n<mb_cache_indexes(ce->e_cache); n++)
-+                      list_del(&ce->e_indexes[n].o_list);
-+      }
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask)
-+{
-+      struct mb_cache *cache = ce->e_cache;
-+
-+      mb_assert(atomic_read(&ce->e_used) == 0);
-+      if (cache->c_op.free && cache->c_op.free(ce, gfp_mask)) {
-+              /* free failed -- put back on the lru list
-+                 for freeing later. */
-+              spin_lock(&mb_cache_spinlock);
-+              list_add(&ce->e_lru_list, &mb_cache_lru_list);
-+              spin_unlock(&mb_cache_spinlock);
-+      } else {
-+              kmem_cache_free(cache->c_entry_cache, ce);
-+              atomic_dec(&cache->c_entry_count);
-+      }
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
-+{
-+      if (atomic_dec_and_test(&ce->e_used)) {
-+              if (__mb_cache_entry_is_hashed(ce))
-+                      list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
-+              else {
-+                      spin_unlock(&mb_cache_spinlock);
-+                      __mb_cache_entry_forget(ce, GFP_KERNEL);
-+                      return;
-+              }
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+}
-+
-+
-+/*
-+ * mb_cache_memory_pressure()  memory pressure callback
-+ *
-+ * This function is called by the kernel memory management when memory
-+ * gets low.
-+ *
-+ * @priority: Amount by which to shrink the cache (0 = highes priority)
-+ * @gfp_mask: (ignored)
-+ */
-+static void
-+mb_cache_memory_pressure(int priority, unsigned int gfp_mask)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+      int count = 0;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &mb_cache_list) {
-+              struct mb_cache *cache =
-+                      list_entry(l, struct mb_cache, c_cache_list);
-+              mb_debug("cache %s (%d)", cache->c_name,
-+                        atomic_read(&cache->c_entry_count));
-+              count += atomic_read(&cache->c_entry_count);
-+      }
-+      mb_debug("trying to free %d of %d entries",
-+                count / (priority ? priority : 1), count);
-+      if (priority)
-+              count /= priority;
-+      while (count-- && !list_empty(&mb_cache_lru_list)) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(mb_cache_lru_list.next,
-+                                 struct mb_cache_entry, e_lru_list);
-+              list_del(&ce->e_lru_list);
-+              __mb_cache_entry_unhash(ce);
-+              list_add_tail(&ce->e_lru_list, &free_list);
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), gfp_mask);
-+      }
-+}
-+
-+
-+/*
-+ * mb_cache_create()  create a new cache
-+ *
-+ * All entries in one cache are equal size. Cache entries may be from
-+ * multiple devices. If this is the first mbcache created, registers
-+ * the cache with kernel memory management. Returns NULL if no more
-+ * memory was available.
-+ *
-+ * @name: name of the cache (informal)
-+ * @cache_op: contains the callback called when freeing a cache entry
-+ * @entry_size: The size of a cache entry, including
-+ *              struct mb_cache_entry
-+ * @indexes_count: number of additional indexes in the cache. Must equal
-+ *                 MB_CACHE_INDEXES_COUNT if the number of indexes is
-+ *                 hardwired.
-+ * @bucket_count: number of hash buckets
-+ */
-+struct mb_cache *
-+mb_cache_create(const char *name, struct mb_cache_op *cache_op,
-+              size_t entry_size, int indexes_count, int bucket_count)
-+{
-+      int m=0, n;
-+      struct mb_cache *cache = NULL;
-+
-+      if(entry_size < sizeof(struct mb_cache_entry) +
-+         indexes_count * sizeof(struct mb_cache_entry_index))
-+              return NULL;
-+
-+      MOD_INC_USE_COUNT;
-+      cache = kmalloc(sizeof(struct mb_cache) +
-+                      indexes_count * sizeof(struct list_head), GFP_KERNEL);
-+      if (!cache)
-+              goto fail;
-+      cache->c_name = name;
-+      cache->c_op.free = NULL;
-+      if (cache_op)
-+              cache->c_op.free = cache_op->free;
-+      atomic_set(&cache->c_entry_count, 0);
-+      cache->c_bucket_count = bucket_count;
-+#ifdef MB_CACHE_INDEXES_COUNT
-+      mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT);
-+#else
-+      cache->c_indexes_count = indexes_count;
-+#endif
-+      cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
-+                                    GFP_KERNEL);
-+      if (!cache->c_block_hash)
-+              goto fail;
-+      for (n=0; n<bucket_count; n++)
-+              INIT_LIST_HEAD(&cache->c_block_hash[n]);
-+      for (m=0; m<indexes_count; m++) {
-+              cache->c_indexes_hash[m] = kmalloc(bucket_count *
-+                                               sizeof(struct list_head),
-+                                               GFP_KERNEL);
-+              if (!cache->c_indexes_hash[m])
-+                      goto fail;
-+              for (n=0; n<bucket_count; n++)
-+                      INIT_LIST_HEAD(&cache->c_indexes_hash[m][n]);
-+      }
-+      cache->c_entry_cache = kmem_cache_create(name, entry_size, 0,
-+              0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL);
-+      if (!cache->c_entry_cache)
-+              goto fail;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_add(&cache->c_cache_list, &mb_cache_list);
-+      spin_unlock(&mb_cache_spinlock);
-+      return cache;
-+
-+fail:
-+      if (cache) {
-+              while (--m >= 0)
-+                      kfree(cache->c_indexes_hash[m]);
-+              if (cache->c_block_hash)
-+                      kfree(cache->c_block_hash);
-+              kfree(cache);
-+      }
-+      MOD_DEC_USE_COUNT;
-+      return NULL;
-+}
-+
-+
-+/*
-+ * mb_cache_shrink()
-+ *
-+ * Removes all cache entires of a device from the cache. All cache entries
-+ * currently in use cannot be freed, and thus remain in the cache.
-+ *
-+ * @cache: which cache to shrink
-+ * @dev: which device's cache entries to shrink
-+ */
-+void
-+mb_cache_shrink(struct mb_cache *cache, kdev_t dev)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              if (ce->e_dev == dev) {
-+                      list_del(&ce->e_lru_list);
-+                      list_add_tail(&ce->e_lru_list, &free_list);
-+                      __mb_cache_entry_unhash(ce);
-+              }
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), GFP_KERNEL);
-+      }
-+}
-+
-+
-+/*
-+ * mb_cache_destroy()
-+ *
-+ * Shrinks the cache to its minimum possible size (hopefully 0 entries),
-+ * and then destroys it. If this was the last mbcache, un-registers the
-+ * mbcache from kernel memory management.
-+ */
-+void
-+mb_cache_destroy(struct mb_cache *cache)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+      int n;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              if (ce->e_cache == cache) {
-+                      list_del(&ce->e_lru_list);
-+                      list_add_tail(&ce->e_lru_list, &free_list);
-+                      __mb_cache_entry_unhash(ce);
-+              }
-+      }
-+      list_del(&cache->c_cache_list);
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), GFP_KERNEL);
-+      }
-+
-+      if (atomic_read(&cache->c_entry_count) > 0) {
-+              mb_error("cache %s: %d orphaned entries",
-+                        cache->c_name,
-+                        atomic_read(&cache->c_entry_count));
-+      }
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-+      /* We don't have kmem_cache_destroy() in 2.2.x */
-+      kmem_cache_shrink(cache->c_entry_cache);
-+#else
-+      kmem_cache_destroy(cache->c_entry_cache);
-+#endif
-+      for (n=0; n < mb_cache_indexes(cache); n++)
-+              kfree(cache->c_indexes_hash[n]);
-+      kfree(cache->c_block_hash);
-+      kfree(cache);
-+
-+      MOD_DEC_USE_COUNT;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_alloc()
-+ *
-+ * Allocates a new cache entry. The new entry will not be valid initially,
-+ * and thus cannot be looked up yet. It should be filled with data, and
-+ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL
-+ * if no more memory was available.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_alloc(struct mb_cache *cache)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      atomic_inc(&cache->c_entry_count);
-+      ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
-+      if (ce) {
-+              INIT_LIST_HEAD(&ce->e_lru_list);
-+              INIT_LIST_HEAD(&ce->e_block_list);
-+              ce->e_cache = cache;
-+              atomic_set(&ce->e_used, 1);
-+      }
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_insert()
-+ *
-+ * Inserts an entry that was allocated using mb_cache_entry_alloc() into
-+ * the cache. After this, the cache entry can be looked up, but is not yet
-+ * in the lru list as the caller still holds a handle to it. Returns 0 on
-+ * success, or -EBUSY if a cache entry for that device + inode exists
-+ * already (this may happen after a failed lookup, if another process has
-+ * inserted the same cache entry in the meantime).
-+ *
-+ * @dev: device the cache entry belongs to
-+ * @block: block number
-+ * @keys: array of additional keys. There must be indexes_count entries
-+ *        in the array (as specified when creating the cache).
-+ */
-+int
-+mb_cache_entry_insert(struct mb_cache_entry *ce, kdev_t dev,
-+                    unsigned long block, unsigned int keys[])
-+{
-+      struct mb_cache *cache = ce->e_cache;
-+      unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
-+      struct list_head *l;
-+      int error = -EBUSY, n;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &cache->c_block_hash[bucket]) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_block_list);
-+              if (ce->e_dev == dev && ce->e_block == block)
-+                      goto out;
-+      }
-+      __mb_cache_entry_unhash(ce);
-+      ce->e_dev = dev;
-+      ce->e_block = block;
-+      list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
-+      for (n=0; n<mb_cache_indexes(cache); n++) {
-+              ce->e_indexes[n].o_key = keys[n];
-+              bucket = keys[n] % cache->c_bucket_count;
-+              list_add(&ce->e_indexes[n].o_list,
-+                       &cache->c_indexes_hash[n][bucket]);
-+      }
-+out:
-+      spin_unlock(&mb_cache_spinlock);
-+      return error;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_release()
-+ *
-+ * Release a handle to a cache entry. When the last handle to a cache entry
-+ * is released it is either freed (if it is invalid) or otherwise inserted
-+ * in to the lru list.
-+ */
-+void
-+mb_cache_entry_release(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      __mb_cache_entry_release_unlock(ce);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_takeout()
-+ *
-+ * Take a cache entry out of the cache, making it invalid. The entry can later
-+ * be re-inserted using mb_cache_entry_insert(), or released using
-+ * mb_cache_entry_release().
-+ */
-+void
-+mb_cache_entry_takeout(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      mb_assert(list_empty(&ce->e_lru_list));
-+      __mb_cache_entry_unhash(ce);
-+      spin_unlock(&mb_cache_spinlock);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_free()
-+ *
-+ * This is equivalent to the sequence mb_cache_entry_takeout() --
-+ * mb_cache_entry_release().
-+ */
-+void
-+mb_cache_entry_free(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      mb_assert(list_empty(&ce->e_lru_list));
-+      __mb_cache_entry_unhash(ce);
-+      __mb_cache_entry_release_unlock(ce);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_dup()
-+ *
-+ * Duplicate a handle to a cache entry (does not duplicate the cache entry
-+ * itself). After the call, both the old and the new handle must be released.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_dup(struct mb_cache_entry *ce)
-+{
-+      atomic_inc(&ce->e_used);
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_get()
-+ *
-+ * Get a cache entry  by device / block number. (There can only be one entry
-+ * in the cache per device and block.) Returns NULL if no such cache entry
-+ * exists.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_get(struct mb_cache *cache, kdev_t dev, unsigned long block)
-+{
-+      unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &cache->c_block_hash[bucket]) {
-+              ce = list_entry(l, struct mb_cache_entry, e_block_list);
-+              if (ce->e_dev == dev && ce->e_block == block) {
-+                      if (!list_empty(&ce->e_lru_list))
-+                              list_del_init(&ce->e_lru_list);
-+                      atomic_inc(&ce->e_used);
-+                      goto cleanup;
-+              }
-+      }
-+      ce = NULL;
-+
-+cleanup:
-+      spin_unlock(&mb_cache_spinlock);
-+      return ce;
-+}
-+
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+
-+static struct mb_cache_entry *
-+__mb_cache_entry_find(struct list_head *l, struct list_head *head,
-+                    int index, kdev_t dev, unsigned int key)
-+{
-+      while (l != head) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry,
-+                                 e_indexes[index].o_list);
-+              if (ce->e_dev == dev && ce->e_indexes[index].o_key == key) {
-+                      if (!list_empty(&ce->e_lru_list))
-+                              list_del_init(&ce->e_lru_list);
-+                      atomic_inc(&ce->e_used);
-+                      return ce;
-+              }
-+              l = l->next;
-+      }
-+      return NULL;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_find_first()
-+ *
-+ * Find the first cache entry on a given device with a certain key in
-+ * an additional index. Additonal matches can be found with
-+ * mb_cache_entry_find_next(). Returns NULL if no match was found.
-+ *
-+ * @cache: the cache to search
-+ * @index: the number of the additonal index to search (0<=index<indexes_count)
-+ * @dev: the device the cache entry should belong to
-+ * @key: the key in the index
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_find_first(struct mb_cache *cache, int index, kdev_t dev,
-+                        unsigned int key)
-+{
-+      unsigned int bucket = key % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      mb_assert(index < mb_cache_indexes(cache));
-+      spin_lock(&mb_cache_spinlock);
-+      l = cache->c_indexes_hash[index][bucket].next;
-+      ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
-+                                 index, dev, key);
-+      spin_unlock(&mb_cache_spinlock);
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_find_next()
-+ *
-+ * Find the next cache entry on a given device with a certain key in an
-+ * additional index. Returns NULL if no match could be found. The previous
-+ * entry is atomatically released, so that mb_cache_entry_find_next() can
-+ * be called like this:
-+ *
-+ * entry = mb_cache_entry_find_first();
-+ * while (entry) {
-+ *    ...
-+ *    entry = mb_cache_entry_find_next(entry, ...);
-+ * }
-+ *
-+ * @prev: The previous match
-+ * @index: the number of the additonal index to search (0<=index<indexes_count)
-+ * @dev: the device the cache entry should belong to
-+ * @key: the key in the index
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_find_next(struct mb_cache_entry *prev, int index, kdev_t dev,
-+                       unsigned int key)
-+{
-+      struct mb_cache *cache = prev->e_cache;
-+      unsigned int bucket = key % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      mb_assert(index < mb_cache_indexes(cache));
-+      spin_lock(&mb_cache_spinlock);
-+      l = prev->e_indexes[index].o_list.next;
-+      ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
-+                                 index, dev, key);
-+      __mb_cache_entry_release_unlock(prev);
-+      return ce;
-+}
-+
-+#endif  /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */
-+
-+static int __init init_mbcache(void)
-+{
-+      register_cache(&mb_cache_definition);
-+      return 0;
-+}
-+
-+static void __exit exit_mbcache(void)
-+{
-+      unregister_cache(&mb_cache_definition);
-+}
-+
-+module_init(init_mbcache)
-+module_exit(exit_mbcache)
-+
---- linux-chaos-2.4.20-6/include/asm-arm/unistd.h~linux-2.4.20-xattr-0.8.54-chaos      2003-03-12 12:51:10.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/include/asm-arm/unistd.h        2003-04-09 16:30:59.000000000 -0600
-@@ -244,7 +244,6 @@
- #define __NR_security                 (__NR_SYSCALL_BASE+223)
- #define __NR_gettid                   (__NR_SYSCALL_BASE+224)
- #define __NR_readahead                        (__NR_SYSCALL_BASE+225)
--#if 0 /* allocated in 2.5 */
- #define __NR_setxattr                 (__NR_SYSCALL_BASE+226)
- #define __NR_lsetxattr                        (__NR_SYSCALL_BASE+227)
- #define __NR_fsetxattr                        (__NR_SYSCALL_BASE+228)
-@@ -257,7 +256,6 @@
- #define __NR_removexattr              (__NR_SYSCALL_BASE+235)
- #define __NR_lremovexattr             (__NR_SYSCALL_BASE+236)
- #define __NR_fremovexattr             (__NR_SYSCALL_BASE+237)
--#endif
- #define __NR_tkill                    (__NR_SYSCALL_BASE+238)
- /*
-  * Please check 2.5 _before_ adding calls here,
---- linux-chaos-2.4.20-6/include/asm-ppc64/unistd.h~linux-2.4.20-xattr-0.8.54-chaos    2002-09-25 11:13:42.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/include/asm-ppc64/unistd.h      2003-04-09 16:30:59.000000000 -0600
-@@ -218,6 +218,7 @@
- #define __NR_gettid           207
- #if 0 /* Reserved syscalls */
- #define __NR_tkill            208
-+#endif
- #define __NR_setxattr         209
- #define __NR_lsetxattr                210
- #define __NR_fsetxattr                211
-@@ -230,6 +231,7 @@
- #define __NR_removexattr      218
- #define __NR_lremovexattr     219
- #define __NR_fremovexattr     220
-+#if 0 /* Reserved syscalls */
- #define __NR_futex            221
- #endif
---- linux-chaos-2.4.20-6/include/asm-s390/unistd.h~linux-2.4.20-xattr-0.8.54-chaos     2002-09-25 11:13:44.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/include/asm-s390/unistd.h       2003-04-09 16:30:59.000000000 -0600
-@@ -212,9 +212,18 @@
- #define __NR_madvise            219
- #define __NR_getdents64               220
- #define __NR_fcntl64          221
--/*
-- * Numbers 224-235 are reserved for posix acl
-- */
-+#define __NR_setxattr         224
-+#define __NR_lsetxattr                225
-+#define __NR_fsetxattr                226
-+#define __NR_getxattr         227
-+#define __NR_lgetxattr                228
-+#define __NR_fgetxattr                229
-+#define __NR_listxattr                230
-+#define __NR_llistxattr               231
-+#define __NR_flistxattr               232
-+#define __NR_removexattr      233
-+#define __NR_lremovexattr     234
-+#define __NR_fremovexattr     235
- #define __NR_gettid           236
- #define __NR_tkill            237
---- linux-chaos-2.4.20-6/include/asm-s390x/unistd.h~linux-2.4.20-xattr-0.8.54-chaos    2002-09-25 11:13:45.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/include/asm-s390x/unistd.h      2003-04-09 16:30:59.000000000 -0600
-@@ -180,9 +180,18 @@
- #define __NR_pivot_root         217
- #define __NR_mincore            218
- #define __NR_madvise            219
--/*
-- * Numbers 224-235 are reserved for posix acl
-- */
-+#define __NR_setxattr         224
-+#define __NR_lsetxattr                225
-+#define __NR_fsetxattr                226
-+#define __NR_getxattr         227
-+#define __NR_lgetxattr                228
-+#define __NR_fgetxattr                229
-+#define __NR_listxattr                230
-+#define __NR_llistxattr               231
-+#define __NR_flistxattr               232
-+#define __NR_removexattr      233
-+#define __NR_lremovexattr     234
-+#define __NR_fremovexattr     235
- #define __NR_gettid           236
- #define __NR_tkill            237
---- linux-chaos-2.4.20-6/include/asm-sparc/unistd.h~linux-2.4.20-xattr-0.8.54-chaos    2002-09-25 11:13:46.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/include/asm-sparc/unistd.h      2003-04-09 16:30:59.000000000 -0600
-@@ -184,24 +184,24 @@
- /* #define __NR_exportfs        166    SunOS Specific                              */
- #define __NR_mount              167 /* Common                                      */
- #define __NR_ustat              168 /* Common                                      */
--/* #define __NR_semsys          169    SunOS Specific                              */
--/* #define __NR_msgsys          170    SunOS Specific                              */
--/* #define __NR_shmsys          171    SunOS Specific                              */
--/* #define __NR_auditsys        172    SunOS Specific                              */
--/* #define __NR_rfssys          173    SunOS Specific                              */
-+#define __NR_setxattr           169 /* SunOS: semsys                               */
-+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-+#define __NR_getxattr           172 /* SunOS: auditsys                             */
-+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
- #define __NR_getdents           174 /* Common                                      */
- #define __NR_setsid             175 /* Common                                      */
- #define __NR_fchdir             176 /* Common                                      */
--/* #define __NR_fchroot         177    SunOS Specific                              */
--/* #define __NR_vpixsys         178    SunOS Specific                              */
--/* #define __NR_aioread         179    SunOS Specific                              */
--/* #define __NR_aiowrite        180    SunOS Specific                              */
--/* #define __NR_aiowait         181    SunOS Specific                              */
--/* #define __NR_aiocancel       182    SunOS Specific                              */
-+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-+#define __NR_llistxattr         179 /* SunOS: aioread                              */
-+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-+#define __NR_removexattr        181 /* SunOS: aiowait                              */
-+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
- #define __NR_sigpending         183 /* Common                                      */
- #define __NR_query_module     184 /* Linux Specific                              */
- #define __NR_setpgid            185 /* Common                                      */
--/* #define __NR_pathconf        186    SunOS Specific                              */
-+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
- #define __NR_tkill              187 /* SunOS: fpathconf                            */
- /* #define __NR_sysconf         188    SunOS Specific                              */
- #define __NR_uname              189 /* Linux Specific                              */
---- linux-chaos-2.4.20-6/include/asm-sparc64/unistd.h~linux-2.4.20-xattr-0.8.54-chaos  2002-09-25 11:13:48.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/include/asm-sparc64/unistd.h    2003-04-09 16:30:59.000000000 -0600
-@@ -184,24 +184,24 @@
- /* #define __NR_exportfs        166    SunOS Specific                              */
- #define __NR_mount              167 /* Common                                      */
- #define __NR_ustat              168 /* Common                                      */
--/* #define __NR_semsys          169    SunOS Specific                              */
--/* #define __NR_msgsys          170    SunOS Specific                              */
--/* #define __NR_shmsys          171    SunOS Specific                              */
--/* #define __NR_auditsys        172    SunOS Specific                              */
--/* #define __NR_rfssys          173    SunOS Specific                              */
-+#define __NR_setxattr           169 /* SunOS: semsys                               */
-+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-+#define __NR_getxattr           172 /* SunOS: auditsys                             */
-+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
- #define __NR_getdents           174 /* Common                                      */
- #define __NR_setsid             175 /* Common                                      */
- #define __NR_fchdir             176 /* Common                                      */
--/* #define __NR_fchroot         177    SunOS Specific                              */
--/* #define __NR_vpixsys         178    SunOS Specific                              */
--/* #define __NR_aioread         179    SunOS Specific                              */
--/* #define __NR_aiowrite        180    SunOS Specific                              */
--/* #define __NR_aiowait         181    SunOS Specific                              */
--/* #define __NR_aiocancel       182    SunOS Specific                              */
-+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-+#define __NR_llistxattr         179 /* SunOS: aioread                              */
-+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-+#define __NR_removexattr        181 /* SunOS: aiowait                              */
-+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
- #define __NR_sigpending         183 /* Common                                      */
- #define __NR_query_module     184 /* Linux Specific                              */
- #define __NR_setpgid            185 /* Common                                      */
--/* #define __NR_pathconf        186    SunOS Specific                              */
-+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
- #define __NR_tkill              187 /* SunOS: fpathconf                            */
- /* #define __NR_sysconf         188    SunOS Specific                              */
- #define __NR_uname              189 /* Linux Specific                              */
---- /dev/null  2003-01-30 03:24:37.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/include/linux/cache_def.h       2003-04-09 16:30:59.000000000 -0600
-@@ -0,0 +1,15 @@
-+/*
-+ * linux/cache_def.h
-+ * Handling of caches defined in drivers, filesystems, ...
-+ *
-+ * Copyright (C) 2002 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+struct cache_definition {
-+      const char *name;
-+      void (*shrink)(int, unsigned int);
-+      struct list_head link;
-+};
-+
-+extern void register_cache(struct cache_definition *);
-+extern void unregister_cache(struct cache_definition *);
---- linux-chaos-2.4.20-6/include/linux/errno.h~linux-2.4.20-xattr-0.8.54-chaos 2003-03-12 12:51:27.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/include/linux/errno.h   2003-04-09 16:30:59.000000000 -0600
-@@ -26,4 +26,8 @@
- #endif
-+/* Defined for extended attributes */
-+#define ENOATTR ENODATA               /* No such attribute */
-+#define ENOTSUP EOPNOTSUPP    /* Operation not supported */
-+
- #endif
---- linux-chaos-2.4.20-6/include/linux/ext2_fs.h~linux-2.4.20-xattr-0.8.54-chaos       2002-05-07 15:53:47.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/include/linux/ext2_fs.h 2003-04-09 16:30:59.000000000 -0600
-@@ -57,8 +57,6 @@
-  */
- #define       EXT2_BAD_INO             1      /* Bad blocks inode */
- #define EXT2_ROOT_INO          2      /* Root inode */
--#define EXT2_ACL_IDX_INO       3      /* ACL inode */
--#define EXT2_ACL_DATA_INO      4      /* ACL inode */
- #define EXT2_BOOT_LOADER_INO   5      /* Boot loader inode */
- #define EXT2_UNDEL_DIR_INO     6      /* Undelete directory inode */
-@@ -86,7 +84,6 @@
- #else
- # define EXT2_BLOCK_SIZE(s)           (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
- #endif
--#define EXT2_ACLE_PER_BLOCK(s)                (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
- #define       EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
- #ifdef __KERNEL__
- # define EXT2_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
-@@ -121,28 +118,6 @@
- #endif
- /*
-- * ACL structures
-- */
--struct ext2_acl_header        /* Header of Access Control Lists */
--{
--      __u32   aclh_size;
--      __u32   aclh_file_count;
--      __u32   aclh_acle_count;
--      __u32   aclh_first_acle;
--};
--
--struct ext2_acl_entry /* Access Control List Entry */
--{
--      __u32   acle_size;
--      __u16   acle_perms;     /* Access permissions */
--      __u16   acle_type;      /* Type of entry */
--      __u16   acle_tag;       /* User or group identity */
--      __u16   acle_pad1;
--      __u32   acle_next;      /* Pointer on next entry for the */
--                                      /* same inode or on next free entry */
--};
--
--/*
-  * Structure of a blocks group descriptor
-  */
- struct ext2_group_desc
-@@ -314,6 +289,7 @@ struct ext2_inode {
- #define EXT2_MOUNT_ERRORS_PANIC               0x0040  /* Panic on errors */
- #define EXT2_MOUNT_MINIX_DF           0x0080  /* Mimics the Minix statfs */
- #define EXT2_MOUNT_NO_UID32           0x0200  /* Disable 32-bit UIDs */
-+#define EXT2_MOUNT_XATTR_USER         0x4000  /* Extended user attributes */
- #define clear_opt(o, opt)             o &= ~EXT2_MOUNT_##opt
- #define set_opt(o, opt)                       o |= EXT2_MOUNT_##opt
-@@ -397,6 +373,7 @@ struct ext2_super_block {
- #ifdef __KERNEL__
- #define EXT2_SB(sb)   (&((sb)->u.ext2_sb))
-+#define EXT2_I(inode) (&((inode)->u.ext2_i))
- #else
- /* Assume that user mode programs are passing in an ext2fs superblock, not
-  * a kernel struct super_block.  This will allow us to call the feature-test
-@@ -466,7 +443,7 @@ struct ext2_super_block {
- #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008
- #define EXT2_FEATURE_INCOMPAT_ANY             0xffffffff
--#define EXT2_FEATURE_COMPAT_SUPP      0
-+#define EXT2_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
- #define EXT2_FEATURE_INCOMPAT_SUPP    EXT2_FEATURE_INCOMPAT_FILETYPE
- #define EXT2_FEATURE_RO_COMPAT_SUPP   (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-                                        EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
-@@ -623,8 +600,10 @@ extern struct address_space_operations e
- /* namei.c */
- extern struct inode_operations ext2_dir_inode_operations;
-+extern struct inode_operations ext2_special_inode_operations;
- /* symlink.c */
-+extern struct inode_operations ext2_symlink_inode_operations;
- extern struct inode_operations ext2_fast_symlink_inode_operations;
- #endif        /* __KERNEL__ */
---- /dev/null  2003-01-30 03:24:37.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/include/linux/ext2_xattr.h      2003-04-09 16:30:59.000000000 -0600
-@@ -0,0 +1,157 @@
-+/*
-+  File: linux/ext2_xattr.h
-+
-+  On-disk format of extended attributes for the ext2 filesystem.
-+
-+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/xattr.h>
-+
-+/* Magic value in attribute blocks */
-+#define EXT2_XATTR_MAGIC              0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT2_XATTR_REFCOUNT_MAX               1024
-+
-+/* Name indexes */
-+#define EXT2_XATTR_INDEX_MAX                  10
-+#define EXT2_XATTR_INDEX_USER                 1
-+#define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS     2
-+#define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT    3
-+
-+struct ext2_xattr_header {
-+      __u32   h_magic;        /* magic number for identification */
-+      __u32   h_refcount;     /* reference count */
-+      __u32   h_blocks;       /* number of disk blocks used */
-+      __u32   h_hash;         /* hash value of all attributes */
-+      __u32   h_reserved[4];  /* zero right now */
-+};
-+
-+struct ext2_xattr_entry {
-+      __u8    e_name_len;     /* length of name */
-+      __u8    e_name_index;   /* attribute name index */
-+      __u16   e_value_offs;   /* offset in disk block of value */
-+      __u32   e_value_block;  /* disk block attribute is stored on (n/i) */
-+      __u32   e_value_size;   /* size of attribute value */
-+      __u32   e_hash;         /* hash value of name and value */
-+      char    e_name[0];      /* attribute name */
-+};
-+
-+#define EXT2_XATTR_PAD_BITS           2
-+#define EXT2_XATTR_PAD                (1<<EXT2_XATTR_PAD_BITS)
-+#define EXT2_XATTR_ROUND              (EXT2_XATTR_PAD-1)
-+#define EXT2_XATTR_LEN(name_len) \
-+      (((name_len) + EXT2_XATTR_ROUND + \
-+      sizeof(struct ext2_xattr_entry)) & ~EXT2_XATTR_ROUND)
-+#define EXT2_XATTR_NEXT(entry) \
-+      ( (struct ext2_xattr_entry *)( \
-+        (char *)(entry) + EXT2_XATTR_LEN((entry)->e_name_len)) )
-+#define EXT2_XATTR_SIZE(size) \
-+      (((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)
-+
-+#ifdef __KERNEL__
-+
-+# ifdef CONFIG_EXT2_FS_XATTR
-+
-+struct ext2_xattr_handler {
-+      char *prefix;
-+      size_t (*list)(char *list, struct inode *inode, const char *name,
-+                     int name_len);
-+      int (*get)(struct inode *inode, const char *name, void *buffer,
-+                 size_t size);
-+      int (*set)(struct inode *inode, const char *name, const void *buffer,
-+                 size_t size, int flags);
-+};
-+
-+extern int ext2_xattr_register(int, struct ext2_xattr_handler *);
-+extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *);
-+
-+extern int ext2_setxattr(struct dentry *, const char *, const void *, size_t, int);
-+extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t);
-+extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
-+extern int ext2_removexattr(struct dentry *, const char *);
-+
-+extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
-+extern int ext2_xattr_list(struct inode *, char *, size_t);
-+extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
-+
-+extern void ext2_xattr_delete_inode(struct inode *);
-+extern void ext2_xattr_put_super(struct super_block *);
-+
-+extern int init_ext2_xattr(void) __init;
-+extern void exit_ext2_xattr(void);
-+
-+# else  /* CONFIG_EXT2_FS_XATTR */
-+#  define ext2_setxattr               NULL
-+#  define ext2_getxattr               NULL
-+#  define ext2_listxattr      NULL
-+#  define ext2_removexattr    NULL
-+
-+static inline int
-+ext2_xattr_get(struct inode *inode, int name_index,
-+             const char *name, void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext2_xattr_list(struct inode *inode, char *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext2_xattr_set(struct inode *inode, int name_index, const char *name,
-+             const void *value, size_t size, int flags)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline void
-+ext2_xattr_delete_inode(struct inode *inode)
-+{
-+}
-+
-+static inline void
-+ext2_xattr_put_super(struct super_block *sb)
-+{
-+}
-+
-+static inline int
-+init_ext2_xattr(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext2_xattr(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT2_FS_XATTR */
-+
-+# ifdef CONFIG_EXT2_FS_XATTR_USER
-+
-+extern int init_ext2_xattr_user(void) __init;
-+extern void exit_ext2_xattr_user(void);
-+
-+# else  /* CONFIG_EXT2_FS_XATTR_USER */
-+
-+static inline int
-+init_ext2_xattr_user(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext2_xattr_user(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT2_FS_XATTR_USER */
-+
-+#endif  /* __KERNEL__ */
-+
---- linux-chaos-2.4.20-6/include/linux/ext3_fs.h~linux-2.4.20-xattr-0.8.54-chaos       2003-04-09 16:26:22.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/include/linux/ext3_fs.h 2003-04-09 16:30:59.000000000 -0600
-@@ -63,8 +63,6 @@
-  */
- #define       EXT3_BAD_INO             1      /* Bad blocks inode */
- #define EXT3_ROOT_INO          2      /* Root inode */
--#define EXT3_ACL_IDX_INO       3      /* ACL inode */
--#define EXT3_ACL_DATA_INO      4      /* ACL inode */
- #define EXT3_BOOT_LOADER_INO   5      /* Boot loader inode */
- #define EXT3_UNDEL_DIR_INO     6      /* Undelete directory inode */
- #define EXT3_RESIZE_INO                7      /* Reserved group descriptors inode */
-@@ -94,7 +92,6 @@
- #else
- # define EXT3_BLOCK_SIZE(s)           (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
- #endif
--#define EXT3_ACLE_PER_BLOCK(s)                (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
- #define       EXT3_ADDR_PER_BLOCK(s)          (EXT3_BLOCK_SIZE(s) / sizeof (__u32))
- #ifdef __KERNEL__
- # define EXT3_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
-@@ -129,28 +126,6 @@
- #endif
- /*
-- * ACL structures
-- */
--struct ext3_acl_header        /* Header of Access Control Lists */
--{
--      __u32   aclh_size;
--      __u32   aclh_file_count;
--      __u32   aclh_acle_count;
--      __u32   aclh_first_acle;
--};
--
--struct ext3_acl_entry /* Access Control List Entry */
--{
--      __u32   acle_size;
--      __u16   acle_perms;     /* Access permissions */
--      __u16   acle_type;      /* Type of entry */
--      __u16   acle_tag;       /* User or group identity */
--      __u16   acle_pad1;
--      __u32   acle_next;      /* Pointer on next entry for the */
--                                      /* same inode or on next free entry */
--};
--
--/*
-  * Structure of a blocks group descriptor
-  */
- struct ext3_group_desc
-@@ -344,6 +319,7 @@ struct ext3_inode {
-   #define EXT3_MOUNT_WRITEBACK_DATA   0x0C00  /* No data ordering */
- #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
-@@ -520,7 +496,7 @@ struct ext3_super_block {
- #define EXT3_FEATURE_INCOMPAT_RECOVER         0x0004 /* Needs recovery */
- #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008 /* Journal device */
--#define EXT3_FEATURE_COMPAT_SUPP      0
-+#define EXT3_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
- #define EXT3_FEATURE_INCOMPAT_SUPP    (EXT3_FEATURE_INCOMPAT_FILETYPE| \
-                                        EXT3_FEATURE_INCOMPAT_RECOVER)
- #define EXT3_FEATURE_RO_COMPAT_SUPP   (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-@@ -703,6 +679,7 @@ extern void ext3_check_inodes_bitmap (st
- extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
- /* inode.c */
-+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
-@@ -771,8 +748,10 @@ extern struct address_space_operations e
- /* namei.c */
- extern struct inode_operations ext3_dir_inode_operations;
-+extern struct inode_operations ext3_special_inode_operations;
- /* symlink.c */
-+extern struct inode_operations ext3_symlink_inode_operations;
- extern struct inode_operations ext3_fast_symlink_inode_operations;
---- linux-chaos-2.4.20-6/include/linux/ext3_jbd.h~linux-2.4.20-xattr-0.8.54-chaos      2003-04-09 16:26:17.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/include/linux/ext3_jbd.h        2003-04-09 16:30:59.000000000 -0600
-@@ -30,13 +30,19 @@
- #define EXT3_SINGLEDATA_TRANS_BLOCKS  8U
-+/* Extended attributes may touch two data buffers, two bitmap buffers,
-+ * and two group and summaries. */
-+
-+#define EXT3_XATTR_TRANS_BLOCKS               8
-+
- /* Define the minimum size for a transaction which modifies data.  This
-  * needs to take into account the fact that we may end up modifying two
-  * quota files too (one for the group, one for the user quota).  The
-  * superblock only gets updated once, of course, so don't bother
-  * counting that again for the quota updates. */
--#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
-+#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
-+                                       EXT3_XATTR_TRANS_BLOCKS - 2)
- extern int ext3_writepage_trans_blocks(struct inode *inode);
---- /dev/null  2003-01-30 03:24:37.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/include/linux/ext3_xattr.h      2003-04-09 16:30:59.000000000 -0600
-@@ -0,0 +1,157 @@
-+/*
-+  File: linux/ext3_xattr.h
-+
-+  On-disk format of extended attributes for the ext3 filesystem.
-+
-+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/xattr.h>
-+
-+/* Magic value in attribute blocks */
-+#define EXT3_XATTR_MAGIC              0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT3_XATTR_REFCOUNT_MAX               1024
-+
-+/* Name indexes */
-+#define EXT3_XATTR_INDEX_MAX                  10
-+#define EXT3_XATTR_INDEX_USER                 1
-+#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS     2
-+#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT    3
-+
-+struct ext3_xattr_header {
-+      __u32   h_magic;        /* magic number for identification */
-+      __u32   h_refcount;     /* reference count */
-+      __u32   h_blocks;       /* number of disk blocks used */
-+      __u32   h_hash;         /* hash value of all attributes */
-+      __u32   h_reserved[4];  /* zero right now */
-+};
-+
-+struct ext3_xattr_entry {
-+      __u8    e_name_len;     /* length of name */
-+      __u8    e_name_index;   /* attribute name index */
-+      __u16   e_value_offs;   /* offset in disk block of value */
-+      __u32   e_value_block;  /* disk block attribute is stored on (n/i) */
-+      __u32   e_value_size;   /* size of attribute value */
-+      __u32   e_hash;         /* hash value of name and value */
-+      char    e_name[0];      /* attribute name */
-+};
-+
-+#define EXT3_XATTR_PAD_BITS           2
-+#define EXT3_XATTR_PAD                (1<<EXT3_XATTR_PAD_BITS)
-+#define EXT3_XATTR_ROUND              (EXT3_XATTR_PAD-1)
-+#define EXT3_XATTR_LEN(name_len) \
-+      (((name_len) + EXT3_XATTR_ROUND + \
-+      sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
-+#define EXT3_XATTR_NEXT(entry) \
-+      ( (struct ext3_xattr_entry *)( \
-+        (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
-+#define EXT3_XATTR_SIZE(size) \
-+      (((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
-+
-+#ifdef __KERNEL__
-+
-+# ifdef CONFIG_EXT3_FS_XATTR
-+
-+struct ext3_xattr_handler {
-+      char *prefix;
-+      size_t (*list)(char *list, struct inode *inode, const char *name,
-+                     int name_len);
-+      int (*get)(struct inode *inode, const char *name, void *buffer,
-+                 size_t size);
-+      int (*set)(struct inode *inode, const char *name, const void *buffer,
-+                 size_t size, int flags);
-+};
-+
-+extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
-+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
-+
-+extern int ext3_setxattr(struct dentry *, const char *, const void *, size_t, int);
-+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
-+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
-+extern int ext3_removexattr(struct dentry *, const char *);
-+
-+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
-+extern int ext3_xattr_list(struct inode *, char *, size_t);
-+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
-+
-+extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
-+extern void ext3_xattr_put_super(struct super_block *);
-+
-+extern int init_ext3_xattr(void) __init;
-+extern void exit_ext3_xattr(void);
-+
-+# else  /* CONFIG_EXT3_FS_XATTR */
-+#  define ext3_setxattr               NULL
-+#  define ext3_getxattr               NULL
-+#  define ext3_listxattr      NULL
-+#  define ext3_removexattr    NULL
-+
-+static inline int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, const void *value, size_t size, int flags)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline void
-+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
-+{
-+}
-+
-+static inline void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+}
-+
-+static inline int
-+init_ext3_xattr(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext3_xattr(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT3_FS_XATTR */
-+
-+# ifdef CONFIG_EXT3_FS_XATTR_USER
-+
-+extern int init_ext3_xattr_user(void) __init;
-+extern void exit_ext3_xattr_user(void);
-+
-+# else  /* CONFIG_EXT3_FS_XATTR_USER */
-+
-+static inline int
-+init_ext3_xattr_user(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext3_xattr_user(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT3_FS_XATTR_USER */
-+
-+#endif  /* __KERNEL__ */
-+
---- linux-chaos-2.4.20-6/include/linux/fs.h~linux-2.4.20-xattr-0.8.54-chaos    2003-04-09 16:10:59.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/include/linux/fs.h      2003-04-09 16:30:59.000000000 -0600
-@@ -918,7 +918,7 @@ struct inode_operations {
-       int (*setattr) (struct dentry *, struct iattr *);
-       int (*setattr_raw) (struct inode *, struct iattr *);
-       int (*getattr) (struct dentry *, struct iattr *);
--      int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
-+      int (*setxattr) (struct dentry *, const char *, const void *, size_t, int);
-       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-       ssize_t (*listxattr) (struct dentry *, char *, size_t);
-       int (*removexattr) (struct dentry *, const char *);
---- /dev/null  2003-01-30 03:24:37.000000000 -0700
-+++ linux-chaos-2.4.20-6-braam/include/linux/mbcache.h 2003-04-09 16:30:59.000000000 -0600
-@@ -0,0 +1,69 @@
-+/*
-+  File: linux/mbcache.h
-+
-+  (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+/* Hardwire the number of additional indexes */
-+#define MB_CACHE_INDEXES_COUNT 1
-+
-+struct mb_cache_entry;
-+
-+struct mb_cache_op {
-+      int (*free)(struct mb_cache_entry *, int);
-+};
-+
-+struct mb_cache {
-+      struct list_head                c_cache_list;
-+      const char                      *c_name;
-+      struct mb_cache_op              c_op;
-+      atomic_t                        c_entry_count;
-+      int                             c_bucket_count;
-+#ifndef MB_CACHE_INDEXES_COUNT
-+      int                             c_indexes_count;
-+#endif
-+      kmem_cache_t                    *c_entry_cache;
-+      struct list_head                *c_block_hash;
-+      struct list_head                *c_indexes_hash[0];
-+};
-+
-+struct mb_cache_entry_index {
-+      struct list_head                o_list;
-+      unsigned int                    o_key;
-+};
-+
-+struct mb_cache_entry {
-+      struct list_head                e_lru_list;
-+      struct mb_cache                 *e_cache;
-+      atomic_t                        e_used;
-+      kdev_t                          e_dev;
-+      unsigned long                   e_block;
-+      struct list_head                e_block_list;
-+      struct mb_cache_entry_index     e_indexes[0];
-+};
-+
-+/* Functions on caches */
-+
-+struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t,
-+                                int, int);
-+void mb_cache_shrink(struct mb_cache *, kdev_t);
-+void mb_cache_destroy(struct mb_cache *);
-+
-+/* Functions on cache entries */
-+
-+struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
-+int mb_cache_entry_insert(struct mb_cache_entry *, kdev_t, unsigned long,
-+                        unsigned int[]);
-+void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
-+void mb_cache_entry_release(struct mb_cache_entry *);
-+void mb_cache_entry_takeout(struct mb_cache_entry *);
-+void mb_cache_entry_free(struct mb_cache_entry *);
-+struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *);
-+struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, kdev_t,
-+                                        unsigned long);
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int,
-+                                               kdev_t, unsigned int);
-+struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int,
-+                                              kdev_t, unsigned int);
-+#endif
---- linux-chaos-2.4.20-6/kernel/ksyms.c~linux-2.4.20-xattr-0.8.54-chaos        2003-04-09 16:10:53.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/kernel/ksyms.c  2003-04-09 16:33:03.000000000 -0600
-@@ -12,6 +12,7 @@
- #define __KERNEL_SYSCALLS__
- #include <linux/config.h>
- #include <linux/slab.h>
-+#include <linux/cache_def.h>
- #include <linux/smp.h>
- #include <linux/module.h>
- #include <linux/blkdev.h>
-@@ -107,6 +108,7 @@ EXPORT_SYMBOL(exit_mm);
- EXPORT_SYMBOL(exit_files);
- EXPORT_SYMBOL(exit_fs);
- EXPORT_SYMBOL(exit_sighand);
-+EXPORT_SYMBOL(copy_fs_struct);
- /* internal kernel memory management */
- EXPORT_SYMBOL(_alloc_pages);
-@@ -125,6 +127,8 @@ EXPORT_SYMBOL(kmem_cache_validate);
- EXPORT_SYMBOL(kmem_cache_alloc);
- EXPORT_SYMBOL(kmem_cache_free);
- EXPORT_SYMBOL(kmem_cache_size);
-+EXPORT_SYMBOL(register_cache);
-+EXPORT_SYMBOL(unregister_cache);
- EXPORT_SYMBOL(kmalloc);
- EXPORT_SYMBOL(kfree);
- EXPORT_SYMBOL(vfree);
---- linux-chaos-2.4.20-6/mm/vmscan.c~linux-2.4.20-xattr-0.8.54-chaos   2003-04-09 16:11:02.000000000 -0600
-+++ linux-chaos-2.4.20-6-braam/mm/vmscan.c     2003-04-09 16:34:57.000000000 -0600
-@@ -21,6 +21,7 @@
- #include <linux/kernel_stat.h>
- #include <linux/swap.h>
- #include <linux/swapctl.h>
-+#include <linux/cache_def.h>
- #include <linux/smp_lock.h>
- #include <linux/pagemap.h>
- #include <linux/init.h>
-@@ -444,6 +445,39 @@ static inline void kachunk_cache(struct 
- #define BATCH_WORK_AMOUNT     64
-+static DECLARE_MUTEX(other_caches_sem);
-+static LIST_HEAD(cache_definitions);
-+
-+void register_cache(struct cache_definition *cache)
-+{
-+      down(&other_caches_sem);
-+      list_add(&cache->link, &cache_definitions);
-+      up(&other_caches_sem);
-+}
-+
-+void unregister_cache(struct cache_definition *cache)
-+{
-+      down(&other_caches_sem);
-+      list_del(&cache->link);
-+      up(&other_caches_sem);
-+}
-+
-+static void shrink_other_caches(unsigned int priority, int gfp_mask)
-+{
-+      struct list_head *p;
-+
-+      if (down_trylock(&other_caches_sem))
-+              return;
-+
-+      list_for_each_prev(p, &cache_definitions) {
-+              struct cache_definition *cache =
-+                      list_entry(p, struct cache_definition, link);
-+
-+              cache->shrink(priority, gfp_mask);
-+      }
-+      up(&other_caches_sem);
-+}
-+
- /*
-  * returns the active cache ratio relative to the total active list
-  * times 10 (eg. 30% cache returns 3)
-@@ -887,7 +921,7 @@ static int do_try_to_free_pages_kswapd(u
-       ret += shrink_dcache_memory(DEF_PRIORITY, gfp_mask);
-       ret += shrink_icache_memory(DEF_PRIORITY, gfp_mask);
--      // ret += shrink_other_caches(DEF_PRIORITY, gfp_mask); 
-+      shrink_other_caches(DEF_PRIORITY, gfp_mask); 
- #ifdef CONFIG_QUOTA
-       ret += shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
- #endif
-
-_
diff --git a/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-hp.patch b/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-hp.patch
deleted file mode 100644 (file)
index 7177d49..0000000
+++ /dev/null
@@ -1,5536 +0,0 @@
- Documentation/Configure.help  |   66 ++
- arch/alpha/defconfig          |    7 
- arch/alpha/kernel/entry.S     |   12 
- arch/arm/defconfig            |    7 
- arch/arm/kernel/calls.S       |   24 
- arch/i386/defconfig           |    7 
- arch/ia64/defconfig           |    7 
- arch/m68k/defconfig           |    7 
- arch/mips/defconfig           |    7 
- arch/mips64/defconfig         |    7 
- arch/ppc/defconfig            |   14 
- arch/ppc64/kernel/misc.S      |    2 
- arch/s390/defconfig           |    7 
- arch/s390/kernel/entry.S      |   24 
- arch/s390x/defconfig          |    7 
- arch/s390x/kernel/entry.S     |   24 
- arch/s390x/kernel/wrapper32.S |   92 +++
- arch/sparc/defconfig          |    7 
- arch/sparc/kernel/systbls.S   |   10 
- arch/sparc64/defconfig        |    7 
- arch/sparc64/kernel/systbls.S |   20 
- fs/Config.in                  |   14 
- fs/Makefile                   |    3 
- fs/ext2/Makefile              |    4 
- fs/ext2/file.c                |    5 
- fs/ext2/ialloc.c              |    2 
- fs/ext2/inode.c               |   34 -
- fs/ext2/namei.c               |   14 
- fs/ext2/super.c               |   29 
- fs/ext2/symlink.c             |   14 
- fs/ext2/xattr.c               | 1212 +++++++++++++++++++++++++++++++++++++++++
- fs/ext2/xattr_user.c          |  103 +++
- fs/ext3/Makefile              |    9 
- fs/ext3/ext3-exports.c        |   13 
- fs/ext3/file.c                |    5 
- fs/ext3/ialloc.c              |    2 
- fs/ext3/inode.c               |   35 -
- fs/ext3/namei.c               |   21 
- fs/ext3/super.c               |   36 +
- fs/ext3/symlink.c             |   14 
- fs/ext3/xattr.c               | 1225 ++++++++++++++++++++++++++++++++++++++++++
- fs/ext3/xattr_user.c          |  111 +++
- fs/jfs/jfs_xattr.h            |    6 
- fs/jfs/xattr.c                |    6 
- fs/mbcache.c                  |  648 ++++++++++++++++++++++
- include/asm-arm/unistd.h      |    2 
- include/asm-ppc64/unistd.h    |    2 
- include/asm-s390/unistd.h     |   15 
- include/asm-s390x/unistd.h    |   15 
- include/asm-sparc/unistd.h    |   24 
- include/asm-sparc64/unistd.h  |   24 
- include/linux/cache_def.h     |   15 
- include/linux/errno.h         |    4 
- include/linux/ext2_fs.h       |   31 -
- include/linux/ext2_xattr.h    |  157 +++++
- include/linux/ext3_fs.h       |   31 -
- include/linux/ext3_jbd.h      |    8 
- include/linux/ext3_xattr.h    |  157 +++++
- include/linux/fs.h            |    2 
- include/linux/mbcache.h       |   69 ++
- kernel/ksyms.c                |    4 
- mm/vmscan.c                   |   35 +
- 62 files changed, 4343 insertions(+), 182 deletions(-)
-
---- linux/Documentation/Configure.help~linux-2.4.20-xattr-0.8.54-hp    Tue Apr 29 09:24:23 2003
-+++ linux-mmonroe/Documentation/Configure.help Tue Apr 29 09:26:41 2003
-@@ -15309,6 +15309,39 @@ CONFIG_EXT2_FS
-   be compiled as a module, and so this could be dangerous.  Most
-   everyone wants to say Y here.
-+Ext2 extended attributes
-+CONFIG_EXT2_FS_XATTR
-+  Extended attributes are name:value pairs associated with inodes by
-+  the kernel or by users (see the attr(5) manual page, or visit
-+  <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext2 extended attribute block sharing
-+CONFIG_EXT2_FS_XATTR_SHARING
-+  This options enables code for sharing identical extended attribute
-+  blocks among multiple inodes.
-+
-+  Usually, say Y.
-+
-+Ext2 extended user attributes
-+CONFIG_EXT2_FS_XATTR_USER
-+  This option enables extended user attributes on ext2. Processes can
-+  associate extended user attributes with inodes to store additional
-+  information such as the character encoding of files, etc. (see the
-+  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext2 trusted extended attributes
-+CONFIG_EXT2_FS_XATTR_TRUSTED
-+  This option enables extended attributes on ext2 that are accessible
-+  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
-+  is only the super user. Trusted extended attributes are meant for
-+  implementing system/security services.
-+
-+  If unsure, say N.
-+
- Ext3 journalling file system support (EXPERIMENTAL)
- CONFIG_EXT3_FS
-   This is the journalling version of the Second extended file system
-@@ -15341,6 +15374,39 @@ CONFIG_EXT3_FS
-   of your root partition (the one containing the directory /) cannot
-   be compiled as a module, and so this may be dangerous.
-+Ext3 extended attributes
-+CONFIG_EXT3_FS_XATTR
-+  Extended attributes are name:value pairs associated with inodes by
-+  the kernel or by users (see the attr(5) manual page, or visit
-+  <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext3 extended attribute block sharing
-+CONFIG_EXT3_FS_XATTR_SHARING
-+  This options enables code for sharing identical extended attribute
-+  blocks among multiple inodes.
-+
-+  Usually, say Y.
-+
-+Ext3 extended user attributes
-+CONFIG_EXT3_FS_XATTR_USER
-+  This option enables extended user attributes on ext3. Processes can
-+  associate extended user attributes with inodes to store additional
-+  information such as the character encoding of files, etc. (see the
-+  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext3 trusted extended attributes
-+CONFIG_EXT3_FS_XATTR_TRUSTED
-+  This option enables extended attributes on ext3 that are accessible
-+  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
-+  is only the super user. Trusted extended attributes are meant for
-+  implementing system/security services.
-+
-+  If unsure, say N.
-+
- Journal Block Device support (JBD for ext3) (EXPERIMENTAL)
- CONFIG_JBD
-   This is a generic journalling layer for block devices.  It is
---- linux/arch/alpha/defconfig~linux-2.4.20-xattr-0.8.54-hp    Tue Apr 29 09:24:08 2003
-+++ linux-mmonroe/arch/alpha/defconfig Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_ALPHA=y
- # CONFIG_UID16 is not set
- # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
---- linux/arch/alpha/kernel/entry.S~linux-2.4.20-xattr-0.8.54-hp       Tue Apr 29 09:24:08 2003
-+++ linux-mmonroe/arch/alpha/kernel/entry.S    Tue Apr 29 09:26:41 2003
-@@ -1154,6 +1154,18 @@ sys_call_table:
-       .quad sys_readahead
-       .quad sys_ni_syscall                    /* 380, sys_security */
-       .quad sys_tkill
-+      .quad sys_setxattr
-+      .quad sys_lsetxattr
-+      .quad sys_fsetxattr
-+      .quad sys_getxattr                      /* 385 */
-+      .quad sys_lgetxattr
-+      .quad sys_fgetxattr
-+      .quad sys_listxattr
-+      .quad sys_llistxattr
-+      .quad sys_flistxattr                    /* 390 */
-+      .quad sys_removexattr
-+      .quad sys_lremovexattr
-+      .quad sys_fremovexattr
- /* Remember to update everything, kids.  */
- .ifne (. - sys_call_table) - (NR_SYSCALLS * 8)
---- linux/arch/arm/defconfig~linux-2.4.20-xattr-0.8.54-hp      Tue Apr 29 09:24:16 2003
-+++ linux-mmonroe/arch/arm/defconfig   Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_ARM=y
- # CONFIG_EISA is not set
- # CONFIG_SBUS is not set
---- linux/arch/arm/kernel/calls.S~linux-2.4.20-xattr-0.8.54-hp Tue Apr 29 09:24:17 2003
-+++ linux-mmonroe/arch/arm/kernel/calls.S      Tue Apr 29 09:26:41 2003
-@@ -240,18 +240,18 @@ __syscall_start:
-               .long   SYMBOL_NAME(sys_ni_syscall) /* Security */
-               .long   SYMBOL_NAME(sys_gettid)
- /* 225 */     .long   SYMBOL_NAME(sys_readahead)
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_setxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lsetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fsetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_getxattr */
--/* 230 */     .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lgetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fgetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_listxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_llistxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_flistxattr */
--/* 235 */     .long   SYMBOL_NAME(sys_ni_syscall) /* sys_removexattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lremovexattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fremovexattr */
-+              .long   SYMBOL_NAME(sys_setxattr)
-+              .long   SYMBOL_NAME(sys_lsetxattr)
-+              .long   SYMBOL_NAME(sys_fsetxattr)
-+              .long   SYMBOL_NAME(sys_getxattr)
-+/* 230 */     .long   SYMBOL_NAME(sys_lgetxattr)
-+              .long   SYMBOL_NAME(sys_fgetxattr)
-+              .long   SYMBOL_NAME(sys_listxattr)
-+              .long   SYMBOL_NAME(sys_llistxattr)
-+              .long   SYMBOL_NAME(sys_flistxattr)
-+/* 235 */     .long   SYMBOL_NAME(sys_removexattr)
-+              .long   SYMBOL_NAME(sys_lremovexattr)
-+              .long   SYMBOL_NAME(sys_fremovexattr)
-               .long   SYMBOL_NAME(sys_tkill)
-               /*
-                * Please check 2.5 _before_ adding calls here,
---- linux/arch/i386/defconfig~linux-2.4.20-xattr-0.8.54-hp     Tue Apr 29 09:24:07 2003
-+++ linux-mmonroe/arch/i386/defconfig  Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_X86=y
- CONFIG_ISA=y
- # CONFIG_SBUS is not set
---- linux/arch/ia64/defconfig~linux-2.4.20-xattr-0.8.54-hp     Tue Apr 29 09:24:19 2003
-+++ linux-mmonroe/arch/ia64/defconfig  Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- #
- # Code maturity level options
---- linux/arch/m68k/defconfig~linux-2.4.20-xattr-0.8.54-hp     Tue Apr 29 09:24:14 2003
-+++ linux-mmonroe/arch/m68k/defconfig  Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_UID16=y
- #
---- linux/arch/mips/defconfig~linux-2.4.20-xattr-0.8.54-hp     Tue Apr 29 09:24:09 2003
-+++ linux-mmonroe/arch/mips/defconfig  Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_MIPS=y
- CONFIG_MIPS32=y
- # CONFIG_MIPS64 is not set
---- linux/arch/mips64/defconfig~linux-2.4.20-xattr-0.8.54-hp   Tue Apr 29 09:24:20 2003
-+++ linux-mmonroe/arch/mips64/defconfig        Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_MIPS=y
- # CONFIG_MIPS32 is not set
- CONFIG_MIPS64=y
---- linux/arch/ppc/defconfig~linux-2.4.20-xattr-0.8.54-hp      Tue Apr 29 09:24:12 2003
-+++ linux-mmonroe/arch/ppc/defconfig   Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,20 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_UID16 is not set
- # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
- CONFIG_RWSEM_XCHGADD_ALGORITHM=y
---- linux/arch/ppc64/kernel/misc.S~linux-2.4.20-xattr-0.8.54-hp        Tue Apr 29 09:24:06 2003
-+++ linux-mmonroe/arch/ppc64/kernel/misc.S     Tue Apr 29 09:26:41 2003
-@@ -731,6 +731,7 @@ _GLOBAL(sys_call_table32)
-       .llong .sys_gettid              /* 207 */
- #if 0 /* Reserved syscalls */
-       .llong .sys_tkill               /* 208 */
-+#endif
-       .llong .sys_setxattr
-       .llong .sys_lsetxattr   /* 210 */
-       .llong .sys_fsetxattr
-@@ -743,6 +744,7 @@ _GLOBAL(sys_call_table32)
-       .llong .sys_removexattr
-       .llong .sys_lremovexattr
-       .llong .sys_fremovexattr        /* 220 */
-+#if 0 /* Reserved syscalls */
-       .llong .sys_futex
- #endif
-       .llong .sys_perfmonctl   /* Put this here for now ... */
---- linux/arch/s390/defconfig~linux-2.4.20-xattr-0.8.54-hp     Tue Apr 29 09:24:20 2003
-+++ linux-mmonroe/arch/s390/defconfig  Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_ISA is not set
- # CONFIG_EISA is not set
- # CONFIG_MCA is not set
---- linux/arch/s390/kernel/entry.S~linux-2.4.20-xattr-0.8.54-hp        Tue Apr 29 09:24:20 2003
-+++ linux-mmonroe/arch/s390/kernel/entry.S     Tue Apr 29 09:26:41 2003
-@@ -558,18 +558,18 @@ sys_call_table:
-         .long  sys_fcntl64 
-       .long  sys_ni_syscall
-       .long  sys_ni_syscall
--      .long  sys_ni_syscall            /* 224 - reserved for setxattr  */
--      .long  sys_ni_syscall            /* 225 - reserved for lsetxattr */
--      .long  sys_ni_syscall            /* 226 - reserved for fsetxattr */
--      .long  sys_ni_syscall            /* 227 - reserved for getxattr  */
--      .long  sys_ni_syscall            /* 228 - reserved for lgetxattr */
--      .long  sys_ni_syscall            /* 229 - reserved for fgetxattr */
--      .long  sys_ni_syscall            /* 230 - reserved for listxattr */
--      .long  sys_ni_syscall            /* 231 - reserved for llistxattr */
--      .long  sys_ni_syscall            /* 232 - reserved for flistxattr */
--      .long  sys_ni_syscall            /* 233 - reserved for removexattr */
--      .long  sys_ni_syscall            /* 234 - reserved for lremovexattr */
--      .long  sys_ni_syscall            /* 235 - reserved for fremovexattr */
-+      .long  sys_setxattr
-+      .long  sys_lsetxattr            /* 225 */
-+      .long  sys_fsetxattr
-+      .long  sys_getxattr
-+      .long  sys_lgetxattr
-+      .long  sys_fgetxattr
-+      .long  sys_listxattr            /* 230 */
-+      .long  sys_llistxattr
-+      .long  sys_flistxattr
-+      .long  sys_removexattr
-+      .long  sys_lremovexattr
-+      .long  sys_fremovexattr         /* 235 */
-       .long  sys_gettid
-       .long  sys_tkill
-       .rept  255-237
---- linux/arch/s390x/defconfig~linux-2.4.20-xattr-0.8.54-hp    Tue Apr 29 09:24:22 2003
-+++ linux-mmonroe/arch/s390x/defconfig Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_ISA is not set
- # CONFIG_EISA is not set
- # CONFIG_MCA is not set
---- linux/arch/s390x/kernel/entry.S~linux-2.4.20-xattr-0.8.54-hp       Tue Apr 29 09:24:22 2003
-+++ linux-mmonroe/arch/s390x/kernel/entry.S    Tue Apr 29 09:26:41 2003
-@@ -591,18 +591,18 @@ sys_call_table:
-       .long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
-       .long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
-       .long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr  */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 226 - reserved for fsetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 227 - reserved for getxattr  */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 228 - reserved for lgetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 229 - reserved for fgetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 230 - reserved for listxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 231 - reserved for llistxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 232 - reserved for flistxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 233 - reserved for removexattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 234 - reserved for lremovexattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 235 - reserved for fremovexattr */
-+      .long  SYSCALL(sys_setxattr,sys32_setxattr_wrapper)
-+      .long  SYSCALL(sys_lsetxattr,sys32_lsetxattr_wrapper)   /* 225 */
-+      .long  SYSCALL(sys_fsetxattr,sys32_fsetxattr_wrapper)
-+      .long  SYSCALL(sys_getxattr,sys32_getxattr_wrapper)
-+      .long  SYSCALL(sys_lgetxattr,sys32_lgetxattr_wrapper)
-+      .long  SYSCALL(sys_fgetxattr,sys32_fgetxattr_wrapper)
-+      .long  SYSCALL(sys_listxattr,sys32_listxattr_wrapper)   /* 230 */
-+      .long  SYSCALL(sys_llistxattr,sys32_llistxattr_wrapper)
-+      .long  SYSCALL(sys_flistxattr,sys32_flistxattr_wrapper)
-+      .long  SYSCALL(sys_removexattr,sys32_removexattr_wrapper)
-+      .long  SYSCALL(sys_lremovexattr,sys32_lremovexattr_wrapper)
-+      .long  SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper)/* 235 */
-       .long  SYSCALL(sys_gettid,sys_gettid)
-       .long  SYSCALL(sys_tkill,sys_tkill)
-       .rept  255-237
---- linux/arch/s390x/kernel/wrapper32.S~linux-2.4.20-xattr-0.8.54-hp   Tue Apr 29 09:24:22 2003
-+++ linux-mmonroe/arch/s390x/kernel/wrapper32.S        Tue Apr 29 09:26:41 2003
-@@ -1091,3 +1091,95 @@ sys32_fstat64_wrapper:
-       llgtr   %r3,%r3                 # struct stat64 *
-       llgfr   %r4,%r4                 # long
-       jg      sys32_fstat64           # branch to system call
-+
-+      .globl  sys32_setxattr_wrapper
-+sys32_setxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_setxattr
-+
-+      .globl  sys32_lsetxattr_wrapper
-+sys32_lsetxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_lsetxattr
-+
-+      .globl  sys32_fsetxattr_wrapper
-+sys32_fsetxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_fsetxattr
-+
-+      .globl  sys32_getxattr_wrapper
-+sys32_getxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_getxattr
-+
-+      .globl  sys32_lgetxattr_wrapper
-+sys32_lgetxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_lgetxattr
-+
-+      .globl  sys32_fgetxattr_wrapper
-+sys32_fgetxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_fgetxattr
-+
-+      .globl  sys32_listxattr_wrapper
-+sys32_listxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_listxattr
-+
-+      .globl  sys32_llistxattr_wrapper
-+sys32_llistxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_llistxattr
-+
-+      .globl  sys32_flistxattr_wrapper
-+sys32_flistxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_flistxattr
-+
-+      .globl  sys32_removexattr_wrapper
-+sys32_removexattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_removexattr
-+
-+      .globl  sys32_lremovexattr_wrapper
-+sys32_lremovexattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_lremovexattr
-+
-+      .globl  sys32_fremovexattr_wrapper
-+sys32_fremovexattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_fremovexattr
-+
-+
---- linux/arch/sparc/defconfig~linux-2.4.20-xattr-0.8.54-hp    Tue Apr 29 09:24:08 2003
-+++ linux-mmonroe/arch/sparc/defconfig Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_UID16=y
- CONFIG_HIGHMEM=y
---- linux/arch/sparc/kernel/systbls.S~linux-2.4.20-xattr-0.8.54-hp     Tue Apr 29 09:24:08 2003
-+++ linux-mmonroe/arch/sparc/kernel/systbls.S  Tue Apr 29 09:26:41 2003
-@@ -51,11 +51,11 @@ sys_call_table:
- /*150*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
- /*155*/       .long sys_fcntl64, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
- /*160*/       .long sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
--/*165*/       .long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
--/*170*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
--/*175*/       .long sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_sigpending, sys_query_module
--/*185*/       .long sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sys_newuname
-+/*165*/       .long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
-+/*170*/       .long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
-+/*175*/       .long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module
-+/*185*/       .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sys_newuname
- /*190*/       .long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
- /*195*/       .long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
- /*200*/       .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
---- linux/arch/sparc64/defconfig~linux-2.4.20-xattr-0.8.54-hp  Tue Apr 29 09:24:15 2003
-+++ linux-mmonroe/arch/sparc64/defconfig       Tue Apr 29 09:26:41 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- #
- # Code maturity level options
---- linux/arch/sparc64/kernel/systbls.S~linux-2.4.20-xattr-0.8.54-hp   Tue Apr 29 09:24:16 2003
-+++ linux-mmonroe/arch/sparc64/kernel/systbls.S        Tue Apr 29 09:26:41 2003
-@@ -52,11 +52,11 @@ sys_call_table32:
- /*150*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
-       .word sys32_fcntl64, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
- /*160*/       .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
--      .word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_nis_syscall
--/*170*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents
--      .word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_sigpending, sys32_query_module
--      .word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
-+      .word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_setxattr
-+/*170*/       .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
-+      .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module
-+      .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
- /*190*/       .word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
-       .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
- /*200*/       .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
-@@ -111,11 +111,11 @@ sys_call_table:
- /*150*/       .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
-       .word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
- /*160*/       .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_utrap_install
--      .word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
--/*170*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
--      .word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_query_module
--      .word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
-+      .word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
-+/*170*/       .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
-+      .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module
-+      .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
- /*190*/       .word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
-       .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
- /*200*/       .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
---- linux/fs/Config.in~linux-2.4.20-xattr-0.8.54-hp    Tue Apr 29 09:23:10 2003
-+++ linux-mmonroe/fs/Config.in Tue Apr 29 09:26:41 2003
-@@ -35,6 +35,11 @@ dep_mbool '  Debug Befs' CONFIG_BEFS_DEB
- dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
- tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS
-+dep_mbool '  Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS
-+dep_bool '    Ext3 extended attribute block sharing' \
-+    CONFIG_EXT3_FS_XATTR_SHARING $CONFIG_EXT3_FS_XATTR
-+dep_bool '    Ext3 extended user attributes' \
-+    CONFIG_EXT3_FS_XATTR_USER $CONFIG_EXT3_FS_XATTR
- # CONFIG_JBD could be its own option (even modular), but until there are
- # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
- # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
-@@ -98,6 +103,11 @@ dep_mbool '  QNX4FS write support (DANGE
- tristate 'ROM file system support' CONFIG_ROMFS_FS
- tristate 'Second extended fs support' CONFIG_EXT2_FS
-+dep_mbool '  Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS
-+dep_bool '    Ext2 extended attribute block sharing' \
-+    CONFIG_EXT2_FS_XATTR_SHARING $CONFIG_EXT2_FS_XATTR
-+dep_bool '    Ext2 extended user attributes' \
-+    CONFIG_EXT2_FS_XATTR_USER $CONFIG_EXT2_FS_XATTR
- tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS
-@@ -176,6 +186,10 @@ else
-    define_tristate CONFIG_ZISOFS_FS n
- fi
-+# Meta block cache for Extended Attributes (ext2/ext3)
-+#tristate 'Meta block cache' CONFIG_FS_MBCACHE
-+define_tristate CONFIG_FS_MBCACHE y
-+
- mainmenu_option next_comment
- comment 'Partition Types'
- source fs/partitions/Config.in
---- linux/fs/Makefile~linux-2.4.20-xattr-0.8.54-hp     Tue Apr 29 09:26:26 2003
-+++ linux-mmonroe/fs/Makefile  Tue Apr 29 09:26:41 2003
-@@ -80,6 +80,9 @@ obj-y                                += binfmt_script.o
- obj-$(CONFIG_BINFMT_ELF)      += binfmt_elf.o
-+export-objs += mbcache.o
-+obj-$(CONFIG_FS_MBCACHE)      += mbcache.o
-+
- # persistent filesystems
- obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
---- linux/fs/ext2/Makefile~linux-2.4.20-xattr-0.8.54-hp        Tue Apr 29 09:23:11 2003
-+++ linux-mmonroe/fs/ext2/Makefile     Tue Apr 29 09:26:41 2003
-@@ -13,4 +13,8 @@ obj-y    := balloc.o bitmap.o dir.o file
-               ioctl.o namei.o super.o symlink.o
- obj-m    := $(O_TARGET)
-+export-objs += xattr.o
-+obj-$(CONFIG_EXT2_FS_XATTR) += xattr.o
-+obj-$(CONFIG_EXT2_FS_XATTR_USER) += xattr_user.o
-+
- include $(TOPDIR)/Rules.make
---- linux/fs/ext2/file.c~linux-2.4.20-xattr-0.8.54-hp  Tue Apr 29 09:23:11 2003
-+++ linux-mmonroe/fs/ext2/file.c       Tue Apr 29 09:26:41 2003
-@@ -20,6 +20,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/sched.h>
- /*
-@@ -51,4 +52,8 @@ struct file_operations ext2_file_operati
- struct inode_operations ext2_file_inode_operations = {
-       truncate:       ext2_truncate,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- linux/fs/ext2/ialloc.c~linux-2.4.20-xattr-0.8.54-hp        Tue Apr 29 09:23:11 2003
-+++ linux-mmonroe/fs/ext2/ialloc.c     Tue Apr 29 09:26:41 2003
-@@ -15,6 +15,7 @@
- #include <linux/config.h>
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/locks.h>
- #include <linux/quotaops.h>
-@@ -167,6 +168,7 @@ void ext2_free_inode (struct inode * ino
-        */
-       if (!is_bad_inode(inode)) {
-               /* Quota is already initialized in iput() */
-+              ext2_xattr_delete_inode(inode);
-               DQUOT_FREE_INODE(inode);
-               DQUOT_DROP(inode);
-       }
---- linux/fs/ext2/inode.c~linux-2.4.20-xattr-0.8.54-hp Tue Apr 29 09:23:11 2003
-+++ linux-mmonroe/fs/ext2/inode.c      Tue Apr 29 09:26:41 2003
-@@ -39,6 +39,18 @@ MODULE_LICENSE("GPL");
- static int ext2_update_inode(struct inode * inode, int do_sync);
- /*
-+ * Test whether an inode is a fast symlink.
-+ */
-+static inline int ext2_inode_is_fast_symlink(struct inode *inode)
-+{
-+      int ea_blocks = inode->u.ext2_i.i_file_acl ?
-+              (inode->i_sb->s_blocksize >> 9) : 0;
-+
-+      return (S_ISLNK(inode->i_mode) &&
-+              inode->i_blocks - ea_blocks == 0);
-+}
-+
-+/*
-  * Called at each iput()
-  */
- void ext2_put_inode (struct inode * inode)
-@@ -53,9 +65,7 @@ void ext2_delete_inode (struct inode * i
- {
-       lock_kernel();
--      if (is_bad_inode(inode) ||
--          inode->i_ino == EXT2_ACL_IDX_INO ||
--          inode->i_ino == EXT2_ACL_DATA_INO)
-+      if (is_bad_inode(inode))
-               goto no_delete;
-       inode->u.ext2_i.i_dtime = CURRENT_TIME;
-       mark_inode_dirty(inode);
-@@ -801,6 +811,8 @@ void ext2_truncate (struct inode * inode
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-+      if (ext2_inode_is_fast_symlink(inode))
-+              return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-@@ -888,8 +900,7 @@ void ext2_read_inode (struct inode * ino
-       unsigned long offset;
-       struct ext2_group_desc * gdp;
--      if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
--           inode->i_ino != EXT2_ACL_DATA_INO &&
-+      if ((inode->i_ino != EXT2_ROOT_INO &&
-            inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||
-           inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {
-               ext2_error (inode->i_sb, "ext2_read_inode",
-@@ -974,10 +985,7 @@ void ext2_read_inode (struct inode * ino
-       for (block = 0; block < EXT2_N_BLOCKS; block++)
-               inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
--      if (inode->i_ino == EXT2_ACL_IDX_INO ||
--          inode->i_ino == EXT2_ACL_DATA_INO)
--              /* Nothing to do */ ;
--      else if (S_ISREG(inode->i_mode)) {
-+      if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &ext2_file_inode_operations;
-               inode->i_fop = &ext2_file_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-@@ -986,15 +994,17 @@ void ext2_read_inode (struct inode * ino
-               inode->i_fop = &ext2_dir_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-       } else if (S_ISLNK(inode->i_mode)) {
--              if (!inode->i_blocks)
-+              if (ext2_inode_is_fast_symlink(inode))
-                       inode->i_op = &ext2_fast_symlink_inode_operations;
-               else {
--                      inode->i_op = &page_symlink_inode_operations;
-+                      inode->i_op = &ext2_symlink_inode_operations;
-                       inode->i_mapping->a_ops = &ext2_aops;
-               }
--      } else 
-+      } else {
-+              inode->i_op = &ext2_special_inode_operations;
-               init_special_inode(inode, inode->i_mode,
-                                  le32_to_cpu(raw_inode->i_block[0]));
-+      }
-       brelse (bh);
-       inode->i_attr_flags = 0;
-       if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) {
---- linux/fs/ext2/namei.c~linux-2.4.20-xattr-0.8.54-hp Tue Apr 29 09:23:11 2003
-+++ linux-mmonroe/fs/ext2/namei.c      Tue Apr 29 09:26:41 2003
-@@ -31,6 +31,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/pagemap.h>
- /*
-@@ -136,7 +137,7 @@ static int ext2_symlink (struct inode * 
-       if (l > sizeof (inode->u.ext2_i.i_data)) {
-               /* slow symlink */
--              inode->i_op = &page_symlink_inode_operations;
-+              inode->i_op = &ext2_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-               err = block_symlink(inode, symname, l);
-               if (err)
-@@ -345,4 +346,15 @@ struct inode_operations ext2_dir_inode_o
-       rmdir:          ext2_rmdir,
-       mknod:          ext2_mknod,
-       rename:         ext2_rename,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
-+};
-+
-+struct inode_operations ext2_special_inode_operations = {
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- linux/fs/ext2/super.c~linux-2.4.20-xattr-0.8.54-hp Tue Apr 29 09:23:11 2003
-+++ linux-mmonroe/fs/ext2/super.c      Tue Apr 29 09:26:41 2003
-@@ -21,6 +21,7 @@
- #include <linux/string.h>
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/locks.h>
-@@ -125,6 +126,7 @@ void ext2_put_super (struct super_block 
-       int db_count;
-       int i;
-+      ext2_xattr_put_super(sb);
-       if (!(sb->s_flags & MS_RDONLY)) {
-               struct ext2_super_block *es = EXT2_SB(sb)->s_es;
-@@ -175,6 +177,13 @@ static int parse_options (char * options
-            this_char = strtok (NULL, ",")) {
-               if ((value = strchr (this_char, '=')) != NULL)
-                       *value++ = 0;
-+#ifdef CONFIG_EXT2_FS_XATTR_USER
-+              if (!strcmp (this_char, "user_xattr"))
-+                      set_opt (*mount_options, XATTR_USER);
-+              else if (!strcmp (this_char, "nouser_xattr"))
-+                      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")) {
-@@ -424,6 +433,9 @@ struct super_block * ext2_read_super (st
-           blocksize = BLOCK_SIZE;
-       sb->u.ext2_sb.s_mount_opt = 0;
-+#ifdef CONFIG_EXT2_FS_XATTR_USER
-+      /* set_opt (sb->u.ext2_sb.s_mount_opt, XATTR_USER); */
-+#endif
-       if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
-           &sb->u.ext2_sb.s_mount_opt)) {
-               return NULL;
-@@ -813,12 +825,27 @@ static DECLARE_FSTYPE_DEV(ext2_fs_type, 
- static int __init init_ext2_fs(void)
- {
--        return register_filesystem(&ext2_fs_type);
-+      int error = init_ext2_xattr();
-+      if (error)
-+              return error;
-+      error = init_ext2_xattr_user();
-+      if (error)
-+              goto fail;
-+      error = register_filesystem(&ext2_fs_type);
-+      if (!error)
-+              return 0;
-+
-+      exit_ext2_xattr_user();
-+fail:
-+      exit_ext2_xattr();
-+      return error;
- }
- static void __exit exit_ext2_fs(void)
- {
-       unregister_filesystem(&ext2_fs_type);
-+      exit_ext2_xattr_user();
-+      exit_ext2_xattr();
- }
- EXPORT_NO_SYMBOLS;
---- linux/fs/ext2/symlink.c~linux-2.4.20-xattr-0.8.54-hp       Tue Apr 29 09:23:11 2003
-+++ linux-mmonroe/fs/ext2/symlink.c    Tue Apr 29 09:26:41 2003
-@@ -19,6 +19,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
-@@ -32,7 +33,20 @@ static int ext2_follow_link(struct dentr
-       return vfs_follow_link(nd, s);
- }
-+struct inode_operations ext2_symlink_inode_operations = {
-+      readlink:       page_readlink,
-+      follow_link:    page_follow_link,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
-+};
-+
- struct inode_operations ext2_fast_symlink_inode_operations = {
-       readlink:       ext2_readlink,
-       follow_link:    ext2_follow_link,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- /dev/null  Mon May 20 21:11:23 2002
-+++ linux-mmonroe/fs/ext2/xattr.c      Tue Apr 29 09:26:41 2003
-@@ -0,0 +1,1212 @@
-+/*
-+ * linux/fs/ext2/xattr.c
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
-+ * Extended attributes for symlinks and special files added per
-+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
-+ */
-+
-+/*
-+ * Extended attributes are stored on disk blocks allocated outside of
-+ * any inode. The i_file_acl field is then made to point to this allocated
-+ * block. If all extended attributes of an inode are identical, these
-+ * inodes may share the same extended attribute block. Such situations
-+ * are automatically detected by keeping a cache of recent attribute block
-+ * numbers and hashes over the block's contents in memory.
-+ *
-+ *
-+ * Extended attribute block layout:
-+ *
-+ *   +------------------+
-+ *   | header           |
-+ *   | entry 1          | |
-+ *   | entry 2          | | growing downwards
-+ *   | entry 3          | v
-+ *   | four null bytes  |
-+ *   | . . .            |
-+ *   | value 1          | ^
-+ *   | value 3          | | growing upwards
-+ *   | value 2          | |
-+ *   +------------------+
-+ *
-+ * The block header is followed by multiple entry descriptors. These entry
-+ * descriptors are variable in size, and alligned to EXT2_XATTR_PAD
-+ * byte boundaries. The entry descriptors are sorted by attribute name,
-+ * so that two extended attribute blocks can be compared efficiently.
-+ *
-+ * Attribute values are aligned to the end of the block, stored in
-+ * no specific order. They are also padded to EXT2_XATTR_PAD byte
-+ * boundaries. No additional gaps are left between them.
-+ *
-+ * Locking strategy
-+ * ----------------
-+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
-+ * the xattr inode operations are called, so we are guaranteed that only one
-+ * processes accesses extended attributes of an inode at any time.
-+ *
-+ * For writing we also grab the ext2_xattr_sem semaphore. This ensures that
-+ * only a single process is modifying an extended attribute block, even
-+ * if the block is shared among inodes.
-+ *
-+ * Note for porting to 2.5
-+ * -----------------------
-+ * The BKL will no longer be held in the xattr inode operations.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/locks.h>
-+#include <linux/slab.h>
-+#include <linux/fs.h>
-+#include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
-+#include <linux/mbcache.h>
-+#include <linux/quotaops.h>
-+#include <asm/semaphore.h>
-+#include <linux/compatmac.h>
-+
-+/* These symbols may be needed by a module. */
-+EXPORT_SYMBOL(ext2_xattr_register);
-+EXPORT_SYMBOL(ext2_xattr_unregister);
-+EXPORT_SYMBOL(ext2_xattr_get);
-+EXPORT_SYMBOL(ext2_xattr_list);
-+EXPORT_SYMBOL(ext2_xattr_set);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
-+#endif
-+
-+#define HDR(bh) ((struct ext2_xattr_header *)((bh)->b_data))
-+#define ENTRY(ptr) ((struct ext2_xattr_entry *)(ptr))
-+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
-+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
-+
-+#ifdef EXT2_XATTR_DEBUG
-+# define ea_idebug(inode, f...) do { \
-+              printk(KERN_DEBUG "inode %s:%ld: ", \
-+                      kdevname(inode->i_dev), inode->i_ino); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+# define ea_bdebug(bh, f...) do { \
-+              printk(KERN_DEBUG "block %s:%ld: ", \
-+                      kdevname(bh->b_dev), bh->b_blocknr); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+#else
-+# define ea_idebug(f...)
-+# define ea_bdebug(f...)
-+#endif
-+
-+static int ext2_xattr_set2(struct inode *, struct buffer_head *,
-+                         struct ext2_xattr_header *);
-+
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+
-+static int ext2_xattr_cache_insert(struct buffer_head *);
-+static struct buffer_head *ext2_xattr_cache_find(struct inode *,
-+                                               struct ext2_xattr_header *);
-+static void ext2_xattr_cache_remove(struct buffer_head *);
-+static void ext2_xattr_rehash(struct ext2_xattr_header *,
-+                            struct ext2_xattr_entry *);
-+
-+static struct mb_cache *ext2_xattr_cache;
-+
-+#else
-+# define ext2_xattr_cache_insert(bh) 0
-+# define ext2_xattr_cache_find(inode, header) NULL
-+# define ext2_xattr_cache_remove(bh) while(0) {}
-+# define ext2_xattr_rehash(header, entry) while(0) {}
-+#endif
-+
-+/*
-+ * If a file system does not share extended attributes among inodes,
-+ * we should not need the ext2_xattr_sem semaphore. However, the
-+ * filesystem may still contain shared blocks, so we always take
-+ * the lock.
-+ */
-+
-+DECLARE_MUTEX(ext2_xattr_sem);
-+
-+static inline int
-+ext2_xattr_new_block(struct inode *inode, int * errp, int force)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      int goal = le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) +
-+              EXT2_I(inode)->i_block_group * EXT2_BLOCKS_PER_GROUP(sb);
-+
-+      /* How can we enforce the allocation? */
-+      int block = ext2_new_block(inode, goal, 0, 0, errp);
-+#ifdef OLD_QUOTAS
-+      if (!*errp)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#endif
-+      return block;
-+}
-+
-+static inline int
-+ext2_xattr_quota_alloc(struct inode *inode, int force)
-+{
-+      /* How can we enforce the allocation? */
-+#ifdef OLD_QUOTAS
-+      int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
-+      if (!error)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#else
-+      int error = DQUOT_ALLOC_BLOCK(inode, 1);
-+#endif
-+      return error;
-+}
-+
-+#ifdef OLD_QUOTAS
-+
-+static inline void
-+ext2_xattr_quota_free(struct inode *inode)
-+{
-+      DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+static inline void
-+ext2_xattr_free_block(struct inode * inode, unsigned long block)
-+{
-+      ext2_free_blocks(inode, block, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+#else
-+# define ext2_xattr_quota_free(inode) \
-+      DQUOT_FREE_BLOCK(inode, 1)
-+# define ext2_xattr_free_block(inode, block) \
-+      ext2_free_blocks(inode, block, 1)
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
-+
-+static inline struct buffer_head *
-+sb_bread(struct super_block *sb, int block)
-+{
-+      return bread(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+static inline struct buffer_head *
-+sb_getblk(struct super_block *sb, int block)
-+{
-+      return getblk(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+#endif
-+
-+struct ext2_xattr_handler *ext2_xattr_handlers[EXT2_XATTR_INDEX_MAX];
-+rwlock_t ext2_handler_lock = RW_LOCK_UNLOCKED;
-+
-+int
-+ext2_xattr_register(int name_index, struct ext2_xattr_handler *handler)
-+{
-+      int error = -EINVAL;
-+
-+      if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
-+              write_lock(&ext2_handler_lock);
-+              if (!ext2_xattr_handlers[name_index-1]) {
-+                      ext2_xattr_handlers[name_index-1] = handler;
-+                      error = 0;
-+              }
-+              write_unlock(&ext2_handler_lock);
-+      }
-+      return error;
-+}
-+
-+void
-+ext2_xattr_unregister(int name_index, struct ext2_xattr_handler *handler)
-+{
-+      if (name_index > 0 || name_index <= EXT2_XATTR_INDEX_MAX) {
-+              write_lock(&ext2_handler_lock);
-+              ext2_xattr_handlers[name_index-1] = NULL;
-+              write_unlock(&ext2_handler_lock);
-+      }
-+}
-+
-+static inline const char *
-+strcmp_prefix(const char *a, const char *a_prefix)
-+{
-+      while (*a_prefix && *a == *a_prefix) {
-+              a++;
-+              a_prefix++;
-+      }
-+      return *a_prefix ? NULL : a;
-+}
-+
-+/*
-+ * Decode the extended attribute name, and translate it into
-+ * the name_index and name suffix.
-+ */
-+static struct ext2_xattr_handler *
-+ext2_xattr_resolve_name(const char **name)
-+{
-+      struct ext2_xattr_handler *handler = NULL;
-+      int i;
-+
-+      if (!*name)
-+              return NULL;
-+      read_lock(&ext2_handler_lock);
-+      for (i=0; i<EXT2_XATTR_INDEX_MAX; i++) {
-+              if (ext2_xattr_handlers[i]) {
-+                      const char *n = strcmp_prefix(*name,
-+                              ext2_xattr_handlers[i]->prefix);
-+                      if (n) {
-+                              handler = ext2_xattr_handlers[i];
-+                              *name = n;
-+                              break;
-+                      }
-+              }
-+      }
-+      read_unlock(&ext2_handler_lock);
-+      return handler;
-+}
-+
-+static inline struct ext2_xattr_handler *
-+ext2_xattr_handler(int name_index)
-+{
-+      struct ext2_xattr_handler *handler = NULL;
-+      if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
-+              read_lock(&ext2_handler_lock);
-+              handler = ext2_xattr_handlers[name_index-1];
-+              read_unlock(&ext2_handler_lock);
-+      }
-+      return handler;
-+}
-+
-+/*
-+ * Inode operation getxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext2_getxattr(struct dentry *dentry, const char *name,
-+            void *buffer, size_t size)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->get(inode, name, buffer, size);
-+}
-+
-+/*
-+ * Inode operation listxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
-+{
-+      return ext2_xattr_list(dentry->d_inode, buffer, size);
-+}
-+
-+/*
-+ * Inode operation setxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext2_setxattr(struct dentry *dentry, const char *name,
-+            const void *value, size_t size, int flags)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      if (size == 0)
-+              value = "";  /* empty EA, do not remove */
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, value, size, flags);
-+}
-+
-+/*
-+ * Inode operation removexattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext2_removexattr(struct dentry *dentry, const char *name)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
-+}
-+
-+/*
-+ * ext2_xattr_get()
-+ *
-+ * Copy an extended attribute into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext2_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_entry *entry;
-+      unsigned int block, size;
-+      char *end;
-+      int name_len, error;
-+
-+      ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
-+                name_index, name, buffer, (long)buffer_size);
-+
-+      if (name == NULL)
-+              return -EINVAL;
-+      if (!EXT2_I(inode)->i_file_acl)
-+              return -ENOATTR;
-+      block = EXT2_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext2_error(inode->i_sb, "ext2_xattr_get",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* find named attribute */
-+      name_len = strlen(name);
-+
-+      error = -ERANGE;
-+      if (name_len > 255)
-+              goto cleanup;
-+      entry = FIRST_ENTRY(bh);
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              if (name_index == entry->e_name_index &&
-+                  name_len == entry->e_name_len &&
-+                  memcmp(name, entry->e_name, name_len) == 0)
-+                      goto found;
-+              entry = next;
-+      }
-+      /* Check the remaining name entries */
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              entry = next;
-+      }
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      error = -ENOATTR;
-+      goto cleanup;
-+found:
-+      /* check the buffer size */
-+      if (entry->e_value_block != 0)
-+              goto bad_block;
-+      size = le32_to_cpu(entry->e_value_size);
-+      if (size > inode->i_sb->s_blocksize ||
-+          le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-+              goto bad_block;
-+
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (buffer) {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+              /* return value of attribute */
-+              memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-+                      size);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_list()
-+ *
-+ * Copy a list of attribute names into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_entry *entry;
-+      unsigned int block, size = 0;
-+      char *buf, *end;
-+      int error;
-+
-+      ea_idebug(inode, "buffer=%p, buffer_size=%ld",
-+                buffer, (long)buffer_size);
-+
-+      if (!EXT2_I(inode)->i_file_acl)
-+              return 0;
-+      block = EXT2_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext2_error(inode->i_sb, "ext2_xattr_list",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* compute the size required for the list of attribute names */
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT2_XATTR_NEXT(entry)) {
-+              struct ext2_xattr_handler *handler;
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+
-+              handler = ext2_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      size += handler->list(NULL, inode, entry->e_name,
-+                                            entry->e_name_len);
-+      }
-+
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (!buffer) {
-+              error = size;
-+              goto cleanup;
-+      } else {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+      }
-+
-+      /* list the attribute names */
-+      buf = buffer;
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT2_XATTR_NEXT(entry)) {
-+              struct ext2_xattr_handler *handler;
-+              
-+              handler = ext2_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      buf += handler->list(buf, inode, entry->e_name,
-+                                           entry->e_name_len);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * If the EXT2_FEATURE_COMPAT_EXT_ATTR feature of this file system is
-+ * not set, set it.
-+ */
-+static void ext2_xattr_update_super_block(struct super_block *sb)
-+{
-+      if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR))
-+              return;
-+
-+      lock_super(sb);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+      EXT2_SB(sb)->s_feature_compat |= EXT2_FEATURE_COMPAT_EXT_ATTR;
-+#endif
-+      EXT2_SB(sb)->s_es->s_feature_compat |=
-+              cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR);
-+      sb->s_dirt = 1;
-+      mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
-+      unlock_super(sb);
-+}
-+
-+/*
-+ * ext2_xattr_set()
-+ *
-+ * Create, replace or remove an extended attribute for this inode. Buffer
-+ * is NULL to remove an existing extended attribute, and non-NULL to
-+ * either replace an existing extended attribute, or create a new extended
-+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
-+ * specify that an extended attribute must exist and must not exist
-+ * previous to the call, respectively.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+int
-+ext2_xattr_set(struct inode *inode, int name_index, const char *name,
-+             const void *value, size_t value_len, int flags)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_header *header = NULL;
-+      struct ext2_xattr_entry *here, *last;
-+      unsigned int name_len;
-+      int block = EXT2_I(inode)->i_file_acl;
-+      int min_offs = sb->s_blocksize, not_found = 1, free, error;
-+      char *end;
-+      
-+      /*
-+       * header -- Points either into bh, or to a temporarily
-+       *           allocated buffer.
-+       * here -- The named entry found, or the place for inserting, within
-+       *         the block pointed to by header.
-+       * last -- Points right after the last named entry within the block
-+       *         pointed to by header.
-+       * min_offs -- The offset of the first value (values are aligned
-+       *             towards the end of the block).
-+       * end -- Points right after the block pointed to by header.
-+       */
-+      
-+      ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-+                name_index, name, value, (long)value_len);
-+
-+      if (IS_RDONLY(inode))
-+              return -EROFS;
-+      if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-+              return -EPERM;
-+      if (value == NULL)
-+              value_len = 0;
-+      if (name == NULL)
-+              return -EINVAL;
-+      name_len = strlen(name);
-+      if (name_len > 255 || value_len > sb->s_blocksize)
-+              return -ERANGE;
-+      down(&ext2_xattr_sem);
-+
-+      if (block) {
-+              /* The inode already has an extended attribute block. */
-+
-+              bh = sb_bread(sb, block);
-+              error = -EIO;
-+              if (!bh)
-+                      goto cleanup;
-+              ea_bdebug(bh, "b_count=%d, refcount=%d",
-+                      atomic_read(&(bh->b_count)),
-+                      le32_to_cpu(HDR(bh)->h_refcount));
-+              header = HDR(bh);
-+              end = bh->b_data + bh->b_size;
-+              if (header->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+                  header->h_blocks != cpu_to_le32(1)) {
-+bad_block:            ext2_error(sb, "ext2_xattr_set",
-+                              "inode %ld: bad block %d", inode->i_ino, block);
-+                      error = -EIO;
-+                      goto cleanup;
-+              }
-+              /* Find the named attribute. */
-+              here = FIRST_ENTRY(bh);
-+              while (!IS_LAST_ENTRY(here)) {
-+                      struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(here);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!here->e_value_block && here->e_value_size) {
-+                              int offs = le16_to_cpu(here->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      not_found = name_index - here->e_name_index;
-+                      if (!not_found)
-+                              not_found = name_len - here->e_name_len;
-+                      if (!not_found)
-+                              not_found = memcmp(name, here->e_name,name_len);
-+                      if (not_found <= 0)
-+                              break;
-+                      here = next;
-+              }
-+              last = here;
-+              /* We still need to compute min_offs and last. */
-+              while (!IS_LAST_ENTRY(last)) {
-+                      struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(last);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!last->e_value_block && last->e_value_size) {
-+                              int offs = le16_to_cpu(last->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      last = next;
-+              }
-+
-+              /* Check whether we have enough space left. */
-+              free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-+      } else {
-+              /* We will use a new extended attribute block. */
-+              free = sb->s_blocksize -
-+                      sizeof(struct ext2_xattr_header) - sizeof(__u32);
-+              here = last = NULL;  /* avoid gcc uninitialized warning. */
-+      }
-+
-+      if (not_found) {
-+              /* Request to remove a nonexistent attribute? */
-+              error = -ENOATTR;
-+              if (flags & XATTR_REPLACE)
-+                      goto cleanup;
-+              error = 0;
-+              if (value == NULL)
-+                      goto cleanup;
-+              else
-+                      free -= EXT2_XATTR_LEN(name_len);
-+      } else {
-+              /* Request to create an existing attribute? */
-+              error = -EEXIST;
-+              if (flags & XATTR_CREATE)
-+                      goto cleanup;
-+              if (!here->e_value_block && here->e_value_size) {
-+                      unsigned int size = le32_to_cpu(here->e_value_size);
-+
-+                      if (le16_to_cpu(here->e_value_offs) + size > 
-+                          sb->s_blocksize || size > sb->s_blocksize)
-+                              goto bad_block;
-+                      free += EXT2_XATTR_SIZE(size);
-+              }
-+      }
-+      free -= EXT2_XATTR_SIZE(value_len);
-+      error = -ENOSPC;
-+      if (free < 0)
-+              goto cleanup;
-+
-+      /* Here we know that we can set the new attribute. */
-+
-+      if (header) {
-+              if (header->h_refcount == cpu_to_le32(1)) {
-+                      ea_bdebug(bh, "modifying in-place");
-+                      ext2_xattr_cache_remove(bh);
-+              } else {
-+                      int offset;
-+
-+                      ea_bdebug(bh, "cloning");
-+                      header = kmalloc(bh->b_size, GFP_KERNEL);
-+                      error = -ENOMEM;
-+                      if (header == NULL)
-+                              goto cleanup;
-+                      memcpy(header, HDR(bh), bh->b_size);
-+                      header->h_refcount = cpu_to_le32(1);
-+                      offset = (char *)header - bh->b_data;
-+                      here = ENTRY((char *)here + offset);
-+                      last = ENTRY((char *)last + offset);
-+              }
-+      } else {
-+              /* Allocate a buffer where we construct the new block. */
-+              header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-+              error = -ENOMEM;
-+              if (header == NULL)
-+                      goto cleanup;
-+              memset(header, 0, sb->s_blocksize);
-+              end = (char *)header + sb->s_blocksize;
-+              header->h_magic = cpu_to_le32(EXT2_XATTR_MAGIC);
-+              header->h_blocks = header->h_refcount = cpu_to_le32(1);
-+              last = here = ENTRY(header+1);
-+      }
-+
-+      if (not_found) {
-+              /* Insert the new name. */
-+              int size = EXT2_XATTR_LEN(name_len);
-+              int rest = (char *)last - (char *)here;
-+              memmove((char *)here + size, here, rest);
-+              memset(here, 0, size);
-+              here->e_name_index = name_index;
-+              here->e_name_len = name_len;
-+              memcpy(here->e_name, name, name_len);
-+      } else {
-+              /* Remove the old value. */
-+              if (!here->e_value_block && here->e_value_size) {
-+                      char *first_val = (char *)header + min_offs;
-+                      int offs = le16_to_cpu(here->e_value_offs);
-+                      char *val = (char *)header + offs;
-+                      size_t size = EXT2_XATTR_SIZE(
-+                              le32_to_cpu(here->e_value_size));
-+                      memmove(first_val + size, first_val, val - first_val);
-+                      memset(first_val, 0, size);
-+                      here->e_value_offs = 0;
-+                      min_offs += size;
-+
-+                      /* Adjust all value offsets. */
-+                      last = ENTRY(header+1);
-+                      while (!IS_LAST_ENTRY(last)) {
-+                              int o = le16_to_cpu(last->e_value_offs);
-+                              if (!last->e_value_block && o < offs)
-+                                      last->e_value_offs =
-+                                              cpu_to_le16(o + size);
-+                              last = EXT2_XATTR_NEXT(last);
-+                      }
-+              }
-+              if (value == NULL) {
-+                      /* Remove this attribute. */
-+                      if (EXT2_XATTR_NEXT(ENTRY(header+1)) == last) {
-+                              /* This block is now empty. */
-+                              error = ext2_xattr_set2(inode, bh, NULL);
-+                              goto cleanup;
-+                      } else {
-+                              /* Remove the old name. */
-+                              int size = EXT2_XATTR_LEN(name_len);
-+                              last = ENTRY((char *)last - size);
-+                              memmove(here, (char*)here + size,
-+                                      (char*)last - (char*)here);
-+                              memset(last, 0, size);
-+                      }
-+              }
-+      }
-+
-+      if (value != NULL) {
-+              /* Insert the new value. */
-+              here->e_value_size = cpu_to_le32(value_len);
-+              if (value_len) {
-+                      size_t size = EXT2_XATTR_SIZE(value_len);
-+                      char *val = (char *)header + min_offs - size;
-+                      here->e_value_offs =
-+                              cpu_to_le16((char *)val - (char *)header);
-+                      memset(val + size - EXT2_XATTR_PAD, 0,
-+                             EXT2_XATTR_PAD); /* Clear the pad bytes. */
-+                      memcpy(val, value, value_len);
-+              }
-+      }
-+      ext2_xattr_rehash(header, here);
-+
-+      error = ext2_xattr_set2(inode, bh, header);
-+
-+cleanup:
-+      brelse(bh);
-+      if (!(bh && header == HDR(bh)))
-+              kfree(header);
-+      up(&ext2_xattr_sem);
-+
-+      return error;
-+}
-+
-+/*
-+ * Second half of ext2_xattr_set(): Update the file system.
-+ */
-+static int
-+ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
-+              struct ext2_xattr_header *header)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *new_bh = NULL;
-+      int error;
-+
-+      if (header) {
-+              new_bh = ext2_xattr_cache_find(inode, header);
-+              if (new_bh) {
-+                      /*
-+                       * We found an identical block in the cache.
-+                       * The old block will be released after updating
-+                       * the inode.
-+                       */
-+                      ea_bdebug(old_bh, "reusing block %ld",
-+                              new_bh->b_blocknr);
-+                      
-+                      error = -EDQUOT;
-+                      if (ext2_xattr_quota_alloc(inode, 1))
-+                              goto cleanup;
-+                      
-+                      HDR(new_bh)->h_refcount = cpu_to_le32(
-+                              le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
-+                      ea_bdebug(new_bh, "refcount now=%d",
-+                              le32_to_cpu(HDR(new_bh)->h_refcount));
-+              } else if (old_bh && header == HDR(old_bh)) {
-+                      /* Keep this block. */
-+                      new_bh = old_bh;
-+                      ext2_xattr_cache_insert(new_bh);
-+              } else {
-+                      /* We need to allocate a new block */
-+                      int force = EXT2_I(inode)->i_file_acl != 0;
-+                      int block = ext2_xattr_new_block(inode, &error, force);
-+                      if (error)
-+                              goto cleanup;
-+                      ea_idebug(inode, "creating block %d", block);
-+
-+                      new_bh = sb_getblk(sb, block);
-+                      if (!new_bh) {
-+                              ext2_xattr_free_block(inode, block);
-+                              error = -EIO;
-+                              goto cleanup;
-+                      }
-+                      lock_buffer(new_bh);
-+                      memcpy(new_bh->b_data, header, new_bh->b_size);
-+                      mark_buffer_uptodate(new_bh, 1);
-+                      unlock_buffer(new_bh);
-+                      ext2_xattr_cache_insert(new_bh);
-+                      
-+                      ext2_xattr_update_super_block(sb);
-+              }
-+              mark_buffer_dirty(new_bh);
-+              if (IS_SYNC(inode)) {
-+                      ll_rw_block(WRITE, 1, &new_bh);
-+                      wait_on_buffer(new_bh); 
-+                      error = -EIO;
-+                      if (buffer_req(new_bh) && !buffer_uptodate(new_bh))
-+                              goto cleanup;
-+              }
-+      }
-+
-+      /* Update the inode. */
-+      EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-+      inode->i_ctime = CURRENT_TIME;
-+      if (IS_SYNC(inode)) {
-+              error = ext2_sync_inode (inode);
-+              if (error)
-+                      goto cleanup;
-+      } else
-+              mark_inode_dirty(inode);
-+
-+      error = 0;
-+      if (old_bh && old_bh != new_bh) {
-+              /*
-+               * If there was an old block, and we are not still using it,
-+               * we now release the old block.
-+              */
-+              unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
-+
-+              if (refcount == 1) {
-+                      /* Free the old block. */
-+                      ea_bdebug(old_bh, "freeing");
-+                      ext2_xattr_free_block(inode, old_bh->b_blocknr);
-+                      mark_buffer_clean(old_bh);
-+              } else {
-+                      /* Decrement the refcount only. */
-+                      refcount--;
-+                      HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
-+                      ext2_xattr_quota_free(inode);
-+                      mark_buffer_dirty(old_bh);
-+                      ea_bdebug(old_bh, "refcount now=%d", refcount);
-+              }
-+      }
-+
-+cleanup:
-+      if (old_bh != new_bh)
-+              brelse(new_bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_delete_inode()
-+ *
-+ * Free extended attribute resources associated with this inode. This
-+ * is called immediately before an inode is freed.
-+ */
-+void
-+ext2_xattr_delete_inode(struct inode *inode)
-+{
-+      struct buffer_head *bh;
-+      unsigned int block = EXT2_I(inode)->i_file_acl;
-+
-+      if (!block)
-+              return;
-+      down(&ext2_xattr_sem);
-+
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh) {
-+              ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
-+                      "inode %ld: block %d read error", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+              ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+      if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-+              ext2_xattr_cache_remove(bh);
-+              ext2_xattr_free_block(inode, block);
-+              bforget(bh);
-+              bh = NULL;
-+      } else {
-+              HDR(bh)->h_refcount = cpu_to_le32(
-+                      le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+              mark_buffer_dirty(bh);
-+              if (IS_SYNC(inode)) {
-+                      ll_rw_block(WRITE, 1, &bh);
-+                      wait_on_buffer(bh);
-+              }
-+              ext2_xattr_quota_free(inode);
-+      }
-+      EXT2_I(inode)->i_file_acl = 0;
-+
-+cleanup:
-+      brelse(bh);
-+      up(&ext2_xattr_sem);
-+}
-+
-+/*
-+ * ext2_xattr_put_super()
-+ *
-+ * This is called when a file system is unmounted.
-+ */
-+void
-+ext2_xattr_put_super(struct super_block *sb)
-+{
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+      mb_cache_shrink(ext2_xattr_cache, sb->s_dev);
-+#endif
-+}
-+
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+
-+/*
-+ * ext2_xattr_cache_insert()
-+ *
-+ * Create a new entry in the extended attribute cache, and insert
-+ * it unless such an entry is already in the cache.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+static int
-+ext2_xattr_cache_insert(struct buffer_head *bh)
-+{
-+      __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
-+      struct mb_cache_entry *ce;
-+      int error;
-+
-+      ce = mb_cache_entry_alloc(ext2_xattr_cache);
-+      if (!ce)
-+              return -ENOMEM;
-+      error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
-+      if (error) {
-+              mb_cache_entry_free(ce);
-+              if (error == -EBUSY) {
-+                      ea_bdebug(bh, "already in cache (%d cache entries)",
-+                              atomic_read(&ext2_xattr_cache->c_entry_count));
-+                      error = 0;
-+              }
-+      } else {
-+              ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-+                        atomic_read(&ext2_xattr_cache->c_entry_count));
-+              mb_cache_entry_release(ce);
-+      }
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_cmp()
-+ *
-+ * Compare two extended attribute blocks for equality.
-+ *
-+ * Returns 0 if the blocks are equal, 1 if they differ, and
-+ * a negative error number on errors.
-+ */
-+static int
-+ext2_xattr_cmp(struct ext2_xattr_header *header1,
-+             struct ext2_xattr_header *header2)
-+{
-+      struct ext2_xattr_entry *entry1, *entry2;
-+
-+      entry1 = ENTRY(header1+1);
-+      entry2 = ENTRY(header2+1);
-+      while (!IS_LAST_ENTRY(entry1)) {
-+              if (IS_LAST_ENTRY(entry2))
-+                      return 1;
-+              if (entry1->e_hash != entry2->e_hash ||
-+                  entry1->e_name_len != entry2->e_name_len ||
-+                  entry1->e_value_size != entry2->e_value_size ||
-+                  memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
-+                      return 1;
-+              if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
-+                      return -EIO;
-+              if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
-+                         (char *)header2 + le16_to_cpu(entry2->e_value_offs),
-+                         le32_to_cpu(entry1->e_value_size)))
-+                      return 1;
-+
-+              entry1 = EXT2_XATTR_NEXT(entry1);
-+              entry2 = EXT2_XATTR_NEXT(entry2);
-+      }
-+      if (!IS_LAST_ENTRY(entry2))
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * ext2_xattr_cache_find()
-+ *
-+ * Find an identical extended attribute block.
-+ *
-+ * Returns a pointer to the block found, or NULL if such a block was
-+ * not found or an error occurred.
-+ */
-+static struct buffer_head *
-+ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header)
-+{
-+      __u32 hash = le32_to_cpu(header->h_hash);
-+      struct mb_cache_entry *ce;
-+
-+      if (!header->h_hash)
-+              return NULL;  /* never share */
-+      ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
-+      ce = mb_cache_entry_find_first(ext2_xattr_cache, 0, inode->i_dev, hash);
-+      while (ce) {
-+              struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
-+
-+              if (!bh) {
-+                      ext2_error(inode->i_sb, "ext2_xattr_cache_find",
-+                              "inode %ld: block %ld read error",
-+                              inode->i_ino, ce->e_block);
-+              } else if (le32_to_cpu(HDR(bh)->h_refcount) >
-+                         EXT2_XATTR_REFCOUNT_MAX) {
-+                      ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
-+                              le32_to_cpu(HDR(bh)->h_refcount),
-+                              EXT2_XATTR_REFCOUNT_MAX);
-+              } else if (!ext2_xattr_cmp(header, HDR(bh))) {
-+                      ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
-+                      mb_cache_entry_release(ce);
-+                      return bh;
-+              }
-+              brelse(bh);
-+              ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * ext2_xattr_cache_remove()
-+ *
-+ * Remove the cache entry of a block from the cache. Called when a
-+ * block becomes invalid.
-+ */
-+static void
-+ext2_xattr_cache_remove(struct buffer_head *bh)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_dev, bh->b_blocknr);
-+      if (ce) {
-+              ea_bdebug(bh, "removing (%d cache entries remaining)",
-+                        atomic_read(&ext2_xattr_cache->c_entry_count)-1);
-+              mb_cache_entry_free(ce);
-+      } else 
-+              ea_bdebug(bh, "no cache entry");
-+}
-+
-+#define NAME_HASH_SHIFT 5
-+#define VALUE_HASH_SHIFT 16
-+
-+/*
-+ * ext2_xattr_hash_entry()
-+ *
-+ * Compute the hash of an extended attribute.
-+ */
-+static inline void ext2_xattr_hash_entry(struct ext2_xattr_header *header,
-+                                       struct ext2_xattr_entry *entry)
-+{
-+      __u32 hash = 0;
-+      char *name = entry->e_name;
-+      int n;
-+
-+      for (n=0; n < entry->e_name_len; n++) {
-+              hash = (hash << NAME_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
-+                     *name++;
-+      }
-+
-+      if (entry->e_value_block == 0 && entry->e_value_size != 0) {
-+              __u32 *value = (__u32 *)((char *)header +
-+                      le16_to_cpu(entry->e_value_offs));
-+              for (n = (le32_to_cpu(entry->e_value_size) +
-+                   EXT2_XATTR_ROUND) >> EXT2_XATTR_PAD_BITS; n; n--) {
-+                      hash = (hash << VALUE_HASH_SHIFT) ^
-+                             (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
-+                             le32_to_cpu(*value++);
-+              }
-+      }
-+      entry->e_hash = cpu_to_le32(hash);
-+}
-+
-+#undef NAME_HASH_SHIFT
-+#undef VALUE_HASH_SHIFT
-+
-+#define BLOCK_HASH_SHIFT 16
-+
-+/*
-+ * ext2_xattr_rehash()
-+ *
-+ * Re-compute the extended attribute hash value after an entry has changed.
-+ */
-+static void ext2_xattr_rehash(struct ext2_xattr_header *header,
-+                            struct ext2_xattr_entry *entry)
-+{
-+      struct ext2_xattr_entry *here;
-+      __u32 hash = 0;
-+      
-+      ext2_xattr_hash_entry(header, entry);
-+      here = ENTRY(header+1);
-+      while (!IS_LAST_ENTRY(here)) {
-+              if (!here->e_hash) {
-+                      /* Block is not shared if an entry's hash value == 0 */
-+                      hash = 0;
-+                      break;
-+              }
-+              hash = (hash << BLOCK_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
-+                     le32_to_cpu(here->e_hash);
-+              here = EXT2_XATTR_NEXT(here);
-+      }
-+      header->h_hash = cpu_to_le32(hash);
-+}
-+
-+#undef BLOCK_HASH_SHIFT
-+
-+int __init
-+init_ext2_xattr(void)
-+{
-+      ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
-+              sizeof(struct mb_cache_entry) +
-+              sizeof(struct mb_cache_entry_index), 1, 61);
-+      if (!ext2_xattr_cache)
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+void
-+exit_ext2_xattr(void)
-+{
-+      mb_cache_destroy(ext2_xattr_cache);
-+}
-+
-+#else  /* CONFIG_EXT2_FS_XATTR_SHARING */
-+
-+int __init
-+init_ext2_xattr(void)
-+{
-+      return 0;
-+}
-+
-+void
-+exit_ext2_xattr(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT2_FS_XATTR_SHARING */
---- /dev/null  Mon May 20 21:11:23 2002
-+++ linux-mmonroe/fs/ext2/xattr_user.c Tue Apr 29 09:26:41 2003
-@@ -0,0 +1,103 @@
-+/*
-+ * linux/fs/ext2/xattr_user.c
-+ * Handler for extended user attributes.
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/fs.h>
-+#include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
-+
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+# include <linux/ext2_acl.h>
-+#endif
-+
-+#define XATTR_USER_PREFIX "user."
-+
-+static size_t
-+ext2_xattr_user_list(char *list, struct inode *inode,
-+                   const char *name, int name_len)
-+{
-+      const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
-+
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return 0;
-+
-+      if (list) {
-+              memcpy(list, XATTR_USER_PREFIX, prefix_len);
-+              memcpy(list+prefix_len, name, name_len);
-+              list[prefix_len + name_len] = '\0';
-+      }
-+      return prefix_len + name_len + 1;
-+}
-+
-+static int
-+ext2_xattr_user_get(struct inode *inode, const char *name,
-+                  void *buffer, size_t size)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+      error = ext2_permission_locked(inode, MAY_READ);
-+#else
-+      error = permission(inode, MAY_READ);
-+#endif
-+      if (error)
-+              return error;
-+
-+      return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name,
-+                            buffer, size);
-+}
-+
-+static int
-+ext2_xattr_user_set(struct inode *inode, const char *name,
-+                  const void *value, size_t size, int flags)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+      if ( !S_ISREG(inode->i_mode) &&
-+          (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-+              return -EPERM;
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+      error = ext2_permission_locked(inode, MAY_WRITE);
-+#else
-+      error = permission(inode, MAY_WRITE);
-+#endif
-+      if (error)
-+              return error;
-+  
-+      return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
-+                            value, size, flags);
-+}
-+
-+struct ext2_xattr_handler ext2_xattr_user_handler = {
-+      prefix: XATTR_USER_PREFIX,
-+      list:   ext2_xattr_user_list,
-+      get:    ext2_xattr_user_get,
-+      set:    ext2_xattr_user_set,
-+};
-+
-+int __init
-+init_ext2_xattr_user(void)
-+{
-+      return ext2_xattr_register(EXT2_XATTR_INDEX_USER,
-+                                 &ext2_xattr_user_handler);
-+}
-+
-+void
-+exit_ext2_xattr_user(void)
-+{
-+      ext2_xattr_unregister(EXT2_XATTR_INDEX_USER,
-+                            &ext2_xattr_user_handler);
-+}
---- linux/fs/ext3/Makefile~linux-2.4.20-xattr-0.8.54-hp        Tue Apr 29 09:26:28 2003
-+++ linux-mmonroe/fs/ext3/Makefile     Tue Apr 29 09:35:44 2003
-@@ -1,5 +1,5 @@
- #
--# Makefile for the linux ext2-filesystem routines.
-+# Makefile for the linux ext3-filesystem routines.
- #
- # Note! Dependencies are done automagically by 'make dep', which also
- # removes any old dependencies. DON'T put your own dependencies here
-@@ -9,10 +9,13 @@
- O_TARGET := ext3.o
--export-objs :=        super.o inode.o
-+export-objs := ext3-exports.o
- obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
--              ioctl.o namei.o super.o symlink.o hash.o
-+              ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o
- obj-m    := $(O_TARGET)
-+obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o
-+obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o
-+
- include $(TOPDIR)/Rules.make
---- linux/fs/ext3/file.c~linux-2.4.20-xattr-0.8.54-hp  Tue Apr 29 09:26:28 2003
-+++ linux-mmonroe/fs/ext3/file.c       Tue Apr 29 09:26:41 2003
-@@ -23,6 +23,7 @@
- #include <linux/locks.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/ext3_jbd.h>
- #include <linux/smp_lock.h>
-@@ -126,5 +127,9 @@ struct file_operations ext3_file_operati
- struct inode_operations ext3_file_inode_operations = {
-       truncate:       ext3_truncate,          /* BKL held */
-       setattr:        ext3_setattr,           /* BKL held */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
---- linux/fs/ext3/ialloc.c~linux-2.4.20-xattr-0.8.54-hp        Tue Apr 29 09:23:15 2003
-+++ linux-mmonroe/fs/ext3/ialloc.c     Tue Apr 29 09:26:41 2003
-@@ -17,6 +17,7 @@
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/stat.h>
- #include <linux/string.h>
- #include <linux/locks.h>
-@@ -216,6 +217,7 @@ void ext3_free_inode (handle_t *handle, 
-        * as writing the quota to disk may need the lock as well.
-        */
-       DQUOT_INIT(inode);
-+      ext3_xattr_delete_inode(handle, inode);
-       DQUOT_FREE_INODE(inode);
-       DQUOT_DROP(inode);
---- linux/fs/ext3/inode.c~linux-2.4.20-xattr-0.8.54-hp Tue Apr 29 09:23:15 2003
-+++ linux-mmonroe/fs/ext3/inode.c      Tue Apr 29 09:26:41 2003
-@@ -39,6 +39,18 @@
-  */
- #undef SEARCH_FROM_ZERO
-+/*
-+ * Test whether an inode is a fast symlink.
-+ */
-+static inline int ext3_inode_is_fast_symlink(struct inode *inode)
-+{
-+      int ea_blocks = inode->u.ext3_i.i_file_acl ?
-+              (inode->i_sb->s_blocksize >> 9) : 0;
-+
-+      return (S_ISLNK(inode->i_mode) &&
-+              inode->i_blocks - ea_blocks == 0);
-+}
-+
- /* The ext3 forget function must perform a revoke if we are freeing data
-  * which has been journaled.  Metadata (eg. indirect blocks) must be
-  * revoked in all cases. 
-@@ -48,7 +60,7 @@
-  * still needs to be revoked.
-  */
--static int ext3_forget(handle_t *handle, int is_metadata,
-+int ext3_forget(handle_t *handle, int is_metadata,
-                      struct inode *inode, struct buffer_head *bh,
-                      int blocknr)
- {
-@@ -164,9 +176,7 @@ void ext3_delete_inode (struct inode * i
- {
-       handle_t *handle;
-       
--      if (is_bad_inode(inode) ||
--          inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
-+      if (is_bad_inode(inode))
-               goto no_delete;
-       lock_kernel();
-@@ -1855,6 +1865,8 @@ void ext3_truncate(struct inode * inode)
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-+      if (ext3_inode_is_fast_symlink(inode))
-+              return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-@@ -2002,8 +2014,6 @@ int ext3_get_inode_loc (struct inode *in
-       struct ext3_group_desc * gdp;
-               
-       if ((inode->i_ino != EXT3_ROOT_INO &&
--              inode->i_ino != EXT3_ACL_IDX_INO &&
--              inode->i_ino != EXT3_ACL_DATA_INO &&
-               inode->i_ino != EXT3_JOURNAL_INO &&
-               inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
-               inode->i_ino > le32_to_cpu(
-@@ -2130,10 +2140,7 @@ void ext3_read_inode(struct inode * inod
-       brelse (iloc.bh);
--      if (inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
--              /* Nothing to do */ ;
--      else if (S_ISREG(inode->i_mode)) {
-+      if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &ext3_file_inode_operations;
-               inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-@@ -2141,15 +2148,17 @@ void ext3_read_inode(struct inode * inod
-               inode->i_op = &ext3_dir_inode_operations;
-               inode->i_fop = &ext3_dir_operations;
-       } else if (S_ISLNK(inode->i_mode)) {
--              if (!inode->i_blocks)
-+              if (ext3_inode_is_fast_symlink(inode))
-                       inode->i_op = &ext3_fast_symlink_inode_operations;
-               else {
--                      inode->i_op = &page_symlink_inode_operations;
-+                      inode->i_op = &ext3_symlink_inode_operations;
-                       inode->i_mapping->a_ops = &ext3_aops;
-               }
--      } else 
-+      } else {
-+              inode->i_op = &ext3_special_inode_operations;
-               init_special_inode(inode, inode->i_mode,
-                                  le32_to_cpu(iloc.raw_inode->i_block[0]));
-+      }
-       /* inode->i_attr_flags = 0;                             unused */
-       if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) {
-               /* inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS; unused */
---- linux/fs/ext3/namei.c~linux-2.4.20-xattr-0.8.54-hp Tue Apr 29 09:26:34 2003
-+++ linux-mmonroe/fs/ext3/namei.c      Tue Apr 29 09:26:41 2003
-@@ -29,6 +29,7 @@
- #include <linux/sched.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/fcntl.h>
- #include <linux/stat.h>
- #include <linux/string.h>
-@@ -1611,7 +1612,7 @@ static int ext3_mkdir(struct inode * dir
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
--      inode = ext3_new_inode (handle, dir, S_IFDIR);
-+      inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
-       err = PTR_ERR(inode);
-       if (IS_ERR(inode))
-               goto out_stop;
-@@ -1619,7 +1620,6 @@ static int ext3_mkdir(struct inode * dir
-       inode->i_op = &ext3_dir_inode_operations;
-       inode->i_fop = &ext3_dir_operations;
-       inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
--      inode->i_blocks = 0;    
-       dir_block = ext3_bread (handle, inode, 0, 1, &err);
-       if (!dir_block) {
-               inode->i_nlink--; /* is this nlink == 0? */
-@@ -1646,9 +1646,6 @@ static int ext3_mkdir(struct inode * dir
-       BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
-       ext3_journal_dirty_metadata(handle, dir_block);
-       brelse (dir_block);
--      inode->i_mode = S_IFDIR | mode;
--      if (dir->i_mode & S_ISGID)
--              inode->i_mode |= S_ISGID;
-       ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_entry (handle, dentry, inode);
-       if (err) {
-@@ -2017,7 +2014,7 @@ static int ext3_symlink (struct inode * 
-               goto out_stop;
-       if (l > sizeof (EXT3_I(inode)->i_data)) {
--              inode->i_op = &page_symlink_inode_operations;
-+              inode->i_op = &ext3_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-               /*
-                * block_symlink() calls back into ext3_prepare/commit_write.
-@@ -2244,4 +2241,16 @@ struct inode_operations ext3_dir_inode_o
-       rmdir:          ext3_rmdir,             /* BKL held */
-       mknod:          ext3_mknod,             /* BKL held */
-       rename:         ext3_rename,            /* BKL held */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
-+
-+struct inode_operations ext3_special_inode_operations = {
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
-+};
-+
---- linux/fs/ext3/super.c~linux-2.4.20-xattr-0.8.54-hp Tue Apr 29 09:26:28 2003
-+++ linux-mmonroe/fs/ext3/super.c      Tue Apr 29 09:36:30 2003
-@@ -24,6 +24,7 @@
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/locks.h>
-@@ -406,6 +407,7 @@ void ext3_put_super (struct super_block 
-       kdev_t j_dev = sbi->s_journal->j_dev;
-       int i;
-+      ext3_xattr_put_super(sb);
-       journal_destroy(sbi->s_journal);
-       if (!(sb->s_flags & MS_RDONLY)) {
-               EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
-@@ -502,6 +504,7 @@ static int parse_options (char * options
-                         int is_remount)
- {
-       unsigned long *mount_options = &sbi->s_mount_opt;
-+      
-       uid_t *resuid = &sbi->s_resuid;
-       gid_t *resgid = &sbi->s_resgid;
-       char * this_char;
-@@ -514,6 +517,13 @@ static int parse_options (char * options
-            this_char = strtok (NULL, ",")) {
-               if ((value = strchr (this_char, '=')) != NULL)
-                       *value++ = 0;
-+#ifdef CONFIG_EXT3_FS_XATTR_USER
-+              if (!strcmp (this_char, "user_xattr"))
-+                      set_opt (*mount_options, XATTR_USER);
-+              else if (!strcmp (this_char, "nouser_xattr"))
-+                      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")) {
-@@ -931,6 +941,12 @@ struct super_block * ext3_read_super (st
-       sbi->s_mount_opt = 0;
-       sbi->s_resuid = EXT3_DEF_RESUID;
-       sbi->s_resgid = EXT3_DEF_RESGID;
-+
-+      /* Default extended attribute flags */
-+#ifdef CONFIG_EXT3_FS_XATTR_USER
-+      /* set_opt(sbi->s_mount_opt, XATTR_USER); */
-+#endif
-+
-       if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) {
-               sb->s_dev = 0;
-               goto out_fail;
-@@ -1768,17 +1784,29 @@ static DECLARE_FSTYPE_DEV(ext3_fs_type, 
- static int __init init_ext3_fs(void)
- {
--        return register_filesystem(&ext3_fs_type);
-+      int error = init_ext3_xattr();
-+      if (error)
-+              return error;
-+      error = init_ext3_xattr_user();
-+      if (error)
-+              goto fail;
-+      error = register_filesystem(&ext3_fs_type);
-+      if (!error)
-+              return 0;
-+      
-+      exit_ext3_xattr_user();
-+fail:
-+      exit_ext3_xattr();
-+      return error;
- }
- static void __exit exit_ext3_fs(void)
- {
-       unregister_filesystem(&ext3_fs_type);
-+      exit_ext3_xattr_user();
-+      exit_ext3_xattr();
- }
--EXPORT_SYMBOL(ext3_force_commit);
--EXPORT_SYMBOL(ext3_bread);
--
- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
- MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
- MODULE_LICENSE("GPL");
---- linux/fs/ext3/symlink.c~linux-2.4.20-xattr-0.8.54-hp       Tue Apr 29 09:23:15 2003
-+++ linux-mmonroe/fs/ext3/symlink.c    Tue Apr 29 09:26:41 2003
-@@ -20,6 +20,7 @@
- #include <linux/fs.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
- static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
-@@ -33,7 +34,20 @@ static int ext3_follow_link(struct dentr
-       return vfs_follow_link(nd, s);
- }
-+struct inode_operations ext3_symlink_inode_operations = {
-+      readlink:       page_readlink,          /* BKL not held.  Don't need */
-+      follow_link:    page_follow_link,       /* BKL not held.  Don't need */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
-+};
-+
- struct inode_operations ext3_fast_symlink_inode_operations = {
-       readlink:       ext3_readlink,          /* BKL not held.  Don't need */
-       follow_link:    ext3_follow_link,       /* BKL not held.  Don't need */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
---- /dev/null  Mon May 20 21:11:23 2002
-+++ linux-mmonroe/fs/ext3/xattr.c      Tue Apr 29 09:36:13 2003
-@@ -0,0 +1,1225 @@
-+/*
-+ * linux/fs/ext3/xattr.c
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
-+ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
-+ * Extended attributes for symlinks and special files added per
-+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
-+ */
-+
-+/*
-+ * Extended attributes are stored on disk blocks allocated outside of
-+ * any inode. The i_file_acl field is then made to point to this allocated
-+ * block. If all extended attributes of an inode are identical, these
-+ * inodes may share the same extended attribute block. Such situations
-+ * are automatically detected by keeping a cache of recent attribute block
-+ * numbers and hashes over the block's contents in memory.
-+ *
-+ *
-+ * Extended attribute block layout:
-+ *
-+ *   +------------------+
-+ *   | header           |
-+ *   | entry 1          | |
-+ *   | entry 2          | | growing downwards
-+ *   | entry 3          | v
-+ *   | four null bytes  |
-+ *   | . . .            |
-+ *   | value 1          | ^
-+ *   | value 3          | | growing upwards
-+ *   | value 2          | |
-+ *   +------------------+
-+ *
-+ * The block header is followed by multiple entry descriptors. These entry
-+ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
-+ * byte boundaries. The entry descriptors are sorted by attribute name,
-+ * so that two extended attribute blocks can be compared efficiently.
-+ *
-+ * Attribute values are aligned to the end of the block, stored in
-+ * no specific order. They are also padded to EXT3_XATTR_PAD byte
-+ * boundaries. No additional gaps are left between them.
-+ *
-+ * Locking strategy
-+ * ----------------
-+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
-+ * the xattr inode operations are called, so we are guaranteed that only one
-+ * processes accesses extended attributes of an inode at any time.
-+ *
-+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
-+ * only a single process is modifying an extended attribute block, even
-+ * if the block is shared among inodes.
-+ *
-+ * Note for porting to 2.5
-+ * -----------------------
-+ * The BKL will no longer be held in the xattr inode operations.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/locks.h>
-+#include <linux/slab.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
-+#include <linux/mbcache.h>
-+#include <linux/quotaops.h>
-+#include <asm/semaphore.h>
-+#include <linux/compatmac.h>
-+
-+#define EXT3_EA_USER "user."
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
-+#endif
-+
-+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
-+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
-+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
-+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
-+
-+#ifdef EXT3_XATTR_DEBUG
-+# define ea_idebug(inode, f...) do { \
-+              printk(KERN_DEBUG "inode %s:%ld: ", \
-+                      kdevname(inode->i_dev), inode->i_ino); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+# define ea_bdebug(bh, f...) do { \
-+              printk(KERN_DEBUG "block %s:%ld: ", \
-+                      kdevname(bh->b_dev), bh->b_blocknr); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+#else
-+# define ea_idebug(f...)
-+# define ea_bdebug(f...)
-+#endif
-+
-+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
-+                         struct ext3_xattr_header *);
-+
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+
-+static int ext3_xattr_cache_insert(struct buffer_head *);
-+static struct buffer_head *ext3_xattr_cache_find(struct inode *,
-+                                               struct ext3_xattr_header *);
-+static void ext3_xattr_cache_remove(struct buffer_head *);
-+static void ext3_xattr_rehash(struct ext3_xattr_header *,
-+                            struct ext3_xattr_entry *);
-+
-+static struct mb_cache *ext3_xattr_cache;
-+
-+#else
-+# define ext3_xattr_cache_insert(bh) 0
-+# define ext3_xattr_cache_find(inode, header) NULL
-+# define ext3_xattr_cache_remove(bh) while(0) {}
-+# define ext3_xattr_rehash(header, entry) while(0) {}
-+#endif
-+
-+/*
-+ * If a file system does not share extended attributes among inodes,
-+ * we should not need the ext3_xattr_sem semaphore. However, the
-+ * filesystem may still contain shared blocks, so we always take
-+ * the lock.
-+ */
-+
-+DECLARE_MUTEX(ext3_xattr_sem);
-+
-+static inline int
-+ext3_xattr_new_block(handle_t *handle, struct inode *inode,
-+                   int * errp, int force)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
-+              EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb);
-+
-+      /* How can we enforce the allocation? */
-+      int block = ext3_new_block(handle, inode, goal, 0, 0, errp);
-+#ifdef OLD_QUOTAS
-+      if (!*errp)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#endif
-+      return block;
-+}
-+
-+static inline int
-+ext3_xattr_quota_alloc(struct inode *inode, int force)
-+{
-+      /* How can we enforce the allocation? */
-+#ifdef OLD_QUOTAS
-+      int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
-+      if (!error)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#else
-+      int error = DQUOT_ALLOC_BLOCK(inode, 1);
-+#endif
-+      return error;
-+}
-+
-+#ifdef OLD_QUOTAS
-+
-+static inline void
-+ext3_xattr_quota_free(struct inode *inode)
-+{
-+      DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+static inline void
-+ext3_xattr_free_block(handle_t *handle, struct inode * inode,
-+                    unsigned long block)
-+{
-+      ext3_free_blocks(handle, inode, block, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+#else
-+# define ext3_xattr_quota_free(inode) \
-+      DQUOT_FREE_BLOCK(inode, 1)
-+# define ext3_xattr_free_block(handle, inode, block) \
-+      ext3_free_blocks(handle, inode, block, 1)
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
-+
-+static inline struct buffer_head *
-+sb_bread(struct super_block *sb, int block)
-+{
-+      return bread(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+static inline struct buffer_head *
-+sb_getblk(struct super_block *sb, int block)
-+{
-+      return getblk(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+#endif
-+
-+struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
-+rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
-+
-+int
-+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      int error = -EINVAL;
-+
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              if (!ext3_xattr_handlers[name_index-1]) {
-+                      ext3_xattr_handlers[name_index-1] = handler;
-+                      error = 0;
-+              }
-+              write_unlock(&ext3_handler_lock);
-+      }
-+      return error;
-+}
-+
-+void
-+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              ext3_xattr_handlers[name_index-1] = NULL;
-+              write_unlock(&ext3_handler_lock);
-+      }
-+}
-+
-+static inline const char *
-+strcmp_prefix(const char *a, const char *a_prefix)
-+{
-+      while (*a_prefix && *a == *a_prefix) {
-+              a++;
-+              a_prefix++;
-+      }
-+      return *a_prefix ? NULL : a;
-+}
-+
-+/*
-+ * Decode the extended attribute name, and translate it into
-+ * the name_index and name suffix.
-+ */
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_resolve_name(const char **name)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      int i;
-+
-+      if (!*name)
-+              return NULL;
-+      read_lock(&ext3_handler_lock);
-+      for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
-+              if (ext3_xattr_handlers[i]) {
-+                      const char *n = strcmp_prefix(*name,
-+                              ext3_xattr_handlers[i]->prefix);
-+                      if (n) {
-+                              handler = ext3_xattr_handlers[i];
-+                              *name = n;
-+                              break;
-+                      }
-+              }
-+      }
-+      read_unlock(&ext3_handler_lock);
-+      return handler;
-+}
-+
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_handler(int name_index)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              read_lock(&ext3_handler_lock);
-+              handler = ext3_xattr_handlers[name_index-1];
-+              read_unlock(&ext3_handler_lock);
-+      }
-+      return handler;
-+}
-+
-+/*
-+ * Inode operation getxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext3_getxattr(struct dentry *dentry, const char *name,
-+            void *buffer, size_t size)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->get(inode, name, buffer, size);
-+}
-+
-+/*
-+ * Inode operation listxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
-+{
-+      return ext3_xattr_list(dentry->d_inode, buffer, size);
-+}
-+
-+/*
-+ * Inode operation setxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext3_setxattr(struct dentry *dentry, const char *name,
-+            const void *value, size_t size, int flags)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      if (size == 0)
-+              value = "";  /* empty EA, do not remove */
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, value, size, flags);
-+}
-+
-+/*
-+ * Inode operation removexattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext3_removexattr(struct dentry *dentry, const char *name)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
-+}
-+
-+/*
-+ * ext3_xattr_get()
-+ *
-+ * Copy an extended attribute into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size;
-+      char *end;
-+      int name_len, error;
-+
-+      ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
-+                name_index, name, buffer, (long)buffer_size);
-+
-+      if (name == NULL)
-+              return -EINVAL;
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return -ENOATTR;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_get",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* find named attribute */
-+      name_len = strlen(name);
-+
-+      error = -ERANGE;
-+      if (name_len > 255)
-+              goto cleanup;
-+      entry = FIRST_ENTRY(bh);
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              if (name_index == entry->e_name_index &&
-+                  name_len == entry->e_name_len &&
-+                  memcmp(name, entry->e_name, name_len) == 0)
-+                      goto found;
-+              entry = next;
-+      }
-+      /* Check the remaining name entries */
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              entry = next;
-+      }
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      error = -ENOATTR;
-+      goto cleanup;
-+found:
-+      /* check the buffer size */
-+      if (entry->e_value_block != 0)
-+              goto bad_block;
-+      size = le32_to_cpu(entry->e_value_size);
-+      if (size > inode->i_sb->s_blocksize ||
-+          le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-+              goto bad_block;
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (buffer) {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+              /* return value of attribute */
-+              memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-+                      size);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_list()
-+ *
-+ * Copy a list of attribute names into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size = 0;
-+      char *buf, *end;
-+      int error;
-+
-+      ea_idebug(inode, "buffer=%p, buffer_size=%ld",
-+                buffer, (long)buffer_size);
-+
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return 0;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_list",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* compute the size required for the list of attribute names */
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      size += handler->list(NULL, inode, entry->e_name,
-+                                            entry->e_name_len);
-+      }
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (!buffer) {
-+              error = size;
-+              goto cleanup;
-+      } else {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+      }
-+
-+      /* list the attribute names */
-+      buf = buffer;
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      buf += handler->list(buf, inode, entry->e_name,
-+                                           entry->e_name_len);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
-+ * not set, set it.
-+ */
-+static void ext3_xattr_update_super_block(handle_t *handle,
-+                                        struct super_block *sb)
-+{
-+      if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
-+              return;
-+
-+      lock_super(sb);
-+      ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+      EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR;
-+#endif
-+      EXT3_SB(sb)->s_es->s_feature_compat |=
-+              cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
-+      sb->s_dirt = 1;
-+      ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-+      unlock_super(sb);
-+}
-+
-+/*
-+ * ext3_xattr_set()
-+ *
-+ * Create, replace or remove an extended attribute for this inode. Buffer
-+ * is NULL to remove an existing extended attribute, and non-NULL to
-+ * either replace an existing extended attribute, or create a new extended
-+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
-+ * specify that an extended attribute must exist and must not exist
-+ * previous to the call, respectively.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, const void *value, size_t value_len, int flags)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_header *header = NULL;
-+      struct ext3_xattr_entry *here, *last;
-+      unsigned int name_len;
-+      int block = EXT3_I(inode)->i_file_acl;
-+      int min_offs = sb->s_blocksize, not_found = 1, free, error;
-+      char *end;
-+      
-+      /*
-+       * header -- Points either into bh, or to a temporarily
-+       *           allocated buffer.
-+       * here -- The named entry found, or the place for inserting, within
-+       *         the block pointed to by header.
-+       * last -- Points right after the last named entry within the block
-+       *         pointed to by header.
-+       * min_offs -- The offset of the first value (values are aligned
-+       *             towards the end of the block).
-+       * end -- Points right after the block pointed to by header.
-+       */
-+      
-+      ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-+                name_index, name, value, (long)value_len);
-+
-+      if (IS_RDONLY(inode))
-+              return -EROFS;
-+      if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-+              return -EPERM;
-+      if (value == NULL)
-+              value_len = 0;
-+      if (name == NULL)
-+              return -EINVAL;
-+      name_len = strlen(name);
-+      if (name_len > 255 || value_len > sb->s_blocksize)
-+              return -ERANGE;
-+      down(&ext3_xattr_sem);
-+
-+      if (block) {
-+              /* The inode already has an extended attribute block. */
-+              bh = sb_bread(sb, block);
-+              error = -EIO;
-+              if (!bh)
-+                      goto cleanup;
-+              ea_bdebug(bh, "b_count=%d, refcount=%d",
-+                      atomic_read(&(bh->b_count)),
-+                      le32_to_cpu(HDR(bh)->h_refcount));
-+              header = HDR(bh);
-+              end = bh->b_data + bh->b_size;
-+              if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+                  header->h_blocks != cpu_to_le32(1)) {
-+bad_block:            ext3_error(sb, "ext3_xattr_set",
-+                              "inode %ld: bad block %d", inode->i_ino, block);
-+                      error = -EIO;
-+                      goto cleanup;
-+              }
-+              /* Find the named attribute. */
-+              here = FIRST_ENTRY(bh);
-+              while (!IS_LAST_ENTRY(here)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!here->e_value_block && here->e_value_size) {
-+                              int offs = le16_to_cpu(here->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      not_found = name_index - here->e_name_index;
-+                      if (!not_found)
-+                              not_found = name_len - here->e_name_len;
-+                      if (!not_found)
-+                              not_found = memcmp(name, here->e_name,name_len);
-+                      if (not_found <= 0)
-+                              break;
-+                      here = next;
-+              }
-+              last = here;
-+              /* We still need to compute min_offs and last. */
-+              while (!IS_LAST_ENTRY(last)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!last->e_value_block && last->e_value_size) {
-+                              int offs = le16_to_cpu(last->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      last = next;
-+              }
-+
-+              /* Check whether we have enough space left. */
-+              free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-+      } else {
-+              /* We will use a new extended attribute block. */
-+              free = sb->s_blocksize -
-+                      sizeof(struct ext3_xattr_header) - sizeof(__u32);
-+              here = last = NULL;  /* avoid gcc uninitialized warning. */
-+      }
-+
-+      if (not_found) {
-+              /* Request to remove a nonexistent attribute? */
-+              error = -ENOATTR;
-+              if (flags & XATTR_REPLACE)
-+                      goto cleanup;
-+              error = 0;
-+              if (value == NULL)
-+                      goto cleanup;
-+              else
-+                      free -= EXT3_XATTR_LEN(name_len);
-+      } else {
-+              /* Request to create an existing attribute? */
-+              error = -EEXIST;
-+              if (flags & XATTR_CREATE)
-+                      goto cleanup;
-+              if (!here->e_value_block && here->e_value_size) {
-+                      unsigned int size = le32_to_cpu(here->e_value_size);
-+
-+                      if (le16_to_cpu(here->e_value_offs) + size > 
-+                          sb->s_blocksize || size > sb->s_blocksize)
-+                              goto bad_block;
-+                      free += EXT3_XATTR_SIZE(size);
-+              }
-+      }
-+      free -= EXT3_XATTR_SIZE(value_len);
-+      error = -ENOSPC;
-+      if (free < 0)
-+              goto cleanup;
-+
-+      /* Here we know that we can set the new attribute. */
-+
-+      if (header) {
-+              if (header->h_refcount == cpu_to_le32(1)) {
-+                      ea_bdebug(bh, "modifying in-place");
-+                      ext3_xattr_cache_remove(bh);
-+                      error = ext3_journal_get_write_access(handle, bh);
-+                      if (error)
-+                              goto cleanup;
-+              } else {
-+                      int offset;
-+
-+                      ea_bdebug(bh, "cloning");
-+                      header = kmalloc(bh->b_size, GFP_KERNEL);
-+                      error = -ENOMEM;
-+                      if (header == NULL)
-+                              goto cleanup;
-+                      memcpy(header, HDR(bh), bh->b_size);
-+                      header->h_refcount = cpu_to_le32(1);
-+                      offset = (char *)header - bh->b_data;
-+                      here = ENTRY((char *)here + offset);
-+                      last = ENTRY((char *)last + offset);
-+              }
-+      } else {
-+              /* Allocate a buffer where we construct the new block. */
-+              header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-+              error = -ENOMEM;
-+              if (header == NULL)
-+                      goto cleanup;
-+              memset(header, 0, sb->s_blocksize);
-+              end = (char *)header + sb->s_blocksize;
-+              header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
-+              header->h_blocks = header->h_refcount = cpu_to_le32(1);
-+              last = here = ENTRY(header+1);
-+      }
-+
-+      if (not_found) {
-+              /* Insert the new name. */
-+              int size = EXT3_XATTR_LEN(name_len);
-+              int rest = (char *)last - (char *)here;
-+              memmove((char *)here + size, here, rest);
-+              memset(here, 0, size);
-+              here->e_name_index = name_index;
-+              here->e_name_len = name_len;
-+              memcpy(here->e_name, name, name_len);
-+      } else {
-+              /* Remove the old value. */
-+              if (!here->e_value_block && here->e_value_size) {
-+                      char *first_val = (char *)header + min_offs;
-+                      int offs = le16_to_cpu(here->e_value_offs);
-+                      char *val = (char *)header + offs;
-+                      size_t size = EXT3_XATTR_SIZE(
-+                              le32_to_cpu(here->e_value_size));
-+                      memmove(first_val + size, first_val, val - first_val);
-+                      memset(first_val, 0, size);
-+                      here->e_value_offs = 0;
-+                      min_offs += size;
-+
-+                      /* Adjust all value offsets. */
-+                      last = ENTRY(header+1);
-+                      while (!IS_LAST_ENTRY(last)) {
-+                              int o = le16_to_cpu(last->e_value_offs);
-+                              if (!last->e_value_block && o < offs)
-+                                      last->e_value_offs =
-+                                              cpu_to_le16(o + size);
-+                              last = EXT3_XATTR_NEXT(last);
-+                      }
-+              }
-+              if (value == NULL) {
-+                      /* Remove this attribute. */
-+                      if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
-+                              /* This block is now empty. */
-+                              error = ext3_xattr_set2(handle, inode, bh,NULL);
-+                              goto cleanup;
-+                      } else {
-+                              /* Remove the old name. */
-+                              int size = EXT3_XATTR_LEN(name_len);
-+                              last = ENTRY((char *)last - size);
-+                              memmove(here, (char*)here + size,
-+                                      (char*)last - (char*)here);
-+                              memset(last, 0, size);
-+                      }
-+              }
-+      }
-+
-+      if (value != NULL) {
-+              /* Insert the new value. */
-+              here->e_value_size = cpu_to_le32(value_len);
-+              if (value_len) {
-+                      size_t size = EXT3_XATTR_SIZE(value_len);
-+                      char *val = (char *)header + min_offs - size;
-+                      here->e_value_offs =
-+                              cpu_to_le16((char *)val - (char *)header);
-+                      memset(val + size - EXT3_XATTR_PAD, 0,
-+                             EXT3_XATTR_PAD); /* Clear the pad bytes. */
-+                      memcpy(val, value, value_len);
-+              }
-+      }
-+      ext3_xattr_rehash(header, here);
-+
-+      error = ext3_xattr_set2(handle, inode, bh, header);
-+
-+cleanup:
-+      brelse(bh);
-+      if (!(bh && header == HDR(bh)))
-+              kfree(header);
-+      up(&ext3_xattr_sem);
-+
-+      return error;
-+}
-+
-+/*
-+ * Second half of ext3_xattr_set(): Update the file system.
-+ */
-+static int
-+ext3_xattr_set2(handle_t *handle, struct inode *inode,
-+              struct buffer_head *old_bh, struct ext3_xattr_header *header)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *new_bh = NULL;
-+      int error;
-+
-+      if (header) {
-+              new_bh = ext3_xattr_cache_find(inode, header);
-+              if (new_bh) {
-+                      /*
-+                       * We found an identical block in the cache.
-+                       * The old block will be released after updating
-+                       * the inode.
-+                       */
-+                      ea_bdebug(old_bh, "reusing block %ld",
-+                              new_bh->b_blocknr);
-+                      
-+                      error = -EDQUOT;
-+                      if (ext3_xattr_quota_alloc(inode, 1))
-+                              goto cleanup;
-+                      
-+                      error = ext3_journal_get_write_access(handle, new_bh);
-+                      if (error)
-+                              goto cleanup;
-+                      HDR(new_bh)->h_refcount = cpu_to_le32(
-+                              le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
-+                      ea_bdebug(new_bh, "refcount now=%d",
-+                              le32_to_cpu(HDR(new_bh)->h_refcount));
-+              } else if (old_bh && header == HDR(old_bh)) {
-+                      /* Keep this block. */
-+                      new_bh = old_bh;
-+                      ext3_xattr_cache_insert(new_bh);
-+              } else {
-+                      /* We need to allocate a new block */
-+                      int force = EXT3_I(inode)->i_file_acl != 0;
-+                      int block = ext3_xattr_new_block(handle, inode,
-+                                                       &error, force);
-+                      if (error)
-+                              goto cleanup;
-+                      ea_idebug(inode, "creating block %d", block);
-+
-+                      new_bh = sb_getblk(sb, block);
-+                      if (!new_bh) {
-+getblk_failed:                        ext3_xattr_free_block(handle, inode, block);
-+                              error = -EIO;
-+                              goto cleanup;
-+                      }
-+                      lock_buffer(new_bh);
-+                      error = ext3_journal_get_create_access(handle, new_bh);
-+                      if (error) {
-+                              unlock_buffer(new_bh);
-+                              goto getblk_failed;
-+                      }
-+                      memcpy(new_bh->b_data, header, new_bh->b_size);
-+                      mark_buffer_uptodate(new_bh, 1);
-+                      unlock_buffer(new_bh);
-+                      ext3_xattr_cache_insert(new_bh);
-+                      
-+                      ext3_xattr_update_super_block(handle, sb);
-+              }
-+              error = ext3_journal_dirty_metadata(handle, new_bh);
-+              if (error)
-+                      goto cleanup;
-+      }
-+
-+      /* Update the inode. */
-+      EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-+      inode->i_ctime = CURRENT_TIME;
-+      ext3_mark_inode_dirty(handle, inode);
-+      if (IS_SYNC(inode))
-+              handle->h_sync = 1;
-+
-+      error = 0;
-+      if (old_bh && old_bh != new_bh) {
-+              /*
-+               * If there was an old block, and we are not still using it,
-+               * we now release the old block.
-+              */
-+              unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
-+
-+              error = ext3_journal_get_write_access(handle, old_bh);
-+              if (error)
-+                      goto cleanup;
-+              if (refcount == 1) {
-+                      /* Free the old block. */
-+                      ea_bdebug(old_bh, "freeing");
-+                      ext3_xattr_free_block(handle, inode, old_bh->b_blocknr);
-+
-+                      /* ext3_forget() calls bforget() for us, but we
-+                         let our caller release old_bh, so we need to
-+                         duplicate the handle before. */
-+                      get_bh(old_bh);
-+                      ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
-+              } else {
-+                      /* Decrement the refcount only. */
-+                      refcount--;
-+                      HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
-+                      ext3_xattr_quota_free(inode);
-+                      ext3_journal_dirty_metadata(handle, old_bh);
-+                      ea_bdebug(old_bh, "refcount now=%d", refcount);
-+              }
-+      }
-+
-+cleanup:
-+      if (old_bh != new_bh)
-+              brelse(new_bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_delete_inode()
-+ *
-+ * Free extended attribute resources associated with this inode. This
-+ * is called immediately before an inode is freed.
-+ */
-+void
-+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
-+{
-+      struct buffer_head *bh;
-+      unsigned int block = EXT3_I(inode)->i_file_acl;
-+
-+      if (!block)
-+              return;
-+      down(&ext3_xattr_sem);
-+
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh) {
-+              ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
-+                      "inode %ld: block %d read error", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+              ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ext3_journal_get_write_access(handle, bh);
-+      ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+      if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-+              ext3_xattr_cache_remove(bh);
-+              ext3_xattr_free_block(handle, inode, block);
-+              ext3_forget(handle, 1, inode, bh, block);
-+              bh = NULL;
-+      } else {
-+              HDR(bh)->h_refcount = cpu_to_le32(
-+                      le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+              ext3_journal_dirty_metadata(handle, bh);
-+              if (IS_SYNC(inode))
-+                      handle->h_sync = 1;
-+              ext3_xattr_quota_free(inode);
-+      }
-+      EXT3_I(inode)->i_file_acl = 0;
-+
-+cleanup:
-+      brelse(bh);
-+      up(&ext3_xattr_sem);
-+}
-+
-+/*
-+ * ext3_xattr_put_super()
-+ *
-+ * This is called when a file system is unmounted.
-+ */
-+void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+      mb_cache_shrink(ext3_xattr_cache, sb->s_dev);
-+#endif
-+}
-+
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+
-+/*
-+ * ext3_xattr_cache_insert()
-+ *
-+ * Create a new entry in the extended attribute cache, and insert
-+ * it unless such an entry is already in the cache.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+static int
-+ext3_xattr_cache_insert(struct buffer_head *bh)
-+{
-+      __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
-+      struct mb_cache_entry *ce;
-+      int error;
-+
-+      ce = mb_cache_entry_alloc(ext3_xattr_cache);
-+      if (!ce)
-+              return -ENOMEM;
-+      error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
-+      if (error) {
-+              mb_cache_entry_free(ce);
-+              if (error == -EBUSY) {
-+                      ea_bdebug(bh, "already in cache (%d cache entries)",
-+                              atomic_read(&ext3_xattr_cache->c_entry_count));
-+                      error = 0;
-+              }
-+      } else {
-+              ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-+                        atomic_read(&ext3_xattr_cache->c_entry_count));
-+              mb_cache_entry_release(ce);
-+      }
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_cmp()
-+ *
-+ * Compare two extended attribute blocks for equality.
-+ *
-+ * Returns 0 if the blocks are equal, 1 if they differ, and
-+ * a negative error number on errors.
-+ */
-+static int
-+ext3_xattr_cmp(struct ext3_xattr_header *header1,
-+             struct ext3_xattr_header *header2)
-+{
-+      struct ext3_xattr_entry *entry1, *entry2;
-+
-+      entry1 = ENTRY(header1+1);
-+      entry2 = ENTRY(header2+1);
-+      while (!IS_LAST_ENTRY(entry1)) {
-+              if (IS_LAST_ENTRY(entry2))
-+                      return 1;
-+              if (entry1->e_hash != entry2->e_hash ||
-+                  entry1->e_name_len != entry2->e_name_len ||
-+                  entry1->e_value_size != entry2->e_value_size ||
-+                  memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
-+                      return 1;
-+              if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
-+                      return -EIO;
-+              if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
-+                         (char *)header2 + le16_to_cpu(entry2->e_value_offs),
-+                         le32_to_cpu(entry1->e_value_size)))
-+                      return 1;
-+
-+              entry1 = EXT3_XATTR_NEXT(entry1);
-+              entry2 = EXT3_XATTR_NEXT(entry2);
-+      }
-+      if (!IS_LAST_ENTRY(entry2))
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * ext3_xattr_cache_find()
-+ *
-+ * Find an identical extended attribute block.
-+ *
-+ * Returns a pointer to the block found, or NULL if such a block was
-+ * not found or an error occurred.
-+ */
-+static struct buffer_head *
-+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
-+{
-+      __u32 hash = le32_to_cpu(header->h_hash);
-+      struct mb_cache_entry *ce;
-+
-+      if (!header->h_hash)
-+              return NULL;  /* never share */
-+      ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
-+      ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash);
-+      while (ce) {
-+              struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
-+
-+              if (!bh) {
-+                      ext3_error(inode->i_sb, "ext3_xattr_cache_find",
-+                              "inode %ld: block %ld read error",
-+                              inode->i_ino, ce->e_block);
-+              } else if (le32_to_cpu(HDR(bh)->h_refcount) >
-+                         EXT3_XATTR_REFCOUNT_MAX) {
-+                      ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
-+                              le32_to_cpu(HDR(bh)->h_refcount),
-+                              EXT3_XATTR_REFCOUNT_MAX);
-+              } else if (!ext3_xattr_cmp(header, HDR(bh))) {
-+                      ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
-+                      mb_cache_entry_release(ce);
-+                      return bh;
-+              }
-+              brelse(bh);
-+              ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * ext3_xattr_cache_remove()
-+ *
-+ * Remove the cache entry of a block from the cache. Called when a
-+ * block becomes invalid.
-+ */
-+static void
-+ext3_xattr_cache_remove(struct buffer_head *bh)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr);
-+      if (ce) {
-+              ea_bdebug(bh, "removing (%d cache entries remaining)",
-+                        atomic_read(&ext3_xattr_cache->c_entry_count)-1);
-+              mb_cache_entry_free(ce);
-+      } else 
-+              ea_bdebug(bh, "no cache entry");
-+}
-+
-+#define NAME_HASH_SHIFT 5
-+#define VALUE_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_hash_entry()
-+ *
-+ * Compute the hash of an extended attribute.
-+ */
-+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
-+                                       struct ext3_xattr_entry *entry)
-+{
-+      __u32 hash = 0;
-+      char *name = entry->e_name;
-+      int n;
-+
-+      for (n=0; n < entry->e_name_len; n++) {
-+              hash = (hash << NAME_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
-+                     *name++;
-+      }
-+
-+      if (entry->e_value_block == 0 && entry->e_value_size != 0) {
-+              __u32 *value = (__u32 *)((char *)header +
-+                      le16_to_cpu(entry->e_value_offs));
-+              for (n = (le32_to_cpu(entry->e_value_size) +
-+                   EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
-+                      hash = (hash << VALUE_HASH_SHIFT) ^
-+                             (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
-+                             le32_to_cpu(*value++);
-+              }
-+      }
-+      entry->e_hash = cpu_to_le32(hash);
-+}
-+
-+#undef NAME_HASH_SHIFT
-+#undef VALUE_HASH_SHIFT
-+
-+#define BLOCK_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_rehash()
-+ *
-+ * Re-compute the extended attribute hash value after an entry has changed.
-+ */
-+static void ext3_xattr_rehash(struct ext3_xattr_header *header,
-+                            struct ext3_xattr_entry *entry)
-+{
-+      struct ext3_xattr_entry *here;
-+      __u32 hash = 0;
-+      
-+      ext3_xattr_hash_entry(header, entry);
-+      here = ENTRY(header+1);
-+      while (!IS_LAST_ENTRY(here)) {
-+              if (!here->e_hash) {
-+                      /* Block is not shared if an entry's hash value == 0 */
-+                      hash = 0;
-+                      break;
-+              }
-+              hash = (hash << BLOCK_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
-+                     le32_to_cpu(here->e_hash);
-+              here = EXT3_XATTR_NEXT(here);
-+      }
-+      header->h_hash = cpu_to_le32(hash);
-+}
-+
-+#undef BLOCK_HASH_SHIFT
-+
-+int __init
-+init_ext3_xattr(void)
-+{
-+      ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
-+              sizeof(struct mb_cache_entry) +
-+              sizeof(struct mb_cache_entry_index), 1, 61);
-+      if (!ext3_xattr_cache)
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+void
-+exit_ext3_xattr(void)
-+{
-+      if (ext3_xattr_cache)
-+              mb_cache_destroy(ext3_xattr_cache);
-+      ext3_xattr_cache = NULL;
-+}
-+
-+#else  /* CONFIG_EXT3_FS_XATTR_SHARING */
-+
-+int __init
-+init_ext3_xattr(void)
-+{
-+      return 0;
-+}
-+
-+void
-+exit_ext3_xattr(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
---- /dev/null  Mon May 20 21:11:23 2002
-+++ linux-mmonroe/fs/ext3/xattr_user.c Tue Apr 29 09:26:41 2003
-@@ -0,0 +1,111 @@
-+/*
-+ * linux/fs/ext3/xattr_user.c
-+ * Handler for extended user attributes.
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/fs.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
-+
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+# include <linux/ext3_acl.h>
-+#endif
-+
-+#define XATTR_USER_PREFIX "user."
-+
-+static size_t
-+ext3_xattr_user_list(char *list, struct inode *inode,
-+                   const char *name, int name_len)
-+{
-+      const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
-+
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return 0;
-+
-+      if (list) {
-+              memcpy(list, XATTR_USER_PREFIX, prefix_len);
-+              memcpy(list+prefix_len, name, name_len);
-+              list[prefix_len + name_len] = '\0';
-+      }
-+      return prefix_len + name_len + 1;
-+}
-+
-+static int
-+ext3_xattr_user_get(struct inode *inode, const char *name,
-+                  void *buffer, size_t size)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+      error = ext3_permission_locked(inode, MAY_READ);
-+#else
-+      error = permission(inode, MAY_READ);
-+#endif
-+      if (error)
-+              return error;
-+
-+      return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name,
-+                            buffer, size);
-+}
-+
-+static int
-+ext3_xattr_user_set(struct inode *inode, const char *name,
-+                  const void *value, size_t size, int flags)
-+{
-+      handle_t *handle;
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+      if ( !S_ISREG(inode->i_mode) &&
-+          (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-+              return -EPERM;
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+      error = ext3_permission_locked(inode, MAY_WRITE);
-+#else
-+      error = permission(inode, MAY_WRITE);
-+#endif
-+      if (error)
-+              return error;
-+  
-+      handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
-+      if (IS_ERR(handle))
-+              return PTR_ERR(handle);
-+      error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name,
-+                             value, size, flags);
-+      ext3_journal_stop(handle, inode);
-+
-+      return error;
-+}
-+
-+struct ext3_xattr_handler ext3_xattr_user_handler = {
-+      prefix: XATTR_USER_PREFIX,
-+      list:   ext3_xattr_user_list,
-+      get:    ext3_xattr_user_get,
-+      set:    ext3_xattr_user_set,
-+};
-+
-+int __init
-+init_ext3_xattr_user(void)
-+{
-+      return ext3_xattr_register(EXT3_XATTR_INDEX_USER,
-+                                 &ext3_xattr_user_handler);
-+}
-+
-+void
-+exit_ext3_xattr_user(void)
-+{
-+      ext3_xattr_unregister(EXT3_XATTR_INDEX_USER,
-+                            &ext3_xattr_user_handler);
-+}
---- /dev/null  Mon May 20 21:11:23 2002
-+++ linux-mmonroe/fs/ext3/ext3-exports.c       Tue Apr 29 09:34:48 2003
-@@ -0,0 +1,13 @@
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
-+
-+EXPORT_SYMBOL(ext3_force_commit);
-+EXPORT_SYMBOL(ext3_bread);
-+EXPORT_SYMBOL(ext3_xattr_register);
-+EXPORT_SYMBOL(ext3_xattr_unregister);
-+EXPORT_SYMBOL(ext3_xattr_get);
-+EXPORT_SYMBOL(ext3_xattr_list);
-+EXPORT_SYMBOL(ext3_xattr_set);
---- linux/fs/jfs/jfs_xattr.h~linux-2.4.20-xattr-0.8.54-hp      Tue Apr 29 09:23:10 2003
-+++ linux-mmonroe/fs/jfs/jfs_xattr.h   Tue Apr 29 09:26:41 2003
-@@ -52,8 +52,10 @@ struct jfs_ea_list {
- #define       END_EALIST(ealist) \
-       ((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist)))
--extern int __jfs_setxattr(struct inode *, const char *, void *, size_t, int);
--extern int jfs_setxattr(struct dentry *, const char *, void *, size_t, int);
-+extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t,
-+                        int);
-+extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
-+                      int);
- extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t);
- extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t);
- extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
---- linux/fs/jfs/xattr.c~linux-2.4.20-xattr-0.8.54-hp  Tue Apr 29 09:23:10 2003
-+++ linux-mmonroe/fs/jfs/xattr.c       Tue Apr 29 09:26:41 2003
-@@ -641,7 +641,7 @@ static int ea_put(struct inode *inode, s
- }
- static int can_set_xattr(struct inode *inode, const char *name,
--                       void *value, size_t value_len)
-+                       const void *value, size_t value_len)
- {
-       if (IS_RDONLY(inode))
-               return -EROFS;
-@@ -660,7 +660,7 @@ static int can_set_xattr(struct inode *i
-       return permission(inode, MAY_WRITE);
- }
--int __jfs_setxattr(struct inode *inode, const char *name, void *value,
-+int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
-                  size_t value_len, int flags)
- {
-       struct jfs_ea_list *ealist;
-@@ -799,7 +799,7 @@ int __jfs_setxattr(struct inode *inode, 
-       return rc;
- }
--int jfs_setxattr(struct dentry *dentry, const char *name, void *value,
-+int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
-                size_t value_len, int flags)
- {
-       if (value == NULL) {    /* empty EA, do not remove */
---- /dev/null  Mon May 20 21:11:23 2002
-+++ linux-mmonroe/fs/mbcache.c Tue Apr 29 09:26:41 2003
-@@ -0,0 +1,648 @@
-+/*
-+ * linux/fs/mbcache.c
-+ * (C) 2001-2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+/*
-+ * Filesystem Meta Information Block Cache (mbcache)
-+ *
-+ * The mbcache caches blocks of block devices that need to be located
-+ * by their device/block number, as well as by other criteria (such
-+ * as the block's contents).
-+ *
-+ * There can only be one cache entry in a cache per device and block number.
-+ * Additional indexes need not be unique in this sense. The number of
-+ * additional indexes (=other criteria) can be hardwired at compile time
-+ * or specified at cache create time.
-+ *
-+ * Each cache entry is of fixed size. An entry may be `valid' or `invalid'
-+ * in the cache. A valid entry is in the main hash tables of the cache,
-+ * and may also be in the lru list. An invalid entry is not in any hashes
-+ * or lists.
-+ *
-+ * A valid cache entry is only in the lru list if no handles refer to it.
-+ * Invalid cache entries will be freed when the last handle to the cache
-+ * entry is released. Entries that cannot be freed immediately are put
-+ * back on the lru list.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+
-+#include <linux/fs.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/cache_def.h>
-+#include <linux/version.h>
-+#include <linux/init.h>
-+#include <linux/mbcache.h>
-+
-+
-+#ifdef MB_CACHE_DEBUG
-+# define mb_debug(f...) do { \
-+              printk(KERN_DEBUG f); \
-+              printk("\n"); \
-+      } while (0)
-+#define mb_assert(c) do { if (!(c)) \
-+              printk(KERN_ERR "assertion " #c " failed\n"); \
-+      } while(0)
-+#else
-+# define mb_debug(f...) do { } while(0)
-+# define mb_assert(c) do { } while(0)
-+#endif
-+#define mb_error(f...) do { \
-+              printk(KERN_ERR f); \
-+              printk("\n"); \
-+      } while(0)
-+              
-+MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
-+MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+EXPORT_SYMBOL(mb_cache_create);
-+EXPORT_SYMBOL(mb_cache_shrink);
-+EXPORT_SYMBOL(mb_cache_destroy);
-+EXPORT_SYMBOL(mb_cache_entry_alloc);
-+EXPORT_SYMBOL(mb_cache_entry_insert);
-+EXPORT_SYMBOL(mb_cache_entry_release);
-+EXPORT_SYMBOL(mb_cache_entry_takeout);
-+EXPORT_SYMBOL(mb_cache_entry_free);
-+EXPORT_SYMBOL(mb_cache_entry_dup);
-+EXPORT_SYMBOL(mb_cache_entry_get);
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+EXPORT_SYMBOL(mb_cache_entry_find_first);
-+EXPORT_SYMBOL(mb_cache_entry_find_next);
-+#endif
-+
-+
-+/*
-+ * Global data: list of all mbcache's, lru list, and a spinlock for
-+ * accessing cache data structures on SMP machines. The lru list is
-+ * global across all mbcaches.
-+ */
-+
-+static LIST_HEAD(mb_cache_list);
-+static LIST_HEAD(mb_cache_lru_list);
-+static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED;
-+
-+static inline int
-+mb_cache_indexes(struct mb_cache *cache)
-+{
-+#ifdef MB_CACHE_INDEXES_COUNT
-+      return MB_CACHE_INDEXES_COUNT;
-+#else
-+      return cache->c_indexes_count;
-+#endif
-+}
-+
-+/*
-+ * What the mbcache registers as to get shrunk dynamically.
-+ */
-+
-+static void
-+mb_cache_memory_pressure(int priority, unsigned int gfp_mask);
-+
-+static struct cache_definition mb_cache_definition = {
-+      "mb_cache",
-+      mb_cache_memory_pressure
-+};
-+
-+
-+static inline int
-+__mb_cache_entry_is_hashed(struct mb_cache_entry *ce)
-+{
-+      return !list_empty(&ce->e_block_list);
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_unhash(struct mb_cache_entry *ce)
-+{
-+      int n;
-+
-+      if (__mb_cache_entry_is_hashed(ce)) {
-+              list_del_init(&ce->e_block_list);
-+              for (n=0; n<mb_cache_indexes(ce->e_cache); n++)
-+                      list_del(&ce->e_indexes[n].o_list);
-+      }
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask)
-+{
-+      struct mb_cache *cache = ce->e_cache;
-+
-+      mb_assert(atomic_read(&ce->e_used) == 0);
-+      if (cache->c_op.free && cache->c_op.free(ce, gfp_mask)) {
-+              /* free failed -- put back on the lru list
-+                 for freeing later. */
-+              spin_lock(&mb_cache_spinlock);
-+              list_add(&ce->e_lru_list, &mb_cache_lru_list);
-+              spin_unlock(&mb_cache_spinlock);
-+      } else {
-+              kmem_cache_free(cache->c_entry_cache, ce);
-+              atomic_dec(&cache->c_entry_count);
-+      }
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
-+{
-+      if (atomic_dec_and_test(&ce->e_used)) {
-+              if (__mb_cache_entry_is_hashed(ce))
-+                      list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
-+              else {
-+                      spin_unlock(&mb_cache_spinlock);
-+                      __mb_cache_entry_forget(ce, GFP_KERNEL);
-+                      return;
-+              }
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+}
-+
-+
-+/*
-+ * mb_cache_memory_pressure()  memory pressure callback
-+ *
-+ * This function is called by the kernel memory management when memory
-+ * gets low.
-+ *
-+ * @priority: Amount by which to shrink the cache (0 = highes priority)
-+ * @gfp_mask: (ignored)
-+ */
-+static void
-+mb_cache_memory_pressure(int priority, unsigned int gfp_mask)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+      int count = 0;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &mb_cache_list) {
-+              struct mb_cache *cache =
-+                      list_entry(l, struct mb_cache, c_cache_list);
-+              mb_debug("cache %s (%d)", cache->c_name,
-+                        atomic_read(&cache->c_entry_count));
-+              count += atomic_read(&cache->c_entry_count);
-+      }
-+      mb_debug("trying to free %d of %d entries",
-+                count / (priority ? priority : 1), count);
-+      if (priority)
-+              count /= priority;
-+      while (count-- && !list_empty(&mb_cache_lru_list)) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(mb_cache_lru_list.next,
-+                                 struct mb_cache_entry, e_lru_list);
-+              list_del(&ce->e_lru_list);
-+              __mb_cache_entry_unhash(ce);
-+              list_add_tail(&ce->e_lru_list, &free_list);
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), gfp_mask);
-+      }
-+}
-+
-+
-+/*
-+ * mb_cache_create()  create a new cache
-+ *
-+ * All entries in one cache are equal size. Cache entries may be from
-+ * multiple devices. If this is the first mbcache created, registers
-+ * the cache with kernel memory management. Returns NULL if no more
-+ * memory was available.
-+ *
-+ * @name: name of the cache (informal)
-+ * @cache_op: contains the callback called when freeing a cache entry
-+ * @entry_size: The size of a cache entry, including
-+ *              struct mb_cache_entry
-+ * @indexes_count: number of additional indexes in the cache. Must equal
-+ *                 MB_CACHE_INDEXES_COUNT if the number of indexes is
-+ *                 hardwired.
-+ * @bucket_count: number of hash buckets
-+ */
-+struct mb_cache *
-+mb_cache_create(const char *name, struct mb_cache_op *cache_op,
-+              size_t entry_size, int indexes_count, int bucket_count)
-+{
-+      int m=0, n;
-+      struct mb_cache *cache = NULL;
-+
-+      if(entry_size < sizeof(struct mb_cache_entry) +
-+         indexes_count * sizeof(struct mb_cache_entry_index))
-+              return NULL;
-+
-+      MOD_INC_USE_COUNT;
-+      cache = kmalloc(sizeof(struct mb_cache) +
-+                      indexes_count * sizeof(struct list_head), GFP_KERNEL);
-+      if (!cache)
-+              goto fail;
-+      cache->c_name = name;
-+      cache->c_op.free = NULL;
-+      if (cache_op)
-+              cache->c_op.free = cache_op->free;
-+      atomic_set(&cache->c_entry_count, 0);
-+      cache->c_bucket_count = bucket_count;
-+#ifdef MB_CACHE_INDEXES_COUNT
-+      mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT);
-+#else
-+      cache->c_indexes_count = indexes_count;
-+#endif
-+      cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
-+                                    GFP_KERNEL);
-+      if (!cache->c_block_hash)
-+              goto fail;
-+      for (n=0; n<bucket_count; n++)
-+              INIT_LIST_HEAD(&cache->c_block_hash[n]);
-+      for (m=0; m<indexes_count; m++) {
-+              cache->c_indexes_hash[m] = kmalloc(bucket_count *
-+                                               sizeof(struct list_head),
-+                                               GFP_KERNEL);
-+              if (!cache->c_indexes_hash[m])
-+                      goto fail;
-+              for (n=0; n<bucket_count; n++)
-+                      INIT_LIST_HEAD(&cache->c_indexes_hash[m][n]);
-+      }
-+      cache->c_entry_cache = kmem_cache_create(name, entry_size, 0,
-+              0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL);
-+      if (!cache->c_entry_cache)
-+              goto fail;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_add(&cache->c_cache_list, &mb_cache_list);
-+      spin_unlock(&mb_cache_spinlock);
-+      return cache;
-+
-+fail:
-+      if (cache) {
-+              while (--m >= 0)
-+                      kfree(cache->c_indexes_hash[m]);
-+              if (cache->c_block_hash)
-+                      kfree(cache->c_block_hash);
-+              kfree(cache);
-+      }
-+      MOD_DEC_USE_COUNT;
-+      return NULL;
-+}
-+
-+
-+/*
-+ * mb_cache_shrink()
-+ *
-+ * Removes all cache entires of a device from the cache. All cache entries
-+ * currently in use cannot be freed, and thus remain in the cache.
-+ *
-+ * @cache: which cache to shrink
-+ * @dev: which device's cache entries to shrink
-+ */
-+void
-+mb_cache_shrink(struct mb_cache *cache, kdev_t dev)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              if (ce->e_dev == dev) {
-+                      list_del(&ce->e_lru_list);
-+                      list_add_tail(&ce->e_lru_list, &free_list);
-+                      __mb_cache_entry_unhash(ce);
-+              }
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), GFP_KERNEL);
-+      }
-+}
-+
-+
-+/*
-+ * mb_cache_destroy()
-+ *
-+ * Shrinks the cache to its minimum possible size (hopefully 0 entries),
-+ * and then destroys it. If this was the last mbcache, un-registers the
-+ * mbcache from kernel memory management.
-+ */
-+void
-+mb_cache_destroy(struct mb_cache *cache)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+      int n;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              if (ce->e_cache == cache) {
-+                      list_del(&ce->e_lru_list);
-+                      list_add_tail(&ce->e_lru_list, &free_list);
-+                      __mb_cache_entry_unhash(ce);
-+              }
-+      }
-+      list_del(&cache->c_cache_list);
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), GFP_KERNEL);
-+      }
-+
-+      if (atomic_read(&cache->c_entry_count) > 0) {
-+              mb_error("cache %s: %d orphaned entries",
-+                        cache->c_name,
-+                        atomic_read(&cache->c_entry_count));
-+      }
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-+      /* We don't have kmem_cache_destroy() in 2.2.x */
-+      kmem_cache_shrink(cache->c_entry_cache);
-+#else
-+      kmem_cache_destroy(cache->c_entry_cache);
-+#endif
-+      for (n=0; n < mb_cache_indexes(cache); n++)
-+              kfree(cache->c_indexes_hash[n]);
-+      kfree(cache->c_block_hash);
-+      kfree(cache);
-+
-+      MOD_DEC_USE_COUNT;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_alloc()
-+ *
-+ * Allocates a new cache entry. The new entry will not be valid initially,
-+ * and thus cannot be looked up yet. It should be filled with data, and
-+ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL
-+ * if no more memory was available.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_alloc(struct mb_cache *cache)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      atomic_inc(&cache->c_entry_count);
-+      ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
-+      if (ce) {
-+              INIT_LIST_HEAD(&ce->e_lru_list);
-+              INIT_LIST_HEAD(&ce->e_block_list);
-+              ce->e_cache = cache;
-+              atomic_set(&ce->e_used, 1);
-+      }
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_insert()
-+ *
-+ * Inserts an entry that was allocated using mb_cache_entry_alloc() into
-+ * the cache. After this, the cache entry can be looked up, but is not yet
-+ * in the lru list as the caller still holds a handle to it. Returns 0 on
-+ * success, or -EBUSY if a cache entry for that device + inode exists
-+ * already (this may happen after a failed lookup, if another process has
-+ * inserted the same cache entry in the meantime).
-+ *
-+ * @dev: device the cache entry belongs to
-+ * @block: block number
-+ * @keys: array of additional keys. There must be indexes_count entries
-+ *        in the array (as specified when creating the cache).
-+ */
-+int
-+mb_cache_entry_insert(struct mb_cache_entry *ce, kdev_t dev,
-+                    unsigned long block, unsigned int keys[])
-+{
-+      struct mb_cache *cache = ce->e_cache;
-+      unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
-+      struct list_head *l;
-+      int error = -EBUSY, n;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &cache->c_block_hash[bucket]) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_block_list);
-+              if (ce->e_dev == dev && ce->e_block == block)
-+                      goto out;
-+      }
-+      __mb_cache_entry_unhash(ce);
-+      ce->e_dev = dev;
-+      ce->e_block = block;
-+      list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
-+      for (n=0; n<mb_cache_indexes(cache); n++) {
-+              ce->e_indexes[n].o_key = keys[n];
-+              bucket = keys[n] % cache->c_bucket_count;
-+              list_add(&ce->e_indexes[n].o_list,
-+                       &cache->c_indexes_hash[n][bucket]);
-+      }
-+out:
-+      spin_unlock(&mb_cache_spinlock);
-+      return error;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_release()
-+ *
-+ * Release a handle to a cache entry. When the last handle to a cache entry
-+ * is released it is either freed (if it is invalid) or otherwise inserted
-+ * in to the lru list.
-+ */
-+void
-+mb_cache_entry_release(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      __mb_cache_entry_release_unlock(ce);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_takeout()
-+ *
-+ * Take a cache entry out of the cache, making it invalid. The entry can later
-+ * be re-inserted using mb_cache_entry_insert(), or released using
-+ * mb_cache_entry_release().
-+ */
-+void
-+mb_cache_entry_takeout(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      mb_assert(list_empty(&ce->e_lru_list));
-+      __mb_cache_entry_unhash(ce);
-+      spin_unlock(&mb_cache_spinlock);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_free()
-+ *
-+ * This is equivalent to the sequence mb_cache_entry_takeout() --
-+ * mb_cache_entry_release().
-+ */
-+void
-+mb_cache_entry_free(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      mb_assert(list_empty(&ce->e_lru_list));
-+      __mb_cache_entry_unhash(ce);
-+      __mb_cache_entry_release_unlock(ce);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_dup()
-+ *
-+ * Duplicate a handle to a cache entry (does not duplicate the cache entry
-+ * itself). After the call, both the old and the new handle must be released.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_dup(struct mb_cache_entry *ce)
-+{
-+      atomic_inc(&ce->e_used);
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_get()
-+ *
-+ * Get a cache entry  by device / block number. (There can only be one entry
-+ * in the cache per device and block.) Returns NULL if no such cache entry
-+ * exists.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_get(struct mb_cache *cache, kdev_t dev, unsigned long block)
-+{
-+      unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &cache->c_block_hash[bucket]) {
-+              ce = list_entry(l, struct mb_cache_entry, e_block_list);
-+              if (ce->e_dev == dev && ce->e_block == block) {
-+                      if (!list_empty(&ce->e_lru_list))
-+                              list_del_init(&ce->e_lru_list);
-+                      atomic_inc(&ce->e_used);
-+                      goto cleanup;
-+              }
-+      }
-+      ce = NULL;
-+
-+cleanup:
-+      spin_unlock(&mb_cache_spinlock);
-+      return ce;
-+}
-+
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+
-+static struct mb_cache_entry *
-+__mb_cache_entry_find(struct list_head *l, struct list_head *head,
-+                    int index, kdev_t dev, unsigned int key)
-+{
-+      while (l != head) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry,
-+                                 e_indexes[index].o_list);
-+              if (ce->e_dev == dev && ce->e_indexes[index].o_key == key) {
-+                      if (!list_empty(&ce->e_lru_list))
-+                              list_del_init(&ce->e_lru_list);
-+                      atomic_inc(&ce->e_used);
-+                      return ce;
-+              }
-+              l = l->next;
-+      }
-+      return NULL;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_find_first()
-+ *
-+ * Find the first cache entry on a given device with a certain key in
-+ * an additional index. Additonal matches can be found with
-+ * mb_cache_entry_find_next(). Returns NULL if no match was found.
-+ *
-+ * @cache: the cache to search
-+ * @index: the number of the additonal index to search (0<=index<indexes_count)
-+ * @dev: the device the cache entry should belong to
-+ * @key: the key in the index
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_find_first(struct mb_cache *cache, int index, kdev_t dev,
-+                        unsigned int key)
-+{
-+      unsigned int bucket = key % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      mb_assert(index < mb_cache_indexes(cache));
-+      spin_lock(&mb_cache_spinlock);
-+      l = cache->c_indexes_hash[index][bucket].next;
-+      ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
-+                                 index, dev, key);
-+      spin_unlock(&mb_cache_spinlock);
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_find_next()
-+ *
-+ * Find the next cache entry on a given device with a certain key in an
-+ * additional index. Returns NULL if no match could be found. The previous
-+ * entry is atomatically released, so that mb_cache_entry_find_next() can
-+ * be called like this:
-+ *
-+ * entry = mb_cache_entry_find_first();
-+ * while (entry) {
-+ *    ...
-+ *    entry = mb_cache_entry_find_next(entry, ...);
-+ * }
-+ *
-+ * @prev: The previous match
-+ * @index: the number of the additonal index to search (0<=index<indexes_count)
-+ * @dev: the device the cache entry should belong to
-+ * @key: the key in the index
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_find_next(struct mb_cache_entry *prev, int index, kdev_t dev,
-+                       unsigned int key)
-+{
-+      struct mb_cache *cache = prev->e_cache;
-+      unsigned int bucket = key % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      mb_assert(index < mb_cache_indexes(cache));
-+      spin_lock(&mb_cache_spinlock);
-+      l = prev->e_indexes[index].o_list.next;
-+      ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
-+                                 index, dev, key);
-+      __mb_cache_entry_release_unlock(prev);
-+      return ce;
-+}
-+
-+#endif  /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */
-+
-+static int __init init_mbcache(void)
-+{
-+      register_cache(&mb_cache_definition);
-+      return 0;
-+}
-+
-+static void __exit exit_mbcache(void)
-+{
-+      unregister_cache(&mb_cache_definition);
-+}
-+
-+module_init(init_mbcache)
-+module_exit(exit_mbcache)
-+
---- linux/include/asm-arm/unistd.h~linux-2.4.20-xattr-0.8.54-hp        Tue Apr 29 09:23:28 2003
-+++ linux-mmonroe/include/asm-arm/unistd.h     Tue Apr 29 09:26:41 2003
-@@ -244,7 +244,6 @@
- #define __NR_security                 (__NR_SYSCALL_BASE+223)
- #define __NR_gettid                   (__NR_SYSCALL_BASE+224)
- #define __NR_readahead                        (__NR_SYSCALL_BASE+225)
--#if 0 /* allocated in 2.5 */
- #define __NR_setxattr                 (__NR_SYSCALL_BASE+226)
- #define __NR_lsetxattr                        (__NR_SYSCALL_BASE+227)
- #define __NR_fsetxattr                        (__NR_SYSCALL_BASE+228)
-@@ -257,7 +256,6 @@
- #define __NR_removexattr              (__NR_SYSCALL_BASE+235)
- #define __NR_lremovexattr             (__NR_SYSCALL_BASE+236)
- #define __NR_fremovexattr             (__NR_SYSCALL_BASE+237)
--#endif
- #define __NR_tkill                    (__NR_SYSCALL_BASE+238)
- /*
-  * Please check 2.5 _before_ adding calls here,
---- linux/include/asm-ppc64/unistd.h~linux-2.4.20-xattr-0.8.54-hp      Tue Apr 29 09:23:18 2003
-+++ linux-mmonroe/include/asm-ppc64/unistd.h   Tue Apr 29 09:26:41 2003
-@@ -218,6 +218,7 @@
- #define __NR_gettid           207
- #if 0 /* Reserved syscalls */
- #define __NR_tkill            208
-+#endif
- #define __NR_setxattr         209
- #define __NR_lsetxattr                210
- #define __NR_fsetxattr                211
-@@ -230,6 +231,7 @@
- #define __NR_removexattr      218
- #define __NR_lremovexattr     219
- #define __NR_fremovexattr     220
-+#if 0 /* Reserved syscalls */
- #define __NR_futex            221
- #endif
---- linux/include/asm-s390/unistd.h~linux-2.4.20-xattr-0.8.54-hp       Tue Apr 29 09:23:34 2003
-+++ linux-mmonroe/include/asm-s390/unistd.h    Tue Apr 29 09:26:41 2003
-@@ -212,9 +212,18 @@
- #define __NR_madvise            219
- #define __NR_getdents64               220
- #define __NR_fcntl64          221
--/*
-- * Numbers 224-235 are reserved for posix acl
-- */
-+#define __NR_setxattr         224
-+#define __NR_lsetxattr                225
-+#define __NR_fsetxattr                226
-+#define __NR_getxattr         227
-+#define __NR_lgetxattr                228
-+#define __NR_fgetxattr                229
-+#define __NR_listxattr                230
-+#define __NR_llistxattr               231
-+#define __NR_flistxattr               232
-+#define __NR_removexattr      233
-+#define __NR_lremovexattr     234
-+#define __NR_fremovexattr     235
- #define __NR_gettid           236
- #define __NR_tkill            237
---- linux/include/asm-s390x/unistd.h~linux-2.4.20-xattr-0.8.54-hp      Tue Apr 29 09:23:35 2003
-+++ linux-mmonroe/include/asm-s390x/unistd.h   Tue Apr 29 09:26:41 2003
-@@ -180,9 +180,18 @@
- #define __NR_pivot_root         217
- #define __NR_mincore            218
- #define __NR_madvise            219
--/*
-- * Numbers 224-235 are reserved for posix acl
-- */
-+#define __NR_setxattr         224
-+#define __NR_lsetxattr                225
-+#define __NR_fsetxattr                226
-+#define __NR_getxattr         227
-+#define __NR_lgetxattr                228
-+#define __NR_fgetxattr                229
-+#define __NR_listxattr                230
-+#define __NR_llistxattr               231
-+#define __NR_flistxattr               232
-+#define __NR_removexattr      233
-+#define __NR_lremovexattr     234
-+#define __NR_fremovexattr     235
- #define __NR_gettid           236
- #define __NR_tkill            237
---- linux/include/asm-sparc/unistd.h~linux-2.4.20-xattr-0.8.54-hp      Tue Apr 29 09:23:25 2003
-+++ linux-mmonroe/include/asm-sparc/unistd.h   Tue Apr 29 09:26:41 2003
-@@ -184,24 +184,24 @@
- /* #define __NR_exportfs        166    SunOS Specific                              */
- #define __NR_mount              167 /* Common                                      */
- #define __NR_ustat              168 /* Common                                      */
--/* #define __NR_semsys          169    SunOS Specific                              */
--/* #define __NR_msgsys          170    SunOS Specific                              */
--/* #define __NR_shmsys          171    SunOS Specific                              */
--/* #define __NR_auditsys        172    SunOS Specific                              */
--/* #define __NR_rfssys          173    SunOS Specific                              */
-+#define __NR_setxattr           169 /* SunOS: semsys                               */
-+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-+#define __NR_getxattr           172 /* SunOS: auditsys                             */
-+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
- #define __NR_getdents           174 /* Common                                      */
- #define __NR_setsid             175 /* Common                                      */
- #define __NR_fchdir             176 /* Common                                      */
--/* #define __NR_fchroot         177    SunOS Specific                              */
--/* #define __NR_vpixsys         178    SunOS Specific                              */
--/* #define __NR_aioread         179    SunOS Specific                              */
--/* #define __NR_aiowrite        180    SunOS Specific                              */
--/* #define __NR_aiowait         181    SunOS Specific                              */
--/* #define __NR_aiocancel       182    SunOS Specific                              */
-+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-+#define __NR_llistxattr         179 /* SunOS: aioread                              */
-+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-+#define __NR_removexattr        181 /* SunOS: aiowait                              */
-+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
- #define __NR_sigpending         183 /* Common                                      */
- #define __NR_query_module     184 /* Linux Specific                              */
- #define __NR_setpgid            185 /* Common                                      */
--/* #define __NR_pathconf        186    SunOS Specific                              */
-+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
- #define __NR_tkill              187 /* SunOS: fpathconf                            */
- /* #define __NR_sysconf         188    SunOS Specific                              */
- #define __NR_uname              189 /* Linux Specific                              */
---- linux/include/asm-sparc64/unistd.h~linux-2.4.20-xattr-0.8.54-hp    Tue Apr 29 09:23:27 2003
-+++ linux-mmonroe/include/asm-sparc64/unistd.h Tue Apr 29 09:26:41 2003
-@@ -184,24 +184,24 @@
- /* #define __NR_exportfs        166    SunOS Specific                              */
- #define __NR_mount              167 /* Common                                      */
- #define __NR_ustat              168 /* Common                                      */
--/* #define __NR_semsys          169    SunOS Specific                              */
--/* #define __NR_msgsys          170    SunOS Specific                              */
--/* #define __NR_shmsys          171    SunOS Specific                              */
--/* #define __NR_auditsys        172    SunOS Specific                              */
--/* #define __NR_rfssys          173    SunOS Specific                              */
-+#define __NR_setxattr           169 /* SunOS: semsys                               */
-+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-+#define __NR_getxattr           172 /* SunOS: auditsys                             */
-+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
- #define __NR_getdents           174 /* Common                                      */
- #define __NR_setsid             175 /* Common                                      */
- #define __NR_fchdir             176 /* Common                                      */
--/* #define __NR_fchroot         177    SunOS Specific                              */
--/* #define __NR_vpixsys         178    SunOS Specific                              */
--/* #define __NR_aioread         179    SunOS Specific                              */
--/* #define __NR_aiowrite        180    SunOS Specific                              */
--/* #define __NR_aiowait         181    SunOS Specific                              */
--/* #define __NR_aiocancel       182    SunOS Specific                              */
-+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-+#define __NR_llistxattr         179 /* SunOS: aioread                              */
-+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-+#define __NR_removexattr        181 /* SunOS: aiowait                              */
-+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
- #define __NR_sigpending         183 /* Common                                      */
- #define __NR_query_module     184 /* Linux Specific                              */
- #define __NR_setpgid            185 /* Common                                      */
--/* #define __NR_pathconf        186    SunOS Specific                              */
-+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
- #define __NR_tkill              187 /* SunOS: fpathconf                            */
- /* #define __NR_sysconf         188    SunOS Specific                              */
- #define __NR_uname              189 /* Linux Specific                              */
---- /dev/null  Mon May 20 21:11:23 2002
-+++ linux-mmonroe/include/linux/cache_def.h    Tue Apr 29 09:26:41 2003
-@@ -0,0 +1,15 @@
-+/*
-+ * linux/cache_def.h
-+ * Handling of caches defined in drivers, filesystems, ...
-+ *
-+ * Copyright (C) 2002 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+struct cache_definition {
-+      const char *name;
-+      void (*shrink)(int, unsigned int);
-+      struct list_head link;
-+};
-+
-+extern void register_cache(struct cache_definition *);
-+extern void unregister_cache(struct cache_definition *);
---- linux/include/linux/errno.h~linux-2.4.20-xattr-0.8.54-hp   Tue Apr 29 09:23:19 2003
-+++ linux-mmonroe/include/linux/errno.h        Tue Apr 29 09:26:41 2003
-@@ -23,4 +23,8 @@
- #endif
-+/* Defined for extended attributes */
-+#define ENOATTR ENODATA               /* No such attribute */
-+#define ENOTSUP EOPNOTSUPP    /* Operation not supported */
-+
- #endif
---- linux/include/linux/ext2_fs.h~linux-2.4.20-xattr-0.8.54-hp Tue Apr 29 09:23:19 2003
-+++ linux-mmonroe/include/linux/ext2_fs.h      Tue Apr 29 09:26:41 2003
-@@ -57,8 +57,6 @@
-  */
- #define       EXT2_BAD_INO             1      /* Bad blocks inode */
- #define EXT2_ROOT_INO          2      /* Root inode */
--#define EXT2_ACL_IDX_INO       3      /* ACL inode */
--#define EXT2_ACL_DATA_INO      4      /* ACL inode */
- #define EXT2_BOOT_LOADER_INO   5      /* Boot loader inode */
- #define EXT2_UNDEL_DIR_INO     6      /* Undelete directory inode */
-@@ -86,7 +84,6 @@
- #else
- # define EXT2_BLOCK_SIZE(s)           (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
- #endif
--#define EXT2_ACLE_PER_BLOCK(s)                (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
- #define       EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
- #ifdef __KERNEL__
- # define EXT2_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
-@@ -121,28 +118,6 @@
- #endif
- /*
-- * ACL structures
-- */
--struct ext2_acl_header        /* Header of Access Control Lists */
--{
--      __u32   aclh_size;
--      __u32   aclh_file_count;
--      __u32   aclh_acle_count;
--      __u32   aclh_first_acle;
--};
--
--struct ext2_acl_entry /* Access Control List Entry */
--{
--      __u32   acle_size;
--      __u16   acle_perms;     /* Access permissions */
--      __u16   acle_type;      /* Type of entry */
--      __u16   acle_tag;       /* User or group identity */
--      __u16   acle_pad1;
--      __u32   acle_next;      /* Pointer on next entry for the */
--                                      /* same inode or on next free entry */
--};
--
--/*
-  * Structure of a blocks group descriptor
-  */
- struct ext2_group_desc
-@@ -314,6 +289,7 @@ struct ext2_inode {
- #define EXT2_MOUNT_ERRORS_PANIC               0x0040  /* Panic on errors */
- #define EXT2_MOUNT_MINIX_DF           0x0080  /* Mimics the Minix statfs */
- #define EXT2_MOUNT_NO_UID32           0x0200  /* Disable 32-bit UIDs */
-+#define EXT2_MOUNT_XATTR_USER         0x4000  /* Extended user attributes */
- #define clear_opt(o, opt)             o &= ~EXT2_MOUNT_##opt
- #define set_opt(o, opt)                       o |= EXT2_MOUNT_##opt
-@@ -397,6 +373,7 @@ struct ext2_super_block {
- #ifdef __KERNEL__
- #define EXT2_SB(sb)   (&((sb)->u.ext2_sb))
-+#define EXT2_I(inode) (&((inode)->u.ext2_i))
- #else
- /* Assume that user mode programs are passing in an ext2fs superblock, not
-  * a kernel struct super_block.  This will allow us to call the feature-test
-@@ -466,7 +443,7 @@ struct ext2_super_block {
- #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008
- #define EXT2_FEATURE_INCOMPAT_ANY             0xffffffff
--#define EXT2_FEATURE_COMPAT_SUPP      0
-+#define EXT2_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
- #define EXT2_FEATURE_INCOMPAT_SUPP    EXT2_FEATURE_INCOMPAT_FILETYPE
- #define EXT2_FEATURE_RO_COMPAT_SUPP   (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-                                        EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
-@@ -623,8 +600,10 @@ extern struct address_space_operations e
- /* namei.c */
- extern struct inode_operations ext2_dir_inode_operations;
-+extern struct inode_operations ext2_special_inode_operations;
- /* symlink.c */
-+extern struct inode_operations ext2_symlink_inode_operations;
- extern struct inode_operations ext2_fast_symlink_inode_operations;
- #endif        /* __KERNEL__ */
---- /dev/null  Mon May 20 21:11:23 2002
-+++ linux-mmonroe/include/linux/ext2_xattr.h   Tue Apr 29 09:26:41 2003
-@@ -0,0 +1,157 @@
-+/*
-+  File: linux/ext2_xattr.h
-+
-+  On-disk format of extended attributes for the ext2 filesystem.
-+
-+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/xattr.h>
-+
-+/* Magic value in attribute blocks */
-+#define EXT2_XATTR_MAGIC              0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT2_XATTR_REFCOUNT_MAX               1024
-+
-+/* Name indexes */
-+#define EXT2_XATTR_INDEX_MAX                  10
-+#define EXT2_XATTR_INDEX_USER                 1
-+#define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS     2
-+#define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT    3
-+
-+struct ext2_xattr_header {
-+      __u32   h_magic;        /* magic number for identification */
-+      __u32   h_refcount;     /* reference count */
-+      __u32   h_blocks;       /* number of disk blocks used */
-+      __u32   h_hash;         /* hash value of all attributes */
-+      __u32   h_reserved[4];  /* zero right now */
-+};
-+
-+struct ext2_xattr_entry {
-+      __u8    e_name_len;     /* length of name */
-+      __u8    e_name_index;   /* attribute name index */
-+      __u16   e_value_offs;   /* offset in disk block of value */
-+      __u32   e_value_block;  /* disk block attribute is stored on (n/i) */
-+      __u32   e_value_size;   /* size of attribute value */
-+      __u32   e_hash;         /* hash value of name and value */
-+      char    e_name[0];      /* attribute name */
-+};
-+
-+#define EXT2_XATTR_PAD_BITS           2
-+#define EXT2_XATTR_PAD                (1<<EXT2_XATTR_PAD_BITS)
-+#define EXT2_XATTR_ROUND              (EXT2_XATTR_PAD-1)
-+#define EXT2_XATTR_LEN(name_len) \
-+      (((name_len) + EXT2_XATTR_ROUND + \
-+      sizeof(struct ext2_xattr_entry)) & ~EXT2_XATTR_ROUND)
-+#define EXT2_XATTR_NEXT(entry) \
-+      ( (struct ext2_xattr_entry *)( \
-+        (char *)(entry) + EXT2_XATTR_LEN((entry)->e_name_len)) )
-+#define EXT2_XATTR_SIZE(size) \
-+      (((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)
-+
-+#ifdef __KERNEL__
-+
-+# ifdef CONFIG_EXT2_FS_XATTR
-+
-+struct ext2_xattr_handler {
-+      char *prefix;
-+      size_t (*list)(char *list, struct inode *inode, const char *name,
-+                     int name_len);
-+      int (*get)(struct inode *inode, const char *name, void *buffer,
-+                 size_t size);
-+      int (*set)(struct inode *inode, const char *name, const void *buffer,
-+                 size_t size, int flags);
-+};
-+
-+extern int ext2_xattr_register(int, struct ext2_xattr_handler *);
-+extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *);
-+
-+extern int ext2_setxattr(struct dentry *, const char *, const void *, size_t, int);
-+extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t);
-+extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
-+extern int ext2_removexattr(struct dentry *, const char *);
-+
-+extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
-+extern int ext2_xattr_list(struct inode *, char *, size_t);
-+extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
-+
-+extern void ext2_xattr_delete_inode(struct inode *);
-+extern void ext2_xattr_put_super(struct super_block *);
-+
-+extern int init_ext2_xattr(void) __init;
-+extern void exit_ext2_xattr(void);
-+
-+# else  /* CONFIG_EXT2_FS_XATTR */
-+#  define ext2_setxattr               NULL
-+#  define ext2_getxattr               NULL
-+#  define ext2_listxattr      NULL
-+#  define ext2_removexattr    NULL
-+
-+static inline int
-+ext2_xattr_get(struct inode *inode, int name_index,
-+             const char *name, void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext2_xattr_list(struct inode *inode, char *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext2_xattr_set(struct inode *inode, int name_index, const char *name,
-+             const void *value, size_t size, int flags)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline void
-+ext2_xattr_delete_inode(struct inode *inode)
-+{
-+}
-+
-+static inline void
-+ext2_xattr_put_super(struct super_block *sb)
-+{
-+}
-+
-+static inline int
-+init_ext2_xattr(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext2_xattr(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT2_FS_XATTR */
-+
-+# ifdef CONFIG_EXT2_FS_XATTR_USER
-+
-+extern int init_ext2_xattr_user(void) __init;
-+extern void exit_ext2_xattr_user(void);
-+
-+# else  /* CONFIG_EXT2_FS_XATTR_USER */
-+
-+static inline int
-+init_ext2_xattr_user(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext2_xattr_user(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT2_FS_XATTR_USER */
-+
-+#endif  /* __KERNEL__ */
-+
---- linux/include/linux/ext3_fs.h~linux-2.4.20-xattr-0.8.54-hp Tue Apr 29 09:26:32 2003
-+++ linux-mmonroe/include/linux/ext3_fs.h      Tue Apr 29 09:26:41 2003
-@@ -63,8 +63,6 @@
-  */
- #define       EXT3_BAD_INO             1      /* Bad blocks inode */
- #define EXT3_ROOT_INO          2      /* Root inode */
--#define EXT3_ACL_IDX_INO       3      /* ACL inode */
--#define EXT3_ACL_DATA_INO      4      /* ACL inode */
- #define EXT3_BOOT_LOADER_INO   5      /* Boot loader inode */
- #define EXT3_UNDEL_DIR_INO     6      /* Undelete directory inode */
- #define EXT3_RESIZE_INO                7      /* Reserved group descriptors inode */
-@@ -94,7 +92,6 @@
- #else
- # define EXT3_BLOCK_SIZE(s)           (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
- #endif
--#define EXT3_ACLE_PER_BLOCK(s)                (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
- #define       EXT3_ADDR_PER_BLOCK(s)          (EXT3_BLOCK_SIZE(s) / sizeof (__u32))
- #ifdef __KERNEL__
- # define EXT3_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
-@@ -129,28 +126,6 @@
- #endif
- /*
-- * ACL structures
-- */
--struct ext3_acl_header        /* Header of Access Control Lists */
--{
--      __u32   aclh_size;
--      __u32   aclh_file_count;
--      __u32   aclh_acle_count;
--      __u32   aclh_first_acle;
--};
--
--struct ext3_acl_entry /* Access Control List Entry */
--{
--      __u32   acle_size;
--      __u16   acle_perms;     /* Access permissions */
--      __u16   acle_type;      /* Type of entry */
--      __u16   acle_tag;       /* User or group identity */
--      __u16   acle_pad1;
--      __u32   acle_next;      /* Pointer on next entry for the */
--                                      /* same inode or on next free entry */
--};
--
--/*
-  * Structure of a blocks group descriptor
-  */
- struct ext3_group_desc
-@@ -344,6 +319,7 @@ struct ext3_inode {
-   #define EXT3_MOUNT_WRITEBACK_DATA   0x0C00  /* No data ordering */
- #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
-@@ -520,7 +496,7 @@ struct ext3_super_block {
- #define EXT3_FEATURE_INCOMPAT_RECOVER         0x0004 /* Needs recovery */
- #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008 /* Journal device */
--#define EXT3_FEATURE_COMPAT_SUPP      0
-+#define EXT3_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
- #define EXT3_FEATURE_INCOMPAT_SUPP    (EXT3_FEATURE_INCOMPAT_FILETYPE| \
-                                        EXT3_FEATURE_INCOMPAT_RECOVER)
- #define EXT3_FEATURE_RO_COMPAT_SUPP   (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-@@ -703,6 +679,7 @@ extern void ext3_check_inodes_bitmap (st
- extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
- /* inode.c */
-+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
-@@ -771,8 +748,10 @@ extern struct address_space_operations e
- /* namei.c */
- extern struct inode_operations ext3_dir_inode_operations;
-+extern struct inode_operations ext3_special_inode_operations;
- /* symlink.c */
-+extern struct inode_operations ext3_symlink_inode_operations;
- extern struct inode_operations ext3_fast_symlink_inode_operations;
---- linux/include/linux/ext3_jbd.h~linux-2.4.20-xattr-0.8.54-hp        Tue Apr 29 09:26:28 2003
-+++ linux-mmonroe/include/linux/ext3_jbd.h     Tue Apr 29 09:26:41 2003
-@@ -30,13 +30,19 @@
- #define EXT3_SINGLEDATA_TRANS_BLOCKS  8
-+/* Extended attributes may touch two data buffers, two bitmap buffers,
-+ * and two group and summaries. */
-+
-+#define EXT3_XATTR_TRANS_BLOCKS               8
-+
- /* Define the minimum size for a transaction which modifies data.  This
-  * needs to take into account the fact that we may end up modifying two
-  * quota files too (one for the group, one for the user quota).  The
-  * superblock only gets updated once, of course, so don't bother
-  * counting that again for the quota updates. */
--#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
-+#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
-+                                       EXT3_XATTR_TRANS_BLOCKS - 2)
- extern int ext3_writepage_trans_blocks(struct inode *inode);
---- /dev/null  Mon May 20 21:11:23 2002
-+++ linux-mmonroe/include/linux/ext3_xattr.h   Tue Apr 29 09:26:41 2003
-@@ -0,0 +1,157 @@
-+/*
-+  File: linux/ext3_xattr.h
-+
-+  On-disk format of extended attributes for the ext3 filesystem.
-+
-+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/xattr.h>
-+
-+/* Magic value in attribute blocks */
-+#define EXT3_XATTR_MAGIC              0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT3_XATTR_REFCOUNT_MAX               1024
-+
-+/* Name indexes */
-+#define EXT3_XATTR_INDEX_MAX                  10
-+#define EXT3_XATTR_INDEX_USER                 1
-+#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS     2
-+#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT    3
-+
-+struct ext3_xattr_header {
-+      __u32   h_magic;        /* magic number for identification */
-+      __u32   h_refcount;     /* reference count */
-+      __u32   h_blocks;       /* number of disk blocks used */
-+      __u32   h_hash;         /* hash value of all attributes */
-+      __u32   h_reserved[4];  /* zero right now */
-+};
-+
-+struct ext3_xattr_entry {
-+      __u8    e_name_len;     /* length of name */
-+      __u8    e_name_index;   /* attribute name index */
-+      __u16   e_value_offs;   /* offset in disk block of value */
-+      __u32   e_value_block;  /* disk block attribute is stored on (n/i) */
-+      __u32   e_value_size;   /* size of attribute value */
-+      __u32   e_hash;         /* hash value of name and value */
-+      char    e_name[0];      /* attribute name */
-+};
-+
-+#define EXT3_XATTR_PAD_BITS           2
-+#define EXT3_XATTR_PAD                (1<<EXT3_XATTR_PAD_BITS)
-+#define EXT3_XATTR_ROUND              (EXT3_XATTR_PAD-1)
-+#define EXT3_XATTR_LEN(name_len) \
-+      (((name_len) + EXT3_XATTR_ROUND + \
-+      sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
-+#define EXT3_XATTR_NEXT(entry) \
-+      ( (struct ext3_xattr_entry *)( \
-+        (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
-+#define EXT3_XATTR_SIZE(size) \
-+      (((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
-+
-+#ifdef __KERNEL__
-+
-+# ifdef CONFIG_EXT3_FS_XATTR
-+
-+struct ext3_xattr_handler {
-+      char *prefix;
-+      size_t (*list)(char *list, struct inode *inode, const char *name,
-+                     int name_len);
-+      int (*get)(struct inode *inode, const char *name, void *buffer,
-+                 size_t size);
-+      int (*set)(struct inode *inode, const char *name, const void *buffer,
-+                 size_t size, int flags);
-+};
-+
-+extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
-+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
-+
-+extern int ext3_setxattr(struct dentry *, const char *, const void *, size_t, int);
-+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
-+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
-+extern int ext3_removexattr(struct dentry *, const char *);
-+
-+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
-+extern int ext3_xattr_list(struct inode *, char *, size_t);
-+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
-+
-+extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
-+extern void ext3_xattr_put_super(struct super_block *);
-+
-+extern int init_ext3_xattr(void) __init;
-+extern void exit_ext3_xattr(void);
-+
-+# else  /* CONFIG_EXT3_FS_XATTR */
-+#  define ext3_setxattr               NULL
-+#  define ext3_getxattr               NULL
-+#  define ext3_listxattr      NULL
-+#  define ext3_removexattr    NULL
-+
-+static inline int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, const void *value, size_t size, int flags)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline void
-+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
-+{
-+}
-+
-+static inline void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+}
-+
-+static inline int
-+init_ext3_xattr(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext3_xattr(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT3_FS_XATTR */
-+
-+# ifdef CONFIG_EXT3_FS_XATTR_USER
-+
-+extern int init_ext3_xattr_user(void) __init;
-+extern void exit_ext3_xattr_user(void);
-+
-+# else  /* CONFIG_EXT3_FS_XATTR_USER */
-+
-+static inline int
-+init_ext3_xattr_user(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext3_xattr_user(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT3_FS_XATTR_USER */
-+
-+#endif  /* __KERNEL__ */
-+
---- linux/include/linux/fs.h~linux-2.4.20-xattr-0.8.54-hp      Tue Apr 29 09:26:24 2003
-+++ linux-mmonroe/include/linux/fs.h   Tue Apr 29 09:26:41 2003
-@@ -909,7 +909,7 @@ struct inode_operations {
-       int (*setattr) (struct dentry *, struct iattr *);
-       int (*setattr_raw) (struct inode *, struct iattr *);
-       int (*getattr) (struct dentry *, struct iattr *);
--      int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
-+      int (*setxattr) (struct dentry *, const char *, const void *, size_t, int);
-       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-       ssize_t (*listxattr) (struct dentry *, char *, size_t);
-       int (*removexattr) (struct dentry *, const char *);
---- /dev/null  Mon May 20 21:11:23 2002
-+++ linux-mmonroe/include/linux/mbcache.h      Tue Apr 29 09:26:41 2003
-@@ -0,0 +1,69 @@
-+/*
-+  File: linux/mbcache.h
-+
-+  (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+/* Hardwire the number of additional indexes */
-+#define MB_CACHE_INDEXES_COUNT 1
-+
-+struct mb_cache_entry;
-+
-+struct mb_cache_op {
-+      int (*free)(struct mb_cache_entry *, int);
-+};
-+
-+struct mb_cache {
-+      struct list_head                c_cache_list;
-+      const char                      *c_name;
-+      struct mb_cache_op              c_op;
-+      atomic_t                        c_entry_count;
-+      int                             c_bucket_count;
-+#ifndef MB_CACHE_INDEXES_COUNT
-+      int                             c_indexes_count;
-+#endif
-+      kmem_cache_t                    *c_entry_cache;
-+      struct list_head                *c_block_hash;
-+      struct list_head                *c_indexes_hash[0];
-+};
-+
-+struct mb_cache_entry_index {
-+      struct list_head                o_list;
-+      unsigned int                    o_key;
-+};
-+
-+struct mb_cache_entry {
-+      struct list_head                e_lru_list;
-+      struct mb_cache                 *e_cache;
-+      atomic_t                        e_used;
-+      kdev_t                          e_dev;
-+      unsigned long                   e_block;
-+      struct list_head                e_block_list;
-+      struct mb_cache_entry_index     e_indexes[0];
-+};
-+
-+/* Functions on caches */
-+
-+struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t,
-+                                int, int);
-+void mb_cache_shrink(struct mb_cache *, kdev_t);
-+void mb_cache_destroy(struct mb_cache *);
-+
-+/* Functions on cache entries */
-+
-+struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
-+int mb_cache_entry_insert(struct mb_cache_entry *, kdev_t, unsigned long,
-+                        unsigned int[]);
-+void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
-+void mb_cache_entry_release(struct mb_cache_entry *);
-+void mb_cache_entry_takeout(struct mb_cache_entry *);
-+void mb_cache_entry_free(struct mb_cache_entry *);
-+struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *);
-+struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, kdev_t,
-+                                        unsigned long);
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int,
-+                                               kdev_t, unsigned int);
-+struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int,
-+                                              kdev_t, unsigned int);
-+#endif
---- linux/kernel/ksyms.c~linux-2.4.20-xattr-0.8.54-hp  Tue Apr 29 09:26:22 2003
-+++ linux-mmonroe/kernel/ksyms.c       Tue Apr 29 09:26:41 2003
-@@ -11,6 +11,7 @@
- #include <linux/config.h>
- #include <linux/slab.h>
-+#include <linux/cache_def.h>
- #include <linux/module.h>
- #include <linux/blkdev.h>
- #include <linux/cdrom.h>
-@@ -103,6 +104,7 @@ EXPORT_SYMBOL(exit_mm);
- EXPORT_SYMBOL(exit_files);
- EXPORT_SYMBOL(exit_fs);
- EXPORT_SYMBOL(exit_sighand);
-+EXPORT_SYMBOL(copy_fs_struct);
- EXPORT_SYMBOL_GPL(make_pages_present);
- /* internal kernel memory management */
-@@ -123,6 +125,8 @@ EXPORT_SYMBOL(kmem_cache_validate);
- EXPORT_SYMBOL(kmem_cache_alloc);
- EXPORT_SYMBOL(kmem_cache_free);
- EXPORT_SYMBOL(kmem_cache_size);
-+EXPORT_SYMBOL(register_cache);
-+EXPORT_SYMBOL(unregister_cache);
- EXPORT_SYMBOL(kmalloc);
- EXPORT_SYMBOL(kfree);
- EXPORT_SYMBOL(vfree);
---- linux/mm/vmscan.c~linux-2.4.20-xattr-0.8.54-hp     Tue Apr 29 09:23:17 2003
-+++ linux-mmonroe/mm/vmscan.c  Tue Apr 29 09:26:41 2003
-@@ -18,6 +18,7 @@
- #include <linux/kernel_stat.h>
- #include <linux/swap.h>
- #include <linux/swapctl.h>
-+#include <linux/cache_def.h>
- #include <linux/smp_lock.h>
- #include <linux/pagemap.h>
- #include <linux/init.h>
-@@ -35,6 +36,39 @@
-  */
- #define DEF_PRIORITY (6)
-+static DECLARE_MUTEX(other_caches_sem);
-+static LIST_HEAD(cache_definitions);
-+
-+void register_cache(struct cache_definition *cache)
-+{
-+      down(&other_caches_sem);
-+      list_add(&cache->link, &cache_definitions);
-+      up(&other_caches_sem);
-+}
-+
-+void unregister_cache(struct cache_definition *cache)
-+{
-+      down(&other_caches_sem);
-+      list_del(&cache->link);
-+      up(&other_caches_sem);
-+}
-+
-+static void shrink_other_caches(unsigned int priority, int gfp_mask)
-+{
-+      struct list_head *p;
-+
-+      if (down_trylock(&other_caches_sem))
-+              return;
-+
-+      list_for_each_prev(p, &cache_definitions) {
-+              struct cache_definition *cache =
-+                      list_entry(p, struct cache_definition, link);
-+
-+              cache->shrink(priority, gfp_mask);
-+      }
-+      up(&other_caches_sem);
-+}
-+
- /*
-  * The swap-out function returns 1 if it successfully
-  * scanned all the pages it was asked to (`count').
-@@ -579,6 +613,7 @@ static int shrink_caches(zone_t * classz
-       shrink_dcache_memory(priority, gfp_mask);
-       shrink_icache_memory(priority, gfp_mask);
-+      shrink_other_caches(priority, gfp_mask);
- #ifdef CONFIG_QUOTA
-       shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
- #endif
-
-_
diff --git a/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54.patch b/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54.patch
deleted file mode 100644 (file)
index 98d95f2..0000000
+++ /dev/null
@@ -1,5509 +0,0 @@
- 0 files changed
-
---- linux-2.4.20/Documentation/Configure.help~linux-2.4.20-xattr-0.8.54        2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/Documentation/Configure.help    2003-04-08 15:11:04.000000000 +0800
-@@ -15242,6 +15242,39 @@ CONFIG_EXT2_FS
-   be compiled as a module, and so this could be dangerous.  Most
-   everyone wants to say Y here.
-+Ext2 extended attributes
-+CONFIG_EXT2_FS_XATTR
-+  Extended attributes are name:value pairs associated with inodes by
-+  the kernel or by users (see the attr(5) manual page, or visit
-+  <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext2 extended attribute block sharing
-+CONFIG_EXT2_FS_XATTR_SHARING
-+  This options enables code for sharing identical extended attribute
-+  blocks among multiple inodes.
-+
-+  Usually, say Y.
-+
-+Ext2 extended user attributes
-+CONFIG_EXT2_FS_XATTR_USER
-+  This option enables extended user attributes on ext2. Processes can
-+  associate extended user attributes with inodes to store additional
-+  information such as the character encoding of files, etc. (see the
-+  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext2 trusted extended attributes
-+CONFIG_EXT2_FS_XATTR_TRUSTED
-+  This option enables extended attributes on ext2 that are accessible
-+  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
-+  is only the super user. Trusted extended attributes are meant for
-+  implementing system/security services.
-+
-+  If unsure, say N.
-+
- Ext3 journalling file system support (EXPERIMENTAL)
- CONFIG_EXT3_FS
-   This is the journalling version of the Second extended file system
-@@ -15274,6 +15307,39 @@ CONFIG_EXT3_FS
-   of your root partition (the one containing the directory /) cannot
-   be compiled as a module, and so this may be dangerous.
-+Ext3 extended attributes
-+CONFIG_EXT3_FS_XATTR
-+  Extended attributes are name:value pairs associated with inodes by
-+  the kernel or by users (see the attr(5) manual page, or visit
-+  <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext3 extended attribute block sharing
-+CONFIG_EXT3_FS_XATTR_SHARING
-+  This options enables code for sharing identical extended attribute
-+  blocks among multiple inodes.
-+
-+  Usually, say Y.
-+
-+Ext3 extended user attributes
-+CONFIG_EXT3_FS_XATTR_USER
-+  This option enables extended user attributes on ext3. Processes can
-+  associate extended user attributes with inodes to store additional
-+  information such as the character encoding of files, etc. (see the
-+  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
-+
-+  If unsure, say N.
-+
-+Ext3 trusted extended attributes
-+CONFIG_EXT3_FS_XATTR_TRUSTED
-+  This option enables extended attributes on ext3 that are accessible
-+  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
-+  is only the super user. Trusted extended attributes are meant for
-+  implementing system/security services.
-+
-+  If unsure, say N.
-+
- Journal Block Device support (JBD for ext3) (EXPERIMENTAL)
- CONFIG_JBD
-   This is a generic journalling layer for block devices.  It is
---- linux-2.4.20/arch/alpha/defconfig~linux-2.4.20-xattr-0.8.54        2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/alpha/defconfig    2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_ALPHA=y
- # CONFIG_UID16 is not set
- # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
---- linux-2.4.20/arch/alpha/kernel/entry.S~linux-2.4.20-xattr-0.8.54   2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/alpha/kernel/entry.S       2003-04-08 15:11:04.000000000 +0800
-@@ -1154,6 +1154,18 @@ sys_call_table:
-       .quad sys_readahead
-       .quad sys_ni_syscall                    /* 380, sys_security */
-       .quad sys_tkill
-+      .quad sys_setxattr
-+      .quad sys_lsetxattr
-+      .quad sys_fsetxattr
-+      .quad sys_getxattr                      /* 385 */
-+      .quad sys_lgetxattr
-+      .quad sys_fgetxattr
-+      .quad sys_listxattr
-+      .quad sys_llistxattr
-+      .quad sys_flistxattr                    /* 390 */
-+      .quad sys_removexattr
-+      .quad sys_lremovexattr
-+      .quad sys_fremovexattr
- /* Remember to update everything, kids.  */
- .ifne (. - sys_call_table) - (NR_SYSCALLS * 8)
---- linux-2.4.20/arch/arm/defconfig~linux-2.4.20-xattr-0.8.54  2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/arm/defconfig      2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_ARM=y
- # CONFIG_EISA is not set
- # CONFIG_SBUS is not set
---- linux-2.4.20/arch/arm/kernel/calls.S~linux-2.4.20-xattr-0.8.54     2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/arm/kernel/calls.S 2003-04-08 15:11:04.000000000 +0800
-@@ -240,18 +240,18 @@ __syscall_start:
-               .long   SYMBOL_NAME(sys_ni_syscall) /* Security */
-               .long   SYMBOL_NAME(sys_gettid)
- /* 225 */     .long   SYMBOL_NAME(sys_readahead)
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_setxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lsetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fsetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_getxattr */
--/* 230 */     .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lgetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fgetxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_listxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_llistxattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_flistxattr */
--/* 235 */     .long   SYMBOL_NAME(sys_ni_syscall) /* sys_removexattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_lremovexattr */
--              .long   SYMBOL_NAME(sys_ni_syscall) /* sys_fremovexattr */
-+              .long   SYMBOL_NAME(sys_setxattr)
-+              .long   SYMBOL_NAME(sys_lsetxattr)
-+              .long   SYMBOL_NAME(sys_fsetxattr)
-+              .long   SYMBOL_NAME(sys_getxattr)
-+/* 230 */     .long   SYMBOL_NAME(sys_lgetxattr)
-+              .long   SYMBOL_NAME(sys_fgetxattr)
-+              .long   SYMBOL_NAME(sys_listxattr)
-+              .long   SYMBOL_NAME(sys_llistxattr)
-+              .long   SYMBOL_NAME(sys_flistxattr)
-+/* 235 */     .long   SYMBOL_NAME(sys_removexattr)
-+              .long   SYMBOL_NAME(sys_lremovexattr)
-+              .long   SYMBOL_NAME(sys_fremovexattr)
-               .long   SYMBOL_NAME(sys_tkill)
-               /*
-                * Please check 2.5 _before_ adding calls here,
---- linux-2.4.20/arch/i386/defconfig~linux-2.4.20-xattr-0.8.54 2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/i386/defconfig     2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_X86=y
- CONFIG_ISA=y
- # CONFIG_SBUS is not set
---- linux-2.4.20/arch/ia64/defconfig~linux-2.4.20-xattr-0.8.54 2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/ia64/defconfig     2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- #
- # Code maturity level options
---- linux-2.4.20/arch/ia64/kernel/entry.S~linux-2.4.20-xattr-0.8.54    2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/ia64/kernel/entry.S        2003-04-08 15:11:04.000000000 +0800
-@@ -1170,18 +1170,18 @@ sys_call_table:
-       data8 sys_getdents64
-       data8 sys_getunwind                     // 1215
-       data8 sys_readahead
--      data8 ia64_ni_syscall
--      data8 ia64_ni_syscall
--      data8 ia64_ni_syscall
--      data8 ia64_ni_syscall                   // 1220
--      data8 ia64_ni_syscall
--      data8 ia64_ni_syscall
--      data8 ia64_ni_syscall
--      data8 ia64_ni_syscall
--      data8 ia64_ni_syscall                   // 1225
--      data8 ia64_ni_syscall
--      data8 ia64_ni_syscall
--      data8 ia64_ni_syscall
-+      data8 sys_setxattr
-+      data8 sys_lsetxattr
-+      data8 sys_fsetxattr
-+      data8 sys_getxattr                      // 1220
-+      data8 sys_lgetxattr
-+      data8 sys_fgetxattr
-+      data8 sys_listxattr
-+      data8 sys_llistxattr
-+      data8 sys_flistxattr                    // 1225
-+      data8 sys_removexattr
-+      data8 sys_lremovexattr
-+      data8 sys_fremovexattr
-       data8 sys_tkill
-       data8 ia64_ni_syscall                   // 1230
-       data8 ia64_ni_syscall
---- linux-2.4.20/arch/m68k/defconfig~linux-2.4.20-xattr-0.8.54 2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/m68k/defconfig     2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_UID16=y
- #
---- linux-2.4.20/arch/mips/defconfig~linux-2.4.20-xattr-0.8.54 2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/mips/defconfig     2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_MIPS=y
- CONFIG_MIPS32=y
- # CONFIG_MIPS64 is not set
---- linux-2.4.20/arch/mips64/defconfig~linux-2.4.20-xattr-0.8.54       2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/mips64/defconfig   2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_MIPS=y
- # CONFIG_MIPS32 is not set
- CONFIG_MIPS64=y
---- linux-2.4.20/arch/ppc/defconfig~linux-2.4.20-xattr-0.8.54  2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/ppc/defconfig      2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,20 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_UID16 is not set
- # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
- CONFIG_RWSEM_XCHGADD_ALGORITHM=y
---- linux-2.4.20/arch/ppc64/kernel/misc.S~linux-2.4.20-xattr-0.8.54    2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/ppc64/kernel/misc.S        2003-04-08 15:11:04.000000000 +0800
-@@ -731,6 +731,7 @@ _GLOBAL(sys_call_table32)
-       .llong .sys_gettid              /* 207 */
- #if 0 /* Reserved syscalls */
-       .llong .sys_tkill               /* 208 */
-+#endif
-       .llong .sys_setxattr
-       .llong .sys_lsetxattr   /* 210 */
-       .llong .sys_fsetxattr
-@@ -743,6 +744,7 @@ _GLOBAL(sys_call_table32)
-       .llong .sys_removexattr
-       .llong .sys_lremovexattr
-       .llong .sys_fremovexattr        /* 220 */
-+#if 0 /* Reserved syscalls */
-       .llong .sys_futex
- #endif
-       .llong .sys_perfmonctl   /* Put this here for now ... */
---- linux-2.4.20/arch/s390/defconfig~linux-2.4.20-xattr-0.8.54 2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/s390/defconfig     2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_ISA is not set
- # CONFIG_EISA is not set
- # CONFIG_MCA is not set
---- linux-2.4.20/arch/s390/kernel/entry.S~linux-2.4.20-xattr-0.8.54    2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/s390/kernel/entry.S        2003-04-08 15:11:04.000000000 +0800
-@@ -558,18 +558,18 @@ sys_call_table:
-         .long  sys_fcntl64 
-       .long  sys_ni_syscall
-       .long  sys_ni_syscall
--      .long  sys_ni_syscall            /* 224 - reserved for setxattr  */
--      .long  sys_ni_syscall            /* 225 - reserved for lsetxattr */
--      .long  sys_ni_syscall            /* 226 - reserved for fsetxattr */
--      .long  sys_ni_syscall            /* 227 - reserved for getxattr  */
--      .long  sys_ni_syscall            /* 228 - reserved for lgetxattr */
--      .long  sys_ni_syscall            /* 229 - reserved for fgetxattr */
--      .long  sys_ni_syscall            /* 230 - reserved for listxattr */
--      .long  sys_ni_syscall            /* 231 - reserved for llistxattr */
--      .long  sys_ni_syscall            /* 232 - reserved for flistxattr */
--      .long  sys_ni_syscall            /* 233 - reserved for removexattr */
--      .long  sys_ni_syscall            /* 234 - reserved for lremovexattr */
--      .long  sys_ni_syscall            /* 235 - reserved for fremovexattr */
-+      .long  sys_setxattr
-+      .long  sys_lsetxattr            /* 225 */
-+      .long  sys_fsetxattr
-+      .long  sys_getxattr
-+      .long  sys_lgetxattr
-+      .long  sys_fgetxattr
-+      .long  sys_listxattr            /* 230 */
-+      .long  sys_llistxattr
-+      .long  sys_flistxattr
-+      .long  sys_removexattr
-+      .long  sys_lremovexattr
-+      .long  sys_fremovexattr         /* 235 */
-       .long  sys_gettid
-       .long  sys_tkill
-       .rept  255-237
---- linux-2.4.20/arch/s390x/defconfig~linux-2.4.20-xattr-0.8.54        2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/s390x/defconfig    2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_ISA is not set
- # CONFIG_EISA is not set
- # CONFIG_MCA is not set
---- linux-2.4.20/arch/s390x/kernel/entry.S~linux-2.4.20-xattr-0.8.54   2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/s390x/kernel/entry.S       2003-04-08 15:11:04.000000000 +0800
-@@ -591,18 +591,18 @@ sys_call_table:
-       .long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
-       .long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
-       .long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr  */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 226 - reserved for fsetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 227 - reserved for getxattr  */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 228 - reserved for lgetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 229 - reserved for fgetxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 230 - reserved for listxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 231 - reserved for llistxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 232 - reserved for flistxattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 233 - reserved for removexattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 234 - reserved for lremovexattr */
--      .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 235 - reserved for fremovexattr */
-+      .long  SYSCALL(sys_setxattr,sys32_setxattr_wrapper)
-+      .long  SYSCALL(sys_lsetxattr,sys32_lsetxattr_wrapper)   /* 225 */
-+      .long  SYSCALL(sys_fsetxattr,sys32_fsetxattr_wrapper)
-+      .long  SYSCALL(sys_getxattr,sys32_getxattr_wrapper)
-+      .long  SYSCALL(sys_lgetxattr,sys32_lgetxattr_wrapper)
-+      .long  SYSCALL(sys_fgetxattr,sys32_fgetxattr_wrapper)
-+      .long  SYSCALL(sys_listxattr,sys32_listxattr_wrapper)   /* 230 */
-+      .long  SYSCALL(sys_llistxattr,sys32_llistxattr_wrapper)
-+      .long  SYSCALL(sys_flistxattr,sys32_flistxattr_wrapper)
-+      .long  SYSCALL(sys_removexattr,sys32_removexattr_wrapper)
-+      .long  SYSCALL(sys_lremovexattr,sys32_lremovexattr_wrapper)
-+      .long  SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper)/* 235 */
-       .long  SYSCALL(sys_gettid,sys_gettid)
-       .long  SYSCALL(sys_tkill,sys_tkill)
-       .rept  255-237
---- linux-2.4.20/arch/s390x/kernel/wrapper32.S~linux-2.4.20-xattr-0.8.54       2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/s390x/kernel/wrapper32.S   2003-04-08 15:11:04.000000000 +0800
-@@ -1091,3 +1091,95 @@ sys32_fstat64_wrapper:
-       llgtr   %r3,%r3                 # struct stat64 *
-       llgfr   %r4,%r4                 # long
-       jg      sys32_fstat64           # branch to system call
-+
-+      .globl  sys32_setxattr_wrapper
-+sys32_setxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_setxattr
-+
-+      .globl  sys32_lsetxattr_wrapper
-+sys32_lsetxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_lsetxattr
-+
-+      .globl  sys32_fsetxattr_wrapper
-+sys32_fsetxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      lgfr    %r6,%r6                 # int
-+      jg      sys_fsetxattr
-+
-+      .globl  sys32_getxattr_wrapper
-+sys32_getxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_getxattr
-+
-+      .globl  sys32_lgetxattr_wrapper
-+sys32_lgetxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_lgetxattr
-+
-+      .globl  sys32_fgetxattr_wrapper
-+sys32_fgetxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgtr   %r4,%r4                 # void *
-+      llgfr   %r5,%r5                 # size_t
-+      jg      sys_fgetxattr
-+
-+      .globl  sys32_listxattr_wrapper
-+sys32_listxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_listxattr
-+
-+      .globl  sys32_llistxattr_wrapper
-+sys32_llistxattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_llistxattr
-+
-+      .globl  sys32_flistxattr_wrapper
-+sys32_flistxattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      llgfr   %r4,%r4                 # size_t
-+      jg      sys_flistxattr
-+
-+      .globl  sys32_removexattr_wrapper
-+sys32_removexattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_removexattr
-+
-+      .globl  sys32_lremovexattr_wrapper
-+sys32_lremovexattr_wrapper:
-+      llgtr   %r2,%r2                 # char *
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_lremovexattr
-+
-+      .globl  sys32_fremovexattr_wrapper
-+sys32_fremovexattr_wrapper:
-+      lgfr    %r2,%r2                 # int
-+      llgtr   %r3,%r3                 # char *
-+      jg      sys_fremovexattr
-+
-+
---- linux-2.4.20/arch/sparc/defconfig~linux-2.4.20-xattr-0.8.54        2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/sparc/defconfig    2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_UID16=y
- CONFIG_HIGHMEM=y
---- linux-2.4.20/arch/sparc/kernel/systbls.S~linux-2.4.20-xattr-0.8.54 2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/sparc/kernel/systbls.S     2003-04-08 15:11:04.000000000 +0800
-@@ -51,11 +51,11 @@ sys_call_table:
- /*150*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
- /*155*/       .long sys_fcntl64, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
- /*160*/       .long sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
--/*165*/       .long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
--/*170*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
--/*175*/       .long sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_sigpending, sys_query_module
--/*185*/       .long sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sys_newuname
-+/*165*/       .long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
-+/*170*/       .long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
-+/*175*/       .long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module
-+/*185*/       .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sys_newuname
- /*190*/       .long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
- /*195*/       .long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
- /*200*/       .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
---- linux-2.4.20/arch/sparc64/defconfig~linux-2.4.20-xattr-0.8.54      2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/sparc64/defconfig  2003-04-08 15:11:04.000000000 +0800
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- #
- # Code maturity level options
---- linux-2.4.20/arch/sparc64/kernel/systbls.S~linux-2.4.20-xattr-0.8.54       2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/arch/sparc64/kernel/systbls.S   2003-04-08 15:11:04.000000000 +0800
-@@ -52,11 +52,11 @@ sys_call_table32:
- /*150*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
-       .word sys32_fcntl64, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
- /*160*/       .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
--      .word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_nis_syscall
--/*170*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents
--      .word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_sigpending, sys32_query_module
--      .word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
-+      .word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_setxattr
-+/*170*/       .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
-+      .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module
-+      .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
- /*190*/       .word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
-       .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
- /*200*/       .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
-@@ -111,11 +111,11 @@ sys_call_table:
- /*150*/       .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
-       .word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
- /*160*/       .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_utrap_install
--      .word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
--/*170*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
--      .word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/       .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_query_module
--      .word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
-+      .word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
-+/*170*/       .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
-+      .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/       .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module
-+      .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
- /*190*/       .word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
-       .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
- /*200*/       .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
---- linux-2.4.20/fs/Config.in~linux-2.4.20-xattr-0.8.54        2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/fs/Config.in    2003-04-08 15:11:04.000000000 +0800
-@@ -25,6 +25,11 @@ dep_mbool '  Debug Befs' CONFIG_BEFS_DEB
- dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
- tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS
-+dep_mbool '  Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS
-+dep_bool '    Ext3 extended attribute block sharing' \
-+    CONFIG_EXT3_FS_XATTR_SHARING $CONFIG_EXT3_FS_XATTR
-+dep_bool '    Ext3 extended user attributes' \
-+    CONFIG_EXT3_FS_XATTR_USER $CONFIG_EXT3_FS_XATTR
- # CONFIG_JBD could be its own option (even modular), but until there are
- # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
- # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
-@@ -84,6 +89,11 @@ dep_mbool '  QNX4FS write support (DANGE
- tristate 'ROM file system support' CONFIG_ROMFS_FS
- tristate 'Second extended fs support' CONFIG_EXT2_FS
-+dep_mbool '  Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS
-+dep_bool '    Ext2 extended attribute block sharing' \
-+    CONFIG_EXT2_FS_XATTR_SHARING $CONFIG_EXT2_FS_XATTR
-+dep_bool '    Ext2 extended user attributes' \
-+    CONFIG_EXT2_FS_XATTR_USER $CONFIG_EXT2_FS_XATTR
- tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS
-@@ -155,6 +165,10 @@ else
-    define_tristate CONFIG_ZISOFS_FS n
- fi
-+# Meta block cache for Extended Attributes (ext2/ext3)
-+#tristate 'Meta block cache' CONFIG_FS_MBCACHE
-+define_tristate CONFIG_FS_MBCACHE y
-+
- mainmenu_option next_comment
- comment 'Partition Types'
- source fs/partitions/Config.in
---- linux-2.4.20/fs/Makefile~linux-2.4.20-xattr-0.8.54 2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/fs/Makefile     2003-04-08 15:11:04.000000000 +0800
-@@ -79,6 +79,9 @@ obj-y                                += binfmt_script.o
- obj-$(CONFIG_BINFMT_ELF)      += binfmt_elf.o
-+export-objs += mbcache.o
-+obj-$(CONFIG_FS_MBCACHE)      += mbcache.o
-+
- # persistent filesystems
- obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
---- linux-2.4.20/fs/ext2/Makefile~linux-2.4.20-xattr-0.8.54    2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext2/Makefile        2003-04-08 15:11:04.000000000 +0800
-@@ -13,4 +13,8 @@ obj-y    := balloc.o bitmap.o dir.o file
-               ioctl.o namei.o super.o symlink.o
- obj-m    := $(O_TARGET)
-+export-objs += xattr.o
-+obj-$(CONFIG_EXT2_FS_XATTR) += xattr.o
-+obj-$(CONFIG_EXT2_FS_XATTR_USER) += xattr_user.o
-+
- include $(TOPDIR)/Rules.make
---- linux-2.4.20/fs/ext2/file.c~linux-2.4.20-xattr-0.8.54      2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext2/file.c  2003-04-08 15:11:04.000000000 +0800
-@@ -20,6 +20,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/sched.h>
- /*
-@@ -51,4 +52,8 @@ struct file_operations ext2_file_operati
- struct inode_operations ext2_file_inode_operations = {
-       truncate:       ext2_truncate,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- linux-2.4.20/fs/ext2/ialloc.c~linux-2.4.20-xattr-0.8.54    2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext2/ialloc.c        2003-04-08 15:11:04.000000000 +0800
-@@ -15,6 +15,7 @@
- #include <linux/config.h>
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/locks.h>
- #include <linux/quotaops.h>
-@@ -167,6 +168,7 @@ void ext2_free_inode (struct inode * ino
-        */
-       if (!is_bad_inode(inode)) {
-               /* Quota is already initialized in iput() */
-+              ext2_xattr_delete_inode(inode);
-               DQUOT_FREE_INODE(inode);
-               DQUOT_DROP(inode);
-       }
---- linux-2.4.20/fs/ext2/inode.c~linux-2.4.20-xattr-0.8.54     2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext2/inode.c 2003-04-08 15:11:04.000000000 +0800
-@@ -39,6 +39,18 @@ MODULE_LICENSE("GPL");
- static int ext2_update_inode(struct inode * inode, int do_sync);
- /*
-+ * Test whether an inode is a fast symlink.
-+ */
-+static inline int ext2_inode_is_fast_symlink(struct inode *inode)
-+{
-+      int ea_blocks = inode->u.ext2_i.i_file_acl ?
-+              (inode->i_sb->s_blocksize >> 9) : 0;
-+
-+      return (S_ISLNK(inode->i_mode) &&
-+              inode->i_blocks - ea_blocks == 0);
-+}
-+
-+/*
-  * Called at each iput()
-  */
- void ext2_put_inode (struct inode * inode)
-@@ -53,9 +65,7 @@ void ext2_delete_inode (struct inode * i
- {
-       lock_kernel();
--      if (is_bad_inode(inode) ||
--          inode->i_ino == EXT2_ACL_IDX_INO ||
--          inode->i_ino == EXT2_ACL_DATA_INO)
-+      if (is_bad_inode(inode))
-               goto no_delete;
-       inode->u.ext2_i.i_dtime = CURRENT_TIME;
-       mark_inode_dirty(inode);
-@@ -801,6 +811,8 @@ void ext2_truncate (struct inode * inode
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-+      if (ext2_inode_is_fast_symlink(inode))
-+              return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-@@ -888,8 +900,7 @@ void ext2_read_inode (struct inode * ino
-       unsigned long offset;
-       struct ext2_group_desc * gdp;
--      if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
--           inode->i_ino != EXT2_ACL_DATA_INO &&
-+      if ((inode->i_ino != EXT2_ROOT_INO &&
-            inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||
-           inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {
-               ext2_error (inode->i_sb, "ext2_read_inode",
-@@ -974,10 +985,7 @@ void ext2_read_inode (struct inode * ino
-       for (block = 0; block < EXT2_N_BLOCKS; block++)
-               inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
--      if (inode->i_ino == EXT2_ACL_IDX_INO ||
--          inode->i_ino == EXT2_ACL_DATA_INO)
--              /* Nothing to do */ ;
--      else if (S_ISREG(inode->i_mode)) {
-+      if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &ext2_file_inode_operations;
-               inode->i_fop = &ext2_file_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-@@ -986,15 +994,17 @@ void ext2_read_inode (struct inode * ino
-               inode->i_fop = &ext2_dir_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-       } else if (S_ISLNK(inode->i_mode)) {
--              if (!inode->i_blocks)
-+              if (ext2_inode_is_fast_symlink(inode))
-                       inode->i_op = &ext2_fast_symlink_inode_operations;
-               else {
--                      inode->i_op = &page_symlink_inode_operations;
-+                      inode->i_op = &ext2_symlink_inode_operations;
-                       inode->i_mapping->a_ops = &ext2_aops;
-               }
--      } else 
-+      } else {
-+              inode->i_op = &ext2_special_inode_operations;
-               init_special_inode(inode, inode->i_mode,
-                                  le32_to_cpu(raw_inode->i_block[0]));
-+      }
-       brelse (bh);
-       inode->i_attr_flags = 0;
-       if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) {
---- linux-2.4.20/fs/ext2/namei.c~linux-2.4.20-xattr-0.8.54     2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext2/namei.c 2003-04-08 15:11:04.000000000 +0800
-@@ -31,6 +31,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/pagemap.h>
- /*
-@@ -136,7 +137,7 @@ static int ext2_symlink (struct inode * 
-       if (l > sizeof (inode->u.ext2_i.i_data)) {
-               /* slow symlink */
--              inode->i_op = &page_symlink_inode_operations;
-+              inode->i_op = &ext2_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext2_aops;
-               err = block_symlink(inode, symname, l);
-               if (err)
-@@ -345,4 +346,15 @@ struct inode_operations ext2_dir_inode_o
-       rmdir:          ext2_rmdir,
-       mknod:          ext2_mknod,
-       rename:         ext2_rename,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
-+};
-+
-+struct inode_operations ext2_special_inode_operations = {
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- linux-2.4.20/fs/ext2/super.c~linux-2.4.20-xattr-0.8.54     2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext2/super.c 2003-04-08 15:11:04.000000000 +0800
-@@ -21,6 +21,7 @@
- #include <linux/string.h>
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/locks.h>
-@@ -125,6 +126,7 @@ void ext2_put_super (struct super_block 
-       int db_count;
-       int i;
-+      ext2_xattr_put_super(sb);
-       if (!(sb->s_flags & MS_RDONLY)) {
-               struct ext2_super_block *es = EXT2_SB(sb)->s_es;
-@@ -175,6 +177,13 @@ static int parse_options (char * options
-            this_char = strtok (NULL, ",")) {
-               if ((value = strchr (this_char, '=')) != NULL)
-                       *value++ = 0;
-+#ifdef CONFIG_EXT2_FS_XATTR_USER
-+              if (!strcmp (this_char, "user_xattr"))
-+                      set_opt (*mount_options, XATTR_USER);
-+              else if (!strcmp (this_char, "nouser_xattr"))
-+                      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")) {
-@@ -424,6 +433,9 @@ struct super_block * ext2_read_super (st
-           blocksize = BLOCK_SIZE;
-       sb->u.ext2_sb.s_mount_opt = 0;
-+#ifdef CONFIG_EXT2_FS_XATTR_USER
-+      /* set_opt (sb->u.ext2_sb.s_mount_opt, XATTR_USER); */
-+#endif
-       if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
-           &sb->u.ext2_sb.s_mount_opt)) {
-               return NULL;
-@@ -813,12 +825,27 @@ static DECLARE_FSTYPE_DEV(ext2_fs_type, 
- static int __init init_ext2_fs(void)
- {
--        return register_filesystem(&ext2_fs_type);
-+      int error = init_ext2_xattr();
-+      if (error)
-+              return error;
-+      error = init_ext2_xattr_user();
-+      if (error)
-+              goto fail;
-+      error = register_filesystem(&ext2_fs_type);
-+      if (!error)
-+              return 0;
-+
-+      exit_ext2_xattr_user();
-+fail:
-+      exit_ext2_xattr();
-+      return error;
- }
- static void __exit exit_ext2_fs(void)
- {
-       unregister_filesystem(&ext2_fs_type);
-+      exit_ext2_xattr_user();
-+      exit_ext2_xattr();
- }
- EXPORT_NO_SYMBOLS;
---- linux-2.4.20/fs/ext2/symlink.c~linux-2.4.20-xattr-0.8.54   2003-04-08 15:11:03.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext2/symlink.c       2003-04-08 15:11:04.000000000 +0800
-@@ -19,6 +19,7 @@
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
- static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
-@@ -32,7 +33,20 @@ static int ext2_follow_link(struct dentr
-       return vfs_follow_link(nd, s);
- }
-+struct inode_operations ext2_symlink_inode_operations = {
-+      readlink:       page_readlink,
-+      follow_link:    page_follow_link,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
-+};
-+
- struct inode_operations ext2_fast_symlink_inode_operations = {
-       readlink:       ext2_readlink,
-       follow_link:    ext2_follow_link,
-+      setxattr:       ext2_setxattr,
-+      getxattr:       ext2_getxattr,
-+      listxattr:      ext2_listxattr,
-+      removexattr:    ext2_removexattr,
- };
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext2/xattr.c 2003-04-08 15:11:04.000000000 +0800
-@@ -0,0 +1,1212 @@
-+/*
-+ * linux/fs/ext2/xattr.c
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
-+ * Extended attributes for symlinks and special files added per
-+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
-+ */
-+
-+/*
-+ * Extended attributes are stored on disk blocks allocated outside of
-+ * any inode. The i_file_acl field is then made to point to this allocated
-+ * block. If all extended attributes of an inode are identical, these
-+ * inodes may share the same extended attribute block. Such situations
-+ * are automatically detected by keeping a cache of recent attribute block
-+ * numbers and hashes over the block's contents in memory.
-+ *
-+ *
-+ * Extended attribute block layout:
-+ *
-+ *   +------------------+
-+ *   | header           |
-+ *   | entry 1          | |
-+ *   | entry 2          | | growing downwards
-+ *   | entry 3          | v
-+ *   | four null bytes  |
-+ *   | . . .            |
-+ *   | value 1          | ^
-+ *   | value 3          | | growing upwards
-+ *   | value 2          | |
-+ *   +------------------+
-+ *
-+ * The block header is followed by multiple entry descriptors. These entry
-+ * descriptors are variable in size, and alligned to EXT2_XATTR_PAD
-+ * byte boundaries. The entry descriptors are sorted by attribute name,
-+ * so that two extended attribute blocks can be compared efficiently.
-+ *
-+ * Attribute values are aligned to the end of the block, stored in
-+ * no specific order. They are also padded to EXT2_XATTR_PAD byte
-+ * boundaries. No additional gaps are left between them.
-+ *
-+ * Locking strategy
-+ * ----------------
-+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
-+ * the xattr inode operations are called, so we are guaranteed that only one
-+ * processes accesses extended attributes of an inode at any time.
-+ *
-+ * For writing we also grab the ext2_xattr_sem semaphore. This ensures that
-+ * only a single process is modifying an extended attribute block, even
-+ * if the block is shared among inodes.
-+ *
-+ * Note for porting to 2.5
-+ * -----------------------
-+ * The BKL will no longer be held in the xattr inode operations.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/locks.h>
-+#include <linux/slab.h>
-+#include <linux/fs.h>
-+#include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
-+#include <linux/mbcache.h>
-+#include <linux/quotaops.h>
-+#include <asm/semaphore.h>
-+#include <linux/compatmac.h>
-+
-+/* These symbols may be needed by a module. */
-+EXPORT_SYMBOL(ext2_xattr_register);
-+EXPORT_SYMBOL(ext2_xattr_unregister);
-+EXPORT_SYMBOL(ext2_xattr_get);
-+EXPORT_SYMBOL(ext2_xattr_list);
-+EXPORT_SYMBOL(ext2_xattr_set);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
-+#endif
-+
-+#define HDR(bh) ((struct ext2_xattr_header *)((bh)->b_data))
-+#define ENTRY(ptr) ((struct ext2_xattr_entry *)(ptr))
-+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
-+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
-+
-+#ifdef EXT2_XATTR_DEBUG
-+# define ea_idebug(inode, f...) do { \
-+              printk(KERN_DEBUG "inode %s:%ld: ", \
-+                      kdevname(inode->i_dev), inode->i_ino); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+# define ea_bdebug(bh, f...) do { \
-+              printk(KERN_DEBUG "block %s:%ld: ", \
-+                      kdevname(bh->b_dev), bh->b_blocknr); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+#else
-+# define ea_idebug(f...)
-+# define ea_bdebug(f...)
-+#endif
-+
-+static int ext2_xattr_set2(struct inode *, struct buffer_head *,
-+                         struct ext2_xattr_header *);
-+
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+
-+static int ext2_xattr_cache_insert(struct buffer_head *);
-+static struct buffer_head *ext2_xattr_cache_find(struct inode *,
-+                                               struct ext2_xattr_header *);
-+static void ext2_xattr_cache_remove(struct buffer_head *);
-+static void ext2_xattr_rehash(struct ext2_xattr_header *,
-+                            struct ext2_xattr_entry *);
-+
-+static struct mb_cache *ext2_xattr_cache;
-+
-+#else
-+# define ext2_xattr_cache_insert(bh) 0
-+# define ext2_xattr_cache_find(inode, header) NULL
-+# define ext2_xattr_cache_remove(bh) while(0) {}
-+# define ext2_xattr_rehash(header, entry) while(0) {}
-+#endif
-+
-+/*
-+ * If a file system does not share extended attributes among inodes,
-+ * we should not need the ext2_xattr_sem semaphore. However, the
-+ * filesystem may still contain shared blocks, so we always take
-+ * the lock.
-+ */
-+
-+DECLARE_MUTEX(ext2_xattr_sem);
-+
-+static inline int
-+ext2_xattr_new_block(struct inode *inode, int * errp, int force)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      int goal = le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) +
-+              EXT2_I(inode)->i_block_group * EXT2_BLOCKS_PER_GROUP(sb);
-+
-+      /* How can we enforce the allocation? */
-+      int block = ext2_new_block(inode, goal, 0, 0, errp);
-+#ifdef OLD_QUOTAS
-+      if (!*errp)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#endif
-+      return block;
-+}
-+
-+static inline int
-+ext2_xattr_quota_alloc(struct inode *inode, int force)
-+{
-+      /* How can we enforce the allocation? */
-+#ifdef OLD_QUOTAS
-+      int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
-+      if (!error)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#else
-+      int error = DQUOT_ALLOC_BLOCK(inode, 1);
-+#endif
-+      return error;
-+}
-+
-+#ifdef OLD_QUOTAS
-+
-+static inline void
-+ext2_xattr_quota_free(struct inode *inode)
-+{
-+      DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+static inline void
-+ext2_xattr_free_block(struct inode * inode, unsigned long block)
-+{
-+      ext2_free_blocks(inode, block, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+#else
-+# define ext2_xattr_quota_free(inode) \
-+      DQUOT_FREE_BLOCK(inode, 1)
-+# define ext2_xattr_free_block(inode, block) \
-+      ext2_free_blocks(inode, block, 1)
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
-+
-+static inline struct buffer_head *
-+sb_bread(struct super_block *sb, int block)
-+{
-+      return bread(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+static inline struct buffer_head *
-+sb_getblk(struct super_block *sb, int block)
-+{
-+      return getblk(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+#endif
-+
-+struct ext2_xattr_handler *ext2_xattr_handlers[EXT2_XATTR_INDEX_MAX];
-+rwlock_t ext2_handler_lock = RW_LOCK_UNLOCKED;
-+
-+int
-+ext2_xattr_register(int name_index, struct ext2_xattr_handler *handler)
-+{
-+      int error = -EINVAL;
-+
-+      if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
-+              write_lock(&ext2_handler_lock);
-+              if (!ext2_xattr_handlers[name_index-1]) {
-+                      ext2_xattr_handlers[name_index-1] = handler;
-+                      error = 0;
-+              }
-+              write_unlock(&ext2_handler_lock);
-+      }
-+      return error;
-+}
-+
-+void
-+ext2_xattr_unregister(int name_index, struct ext2_xattr_handler *handler)
-+{
-+      if (name_index > 0 || name_index <= EXT2_XATTR_INDEX_MAX) {
-+              write_lock(&ext2_handler_lock);
-+              ext2_xattr_handlers[name_index-1] = NULL;
-+              write_unlock(&ext2_handler_lock);
-+      }
-+}
-+
-+static inline const char *
-+strcmp_prefix(const char *a, const char *a_prefix)
-+{
-+      while (*a_prefix && *a == *a_prefix) {
-+              a++;
-+              a_prefix++;
-+      }
-+      return *a_prefix ? NULL : a;
-+}
-+
-+/*
-+ * Decode the extended attribute name, and translate it into
-+ * the name_index and name suffix.
-+ */
-+static struct ext2_xattr_handler *
-+ext2_xattr_resolve_name(const char **name)
-+{
-+      struct ext2_xattr_handler *handler = NULL;
-+      int i;
-+
-+      if (!*name)
-+              return NULL;
-+      read_lock(&ext2_handler_lock);
-+      for (i=0; i<EXT2_XATTR_INDEX_MAX; i++) {
-+              if (ext2_xattr_handlers[i]) {
-+                      const char *n = strcmp_prefix(*name,
-+                              ext2_xattr_handlers[i]->prefix);
-+                      if (n) {
-+                              handler = ext2_xattr_handlers[i];
-+                              *name = n;
-+                              break;
-+                      }
-+              }
-+      }
-+      read_unlock(&ext2_handler_lock);
-+      return handler;
-+}
-+
-+static inline struct ext2_xattr_handler *
-+ext2_xattr_handler(int name_index)
-+{
-+      struct ext2_xattr_handler *handler = NULL;
-+      if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
-+              read_lock(&ext2_handler_lock);
-+              handler = ext2_xattr_handlers[name_index-1];
-+              read_unlock(&ext2_handler_lock);
-+      }
-+      return handler;
-+}
-+
-+/*
-+ * Inode operation getxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext2_getxattr(struct dentry *dentry, const char *name,
-+            void *buffer, size_t size)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->get(inode, name, buffer, size);
-+}
-+
-+/*
-+ * Inode operation listxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
-+{
-+      return ext2_xattr_list(dentry->d_inode, buffer, size);
-+}
-+
-+/*
-+ * Inode operation setxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext2_setxattr(struct dentry *dentry, const char *name,
-+            const void *value, size_t size, int flags)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      if (size == 0)
-+              value = "";  /* empty EA, do not remove */
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, value, size, flags);
-+}
-+
-+/*
-+ * Inode operation removexattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext2_removexattr(struct dentry *dentry, const char *name)
-+{
-+      struct ext2_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext2_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
-+}
-+
-+/*
-+ * ext2_xattr_get()
-+ *
-+ * Copy an extended attribute into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext2_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_entry *entry;
-+      unsigned int block, size;
-+      char *end;
-+      int name_len, error;
-+
-+      ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
-+                name_index, name, buffer, (long)buffer_size);
-+
-+      if (name == NULL)
-+              return -EINVAL;
-+      if (!EXT2_I(inode)->i_file_acl)
-+              return -ENOATTR;
-+      block = EXT2_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext2_error(inode->i_sb, "ext2_xattr_get",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* find named attribute */
-+      name_len = strlen(name);
-+
-+      error = -ERANGE;
-+      if (name_len > 255)
-+              goto cleanup;
-+      entry = FIRST_ENTRY(bh);
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              if (name_index == entry->e_name_index &&
-+                  name_len == entry->e_name_len &&
-+                  memcmp(name, entry->e_name, name_len) == 0)
-+                      goto found;
-+              entry = next;
-+      }
-+      /* Check the remaining name entries */
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              entry = next;
-+      }
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      error = -ENOATTR;
-+      goto cleanup;
-+found:
-+      /* check the buffer size */
-+      if (entry->e_value_block != 0)
-+              goto bad_block;
-+      size = le32_to_cpu(entry->e_value_size);
-+      if (size > inode->i_sb->s_blocksize ||
-+          le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-+              goto bad_block;
-+
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (buffer) {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+              /* return value of attribute */
-+              memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-+                      size);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_list()
-+ *
-+ * Copy a list of attribute names into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_entry *entry;
-+      unsigned int block, size = 0;
-+      char *buf, *end;
-+      int error;
-+
-+      ea_idebug(inode, "buffer=%p, buffer_size=%ld",
-+                buffer, (long)buffer_size);
-+
-+      if (!EXT2_I(inode)->i_file_acl)
-+              return 0;
-+      block = EXT2_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext2_error(inode->i_sb, "ext2_xattr_list",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* compute the size required for the list of attribute names */
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT2_XATTR_NEXT(entry)) {
-+              struct ext2_xattr_handler *handler;
-+              struct ext2_xattr_entry *next =
-+                      EXT2_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+
-+              handler = ext2_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      size += handler->list(NULL, inode, entry->e_name,
-+                                            entry->e_name_len);
-+      }
-+
-+      if (ext2_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (!buffer) {
-+              error = size;
-+              goto cleanup;
-+      } else {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+      }
-+
-+      /* list the attribute names */
-+      buf = buffer;
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT2_XATTR_NEXT(entry)) {
-+              struct ext2_xattr_handler *handler;
-+              
-+              handler = ext2_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      buf += handler->list(buf, inode, entry->e_name,
-+                                           entry->e_name_len);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * If the EXT2_FEATURE_COMPAT_EXT_ATTR feature of this file system is
-+ * not set, set it.
-+ */
-+static void ext2_xattr_update_super_block(struct super_block *sb)
-+{
-+      if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR))
-+              return;
-+
-+      lock_super(sb);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+      EXT2_SB(sb)->s_feature_compat |= EXT2_FEATURE_COMPAT_EXT_ATTR;
-+#endif
-+      EXT2_SB(sb)->s_es->s_feature_compat |=
-+              cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR);
-+      sb->s_dirt = 1;
-+      mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
-+      unlock_super(sb);
-+}
-+
-+/*
-+ * ext2_xattr_set()
-+ *
-+ * Create, replace or remove an extended attribute for this inode. Buffer
-+ * is NULL to remove an existing extended attribute, and non-NULL to
-+ * either replace an existing extended attribute, or create a new extended
-+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
-+ * specify that an extended attribute must exist and must not exist
-+ * previous to the call, respectively.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+int
-+ext2_xattr_set(struct inode *inode, int name_index, const char *name,
-+             const void *value, size_t value_len, int flags)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *bh = NULL;
-+      struct ext2_xattr_header *header = NULL;
-+      struct ext2_xattr_entry *here, *last;
-+      unsigned int name_len;
-+      int block = EXT2_I(inode)->i_file_acl;
-+      int min_offs = sb->s_blocksize, not_found = 1, free, error;
-+      char *end;
-+      
-+      /*
-+       * header -- Points either into bh, or to a temporarily
-+       *           allocated buffer.
-+       * here -- The named entry found, or the place for inserting, within
-+       *         the block pointed to by header.
-+       * last -- Points right after the last named entry within the block
-+       *         pointed to by header.
-+       * min_offs -- The offset of the first value (values are aligned
-+       *             towards the end of the block).
-+       * end -- Points right after the block pointed to by header.
-+       */
-+      
-+      ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-+                name_index, name, value, (long)value_len);
-+
-+      if (IS_RDONLY(inode))
-+              return -EROFS;
-+      if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-+              return -EPERM;
-+      if (value == NULL)
-+              value_len = 0;
-+      if (name == NULL)
-+              return -EINVAL;
-+      name_len = strlen(name);
-+      if (name_len > 255 || value_len > sb->s_blocksize)
-+              return -ERANGE;
-+      down(&ext2_xattr_sem);
-+
-+      if (block) {
-+              /* The inode already has an extended attribute block. */
-+
-+              bh = sb_bread(sb, block);
-+              error = -EIO;
-+              if (!bh)
-+                      goto cleanup;
-+              ea_bdebug(bh, "b_count=%d, refcount=%d",
-+                      atomic_read(&(bh->b_count)),
-+                      le32_to_cpu(HDR(bh)->h_refcount));
-+              header = HDR(bh);
-+              end = bh->b_data + bh->b_size;
-+              if (header->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+                  header->h_blocks != cpu_to_le32(1)) {
-+bad_block:            ext2_error(sb, "ext2_xattr_set",
-+                              "inode %ld: bad block %d", inode->i_ino, block);
-+                      error = -EIO;
-+                      goto cleanup;
-+              }
-+              /* Find the named attribute. */
-+              here = FIRST_ENTRY(bh);
-+              while (!IS_LAST_ENTRY(here)) {
-+                      struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(here);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!here->e_value_block && here->e_value_size) {
-+                              int offs = le16_to_cpu(here->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      not_found = name_index - here->e_name_index;
-+                      if (!not_found)
-+                              not_found = name_len - here->e_name_len;
-+                      if (!not_found)
-+                              not_found = memcmp(name, here->e_name,name_len);
-+                      if (not_found <= 0)
-+                              break;
-+                      here = next;
-+              }
-+              last = here;
-+              /* We still need to compute min_offs and last. */
-+              while (!IS_LAST_ENTRY(last)) {
-+                      struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(last);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!last->e_value_block && last->e_value_size) {
-+                              int offs = le16_to_cpu(last->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      last = next;
-+              }
-+
-+              /* Check whether we have enough space left. */
-+              free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-+      } else {
-+              /* We will use a new extended attribute block. */
-+              free = sb->s_blocksize -
-+                      sizeof(struct ext2_xattr_header) - sizeof(__u32);
-+              here = last = NULL;  /* avoid gcc uninitialized warning. */
-+      }
-+
-+      if (not_found) {
-+              /* Request to remove a nonexistent attribute? */
-+              error = -ENOATTR;
-+              if (flags & XATTR_REPLACE)
-+                      goto cleanup;
-+              error = 0;
-+              if (value == NULL)
-+                      goto cleanup;
-+              else
-+                      free -= EXT2_XATTR_LEN(name_len);
-+      } else {
-+              /* Request to create an existing attribute? */
-+              error = -EEXIST;
-+              if (flags & XATTR_CREATE)
-+                      goto cleanup;
-+              if (!here->e_value_block && here->e_value_size) {
-+                      unsigned int size = le32_to_cpu(here->e_value_size);
-+
-+                      if (le16_to_cpu(here->e_value_offs) + size > 
-+                          sb->s_blocksize || size > sb->s_blocksize)
-+                              goto bad_block;
-+                      free += EXT2_XATTR_SIZE(size);
-+              }
-+      }
-+      free -= EXT2_XATTR_SIZE(value_len);
-+      error = -ENOSPC;
-+      if (free < 0)
-+              goto cleanup;
-+
-+      /* Here we know that we can set the new attribute. */
-+
-+      if (header) {
-+              if (header->h_refcount == cpu_to_le32(1)) {
-+                      ea_bdebug(bh, "modifying in-place");
-+                      ext2_xattr_cache_remove(bh);
-+              } else {
-+                      int offset;
-+
-+                      ea_bdebug(bh, "cloning");
-+                      header = kmalloc(bh->b_size, GFP_KERNEL);
-+                      error = -ENOMEM;
-+                      if (header == NULL)
-+                              goto cleanup;
-+                      memcpy(header, HDR(bh), bh->b_size);
-+                      header->h_refcount = cpu_to_le32(1);
-+                      offset = (char *)header - bh->b_data;
-+                      here = ENTRY((char *)here + offset);
-+                      last = ENTRY((char *)last + offset);
-+              }
-+      } else {
-+              /* Allocate a buffer where we construct the new block. */
-+              header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-+              error = -ENOMEM;
-+              if (header == NULL)
-+                      goto cleanup;
-+              memset(header, 0, sb->s_blocksize);
-+              end = (char *)header + sb->s_blocksize;
-+              header->h_magic = cpu_to_le32(EXT2_XATTR_MAGIC);
-+              header->h_blocks = header->h_refcount = cpu_to_le32(1);
-+              last = here = ENTRY(header+1);
-+      }
-+
-+      if (not_found) {
-+              /* Insert the new name. */
-+              int size = EXT2_XATTR_LEN(name_len);
-+              int rest = (char *)last - (char *)here;
-+              memmove((char *)here + size, here, rest);
-+              memset(here, 0, size);
-+              here->e_name_index = name_index;
-+              here->e_name_len = name_len;
-+              memcpy(here->e_name, name, name_len);
-+      } else {
-+              /* Remove the old value. */
-+              if (!here->e_value_block && here->e_value_size) {
-+                      char *first_val = (char *)header + min_offs;
-+                      int offs = le16_to_cpu(here->e_value_offs);
-+                      char *val = (char *)header + offs;
-+                      size_t size = EXT2_XATTR_SIZE(
-+                              le32_to_cpu(here->e_value_size));
-+                      memmove(first_val + size, first_val, val - first_val);
-+                      memset(first_val, 0, size);
-+                      here->e_value_offs = 0;
-+                      min_offs += size;
-+
-+                      /* Adjust all value offsets. */
-+                      last = ENTRY(header+1);
-+                      while (!IS_LAST_ENTRY(last)) {
-+                              int o = le16_to_cpu(last->e_value_offs);
-+                              if (!last->e_value_block && o < offs)
-+                                      last->e_value_offs =
-+                                              cpu_to_le16(o + size);
-+                              last = EXT2_XATTR_NEXT(last);
-+                      }
-+              }
-+              if (value == NULL) {
-+                      /* Remove this attribute. */
-+                      if (EXT2_XATTR_NEXT(ENTRY(header+1)) == last) {
-+                              /* This block is now empty. */
-+                              error = ext2_xattr_set2(inode, bh, NULL);
-+                              goto cleanup;
-+                      } else {
-+                              /* Remove the old name. */
-+                              int size = EXT2_XATTR_LEN(name_len);
-+                              last = ENTRY((char *)last - size);
-+                              memmove(here, (char*)here + size,
-+                                      (char*)last - (char*)here);
-+                              memset(last, 0, size);
-+                      }
-+              }
-+      }
-+
-+      if (value != NULL) {
-+              /* Insert the new value. */
-+              here->e_value_size = cpu_to_le32(value_len);
-+              if (value_len) {
-+                      size_t size = EXT2_XATTR_SIZE(value_len);
-+                      char *val = (char *)header + min_offs - size;
-+                      here->e_value_offs =
-+                              cpu_to_le16((char *)val - (char *)header);
-+                      memset(val + size - EXT2_XATTR_PAD, 0,
-+                             EXT2_XATTR_PAD); /* Clear the pad bytes. */
-+                      memcpy(val, value, value_len);
-+              }
-+      }
-+      ext2_xattr_rehash(header, here);
-+
-+      error = ext2_xattr_set2(inode, bh, header);
-+
-+cleanup:
-+      brelse(bh);
-+      if (!(bh && header == HDR(bh)))
-+              kfree(header);
-+      up(&ext2_xattr_sem);
-+
-+      return error;
-+}
-+
-+/*
-+ * Second half of ext2_xattr_set(): Update the file system.
-+ */
-+static int
-+ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
-+              struct ext2_xattr_header *header)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *new_bh = NULL;
-+      int error;
-+
-+      if (header) {
-+              new_bh = ext2_xattr_cache_find(inode, header);
-+              if (new_bh) {
-+                      /*
-+                       * We found an identical block in the cache.
-+                       * The old block will be released after updating
-+                       * the inode.
-+                       */
-+                      ea_bdebug(old_bh, "reusing block %ld",
-+                              new_bh->b_blocknr);
-+                      
-+                      error = -EDQUOT;
-+                      if (ext2_xattr_quota_alloc(inode, 1))
-+                              goto cleanup;
-+                      
-+                      HDR(new_bh)->h_refcount = cpu_to_le32(
-+                              le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
-+                      ea_bdebug(new_bh, "refcount now=%d",
-+                              le32_to_cpu(HDR(new_bh)->h_refcount));
-+              } else if (old_bh && header == HDR(old_bh)) {
-+                      /* Keep this block. */
-+                      new_bh = old_bh;
-+                      ext2_xattr_cache_insert(new_bh);
-+              } else {
-+                      /* We need to allocate a new block */
-+                      int force = EXT2_I(inode)->i_file_acl != 0;
-+                      int block = ext2_xattr_new_block(inode, &error, force);
-+                      if (error)
-+                              goto cleanup;
-+                      ea_idebug(inode, "creating block %d", block);
-+
-+                      new_bh = sb_getblk(sb, block);
-+                      if (!new_bh) {
-+                              ext2_xattr_free_block(inode, block);
-+                              error = -EIO;
-+                              goto cleanup;
-+                      }
-+                      lock_buffer(new_bh);
-+                      memcpy(new_bh->b_data, header, new_bh->b_size);
-+                      mark_buffer_uptodate(new_bh, 1);
-+                      unlock_buffer(new_bh);
-+                      ext2_xattr_cache_insert(new_bh);
-+                      
-+                      ext2_xattr_update_super_block(sb);
-+              }
-+              mark_buffer_dirty(new_bh);
-+              if (IS_SYNC(inode)) {
-+                      ll_rw_block(WRITE, 1, &new_bh);
-+                      wait_on_buffer(new_bh); 
-+                      error = -EIO;
-+                      if (buffer_req(new_bh) && !buffer_uptodate(new_bh))
-+                              goto cleanup;
-+              }
-+      }
-+
-+      /* Update the inode. */
-+      EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-+      inode->i_ctime = CURRENT_TIME;
-+      if (IS_SYNC(inode)) {
-+              error = ext2_sync_inode (inode);
-+              if (error)
-+                      goto cleanup;
-+      } else
-+              mark_inode_dirty(inode);
-+
-+      error = 0;
-+      if (old_bh && old_bh != new_bh) {
-+              /*
-+               * If there was an old block, and we are not still using it,
-+               * we now release the old block.
-+              */
-+              unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
-+
-+              if (refcount == 1) {
-+                      /* Free the old block. */
-+                      ea_bdebug(old_bh, "freeing");
-+                      ext2_xattr_free_block(inode, old_bh->b_blocknr);
-+                      mark_buffer_clean(old_bh);
-+              } else {
-+                      /* Decrement the refcount only. */
-+                      refcount--;
-+                      HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
-+                      ext2_xattr_quota_free(inode);
-+                      mark_buffer_dirty(old_bh);
-+                      ea_bdebug(old_bh, "refcount now=%d", refcount);
-+              }
-+      }
-+
-+cleanup:
-+      if (old_bh != new_bh)
-+              brelse(new_bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_delete_inode()
-+ *
-+ * Free extended attribute resources associated with this inode. This
-+ * is called immediately before an inode is freed.
-+ */
-+void
-+ext2_xattr_delete_inode(struct inode *inode)
-+{
-+      struct buffer_head *bh;
-+      unsigned int block = EXT2_I(inode)->i_file_acl;
-+
-+      if (!block)
-+              return;
-+      down(&ext2_xattr_sem);
-+
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh) {
-+              ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
-+                      "inode %ld: block %d read error", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+              ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+      if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-+              ext2_xattr_cache_remove(bh);
-+              ext2_xattr_free_block(inode, block);
-+              bforget(bh);
-+              bh = NULL;
-+      } else {
-+              HDR(bh)->h_refcount = cpu_to_le32(
-+                      le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+              mark_buffer_dirty(bh);
-+              if (IS_SYNC(inode)) {
-+                      ll_rw_block(WRITE, 1, &bh);
-+                      wait_on_buffer(bh);
-+              }
-+              ext2_xattr_quota_free(inode);
-+      }
-+      EXT2_I(inode)->i_file_acl = 0;
-+
-+cleanup:
-+      brelse(bh);
-+      up(&ext2_xattr_sem);
-+}
-+
-+/*
-+ * ext2_xattr_put_super()
-+ *
-+ * This is called when a file system is unmounted.
-+ */
-+void
-+ext2_xattr_put_super(struct super_block *sb)
-+{
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+      mb_cache_shrink(ext2_xattr_cache, sb->s_dev);
-+#endif
-+}
-+
-+#ifdef CONFIG_EXT2_FS_XATTR_SHARING
-+
-+/*
-+ * ext2_xattr_cache_insert()
-+ *
-+ * Create a new entry in the extended attribute cache, and insert
-+ * it unless such an entry is already in the cache.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+static int
-+ext2_xattr_cache_insert(struct buffer_head *bh)
-+{
-+      __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
-+      struct mb_cache_entry *ce;
-+      int error;
-+
-+      ce = mb_cache_entry_alloc(ext2_xattr_cache);
-+      if (!ce)
-+              return -ENOMEM;
-+      error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
-+      if (error) {
-+              mb_cache_entry_free(ce);
-+              if (error == -EBUSY) {
-+                      ea_bdebug(bh, "already in cache (%d cache entries)",
-+                              atomic_read(&ext2_xattr_cache->c_entry_count));
-+                      error = 0;
-+              }
-+      } else {
-+              ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-+                        atomic_read(&ext2_xattr_cache->c_entry_count));
-+              mb_cache_entry_release(ce);
-+      }
-+      return error;
-+}
-+
-+/*
-+ * ext2_xattr_cmp()
-+ *
-+ * Compare two extended attribute blocks for equality.
-+ *
-+ * Returns 0 if the blocks are equal, 1 if they differ, and
-+ * a negative error number on errors.
-+ */
-+static int
-+ext2_xattr_cmp(struct ext2_xattr_header *header1,
-+             struct ext2_xattr_header *header2)
-+{
-+      struct ext2_xattr_entry *entry1, *entry2;
-+
-+      entry1 = ENTRY(header1+1);
-+      entry2 = ENTRY(header2+1);
-+      while (!IS_LAST_ENTRY(entry1)) {
-+              if (IS_LAST_ENTRY(entry2))
-+                      return 1;
-+              if (entry1->e_hash != entry2->e_hash ||
-+                  entry1->e_name_len != entry2->e_name_len ||
-+                  entry1->e_value_size != entry2->e_value_size ||
-+                  memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
-+                      return 1;
-+              if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
-+                      return -EIO;
-+              if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
-+                         (char *)header2 + le16_to_cpu(entry2->e_value_offs),
-+                         le32_to_cpu(entry1->e_value_size)))
-+                      return 1;
-+
-+              entry1 = EXT2_XATTR_NEXT(entry1);
-+              entry2 = EXT2_XATTR_NEXT(entry2);
-+      }
-+      if (!IS_LAST_ENTRY(entry2))
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * ext2_xattr_cache_find()
-+ *
-+ * Find an identical extended attribute block.
-+ *
-+ * Returns a pointer to the block found, or NULL if such a block was
-+ * not found or an error occurred.
-+ */
-+static struct buffer_head *
-+ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header)
-+{
-+      __u32 hash = le32_to_cpu(header->h_hash);
-+      struct mb_cache_entry *ce;
-+
-+      if (!header->h_hash)
-+              return NULL;  /* never share */
-+      ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
-+      ce = mb_cache_entry_find_first(ext2_xattr_cache, 0, inode->i_dev, hash);
-+      while (ce) {
-+              struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
-+
-+              if (!bh) {
-+                      ext2_error(inode->i_sb, "ext2_xattr_cache_find",
-+                              "inode %ld: block %ld read error",
-+                              inode->i_ino, ce->e_block);
-+              } else if (le32_to_cpu(HDR(bh)->h_refcount) >
-+                         EXT2_XATTR_REFCOUNT_MAX) {
-+                      ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
-+                              le32_to_cpu(HDR(bh)->h_refcount),
-+                              EXT2_XATTR_REFCOUNT_MAX);
-+              } else if (!ext2_xattr_cmp(header, HDR(bh))) {
-+                      ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
-+                      mb_cache_entry_release(ce);
-+                      return bh;
-+              }
-+              brelse(bh);
-+              ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * ext2_xattr_cache_remove()
-+ *
-+ * Remove the cache entry of a block from the cache. Called when a
-+ * block becomes invalid.
-+ */
-+static void
-+ext2_xattr_cache_remove(struct buffer_head *bh)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_dev, bh->b_blocknr);
-+      if (ce) {
-+              ea_bdebug(bh, "removing (%d cache entries remaining)",
-+                        atomic_read(&ext2_xattr_cache->c_entry_count)-1);
-+              mb_cache_entry_free(ce);
-+      } else 
-+              ea_bdebug(bh, "no cache entry");
-+}
-+
-+#define NAME_HASH_SHIFT 5
-+#define VALUE_HASH_SHIFT 16
-+
-+/*
-+ * ext2_xattr_hash_entry()
-+ *
-+ * Compute the hash of an extended attribute.
-+ */
-+static inline void ext2_xattr_hash_entry(struct ext2_xattr_header *header,
-+                                       struct ext2_xattr_entry *entry)
-+{
-+      __u32 hash = 0;
-+      char *name = entry->e_name;
-+      int n;
-+
-+      for (n=0; n < entry->e_name_len; n++) {
-+              hash = (hash << NAME_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
-+                     *name++;
-+      }
-+
-+      if (entry->e_value_block == 0 && entry->e_value_size != 0) {
-+              __u32 *value = (__u32 *)((char *)header +
-+                      le16_to_cpu(entry->e_value_offs));
-+              for (n = (le32_to_cpu(entry->e_value_size) +
-+                   EXT2_XATTR_ROUND) >> EXT2_XATTR_PAD_BITS; n; n--) {
-+                      hash = (hash << VALUE_HASH_SHIFT) ^
-+                             (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
-+                             le32_to_cpu(*value++);
-+              }
-+      }
-+      entry->e_hash = cpu_to_le32(hash);
-+}
-+
-+#undef NAME_HASH_SHIFT
-+#undef VALUE_HASH_SHIFT
-+
-+#define BLOCK_HASH_SHIFT 16
-+
-+/*
-+ * ext2_xattr_rehash()
-+ *
-+ * Re-compute the extended attribute hash value after an entry has changed.
-+ */
-+static void ext2_xattr_rehash(struct ext2_xattr_header *header,
-+                            struct ext2_xattr_entry *entry)
-+{
-+      struct ext2_xattr_entry *here;
-+      __u32 hash = 0;
-+      
-+      ext2_xattr_hash_entry(header, entry);
-+      here = ENTRY(header+1);
-+      while (!IS_LAST_ENTRY(here)) {
-+              if (!here->e_hash) {
-+                      /* Block is not shared if an entry's hash value == 0 */
-+                      hash = 0;
-+                      break;
-+              }
-+              hash = (hash << BLOCK_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
-+                     le32_to_cpu(here->e_hash);
-+              here = EXT2_XATTR_NEXT(here);
-+      }
-+      header->h_hash = cpu_to_le32(hash);
-+}
-+
-+#undef BLOCK_HASH_SHIFT
-+
-+int __init
-+init_ext2_xattr(void)
-+{
-+      ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
-+              sizeof(struct mb_cache_entry) +
-+              sizeof(struct mb_cache_entry_index), 1, 61);
-+      if (!ext2_xattr_cache)
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+void
-+exit_ext2_xattr(void)
-+{
-+      mb_cache_destroy(ext2_xattr_cache);
-+}
-+
-+#else  /* CONFIG_EXT2_FS_XATTR_SHARING */
-+
-+int __init
-+init_ext2_xattr(void)
-+{
-+      return 0;
-+}
-+
-+void
-+exit_ext2_xattr(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT2_FS_XATTR_SHARING */
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext2/xattr_user.c    2003-04-08 15:11:04.000000000 +0800
-@@ -0,0 +1,103 @@
-+/*
-+ * linux/fs/ext2/xattr_user.c
-+ * Handler for extended user attributes.
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/fs.h>
-+#include <linux/ext2_fs.h>
-+#include <linux/ext2_xattr.h>
-+
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+# include <linux/ext2_acl.h>
-+#endif
-+
-+#define XATTR_USER_PREFIX "user."
-+
-+static size_t
-+ext2_xattr_user_list(char *list, struct inode *inode,
-+                   const char *name, int name_len)
-+{
-+      const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
-+
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return 0;
-+
-+      if (list) {
-+              memcpy(list, XATTR_USER_PREFIX, prefix_len);
-+              memcpy(list+prefix_len, name, name_len);
-+              list[prefix_len + name_len] = '\0';
-+      }
-+      return prefix_len + name_len + 1;
-+}
-+
-+static int
-+ext2_xattr_user_get(struct inode *inode, const char *name,
-+                  void *buffer, size_t size)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+      error = ext2_permission_locked(inode, MAY_READ);
-+#else
-+      error = permission(inode, MAY_READ);
-+#endif
-+      if (error)
-+              return error;
-+
-+      return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name,
-+                            buffer, size);
-+}
-+
-+static int
-+ext2_xattr_user_set(struct inode *inode, const char *name,
-+                  const void *value, size_t size, int flags)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+      if ( !S_ISREG(inode->i_mode) &&
-+          (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-+              return -EPERM;
-+#ifdef CONFIG_EXT2_FS_POSIX_ACL
-+      error = ext2_permission_locked(inode, MAY_WRITE);
-+#else
-+      error = permission(inode, MAY_WRITE);
-+#endif
-+      if (error)
-+              return error;
-+  
-+      return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
-+                            value, size, flags);
-+}
-+
-+struct ext2_xattr_handler ext2_xattr_user_handler = {
-+      prefix: XATTR_USER_PREFIX,
-+      list:   ext2_xattr_user_list,
-+      get:    ext2_xattr_user_get,
-+      set:    ext2_xattr_user_set,
-+};
-+
-+int __init
-+init_ext2_xattr_user(void)
-+{
-+      return ext2_xattr_register(EXT2_XATTR_INDEX_USER,
-+                                 &ext2_xattr_user_handler);
-+}
-+
-+void
-+exit_ext2_xattr_user(void)
-+{
-+      ext2_xattr_unregister(EXT2_XATTR_INDEX_USER,
-+                            &ext2_xattr_user_handler);
-+}
---- linux-2.4.20/fs/ext3/Makefile~linux-2.4.20-xattr-0.8.54    2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext3/Makefile        2003-04-08 15:11:44.000000000 +0800
-@@ -1,5 +1,5 @@
- #
--# Makefile for the linux ext2-filesystem routines.
-+# Makefile for the linux ext3-filesystem routines.
- #
- # Note! Dependencies are done automagically by 'make dep', which also
- # removes any old dependencies. DON'T put your own dependencies here
-@@ -15,4 +15,8 @@ obj-y    := balloc.o bitmap.o dir.o file
-               ioctl.o namei.o super.o symlink.o hash.o
- obj-m    := $(O_TARGET)
-+export-objs += xattr.o
-+obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o
-+obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o
-+
- include $(TOPDIR)/Rules.make
---- linux-2.4.20/fs/ext3/file.c~linux-2.4.20-xattr-0.8.54      2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext3/file.c  2003-04-08 15:11:04.000000000 +0800
-@@ -23,6 +23,7 @@
- #include <linux/locks.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/ext3_jbd.h>
- #include <linux/smp_lock.h>
-@@ -126,5 +127,9 @@ struct file_operations ext3_file_operati
- struct inode_operations ext3_file_inode_operations = {
-       truncate:       ext3_truncate,          /* BKL held */
-       setattr:        ext3_setattr,           /* BKL held */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
---- linux-2.4.20/fs/ext3/ialloc.c~linux-2.4.20-xattr-0.8.54    2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext3/ialloc.c        2003-04-08 15:11:04.000000000 +0800
-@@ -17,6 +17,7 @@
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/stat.h>
- #include <linux/string.h>
- #include <linux/locks.h>
-@@ -216,6 +217,7 @@ void ext3_free_inode (handle_t *handle, 
-        * as writing the quota to disk may need the lock as well.
-        */
-       DQUOT_INIT(inode);
-+      ext3_xattr_delete_inode(handle, inode);
-       DQUOT_FREE_INODE(inode);
-       DQUOT_DROP(inode);
---- linux-2.4.20/fs/ext3/inode.c~linux-2.4.20-xattr-0.8.54     2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext3/inode.c 2003-04-08 15:11:05.000000000 +0800
-@@ -39,6 +39,18 @@
-  */
- #undef SEARCH_FROM_ZERO
-+/*
-+ * Test whether an inode is a fast symlink.
-+ */
-+static inline int ext3_inode_is_fast_symlink(struct inode *inode)
-+{
-+      int ea_blocks = inode->u.ext3_i.i_file_acl ?
-+              (inode->i_sb->s_blocksize >> 9) : 0;
-+
-+      return (S_ISLNK(inode->i_mode) &&
-+              inode->i_blocks - ea_blocks == 0);
-+}
-+
- /* The ext3 forget function must perform a revoke if we are freeing data
-  * which has been journaled.  Metadata (eg. indirect blocks) must be
-  * revoked in all cases. 
-@@ -48,7 +60,7 @@
-  * still needs to be revoked.
-  */
--static int ext3_forget(handle_t *handle, int is_metadata,
-+int ext3_forget(handle_t *handle, int is_metadata,
-                      struct inode *inode, struct buffer_head *bh,
-                      int blocknr)
- {
-@@ -164,9 +176,7 @@ void ext3_delete_inode (struct inode * i
- {
-       handle_t *handle;
-       
--      if (is_bad_inode(inode) ||
--          inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
-+      if (is_bad_inode(inode))
-               goto no_delete;
-       lock_kernel();
-@@ -1855,6 +1865,8 @@ void ext3_truncate(struct inode * inode)
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-+      if (ext3_inode_is_fast_symlink(inode))
-+              return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-@@ -2002,8 +2014,6 @@ int ext3_get_inode_loc (struct inode *in
-       struct ext3_group_desc * gdp;
-               
-       if ((inode->i_ino != EXT3_ROOT_INO &&
--              inode->i_ino != EXT3_ACL_IDX_INO &&
--              inode->i_ino != EXT3_ACL_DATA_INO &&
-               inode->i_ino != EXT3_JOURNAL_INO &&
-               inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
-               inode->i_ino > le32_to_cpu(
-@@ -2130,10 +2140,7 @@ void ext3_read_inode(struct inode * inod
-       brelse (iloc.bh);
--      if (inode->i_ino == EXT3_ACL_IDX_INO ||
--          inode->i_ino == EXT3_ACL_DATA_INO)
--              /* Nothing to do */ ;
--      else if (S_ISREG(inode->i_mode)) {
-+      if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &ext3_file_inode_operations;
-               inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-@@ -2141,15 +2148,17 @@ void ext3_read_inode(struct inode * inod
-               inode->i_op = &ext3_dir_inode_operations;
-               inode->i_fop = &ext3_dir_operations;
-       } else if (S_ISLNK(inode->i_mode)) {
--              if (!inode->i_blocks)
-+              if (ext3_inode_is_fast_symlink(inode))
-                       inode->i_op = &ext3_fast_symlink_inode_operations;
-               else {
--                      inode->i_op = &page_symlink_inode_operations;
-+                      inode->i_op = &ext3_symlink_inode_operations;
-                       inode->i_mapping->a_ops = &ext3_aops;
-               }
--      } else 
-+      } else {
-+              inode->i_op = &ext3_special_inode_operations;
-               init_special_inode(inode, inode->i_mode,
-                                  le32_to_cpu(iloc.raw_inode->i_block[0]));
-+      }
-       /* inode->i_attr_flags = 0;                             unused */
-       if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) {
-               /* inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS; unused */
---- linux-2.4.20/fs/ext3/namei.c~linux-2.4.20-xattr-0.8.54     2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext3/namei.c 2003-04-08 15:11:05.000000000 +0800
-@@ -29,6 +29,7 @@
- #include <linux/sched.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/fcntl.h>
- #include <linux/stat.h>
- #include <linux/string.h>
-@@ -1611,7 +1612,7 @@ static int ext3_mkdir(struct inode * dir
-       if (IS_SYNC(dir))
-               handle->h_sync = 1;
--      inode = ext3_new_inode (handle, dir, S_IFDIR);
-+      inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
-       err = PTR_ERR(inode);
-       if (IS_ERR(inode))
-               goto out_stop;
-@@ -1619,7 +1620,6 @@ static int ext3_mkdir(struct inode * dir
-       inode->i_op = &ext3_dir_inode_operations;
-       inode->i_fop = &ext3_dir_operations;
-       inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
--      inode->i_blocks = 0;    
-       dir_block = ext3_bread (handle, inode, 0, 1, &err);
-       if (!dir_block) {
-               inode->i_nlink--; /* is this nlink == 0? */
-@@ -1646,9 +1646,6 @@ static int ext3_mkdir(struct inode * dir
-       BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
-       ext3_journal_dirty_metadata(handle, dir_block);
-       brelse (dir_block);
--      inode->i_mode = S_IFDIR | mode;
--      if (dir->i_mode & S_ISGID)
--              inode->i_mode |= S_ISGID;
-       ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_entry (handle, dentry, inode);
-       if (err) {
-@@ -2017,7 +2014,7 @@ static int ext3_symlink (struct inode * 
-               goto out_stop;
-       if (l > sizeof (EXT3_I(inode)->i_data)) {
--              inode->i_op = &page_symlink_inode_operations;
-+              inode->i_op = &ext3_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
-               /*
-                * block_symlink() calls back into ext3_prepare/commit_write.
-@@ -2244,4 +2241,16 @@ struct inode_operations ext3_dir_inode_o
-       rmdir:          ext3_rmdir,             /* BKL held */
-       mknod:          ext3_mknod,             /* BKL held */
-       rename:         ext3_rename,            /* BKL held */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
-+
-+struct inode_operations ext3_special_inode_operations = {
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
-+};
-+
---- linux-2.4.20/fs/ext3/super.c~linux-2.4.20-xattr-0.8.54     2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext3/super.c 2003-04-08 15:11:05.000000000 +0800
-@@ -24,6 +24,7 @@
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
- #include <linux/ext3_jbd.h>
-+#include <linux/ext3_xattr.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/locks.h>
-@@ -404,6 +405,7 @@ void ext3_put_super (struct super_block 
-       kdev_t j_dev = sbi->s_journal->j_dev;
-       int i;
-+      ext3_xattr_put_super(sb);
-       journal_destroy(sbi->s_journal);
-       if (!(sb->s_flags & MS_RDONLY)) {
-               EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
-@@ -499,6 +501,7 @@ static int parse_options (char * options
-                         int is_remount)
- {
-       unsigned long *mount_options = &sbi->s_mount_opt;
-+      
-       uid_t *resuid = &sbi->s_resuid;
-       gid_t *resgid = &sbi->s_resgid;
-       char * this_char;
-@@ -511,6 +514,13 @@ static int parse_options (char * options
-            this_char = strtok (NULL, ",")) {
-               if ((value = strchr (this_char, '=')) != NULL)
-                       *value++ = 0;
-+#ifdef CONFIG_EXT3_FS_XATTR_USER
-+              if (!strcmp (this_char, "user_xattr"))
-+                      set_opt (*mount_options, XATTR_USER);
-+              else if (!strcmp (this_char, "nouser_xattr"))
-+                      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")) {
-@@ -928,6 +938,12 @@ struct super_block * ext3_read_super (st
-       sbi->s_mount_opt = 0;
-       sbi->s_resuid = EXT3_DEF_RESUID;
-       sbi->s_resgid = EXT3_DEF_RESGID;
-+
-+      /* Default extended attribute flags */
-+#ifdef CONFIG_EXT3_FS_XATTR_USER
-+      /* set_opt(sbi->s_mount_opt, XATTR_USER); */
-+#endif
-+
-       if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) {
-               sb->s_dev = 0;
-               goto out_fail;
-@@ -1767,12 +1783,27 @@ static DECLARE_FSTYPE_DEV(ext3_fs_type, 
- static int __init init_ext3_fs(void)
- {
--        return register_filesystem(&ext3_fs_type);
-+      int error = init_ext3_xattr();
-+      if (error)
-+              return error;
-+      error = init_ext3_xattr_user();
-+      if (error)
-+              goto fail;
-+      error = register_filesystem(&ext3_fs_type);
-+      if (!error)
-+              return 0;
-+      
-+      exit_ext3_xattr_user();
-+fail:
-+      exit_ext3_xattr();
-+      return error;
- }
- static void __exit exit_ext3_fs(void)
- {
-       unregister_filesystem(&ext3_fs_type);
-+      exit_ext3_xattr_user();
-+      exit_ext3_xattr();
- }
- EXPORT_SYMBOL(ext3_force_commit);
---- linux-2.4.20/fs/ext3/symlink.c~linux-2.4.20-xattr-0.8.54   2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext3/symlink.c       2003-04-08 15:11:05.000000000 +0800
-@@ -20,6 +20,7 @@
- #include <linux/fs.h>
- #include <linux/jbd.h>
- #include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
- static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
-@@ -33,7 +34,20 @@ static int ext3_follow_link(struct dentr
-       return vfs_follow_link(nd, s);
- }
-+struct inode_operations ext3_symlink_inode_operations = {
-+      readlink:       page_readlink,          /* BKL not held.  Don't need */
-+      follow_link:    page_follow_link,       /* BKL not held.  Don't need */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
-+};
-+
- struct inode_operations ext3_fast_symlink_inode_operations = {
-       readlink:       ext3_readlink,          /* BKL not held.  Don't need */
-       follow_link:    ext3_follow_link,       /* BKL not held.  Don't need */
-+      setxattr:       ext3_setxattr,          /* BKL held */
-+      getxattr:       ext3_getxattr,          /* BKL held */
-+      listxattr:      ext3_listxattr,         /* BKL held */
-+      removexattr:    ext3_removexattr,       /* BKL held */
- };
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext3/xattr.c 2003-04-08 15:11:05.000000000 +0800
-@@ -0,0 +1,1232 @@
-+/*
-+ * linux/fs/ext3/xattr.c
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
-+ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
-+ * Extended attributes for symlinks and special files added per
-+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
-+ */
-+
-+/*
-+ * Extended attributes are stored on disk blocks allocated outside of
-+ * any inode. The i_file_acl field is then made to point to this allocated
-+ * block. If all extended attributes of an inode are identical, these
-+ * inodes may share the same extended attribute block. Such situations
-+ * are automatically detected by keeping a cache of recent attribute block
-+ * numbers and hashes over the block's contents in memory.
-+ *
-+ *
-+ * Extended attribute block layout:
-+ *
-+ *   +------------------+
-+ *   | header           |
-+ *   | entry 1          | |
-+ *   | entry 2          | | growing downwards
-+ *   | entry 3          | v
-+ *   | four null bytes  |
-+ *   | . . .            |
-+ *   | value 1          | ^
-+ *   | value 3          | | growing upwards
-+ *   | value 2          | |
-+ *   +------------------+
-+ *
-+ * The block header is followed by multiple entry descriptors. These entry
-+ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
-+ * byte boundaries. The entry descriptors are sorted by attribute name,
-+ * so that two extended attribute blocks can be compared efficiently.
-+ *
-+ * Attribute values are aligned to the end of the block, stored in
-+ * no specific order. They are also padded to EXT3_XATTR_PAD byte
-+ * boundaries. No additional gaps are left between them.
-+ *
-+ * Locking strategy
-+ * ----------------
-+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
-+ * the xattr inode operations are called, so we are guaranteed that only one
-+ * processes accesses extended attributes of an inode at any time.
-+ *
-+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
-+ * only a single process is modifying an extended attribute block, even
-+ * if the block is shared among inodes.
-+ *
-+ * Note for porting to 2.5
-+ * -----------------------
-+ * The BKL will no longer be held in the xattr inode operations.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/locks.h>
-+#include <linux/slab.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
-+#include <linux/mbcache.h>
-+#include <linux/quotaops.h>
-+#include <asm/semaphore.h>
-+#include <linux/compatmac.h>
-+
-+#define EXT3_EA_USER "user."
-+
-+/* These symbols may be needed by a module. */
-+EXPORT_SYMBOL(ext3_xattr_register);
-+EXPORT_SYMBOL(ext3_xattr_unregister);
-+EXPORT_SYMBOL(ext3_xattr_get);
-+EXPORT_SYMBOL(ext3_xattr_list);
-+EXPORT_SYMBOL(ext3_xattr_set);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
-+#endif
-+
-+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
-+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
-+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
-+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
-+
-+#ifdef EXT3_XATTR_DEBUG
-+# define ea_idebug(inode, f...) do { \
-+              printk(KERN_DEBUG "inode %s:%ld: ", \
-+                      kdevname(inode->i_dev), inode->i_ino); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+# define ea_bdebug(bh, f...) do { \
-+              printk(KERN_DEBUG "block %s:%ld: ", \
-+                      kdevname(bh->b_dev), bh->b_blocknr); \
-+              printk(f); \
-+              printk("\n"); \
-+      } while (0)
-+#else
-+# define ea_idebug(f...)
-+# define ea_bdebug(f...)
-+#endif
-+
-+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
-+                         struct ext3_xattr_header *);
-+
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+
-+static int ext3_xattr_cache_insert(struct buffer_head *);
-+static struct buffer_head *ext3_xattr_cache_find(struct inode *,
-+                                               struct ext3_xattr_header *);
-+static void ext3_xattr_cache_remove(struct buffer_head *);
-+static void ext3_xattr_rehash(struct ext3_xattr_header *,
-+                            struct ext3_xattr_entry *);
-+
-+static struct mb_cache *ext3_xattr_cache;
-+
-+#else
-+# define ext3_xattr_cache_insert(bh) 0
-+# define ext3_xattr_cache_find(inode, header) NULL
-+# define ext3_xattr_cache_remove(bh) while(0) {}
-+# define ext3_xattr_rehash(header, entry) while(0) {}
-+#endif
-+
-+/*
-+ * If a file system does not share extended attributes among inodes,
-+ * we should not need the ext3_xattr_sem semaphore. However, the
-+ * filesystem may still contain shared blocks, so we always take
-+ * the lock.
-+ */
-+
-+DECLARE_MUTEX(ext3_xattr_sem);
-+
-+static inline int
-+ext3_xattr_new_block(handle_t *handle, struct inode *inode,
-+                   int * errp, int force)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
-+              EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb);
-+
-+      /* How can we enforce the allocation? */
-+      int block = ext3_new_block(handle, inode, goal, 0, 0, errp);
-+#ifdef OLD_QUOTAS
-+      if (!*errp)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#endif
-+      return block;
-+}
-+
-+static inline int
-+ext3_xattr_quota_alloc(struct inode *inode, int force)
-+{
-+      /* How can we enforce the allocation? */
-+#ifdef OLD_QUOTAS
-+      int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
-+      if (!error)
-+              inode->i_blocks += inode->i_sb->s_blocksize >> 9;
-+#else
-+      int error = DQUOT_ALLOC_BLOCK(inode, 1);
-+#endif
-+      return error;
-+}
-+
-+#ifdef OLD_QUOTAS
-+
-+static inline void
-+ext3_xattr_quota_free(struct inode *inode)
-+{
-+      DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+static inline void
-+ext3_xattr_free_block(handle_t *handle, struct inode * inode,
-+                    unsigned long block)
-+{
-+      ext3_free_blocks(handle, inode, block, 1);
-+      inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
-+}
-+
-+#else
-+# define ext3_xattr_quota_free(inode) \
-+      DQUOT_FREE_BLOCK(inode, 1)
-+# define ext3_xattr_free_block(handle, inode, block) \
-+      ext3_free_blocks(handle, inode, block, 1)
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
-+
-+static inline struct buffer_head *
-+sb_bread(struct super_block *sb, int block)
-+{
-+      return bread(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+static inline struct buffer_head *
-+sb_getblk(struct super_block *sb, int block)
-+{
-+      return getblk(sb->s_dev, block, sb->s_blocksize);
-+}
-+
-+#endif
-+
-+struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
-+rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
-+
-+int
-+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      int error = -EINVAL;
-+
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              if (!ext3_xattr_handlers[name_index-1]) {
-+                      ext3_xattr_handlers[name_index-1] = handler;
-+                      error = 0;
-+              }
-+              write_unlock(&ext3_handler_lock);
-+      }
-+      return error;
-+}
-+
-+void
-+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
-+{
-+      if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
-+              write_lock(&ext3_handler_lock);
-+              ext3_xattr_handlers[name_index-1] = NULL;
-+              write_unlock(&ext3_handler_lock);
-+      }
-+}
-+
-+static inline const char *
-+strcmp_prefix(const char *a, const char *a_prefix)
-+{
-+      while (*a_prefix && *a == *a_prefix) {
-+              a++;
-+              a_prefix++;
-+      }
-+      return *a_prefix ? NULL : a;
-+}
-+
-+/*
-+ * Decode the extended attribute name, and translate it into
-+ * the name_index and name suffix.
-+ */
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_resolve_name(const char **name)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      int i;
-+
-+      if (!*name)
-+              return NULL;
-+      read_lock(&ext3_handler_lock);
-+      for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
-+              if (ext3_xattr_handlers[i]) {
-+                      const char *n = strcmp_prefix(*name,
-+                              ext3_xattr_handlers[i]->prefix);
-+                      if (n) {
-+                              handler = ext3_xattr_handlers[i];
-+                              *name = n;
-+                              break;
-+                      }
-+              }
-+      }
-+      read_unlock(&ext3_handler_lock);
-+      return handler;
-+}
-+
-+static inline struct ext3_xattr_handler *
-+ext3_xattr_handler(int name_index)
-+{
-+      struct ext3_xattr_handler *handler = NULL;
-+      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
-+              read_lock(&ext3_handler_lock);
-+              handler = ext3_xattr_handlers[name_index-1];
-+              read_unlock(&ext3_handler_lock);
-+      }
-+      return handler;
-+}
-+
-+/*
-+ * Inode operation getxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext3_getxattr(struct dentry *dentry, const char *name,
-+            void *buffer, size_t size)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->get(inode, name, buffer, size);
-+}
-+
-+/*
-+ * Inode operation listxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+ssize_t
-+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
-+{
-+      return ext3_xattr_list(dentry->d_inode, buffer, size);
-+}
-+
-+/*
-+ * Inode operation setxattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext3_setxattr(struct dentry *dentry, const char *name,
-+            const void *value, size_t size, int flags)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      if (size == 0)
-+              value = "";  /* empty EA, do not remove */
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, value, size, flags);
-+}
-+
-+/*
-+ * Inode operation removexattr()
-+ *
-+ * dentry->d_inode->i_sem down
-+ * BKL held [before 2.5.x]
-+ */
-+int
-+ext3_removexattr(struct dentry *dentry, const char *name)
-+{
-+      struct ext3_xattr_handler *handler;
-+      struct inode *inode = dentry->d_inode;
-+
-+      handler = ext3_xattr_resolve_name(&name);
-+      if (!handler)
-+              return -ENOTSUP;
-+      return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
-+}
-+
-+/*
-+ * ext3_xattr_get()
-+ *
-+ * Copy an extended attribute into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size;
-+      char *end;
-+      int name_len, error;
-+
-+      ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
-+                name_index, name, buffer, (long)buffer_size);
-+
-+      if (name == NULL)
-+              return -EINVAL;
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return -ENOATTR;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_get",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* find named attribute */
-+      name_len = strlen(name);
-+
-+      error = -ERANGE;
-+      if (name_len > 255)
-+              goto cleanup;
-+      entry = FIRST_ENTRY(bh);
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              if (name_index == entry->e_name_index &&
-+                  name_len == entry->e_name_len &&
-+                  memcmp(name, entry->e_name, name_len) == 0)
-+                      goto found;
-+              entry = next;
-+      }
-+      /* Check the remaining name entries */
-+      while (!IS_LAST_ENTRY(entry)) {
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+              entry = next;
-+      }
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      error = -ENOATTR;
-+      goto cleanup;
-+found:
-+      /* check the buffer size */
-+      if (entry->e_value_block != 0)
-+              goto bad_block;
-+      size = le32_to_cpu(entry->e_value_size);
-+      if (size > inode->i_sb->s_blocksize ||
-+          le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-+              goto bad_block;
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (buffer) {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+              /* return value of attribute */
-+              memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-+                      size);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_list()
-+ *
-+ * Copy a list of attribute names into the buffer
-+ * provided, or compute the buffer size required.
-+ * Buffer is NULL to compute the size of the buffer required.
-+ *
-+ * Returns a negative error number on failure, or the number of bytes
-+ * used / required on success.
-+ */
-+int
-+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
-+{
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_entry *entry;
-+      unsigned int block, size = 0;
-+      char *buf, *end;
-+      int error;
-+
-+      ea_idebug(inode, "buffer=%p, buffer_size=%ld",
-+                buffer, (long)buffer_size);
-+
-+      if (!EXT3_I(inode)->i_file_acl)
-+              return 0;
-+      block = EXT3_I(inode)->i_file_acl;
-+      ea_idebug(inode, "reading block %d", block);
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh)
-+              return -EIO;
-+      ea_bdebug(bh, "b_count=%d, refcount=%d",
-+              atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-+      end = bh->b_data + bh->b_size;
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+bad_block:    ext3_error(inode->i_sb, "ext3_xattr_list",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              error = -EIO;
-+              goto cleanup;
-+      }
-+      /* compute the size required for the list of attribute names */
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+              struct ext3_xattr_entry *next =
-+                      EXT3_XATTR_NEXT(entry);
-+              if ((char *)next >= end)
-+                      goto bad_block;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      size += handler->list(NULL, inode, entry->e_name,
-+                                            entry->e_name_len);
-+      }
-+
-+      if (ext3_xattr_cache_insert(bh))
-+              ea_idebug(inode, "cache insert failed");
-+      if (!buffer) {
-+              error = size;
-+              goto cleanup;
-+      } else {
-+              error = -ERANGE;
-+              if (size > buffer_size)
-+                      goto cleanup;
-+      }
-+
-+      /* list the attribute names */
-+      buf = buffer;
-+      for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-+           entry = EXT3_XATTR_NEXT(entry)) {
-+              struct ext3_xattr_handler *handler;
-+
-+              handler = ext3_xattr_handler(entry->e_name_index);
-+              if (handler)
-+                      buf += handler->list(buf, inode, entry->e_name,
-+                                           entry->e_name_len);
-+      }
-+      error = size;
-+
-+cleanup:
-+      brelse(bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
-+ * not set, set it.
-+ */
-+static void ext3_xattr_update_super_block(handle_t *handle,
-+                                        struct super_block *sb)
-+{
-+      if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
-+              return;
-+
-+      lock_super(sb);
-+      ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+      EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR;
-+#endif
-+      EXT3_SB(sb)->s_es->s_feature_compat |=
-+              cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
-+      sb->s_dirt = 1;
-+      ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-+      unlock_super(sb);
-+}
-+
-+/*
-+ * ext3_xattr_set()
-+ *
-+ * Create, replace or remove an extended attribute for this inode. Buffer
-+ * is NULL to remove an existing extended attribute, and non-NULL to
-+ * either replace an existing extended attribute, or create a new extended
-+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
-+ * specify that an extended attribute must exist and must not exist
-+ * previous to the call, respectively.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, const void *value, size_t value_len, int flags)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *bh = NULL;
-+      struct ext3_xattr_header *header = NULL;
-+      struct ext3_xattr_entry *here, *last;
-+      unsigned int name_len;
-+      int block = EXT3_I(inode)->i_file_acl;
-+      int min_offs = sb->s_blocksize, not_found = 1, free, error;
-+      char *end;
-+      
-+      /*
-+       * header -- Points either into bh, or to a temporarily
-+       *           allocated buffer.
-+       * here -- The named entry found, or the place for inserting, within
-+       *         the block pointed to by header.
-+       * last -- Points right after the last named entry within the block
-+       *         pointed to by header.
-+       * min_offs -- The offset of the first value (values are aligned
-+       *             towards the end of the block).
-+       * end -- Points right after the block pointed to by header.
-+       */
-+      
-+      ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-+                name_index, name, value, (long)value_len);
-+
-+      if (IS_RDONLY(inode))
-+              return -EROFS;
-+      if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-+              return -EPERM;
-+      if (value == NULL)
-+              value_len = 0;
-+      if (name == NULL)
-+              return -EINVAL;
-+      name_len = strlen(name);
-+      if (name_len > 255 || value_len > sb->s_blocksize)
-+              return -ERANGE;
-+      down(&ext3_xattr_sem);
-+
-+      if (block) {
-+              /* The inode already has an extended attribute block. */
-+              bh = sb_bread(sb, block);
-+              error = -EIO;
-+              if (!bh)
-+                      goto cleanup;
-+              ea_bdebug(bh, "b_count=%d, refcount=%d",
-+                      atomic_read(&(bh->b_count)),
-+                      le32_to_cpu(HDR(bh)->h_refcount));
-+              header = HDR(bh);
-+              end = bh->b_data + bh->b_size;
-+              if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+                  header->h_blocks != cpu_to_le32(1)) {
-+bad_block:            ext3_error(sb, "ext3_xattr_set",
-+                              "inode %ld: bad block %d", inode->i_ino, block);
-+                      error = -EIO;
-+                      goto cleanup;
-+              }
-+              /* Find the named attribute. */
-+              here = FIRST_ENTRY(bh);
-+              while (!IS_LAST_ENTRY(here)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!here->e_value_block && here->e_value_size) {
-+                              int offs = le16_to_cpu(here->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      not_found = name_index - here->e_name_index;
-+                      if (!not_found)
-+                              not_found = name_len - here->e_name_len;
-+                      if (!not_found)
-+                              not_found = memcmp(name, here->e_name,name_len);
-+                      if (not_found <= 0)
-+                              break;
-+                      here = next;
-+              }
-+              last = here;
-+              /* We still need to compute min_offs and last. */
-+              while (!IS_LAST_ENTRY(last)) {
-+                      struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
-+                      if ((char *)next >= end)
-+                              goto bad_block;
-+                      if (!last->e_value_block && last->e_value_size) {
-+                              int offs = le16_to_cpu(last->e_value_offs);
-+                              if (offs < min_offs)
-+                                      min_offs = offs;
-+                      }
-+                      last = next;
-+              }
-+
-+              /* Check whether we have enough space left. */
-+              free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-+      } else {
-+              /* We will use a new extended attribute block. */
-+              free = sb->s_blocksize -
-+                      sizeof(struct ext3_xattr_header) - sizeof(__u32);
-+              here = last = NULL;  /* avoid gcc uninitialized warning. */
-+      }
-+
-+      if (not_found) {
-+              /* Request to remove a nonexistent attribute? */
-+              error = -ENOATTR;
-+              if (flags & XATTR_REPLACE)
-+                      goto cleanup;
-+              error = 0;
-+              if (value == NULL)
-+                      goto cleanup;
-+              else
-+                      free -= EXT3_XATTR_LEN(name_len);
-+      } else {
-+              /* Request to create an existing attribute? */
-+              error = -EEXIST;
-+              if (flags & XATTR_CREATE)
-+                      goto cleanup;
-+              if (!here->e_value_block && here->e_value_size) {
-+                      unsigned int size = le32_to_cpu(here->e_value_size);
-+
-+                      if (le16_to_cpu(here->e_value_offs) + size > 
-+                          sb->s_blocksize || size > sb->s_blocksize)
-+                              goto bad_block;
-+                      free += EXT3_XATTR_SIZE(size);
-+              }
-+      }
-+      free -= EXT3_XATTR_SIZE(value_len);
-+      error = -ENOSPC;
-+      if (free < 0)
-+              goto cleanup;
-+
-+      /* Here we know that we can set the new attribute. */
-+
-+      if (header) {
-+              if (header->h_refcount == cpu_to_le32(1)) {
-+                      ea_bdebug(bh, "modifying in-place");
-+                      ext3_xattr_cache_remove(bh);
-+                      error = ext3_journal_get_write_access(handle, bh);
-+                      if (error)
-+                              goto cleanup;
-+              } else {
-+                      int offset;
-+
-+                      ea_bdebug(bh, "cloning");
-+                      header = kmalloc(bh->b_size, GFP_KERNEL);
-+                      error = -ENOMEM;
-+                      if (header == NULL)
-+                              goto cleanup;
-+                      memcpy(header, HDR(bh), bh->b_size);
-+                      header->h_refcount = cpu_to_le32(1);
-+                      offset = (char *)header - bh->b_data;
-+                      here = ENTRY((char *)here + offset);
-+                      last = ENTRY((char *)last + offset);
-+              }
-+      } else {
-+              /* Allocate a buffer where we construct the new block. */
-+              header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-+              error = -ENOMEM;
-+              if (header == NULL)
-+                      goto cleanup;
-+              memset(header, 0, sb->s_blocksize);
-+              end = (char *)header + sb->s_blocksize;
-+              header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
-+              header->h_blocks = header->h_refcount = cpu_to_le32(1);
-+              last = here = ENTRY(header+1);
-+      }
-+
-+      if (not_found) {
-+              /* Insert the new name. */
-+              int size = EXT3_XATTR_LEN(name_len);
-+              int rest = (char *)last - (char *)here;
-+              memmove((char *)here + size, here, rest);
-+              memset(here, 0, size);
-+              here->e_name_index = name_index;
-+              here->e_name_len = name_len;
-+              memcpy(here->e_name, name, name_len);
-+      } else {
-+              /* Remove the old value. */
-+              if (!here->e_value_block && here->e_value_size) {
-+                      char *first_val = (char *)header + min_offs;
-+                      int offs = le16_to_cpu(here->e_value_offs);
-+                      char *val = (char *)header + offs;
-+                      size_t size = EXT3_XATTR_SIZE(
-+                              le32_to_cpu(here->e_value_size));
-+                      memmove(first_val + size, first_val, val - first_val);
-+                      memset(first_val, 0, size);
-+                      here->e_value_offs = 0;
-+                      min_offs += size;
-+
-+                      /* Adjust all value offsets. */
-+                      last = ENTRY(header+1);
-+                      while (!IS_LAST_ENTRY(last)) {
-+                              int o = le16_to_cpu(last->e_value_offs);
-+                              if (!last->e_value_block && o < offs)
-+                                      last->e_value_offs =
-+                                              cpu_to_le16(o + size);
-+                              last = EXT3_XATTR_NEXT(last);
-+                      }
-+              }
-+              if (value == NULL) {
-+                      /* Remove this attribute. */
-+                      if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
-+                              /* This block is now empty. */
-+                              error = ext3_xattr_set2(handle, inode, bh,NULL);
-+                              goto cleanup;
-+                      } else {
-+                              /* Remove the old name. */
-+                              int size = EXT3_XATTR_LEN(name_len);
-+                              last = ENTRY((char *)last - size);
-+                              memmove(here, (char*)here + size,
-+                                      (char*)last - (char*)here);
-+                              memset(last, 0, size);
-+                      }
-+              }
-+      }
-+
-+      if (value != NULL) {
-+              /* Insert the new value. */
-+              here->e_value_size = cpu_to_le32(value_len);
-+              if (value_len) {
-+                      size_t size = EXT3_XATTR_SIZE(value_len);
-+                      char *val = (char *)header + min_offs - size;
-+                      here->e_value_offs =
-+                              cpu_to_le16((char *)val - (char *)header);
-+                      memset(val + size - EXT3_XATTR_PAD, 0,
-+                             EXT3_XATTR_PAD); /* Clear the pad bytes. */
-+                      memcpy(val, value, value_len);
-+              }
-+      }
-+      ext3_xattr_rehash(header, here);
-+
-+      error = ext3_xattr_set2(handle, inode, bh, header);
-+
-+cleanup:
-+      brelse(bh);
-+      if (!(bh && header == HDR(bh)))
-+              kfree(header);
-+      up(&ext3_xattr_sem);
-+
-+      return error;
-+}
-+
-+/*
-+ * Second half of ext3_xattr_set(): Update the file system.
-+ */
-+static int
-+ext3_xattr_set2(handle_t *handle, struct inode *inode,
-+              struct buffer_head *old_bh, struct ext3_xattr_header *header)
-+{
-+      struct super_block *sb = inode->i_sb;
-+      struct buffer_head *new_bh = NULL;
-+      int error;
-+
-+      if (header) {
-+              new_bh = ext3_xattr_cache_find(inode, header);
-+              if (new_bh) {
-+                      /*
-+                       * We found an identical block in the cache.
-+                       * The old block will be released after updating
-+                       * the inode.
-+                       */
-+                      ea_bdebug(old_bh, "reusing block %ld",
-+                              new_bh->b_blocknr);
-+                      
-+                      error = -EDQUOT;
-+                      if (ext3_xattr_quota_alloc(inode, 1))
-+                              goto cleanup;
-+                      
-+                      error = ext3_journal_get_write_access(handle, new_bh);
-+                      if (error)
-+                              goto cleanup;
-+                      HDR(new_bh)->h_refcount = cpu_to_le32(
-+                              le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
-+                      ea_bdebug(new_bh, "refcount now=%d",
-+                              le32_to_cpu(HDR(new_bh)->h_refcount));
-+              } else if (old_bh && header == HDR(old_bh)) {
-+                      /* Keep this block. */
-+                      new_bh = old_bh;
-+                      ext3_xattr_cache_insert(new_bh);
-+              } else {
-+                      /* We need to allocate a new block */
-+                      int force = EXT3_I(inode)->i_file_acl != 0;
-+                      int block = ext3_xattr_new_block(handle, inode,
-+                                                       &error, force);
-+                      if (error)
-+                              goto cleanup;
-+                      ea_idebug(inode, "creating block %d", block);
-+
-+                      new_bh = sb_getblk(sb, block);
-+                      if (!new_bh) {
-+getblk_failed:                        ext3_xattr_free_block(handle, inode, block);
-+                              error = -EIO;
-+                              goto cleanup;
-+                      }
-+                      lock_buffer(new_bh);
-+                      error = ext3_journal_get_create_access(handle, new_bh);
-+                      if (error) {
-+                              unlock_buffer(new_bh);
-+                              goto getblk_failed;
-+                      }
-+                      memcpy(new_bh->b_data, header, new_bh->b_size);
-+                      mark_buffer_uptodate(new_bh, 1);
-+                      unlock_buffer(new_bh);
-+                      ext3_xattr_cache_insert(new_bh);
-+                      
-+                      ext3_xattr_update_super_block(handle, sb);
-+              }
-+              error = ext3_journal_dirty_metadata(handle, new_bh);
-+              if (error)
-+                      goto cleanup;
-+      }
-+
-+      /* Update the inode. */
-+      EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-+      inode->i_ctime = CURRENT_TIME;
-+      ext3_mark_inode_dirty(handle, inode);
-+      if (IS_SYNC(inode))
-+              handle->h_sync = 1;
-+
-+      error = 0;
-+      if (old_bh && old_bh != new_bh) {
-+              /*
-+               * If there was an old block, and we are not still using it,
-+               * we now release the old block.
-+              */
-+              unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
-+
-+              error = ext3_journal_get_write_access(handle, old_bh);
-+              if (error)
-+                      goto cleanup;
-+              if (refcount == 1) {
-+                      /* Free the old block. */
-+                      ea_bdebug(old_bh, "freeing");
-+                      ext3_xattr_free_block(handle, inode, old_bh->b_blocknr);
-+
-+                      /* ext3_forget() calls bforget() for us, but we
-+                         let our caller release old_bh, so we need to
-+                         duplicate the handle before. */
-+                      get_bh(old_bh);
-+                      ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
-+              } else {
-+                      /* Decrement the refcount only. */
-+                      refcount--;
-+                      HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
-+                      ext3_xattr_quota_free(inode);
-+                      ext3_journal_dirty_metadata(handle, old_bh);
-+                      ea_bdebug(old_bh, "refcount now=%d", refcount);
-+              }
-+      }
-+
-+cleanup:
-+      if (old_bh != new_bh)
-+              brelse(new_bh);
-+
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_delete_inode()
-+ *
-+ * Free extended attribute resources associated with this inode. This
-+ * is called immediately before an inode is freed.
-+ */
-+void
-+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
-+{
-+      struct buffer_head *bh;
-+      unsigned int block = EXT3_I(inode)->i_file_acl;
-+
-+      if (!block)
-+              return;
-+      down(&ext3_xattr_sem);
-+
-+      bh = sb_bread(inode->i_sb, block);
-+      if (!bh) {
-+              ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
-+                      "inode %ld: block %d read error", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
-+      if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-+          HDR(bh)->h_blocks != cpu_to_le32(1)) {
-+              ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
-+                      "inode %ld: bad block %d", inode->i_ino, block);
-+              goto cleanup;
-+      }
-+      ext3_journal_get_write_access(handle, bh);
-+      ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+      if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-+              ext3_xattr_cache_remove(bh);
-+              ext3_xattr_free_block(handle, inode, block);
-+              ext3_forget(handle, 1, inode, bh, block);
-+              bh = NULL;
-+      } else {
-+              HDR(bh)->h_refcount = cpu_to_le32(
-+                      le32_to_cpu(HDR(bh)->h_refcount) - 1);
-+              ext3_journal_dirty_metadata(handle, bh);
-+              if (IS_SYNC(inode))
-+                      handle->h_sync = 1;
-+              ext3_xattr_quota_free(inode);
-+      }
-+      EXT3_I(inode)->i_file_acl = 0;
-+
-+cleanup:
-+      brelse(bh);
-+      up(&ext3_xattr_sem);
-+}
-+
-+/*
-+ * ext3_xattr_put_super()
-+ *
-+ * This is called when a file system is unmounted.
-+ */
-+void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+      mb_cache_shrink(ext3_xattr_cache, sb->s_dev);
-+#endif
-+}
-+
-+#ifdef CONFIG_EXT3_FS_XATTR_SHARING
-+
-+/*
-+ * ext3_xattr_cache_insert()
-+ *
-+ * Create a new entry in the extended attribute cache, and insert
-+ * it unless such an entry is already in the cache.
-+ *
-+ * Returns 0, or a negative error number on failure.
-+ */
-+static int
-+ext3_xattr_cache_insert(struct buffer_head *bh)
-+{
-+      __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
-+      struct mb_cache_entry *ce;
-+      int error;
-+
-+      ce = mb_cache_entry_alloc(ext3_xattr_cache);
-+      if (!ce)
-+              return -ENOMEM;
-+      error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
-+      if (error) {
-+              mb_cache_entry_free(ce);
-+              if (error == -EBUSY) {
-+                      ea_bdebug(bh, "already in cache (%d cache entries)",
-+                              atomic_read(&ext3_xattr_cache->c_entry_count));
-+                      error = 0;
-+              }
-+      } else {
-+              ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-+                        atomic_read(&ext3_xattr_cache->c_entry_count));
-+              mb_cache_entry_release(ce);
-+      }
-+      return error;
-+}
-+
-+/*
-+ * ext3_xattr_cmp()
-+ *
-+ * Compare two extended attribute blocks for equality.
-+ *
-+ * Returns 0 if the blocks are equal, 1 if they differ, and
-+ * a negative error number on errors.
-+ */
-+static int
-+ext3_xattr_cmp(struct ext3_xattr_header *header1,
-+             struct ext3_xattr_header *header2)
-+{
-+      struct ext3_xattr_entry *entry1, *entry2;
-+
-+      entry1 = ENTRY(header1+1);
-+      entry2 = ENTRY(header2+1);
-+      while (!IS_LAST_ENTRY(entry1)) {
-+              if (IS_LAST_ENTRY(entry2))
-+                      return 1;
-+              if (entry1->e_hash != entry2->e_hash ||
-+                  entry1->e_name_len != entry2->e_name_len ||
-+                  entry1->e_value_size != entry2->e_value_size ||
-+                  memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
-+                      return 1;
-+              if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
-+                      return -EIO;
-+              if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
-+                         (char *)header2 + le16_to_cpu(entry2->e_value_offs),
-+                         le32_to_cpu(entry1->e_value_size)))
-+                      return 1;
-+
-+              entry1 = EXT3_XATTR_NEXT(entry1);
-+              entry2 = EXT3_XATTR_NEXT(entry2);
-+      }
-+      if (!IS_LAST_ENTRY(entry2))
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * ext3_xattr_cache_find()
-+ *
-+ * Find an identical extended attribute block.
-+ *
-+ * Returns a pointer to the block found, or NULL if such a block was
-+ * not found or an error occurred.
-+ */
-+static struct buffer_head *
-+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
-+{
-+      __u32 hash = le32_to_cpu(header->h_hash);
-+      struct mb_cache_entry *ce;
-+
-+      if (!header->h_hash)
-+              return NULL;  /* never share */
-+      ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
-+      ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash);
-+      while (ce) {
-+              struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
-+
-+              if (!bh) {
-+                      ext3_error(inode->i_sb, "ext3_xattr_cache_find",
-+                              "inode %ld: block %ld read error",
-+                              inode->i_ino, ce->e_block);
-+              } else if (le32_to_cpu(HDR(bh)->h_refcount) >
-+                         EXT3_XATTR_REFCOUNT_MAX) {
-+                      ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
-+                              le32_to_cpu(HDR(bh)->h_refcount),
-+                              EXT3_XATTR_REFCOUNT_MAX);
-+              } else if (!ext3_xattr_cmp(header, HDR(bh))) {
-+                      ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
-+                      mb_cache_entry_release(ce);
-+                      return bh;
-+              }
-+              brelse(bh);
-+              ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * ext3_xattr_cache_remove()
-+ *
-+ * Remove the cache entry of a block from the cache. Called when a
-+ * block becomes invalid.
-+ */
-+static void
-+ext3_xattr_cache_remove(struct buffer_head *bh)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr);
-+      if (ce) {
-+              ea_bdebug(bh, "removing (%d cache entries remaining)",
-+                        atomic_read(&ext3_xattr_cache->c_entry_count)-1);
-+              mb_cache_entry_free(ce);
-+      } else 
-+              ea_bdebug(bh, "no cache entry");
-+}
-+
-+#define NAME_HASH_SHIFT 5
-+#define VALUE_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_hash_entry()
-+ *
-+ * Compute the hash of an extended attribute.
-+ */
-+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
-+                                       struct ext3_xattr_entry *entry)
-+{
-+      __u32 hash = 0;
-+      char *name = entry->e_name;
-+      int n;
-+
-+      for (n=0; n < entry->e_name_len; n++) {
-+              hash = (hash << NAME_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
-+                     *name++;
-+      }
-+
-+      if (entry->e_value_block == 0 && entry->e_value_size != 0) {
-+              __u32 *value = (__u32 *)((char *)header +
-+                      le16_to_cpu(entry->e_value_offs));
-+              for (n = (le32_to_cpu(entry->e_value_size) +
-+                   EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
-+                      hash = (hash << VALUE_HASH_SHIFT) ^
-+                             (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
-+                             le32_to_cpu(*value++);
-+              }
-+      }
-+      entry->e_hash = cpu_to_le32(hash);
-+}
-+
-+#undef NAME_HASH_SHIFT
-+#undef VALUE_HASH_SHIFT
-+
-+#define BLOCK_HASH_SHIFT 16
-+
-+/*
-+ * ext3_xattr_rehash()
-+ *
-+ * Re-compute the extended attribute hash value after an entry has changed.
-+ */
-+static void ext3_xattr_rehash(struct ext3_xattr_header *header,
-+                            struct ext3_xattr_entry *entry)
-+{
-+      struct ext3_xattr_entry *here;
-+      __u32 hash = 0;
-+      
-+      ext3_xattr_hash_entry(header, entry);
-+      here = ENTRY(header+1);
-+      while (!IS_LAST_ENTRY(here)) {
-+              if (!here->e_hash) {
-+                      /* Block is not shared if an entry's hash value == 0 */
-+                      hash = 0;
-+                      break;
-+              }
-+              hash = (hash << BLOCK_HASH_SHIFT) ^
-+                     (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
-+                     le32_to_cpu(here->e_hash);
-+              here = EXT3_XATTR_NEXT(here);
-+      }
-+      header->h_hash = cpu_to_le32(hash);
-+}
-+
-+#undef BLOCK_HASH_SHIFT
-+
-+int __init
-+init_ext3_xattr(void)
-+{
-+      ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
-+              sizeof(struct mb_cache_entry) +
-+              sizeof(struct mb_cache_entry_index), 1, 61);
-+      if (!ext3_xattr_cache)
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+void
-+exit_ext3_xattr(void)
-+{
-+      if (ext3_xattr_cache)
-+              mb_cache_destroy(ext3_xattr_cache);
-+      ext3_xattr_cache = NULL;
-+}
-+
-+#else  /* CONFIG_EXT3_FS_XATTR_SHARING */
-+
-+int __init
-+init_ext3_xattr(void)
-+{
-+      return 0;
-+}
-+
-+void
-+exit_ext3_xattr(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.20-braam/fs/ext3/xattr_user.c    2003-04-08 15:11:05.000000000 +0800
-@@ -0,0 +1,111 @@
-+/*
-+ * linux/fs/ext3/xattr_user.c
-+ * Handler for extended user attributes.
-+ *
-+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/fs.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/ext3_xattr.h>
-+
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+# include <linux/ext3_acl.h>
-+#endif
-+
-+#define XATTR_USER_PREFIX "user."
-+
-+static size_t
-+ext3_xattr_user_list(char *list, struct inode *inode,
-+                   const char *name, int name_len)
-+{
-+      const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
-+
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return 0;
-+
-+      if (list) {
-+              memcpy(list, XATTR_USER_PREFIX, prefix_len);
-+              memcpy(list+prefix_len, name, name_len);
-+              list[prefix_len + name_len] = '\0';
-+      }
-+      return prefix_len + name_len + 1;
-+}
-+
-+static int
-+ext3_xattr_user_get(struct inode *inode, const char *name,
-+                  void *buffer, size_t size)
-+{
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+      error = ext3_permission_locked(inode, MAY_READ);
-+#else
-+      error = permission(inode, MAY_READ);
-+#endif
-+      if (error)
-+              return error;
-+
-+      return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name,
-+                            buffer, size);
-+}
-+
-+static int
-+ext3_xattr_user_set(struct inode *inode, const char *name,
-+                  const void *value, size_t size, int flags)
-+{
-+      handle_t *handle;
-+      int error;
-+
-+      if (strcmp(name, "") == 0)
-+              return -EINVAL;
-+      if (!test_opt(inode->i_sb, XATTR_USER))
-+              return -ENOTSUP;
-+      if ( !S_ISREG(inode->i_mode) &&
-+          (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-+              return -EPERM;
-+#ifdef CONFIG_EXT3_FS_POSIX_ACL
-+      error = ext3_permission_locked(inode, MAY_WRITE);
-+#else
-+      error = permission(inode, MAY_WRITE);
-+#endif
-+      if (error)
-+              return error;
-+  
-+      handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
-+      if (IS_ERR(handle))
-+              return PTR_ERR(handle);
-+      error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name,
-+                             value, size, flags);
-+      ext3_journal_stop(handle, inode);
-+
-+      return error;
-+}
-+
-+struct ext3_xattr_handler ext3_xattr_user_handler = {
-+      prefix: XATTR_USER_PREFIX,
-+      list:   ext3_xattr_user_list,
-+      get:    ext3_xattr_user_get,
-+      set:    ext3_xattr_user_set,
-+};
-+
-+int __init
-+init_ext3_xattr_user(void)
-+{
-+      return ext3_xattr_register(EXT3_XATTR_INDEX_USER,
-+                                 &ext3_xattr_user_handler);
-+}
-+
-+void
-+exit_ext3_xattr_user(void)
-+{
-+      ext3_xattr_unregister(EXT3_XATTR_INDEX_USER,
-+                            &ext3_xattr_user_handler);
-+}
---- linux-2.4.20/fs/jfs/jfs_xattr.h~linux-2.4.20-xattr-0.8.54  2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/fs/jfs/jfs_xattr.h      2003-04-08 15:11:05.000000000 +0800
-@@ -52,8 +52,10 @@ struct jfs_ea_list {
- #define       END_EALIST(ealist) \
-       ((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist)))
--extern int __jfs_setxattr(struct inode *, const char *, void *, size_t, int);
--extern int jfs_setxattr(struct dentry *, const char *, void *, size_t, int);
-+extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t,
-+                        int);
-+extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
-+                      int);
- extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t);
- extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t);
- extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
---- linux-2.4.20/fs/jfs/xattr.c~linux-2.4.20-xattr-0.8.54      2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/fs/jfs/xattr.c  2003-04-08 15:11:05.000000000 +0800
-@@ -641,7 +641,7 @@ static int ea_put(struct inode *inode, s
- }
- static int can_set_xattr(struct inode *inode, const char *name,
--                       void *value, size_t value_len)
-+                       const void *value, size_t value_len)
- {
-       if (IS_RDONLY(inode))
-               return -EROFS;
-@@ -660,7 +660,7 @@ static int can_set_xattr(struct inode *i
-       return permission(inode, MAY_WRITE);
- }
--int __jfs_setxattr(struct inode *inode, const char *name, void *value,
-+int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
-                  size_t value_len, int flags)
- {
-       struct jfs_ea_list *ealist;
-@@ -799,7 +799,7 @@ int __jfs_setxattr(struct inode *inode, 
-       return rc;
- }
--int jfs_setxattr(struct dentry *dentry, const char *name, void *value,
-+int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
-                size_t value_len, int flags)
- {
-       if (value == NULL) {    /* empty EA, do not remove */
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.20-braam/fs/mbcache.c    2003-04-08 15:11:05.000000000 +0800
-@@ -0,0 +1,648 @@
-+/*
-+ * linux/fs/mbcache.c
-+ * (C) 2001-2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+/*
-+ * Filesystem Meta Information Block Cache (mbcache)
-+ *
-+ * The mbcache caches blocks of block devices that need to be located
-+ * by their device/block number, as well as by other criteria (such
-+ * as the block's contents).
-+ *
-+ * There can only be one cache entry in a cache per device and block number.
-+ * Additional indexes need not be unique in this sense. The number of
-+ * additional indexes (=other criteria) can be hardwired at compile time
-+ * or specified at cache create time.
-+ *
-+ * Each cache entry is of fixed size. An entry may be `valid' or `invalid'
-+ * in the cache. A valid entry is in the main hash tables of the cache,
-+ * and may also be in the lru list. An invalid entry is not in any hashes
-+ * or lists.
-+ *
-+ * A valid cache entry is only in the lru list if no handles refer to it.
-+ * Invalid cache entries will be freed when the last handle to the cache
-+ * entry is released. Entries that cannot be freed immediately are put
-+ * back on the lru list.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+
-+#include <linux/fs.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/cache_def.h>
-+#include <linux/version.h>
-+#include <linux/init.h>
-+#include <linux/mbcache.h>
-+
-+
-+#ifdef MB_CACHE_DEBUG
-+# define mb_debug(f...) do { \
-+              printk(KERN_DEBUG f); \
-+              printk("\n"); \
-+      } while (0)
-+#define mb_assert(c) do { if (!(c)) \
-+              printk(KERN_ERR "assertion " #c " failed\n"); \
-+      } while(0)
-+#else
-+# define mb_debug(f...) do { } while(0)
-+# define mb_assert(c) do { } while(0)
-+#endif
-+#define mb_error(f...) do { \
-+              printk(KERN_ERR f); \
-+              printk("\n"); \
-+      } while(0)
-+              
-+MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
-+MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+EXPORT_SYMBOL(mb_cache_create);
-+EXPORT_SYMBOL(mb_cache_shrink);
-+EXPORT_SYMBOL(mb_cache_destroy);
-+EXPORT_SYMBOL(mb_cache_entry_alloc);
-+EXPORT_SYMBOL(mb_cache_entry_insert);
-+EXPORT_SYMBOL(mb_cache_entry_release);
-+EXPORT_SYMBOL(mb_cache_entry_takeout);
-+EXPORT_SYMBOL(mb_cache_entry_free);
-+EXPORT_SYMBOL(mb_cache_entry_dup);
-+EXPORT_SYMBOL(mb_cache_entry_get);
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+EXPORT_SYMBOL(mb_cache_entry_find_first);
-+EXPORT_SYMBOL(mb_cache_entry_find_next);
-+#endif
-+
-+
-+/*
-+ * Global data: list of all mbcache's, lru list, and a spinlock for
-+ * accessing cache data structures on SMP machines. The lru list is
-+ * global across all mbcaches.
-+ */
-+
-+static LIST_HEAD(mb_cache_list);
-+static LIST_HEAD(mb_cache_lru_list);
-+static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED;
-+
-+static inline int
-+mb_cache_indexes(struct mb_cache *cache)
-+{
-+#ifdef MB_CACHE_INDEXES_COUNT
-+      return MB_CACHE_INDEXES_COUNT;
-+#else
-+      return cache->c_indexes_count;
-+#endif
-+}
-+
-+/*
-+ * What the mbcache registers as to get shrunk dynamically.
-+ */
-+
-+static void
-+mb_cache_memory_pressure(int priority, unsigned int gfp_mask);
-+
-+static struct cache_definition mb_cache_definition = {
-+      "mb_cache",
-+      mb_cache_memory_pressure
-+};
-+
-+
-+static inline int
-+__mb_cache_entry_is_hashed(struct mb_cache_entry *ce)
-+{
-+      return !list_empty(&ce->e_block_list);
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_unhash(struct mb_cache_entry *ce)
-+{
-+      int n;
-+
-+      if (__mb_cache_entry_is_hashed(ce)) {
-+              list_del_init(&ce->e_block_list);
-+              for (n=0; n<mb_cache_indexes(ce->e_cache); n++)
-+                      list_del(&ce->e_indexes[n].o_list);
-+      }
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask)
-+{
-+      struct mb_cache *cache = ce->e_cache;
-+
-+      mb_assert(atomic_read(&ce->e_used) == 0);
-+      if (cache->c_op.free && cache->c_op.free(ce, gfp_mask)) {
-+              /* free failed -- put back on the lru list
-+                 for freeing later. */
-+              spin_lock(&mb_cache_spinlock);
-+              list_add(&ce->e_lru_list, &mb_cache_lru_list);
-+              spin_unlock(&mb_cache_spinlock);
-+      } else {
-+              kmem_cache_free(cache->c_entry_cache, ce);
-+              atomic_dec(&cache->c_entry_count);
-+      }
-+}
-+
-+
-+static inline void
-+__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
-+{
-+      if (atomic_dec_and_test(&ce->e_used)) {
-+              if (__mb_cache_entry_is_hashed(ce))
-+                      list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
-+              else {
-+                      spin_unlock(&mb_cache_spinlock);
-+                      __mb_cache_entry_forget(ce, GFP_KERNEL);
-+                      return;
-+              }
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+}
-+
-+
-+/*
-+ * mb_cache_memory_pressure()  memory pressure callback
-+ *
-+ * This function is called by the kernel memory management when memory
-+ * gets low.
-+ *
-+ * @priority: Amount by which to shrink the cache (0 = highes priority)
-+ * @gfp_mask: (ignored)
-+ */
-+static void
-+mb_cache_memory_pressure(int priority, unsigned int gfp_mask)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+      int count = 0;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &mb_cache_list) {
-+              struct mb_cache *cache =
-+                      list_entry(l, struct mb_cache, c_cache_list);
-+              mb_debug("cache %s (%d)", cache->c_name,
-+                        atomic_read(&cache->c_entry_count));
-+              count += atomic_read(&cache->c_entry_count);
-+      }
-+      mb_debug("trying to free %d of %d entries",
-+                count / (priority ? priority : 1), count);
-+      if (priority)
-+              count /= priority;
-+      while (count-- && !list_empty(&mb_cache_lru_list)) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(mb_cache_lru_list.next,
-+                                 struct mb_cache_entry, e_lru_list);
-+              list_del(&ce->e_lru_list);
-+              __mb_cache_entry_unhash(ce);
-+              list_add_tail(&ce->e_lru_list, &free_list);
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), gfp_mask);
-+      }
-+}
-+
-+
-+/*
-+ * mb_cache_create()  create a new cache
-+ *
-+ * All entries in one cache are equal size. Cache entries may be from
-+ * multiple devices. If this is the first mbcache created, registers
-+ * the cache with kernel memory management. Returns NULL if no more
-+ * memory was available.
-+ *
-+ * @name: name of the cache (informal)
-+ * @cache_op: contains the callback called when freeing a cache entry
-+ * @entry_size: The size of a cache entry, including
-+ *              struct mb_cache_entry
-+ * @indexes_count: number of additional indexes in the cache. Must equal
-+ *                 MB_CACHE_INDEXES_COUNT if the number of indexes is
-+ *                 hardwired.
-+ * @bucket_count: number of hash buckets
-+ */
-+struct mb_cache *
-+mb_cache_create(const char *name, struct mb_cache_op *cache_op,
-+              size_t entry_size, int indexes_count, int bucket_count)
-+{
-+      int m=0, n;
-+      struct mb_cache *cache = NULL;
-+
-+      if(entry_size < sizeof(struct mb_cache_entry) +
-+         indexes_count * sizeof(struct mb_cache_entry_index))
-+              return NULL;
-+
-+      MOD_INC_USE_COUNT;
-+      cache = kmalloc(sizeof(struct mb_cache) +
-+                      indexes_count * sizeof(struct list_head), GFP_KERNEL);
-+      if (!cache)
-+              goto fail;
-+      cache->c_name = name;
-+      cache->c_op.free = NULL;
-+      if (cache_op)
-+              cache->c_op.free = cache_op->free;
-+      atomic_set(&cache->c_entry_count, 0);
-+      cache->c_bucket_count = bucket_count;
-+#ifdef MB_CACHE_INDEXES_COUNT
-+      mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT);
-+#else
-+      cache->c_indexes_count = indexes_count;
-+#endif
-+      cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
-+                                    GFP_KERNEL);
-+      if (!cache->c_block_hash)
-+              goto fail;
-+      for (n=0; n<bucket_count; n++)
-+              INIT_LIST_HEAD(&cache->c_block_hash[n]);
-+      for (m=0; m<indexes_count; m++) {
-+              cache->c_indexes_hash[m] = kmalloc(bucket_count *
-+                                               sizeof(struct list_head),
-+                                               GFP_KERNEL);
-+              if (!cache->c_indexes_hash[m])
-+                      goto fail;
-+              for (n=0; n<bucket_count; n++)
-+                      INIT_LIST_HEAD(&cache->c_indexes_hash[m][n]);
-+      }
-+      cache->c_entry_cache = kmem_cache_create(name, entry_size, 0,
-+              0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL);
-+      if (!cache->c_entry_cache)
-+              goto fail;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_add(&cache->c_cache_list, &mb_cache_list);
-+      spin_unlock(&mb_cache_spinlock);
-+      return cache;
-+
-+fail:
-+      if (cache) {
-+              while (--m >= 0)
-+                      kfree(cache->c_indexes_hash[m]);
-+              if (cache->c_block_hash)
-+                      kfree(cache->c_block_hash);
-+              kfree(cache);
-+      }
-+      MOD_DEC_USE_COUNT;
-+      return NULL;
-+}
-+
-+
-+/*
-+ * mb_cache_shrink()
-+ *
-+ * Removes all cache entires of a device from the cache. All cache entries
-+ * currently in use cannot be freed, and thus remain in the cache.
-+ *
-+ * @cache: which cache to shrink
-+ * @dev: which device's cache entries to shrink
-+ */
-+void
-+mb_cache_shrink(struct mb_cache *cache, kdev_t dev)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              if (ce->e_dev == dev) {
-+                      list_del(&ce->e_lru_list);
-+                      list_add_tail(&ce->e_lru_list, &free_list);
-+                      __mb_cache_entry_unhash(ce);
-+              }
-+      }
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), GFP_KERNEL);
-+      }
-+}
-+
-+
-+/*
-+ * mb_cache_destroy()
-+ *
-+ * Shrinks the cache to its minimum possible size (hopefully 0 entries),
-+ * and then destroys it. If this was the last mbcache, un-registers the
-+ * mbcache from kernel memory management.
-+ */
-+void
-+mb_cache_destroy(struct mb_cache *cache)
-+{
-+      LIST_HEAD(free_list);
-+      struct list_head *l, *ltmp;
-+      int n;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_lru_list);
-+              if (ce->e_cache == cache) {
-+                      list_del(&ce->e_lru_list);
-+                      list_add_tail(&ce->e_lru_list, &free_list);
-+                      __mb_cache_entry_unhash(ce);
-+              }
-+      }
-+      list_del(&cache->c_cache_list);
-+      spin_unlock(&mb_cache_spinlock);
-+      list_for_each_safe(l, ltmp, &free_list) {
-+              __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-+                                                 e_lru_list), GFP_KERNEL);
-+      }
-+
-+      if (atomic_read(&cache->c_entry_count) > 0) {
-+              mb_error("cache %s: %d orphaned entries",
-+                        cache->c_name,
-+                        atomic_read(&cache->c_entry_count));
-+      }
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-+      /* We don't have kmem_cache_destroy() in 2.2.x */
-+      kmem_cache_shrink(cache->c_entry_cache);
-+#else
-+      kmem_cache_destroy(cache->c_entry_cache);
-+#endif
-+      for (n=0; n < mb_cache_indexes(cache); n++)
-+              kfree(cache->c_indexes_hash[n]);
-+      kfree(cache->c_block_hash);
-+      kfree(cache);
-+
-+      MOD_DEC_USE_COUNT;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_alloc()
-+ *
-+ * Allocates a new cache entry. The new entry will not be valid initially,
-+ * and thus cannot be looked up yet. It should be filled with data, and
-+ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL
-+ * if no more memory was available.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_alloc(struct mb_cache *cache)
-+{
-+      struct mb_cache_entry *ce;
-+
-+      atomic_inc(&cache->c_entry_count);
-+      ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
-+      if (ce) {
-+              INIT_LIST_HEAD(&ce->e_lru_list);
-+              INIT_LIST_HEAD(&ce->e_block_list);
-+              ce->e_cache = cache;
-+              atomic_set(&ce->e_used, 1);
-+      }
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_insert()
-+ *
-+ * Inserts an entry that was allocated using mb_cache_entry_alloc() into
-+ * the cache. After this, the cache entry can be looked up, but is not yet
-+ * in the lru list as the caller still holds a handle to it. Returns 0 on
-+ * success, or -EBUSY if a cache entry for that device + inode exists
-+ * already (this may happen after a failed lookup, if another process has
-+ * inserted the same cache entry in the meantime).
-+ *
-+ * @dev: device the cache entry belongs to
-+ * @block: block number
-+ * @keys: array of additional keys. There must be indexes_count entries
-+ *        in the array (as specified when creating the cache).
-+ */
-+int
-+mb_cache_entry_insert(struct mb_cache_entry *ce, kdev_t dev,
-+                    unsigned long block, unsigned int keys[])
-+{
-+      struct mb_cache *cache = ce->e_cache;
-+      unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
-+      struct list_head *l;
-+      int error = -EBUSY, n;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &cache->c_block_hash[bucket]) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry, e_block_list);
-+              if (ce->e_dev == dev && ce->e_block == block)
-+                      goto out;
-+      }
-+      __mb_cache_entry_unhash(ce);
-+      ce->e_dev = dev;
-+      ce->e_block = block;
-+      list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
-+      for (n=0; n<mb_cache_indexes(cache); n++) {
-+              ce->e_indexes[n].o_key = keys[n];
-+              bucket = keys[n] % cache->c_bucket_count;
-+              list_add(&ce->e_indexes[n].o_list,
-+                       &cache->c_indexes_hash[n][bucket]);
-+      }
-+out:
-+      spin_unlock(&mb_cache_spinlock);
-+      return error;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_release()
-+ *
-+ * Release a handle to a cache entry. When the last handle to a cache entry
-+ * is released it is either freed (if it is invalid) or otherwise inserted
-+ * in to the lru list.
-+ */
-+void
-+mb_cache_entry_release(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      __mb_cache_entry_release_unlock(ce);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_takeout()
-+ *
-+ * Take a cache entry out of the cache, making it invalid. The entry can later
-+ * be re-inserted using mb_cache_entry_insert(), or released using
-+ * mb_cache_entry_release().
-+ */
-+void
-+mb_cache_entry_takeout(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      mb_assert(list_empty(&ce->e_lru_list));
-+      __mb_cache_entry_unhash(ce);
-+      spin_unlock(&mb_cache_spinlock);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_free()
-+ *
-+ * This is equivalent to the sequence mb_cache_entry_takeout() --
-+ * mb_cache_entry_release().
-+ */
-+void
-+mb_cache_entry_free(struct mb_cache_entry *ce)
-+{
-+      spin_lock(&mb_cache_spinlock);
-+      mb_assert(list_empty(&ce->e_lru_list));
-+      __mb_cache_entry_unhash(ce);
-+      __mb_cache_entry_release_unlock(ce);
-+}
-+
-+
-+/*
-+ * mb_cache_entry_dup()
-+ *
-+ * Duplicate a handle to a cache entry (does not duplicate the cache entry
-+ * itself). After the call, both the old and the new handle must be released.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_dup(struct mb_cache_entry *ce)
-+{
-+      atomic_inc(&ce->e_used);
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_get()
-+ *
-+ * Get a cache entry  by device / block number. (There can only be one entry
-+ * in the cache per device and block.) Returns NULL if no such cache entry
-+ * exists.
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_get(struct mb_cache *cache, kdev_t dev, unsigned long block)
-+{
-+      unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      spin_lock(&mb_cache_spinlock);
-+      list_for_each(l, &cache->c_block_hash[bucket]) {
-+              ce = list_entry(l, struct mb_cache_entry, e_block_list);
-+              if (ce->e_dev == dev && ce->e_block == block) {
-+                      if (!list_empty(&ce->e_lru_list))
-+                              list_del_init(&ce->e_lru_list);
-+                      atomic_inc(&ce->e_used);
-+                      goto cleanup;
-+              }
-+      }
-+      ce = NULL;
-+
-+cleanup:
-+      spin_unlock(&mb_cache_spinlock);
-+      return ce;
-+}
-+
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+
-+static struct mb_cache_entry *
-+__mb_cache_entry_find(struct list_head *l, struct list_head *head,
-+                    int index, kdev_t dev, unsigned int key)
-+{
-+      while (l != head) {
-+              struct mb_cache_entry *ce =
-+                      list_entry(l, struct mb_cache_entry,
-+                                 e_indexes[index].o_list);
-+              if (ce->e_dev == dev && ce->e_indexes[index].o_key == key) {
-+                      if (!list_empty(&ce->e_lru_list))
-+                              list_del_init(&ce->e_lru_list);
-+                      atomic_inc(&ce->e_used);
-+                      return ce;
-+              }
-+              l = l->next;
-+      }
-+      return NULL;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_find_first()
-+ *
-+ * Find the first cache entry on a given device with a certain key in
-+ * an additional index. Additonal matches can be found with
-+ * mb_cache_entry_find_next(). Returns NULL if no match was found.
-+ *
-+ * @cache: the cache to search
-+ * @index: the number of the additonal index to search (0<=index<indexes_count)
-+ * @dev: the device the cache entry should belong to
-+ * @key: the key in the index
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_find_first(struct mb_cache *cache, int index, kdev_t dev,
-+                        unsigned int key)
-+{
-+      unsigned int bucket = key % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      mb_assert(index < mb_cache_indexes(cache));
-+      spin_lock(&mb_cache_spinlock);
-+      l = cache->c_indexes_hash[index][bucket].next;
-+      ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
-+                                 index, dev, key);
-+      spin_unlock(&mb_cache_spinlock);
-+      return ce;
-+}
-+
-+
-+/*
-+ * mb_cache_entry_find_next()
-+ *
-+ * Find the next cache entry on a given device with a certain key in an
-+ * additional index. Returns NULL if no match could be found. The previous
-+ * entry is atomatically released, so that mb_cache_entry_find_next() can
-+ * be called like this:
-+ *
-+ * entry = mb_cache_entry_find_first();
-+ * while (entry) {
-+ *    ...
-+ *    entry = mb_cache_entry_find_next(entry, ...);
-+ * }
-+ *
-+ * @prev: The previous match
-+ * @index: the number of the additonal index to search (0<=index<indexes_count)
-+ * @dev: the device the cache entry should belong to
-+ * @key: the key in the index
-+ */
-+struct mb_cache_entry *
-+mb_cache_entry_find_next(struct mb_cache_entry *prev, int index, kdev_t dev,
-+                       unsigned int key)
-+{
-+      struct mb_cache *cache = prev->e_cache;
-+      unsigned int bucket = key % cache->c_bucket_count;
-+      struct list_head *l;
-+      struct mb_cache_entry *ce;
-+
-+      mb_assert(index < mb_cache_indexes(cache));
-+      spin_lock(&mb_cache_spinlock);
-+      l = prev->e_indexes[index].o_list.next;
-+      ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
-+                                 index, dev, key);
-+      __mb_cache_entry_release_unlock(prev);
-+      return ce;
-+}
-+
-+#endif  /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */
-+
-+static int __init init_mbcache(void)
-+{
-+      register_cache(&mb_cache_definition);
-+      return 0;
-+}
-+
-+static void __exit exit_mbcache(void)
-+{
-+      unregister_cache(&mb_cache_definition);
-+}
-+
-+module_init(init_mbcache)
-+module_exit(exit_mbcache)
-+
---- linux-2.4.20/include/asm-arm/unistd.h~linux-2.4.20-xattr-0.8.54    2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/asm-arm/unistd.h        2003-04-08 15:11:05.000000000 +0800
-@@ -244,7 +244,6 @@
- #define __NR_security                 (__NR_SYSCALL_BASE+223)
- #define __NR_gettid                   (__NR_SYSCALL_BASE+224)
- #define __NR_readahead                        (__NR_SYSCALL_BASE+225)
--#if 0 /* allocated in 2.5 */
- #define __NR_setxattr                 (__NR_SYSCALL_BASE+226)
- #define __NR_lsetxattr                        (__NR_SYSCALL_BASE+227)
- #define __NR_fsetxattr                        (__NR_SYSCALL_BASE+228)
-@@ -257,7 +256,6 @@
- #define __NR_removexattr              (__NR_SYSCALL_BASE+235)
- #define __NR_lremovexattr             (__NR_SYSCALL_BASE+236)
- #define __NR_fremovexattr             (__NR_SYSCALL_BASE+237)
--#endif
- #define __NR_tkill                    (__NR_SYSCALL_BASE+238)
- /*
-  * Please check 2.5 _before_ adding calls here,
---- linux-2.4.20/include/asm-ia64/unistd.h~linux-2.4.20-xattr-0.8.54   2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/asm-ia64/unistd.h       2003-04-08 15:11:05.000000000 +0800
-@@ -206,8 +206,19 @@
- #define __NR_getdents64                       1214
- #define __NR_getunwind                        1215
- #define __NR_readahead                        1216
-+#define __NR_setxattr                 1217
-+#define __NR_lsetxattr                        1218
-+#define __NR_fsetxattr                        1219
-+#define __NR_getxattr                 1220
-+#define __NR_lgetxattr                        1221
-+#define __NR_fgetxattr                        1222
-+#define __NR_listxattr                        1223
-+#define __NR_llistxattr                       1224
-+#define __NR_flistxattr                       1225
-+#define __NR_removexattr              1226
-+#define __NR_lremovexattr             1227
-+#define __NR_fremovexattr             1228
- /*
-- * 1217-1228: reserved for xattr
-  * 1230-1232: reserved for futex and sched_[sg]etaffinity.
-  */
- #define __NR_tkill                    1229
---- linux-2.4.20/include/asm-ppc64/unistd.h~linux-2.4.20-xattr-0.8.54  2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/asm-ppc64/unistd.h      2003-04-08 15:11:05.000000000 +0800
-@@ -218,6 +218,7 @@
- #define __NR_gettid           207
- #if 0 /* Reserved syscalls */
- #define __NR_tkill            208
-+#endif
- #define __NR_setxattr         209
- #define __NR_lsetxattr                210
- #define __NR_fsetxattr                211
-@@ -230,6 +231,7 @@
- #define __NR_removexattr      218
- #define __NR_lremovexattr     219
- #define __NR_fremovexattr     220
-+#if 0 /* Reserved syscalls */
- #define __NR_futex            221
- #endif
---- linux-2.4.20/include/asm-s390/unistd.h~linux-2.4.20-xattr-0.8.54   2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/asm-s390/unistd.h       2003-04-08 15:11:05.000000000 +0800
-@@ -212,9 +212,18 @@
- #define __NR_madvise            219
- #define __NR_getdents64               220
- #define __NR_fcntl64          221
--/*
-- * Numbers 224-235 are reserved for posix acl
-- */
-+#define __NR_setxattr         224
-+#define __NR_lsetxattr                225
-+#define __NR_fsetxattr                226
-+#define __NR_getxattr         227
-+#define __NR_lgetxattr                228
-+#define __NR_fgetxattr                229
-+#define __NR_listxattr                230
-+#define __NR_llistxattr               231
-+#define __NR_flistxattr               232
-+#define __NR_removexattr      233
-+#define __NR_lremovexattr     234
-+#define __NR_fremovexattr     235
- #define __NR_gettid           236
- #define __NR_tkill            237
---- linux-2.4.20/include/asm-s390x/unistd.h~linux-2.4.20-xattr-0.8.54  2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/asm-s390x/unistd.h      2003-04-08 15:11:05.000000000 +0800
-@@ -180,9 +180,18 @@
- #define __NR_pivot_root         217
- #define __NR_mincore            218
- #define __NR_madvise            219
--/*
-- * Numbers 224-235 are reserved for posix acl
-- */
-+#define __NR_setxattr         224
-+#define __NR_lsetxattr                225
-+#define __NR_fsetxattr                226
-+#define __NR_getxattr         227
-+#define __NR_lgetxattr                228
-+#define __NR_fgetxattr                229
-+#define __NR_listxattr                230
-+#define __NR_llistxattr               231
-+#define __NR_flistxattr               232
-+#define __NR_removexattr      233
-+#define __NR_lremovexattr     234
-+#define __NR_fremovexattr     235
- #define __NR_gettid           236
- #define __NR_tkill            237
---- linux-2.4.20/include/asm-sparc/unistd.h~linux-2.4.20-xattr-0.8.54  2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/asm-sparc/unistd.h      2003-04-08 15:11:05.000000000 +0800
-@@ -184,24 +184,24 @@
- /* #define __NR_exportfs        166    SunOS Specific                              */
- #define __NR_mount              167 /* Common                                      */
- #define __NR_ustat              168 /* Common                                      */
--/* #define __NR_semsys          169    SunOS Specific                              */
--/* #define __NR_msgsys          170    SunOS Specific                              */
--/* #define __NR_shmsys          171    SunOS Specific                              */
--/* #define __NR_auditsys        172    SunOS Specific                              */
--/* #define __NR_rfssys          173    SunOS Specific                              */
-+#define __NR_setxattr           169 /* SunOS: semsys                               */
-+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-+#define __NR_getxattr           172 /* SunOS: auditsys                             */
-+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
- #define __NR_getdents           174 /* Common                                      */
- #define __NR_setsid             175 /* Common                                      */
- #define __NR_fchdir             176 /* Common                                      */
--/* #define __NR_fchroot         177    SunOS Specific                              */
--/* #define __NR_vpixsys         178    SunOS Specific                              */
--/* #define __NR_aioread         179    SunOS Specific                              */
--/* #define __NR_aiowrite        180    SunOS Specific                              */
--/* #define __NR_aiowait         181    SunOS Specific                              */
--/* #define __NR_aiocancel       182    SunOS Specific                              */
-+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-+#define __NR_llistxattr         179 /* SunOS: aioread                              */
-+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-+#define __NR_removexattr        181 /* SunOS: aiowait                              */
-+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
- #define __NR_sigpending         183 /* Common                                      */
- #define __NR_query_module     184 /* Linux Specific                              */
- #define __NR_setpgid            185 /* Common                                      */
--/* #define __NR_pathconf        186    SunOS Specific                              */
-+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
- #define __NR_tkill              187 /* SunOS: fpathconf                            */
- /* #define __NR_sysconf         188    SunOS Specific                              */
- #define __NR_uname              189 /* Linux Specific                              */
---- linux-2.4.20/include/asm-sparc64/unistd.h~linux-2.4.20-xattr-0.8.54        2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/asm-sparc64/unistd.h    2003-04-08 15:11:05.000000000 +0800
-@@ -184,24 +184,24 @@
- /* #define __NR_exportfs        166    SunOS Specific                              */
- #define __NR_mount              167 /* Common                                      */
- #define __NR_ustat              168 /* Common                                      */
--/* #define __NR_semsys          169    SunOS Specific                              */
--/* #define __NR_msgsys          170    SunOS Specific                              */
--/* #define __NR_shmsys          171    SunOS Specific                              */
--/* #define __NR_auditsys        172    SunOS Specific                              */
--/* #define __NR_rfssys          173    SunOS Specific                              */
-+#define __NR_setxattr           169 /* SunOS: semsys                               */
-+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-+#define __NR_getxattr           172 /* SunOS: auditsys                             */
-+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
- #define __NR_getdents           174 /* Common                                      */
- #define __NR_setsid             175 /* Common                                      */
- #define __NR_fchdir             176 /* Common                                      */
--/* #define __NR_fchroot         177    SunOS Specific                              */
--/* #define __NR_vpixsys         178    SunOS Specific                              */
--/* #define __NR_aioread         179    SunOS Specific                              */
--/* #define __NR_aiowrite        180    SunOS Specific                              */
--/* #define __NR_aiowait         181    SunOS Specific                              */
--/* #define __NR_aiocancel       182    SunOS Specific                              */
-+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-+#define __NR_llistxattr         179 /* SunOS: aioread                              */
-+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-+#define __NR_removexattr        181 /* SunOS: aiowait                              */
-+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
- #define __NR_sigpending         183 /* Common                                      */
- #define __NR_query_module     184 /* Linux Specific                              */
- #define __NR_setpgid            185 /* Common                                      */
--/* #define __NR_pathconf        186    SunOS Specific                              */
-+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
- #define __NR_tkill              187 /* SunOS: fpathconf                            */
- /* #define __NR_sysconf         188    SunOS Specific                              */
- #define __NR_uname              189 /* Linux Specific                              */
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.20-braam/include/linux/cache_def.h       2003-04-08 15:11:05.000000000 +0800
-@@ -0,0 +1,15 @@
-+/*
-+ * linux/cache_def.h
-+ * Handling of caches defined in drivers, filesystems, ...
-+ *
-+ * Copyright (C) 2002 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ */
-+
-+struct cache_definition {
-+      const char *name;
-+      void (*shrink)(int, unsigned int);
-+      struct list_head link;
-+};
-+
-+extern void register_cache(struct cache_definition *);
-+extern void unregister_cache(struct cache_definition *);
---- linux-2.4.20/include/linux/errno.h~linux-2.4.20-xattr-0.8.54       2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/linux/errno.h   2003-04-08 15:11:05.000000000 +0800
-@@ -23,4 +23,8 @@
- #endif
-+/* Defined for extended attributes */
-+#define ENOATTR ENODATA               /* No such attribute */
-+#define ENOTSUP EOPNOTSUPP    /* Operation not supported */
-+
- #endif
---- linux-2.4.20/include/linux/ext2_fs.h~linux-2.4.20-xattr-0.8.54     2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/linux/ext2_fs.h 2003-04-08 15:11:05.000000000 +0800
-@@ -57,8 +57,6 @@
-  */
- #define       EXT2_BAD_INO             1      /* Bad blocks inode */
- #define EXT2_ROOT_INO          2      /* Root inode */
--#define EXT2_ACL_IDX_INO       3      /* ACL inode */
--#define EXT2_ACL_DATA_INO      4      /* ACL inode */
- #define EXT2_BOOT_LOADER_INO   5      /* Boot loader inode */
- #define EXT2_UNDEL_DIR_INO     6      /* Undelete directory inode */
-@@ -86,7 +84,6 @@
- #else
- # define EXT2_BLOCK_SIZE(s)           (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
- #endif
--#define EXT2_ACLE_PER_BLOCK(s)                (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
- #define       EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
- #ifdef __KERNEL__
- # define EXT2_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
-@@ -121,28 +118,6 @@
- #endif
- /*
-- * ACL structures
-- */
--struct ext2_acl_header        /* Header of Access Control Lists */
--{
--      __u32   aclh_size;
--      __u32   aclh_file_count;
--      __u32   aclh_acle_count;
--      __u32   aclh_first_acle;
--};
--
--struct ext2_acl_entry /* Access Control List Entry */
--{
--      __u32   acle_size;
--      __u16   acle_perms;     /* Access permissions */
--      __u16   acle_type;      /* Type of entry */
--      __u16   acle_tag;       /* User or group identity */
--      __u16   acle_pad1;
--      __u32   acle_next;      /* Pointer on next entry for the */
--                                      /* same inode or on next free entry */
--};
--
--/*
-  * Structure of a blocks group descriptor
-  */
- struct ext2_group_desc
-@@ -314,6 +289,7 @@ struct ext2_inode {
- #define EXT2_MOUNT_ERRORS_PANIC               0x0040  /* Panic on errors */
- #define EXT2_MOUNT_MINIX_DF           0x0080  /* Mimics the Minix statfs */
- #define EXT2_MOUNT_NO_UID32           0x0200  /* Disable 32-bit UIDs */
-+#define EXT2_MOUNT_XATTR_USER         0x4000  /* Extended user attributes */
- #define clear_opt(o, opt)             o &= ~EXT2_MOUNT_##opt
- #define set_opt(o, opt)                       o |= EXT2_MOUNT_##opt
-@@ -397,6 +373,7 @@ struct ext2_super_block {
- #ifdef __KERNEL__
- #define EXT2_SB(sb)   (&((sb)->u.ext2_sb))
-+#define EXT2_I(inode) (&((inode)->u.ext2_i))
- #else
- /* Assume that user mode programs are passing in an ext2fs superblock, not
-  * a kernel struct super_block.  This will allow us to call the feature-test
-@@ -466,7 +443,7 @@ struct ext2_super_block {
- #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008
- #define EXT2_FEATURE_INCOMPAT_ANY             0xffffffff
--#define EXT2_FEATURE_COMPAT_SUPP      0
-+#define EXT2_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
- #define EXT2_FEATURE_INCOMPAT_SUPP    EXT2_FEATURE_INCOMPAT_FILETYPE
- #define EXT2_FEATURE_RO_COMPAT_SUPP   (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-                                        EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
-@@ -623,8 +600,10 @@ extern struct address_space_operations e
- /* namei.c */
- extern struct inode_operations ext2_dir_inode_operations;
-+extern struct inode_operations ext2_special_inode_operations;
- /* symlink.c */
-+extern struct inode_operations ext2_symlink_inode_operations;
- extern struct inode_operations ext2_fast_symlink_inode_operations;
- #endif        /* __KERNEL__ */
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.20-braam/include/linux/ext2_xattr.h      2003-04-08 15:11:05.000000000 +0800
-@@ -0,0 +1,157 @@
-+/*
-+  File: linux/ext2_xattr.h
-+
-+  On-disk format of extended attributes for the ext2 filesystem.
-+
-+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/xattr.h>
-+
-+/* Magic value in attribute blocks */
-+#define EXT2_XATTR_MAGIC              0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT2_XATTR_REFCOUNT_MAX               1024
-+
-+/* Name indexes */
-+#define EXT2_XATTR_INDEX_MAX                  10
-+#define EXT2_XATTR_INDEX_USER                 1
-+#define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS     2
-+#define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT    3
-+
-+struct ext2_xattr_header {
-+      __u32   h_magic;        /* magic number for identification */
-+      __u32   h_refcount;     /* reference count */
-+      __u32   h_blocks;       /* number of disk blocks used */
-+      __u32   h_hash;         /* hash value of all attributes */
-+      __u32   h_reserved[4];  /* zero right now */
-+};
-+
-+struct ext2_xattr_entry {
-+      __u8    e_name_len;     /* length of name */
-+      __u8    e_name_index;   /* attribute name index */
-+      __u16   e_value_offs;   /* offset in disk block of value */
-+      __u32   e_value_block;  /* disk block attribute is stored on (n/i) */
-+      __u32   e_value_size;   /* size of attribute value */
-+      __u32   e_hash;         /* hash value of name and value */
-+      char    e_name[0];      /* attribute name */
-+};
-+
-+#define EXT2_XATTR_PAD_BITS           2
-+#define EXT2_XATTR_PAD                (1<<EXT2_XATTR_PAD_BITS)
-+#define EXT2_XATTR_ROUND              (EXT2_XATTR_PAD-1)
-+#define EXT2_XATTR_LEN(name_len) \
-+      (((name_len) + EXT2_XATTR_ROUND + \
-+      sizeof(struct ext2_xattr_entry)) & ~EXT2_XATTR_ROUND)
-+#define EXT2_XATTR_NEXT(entry) \
-+      ( (struct ext2_xattr_entry *)( \
-+        (char *)(entry) + EXT2_XATTR_LEN((entry)->e_name_len)) )
-+#define EXT2_XATTR_SIZE(size) \
-+      (((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)
-+
-+#ifdef __KERNEL__
-+
-+# ifdef CONFIG_EXT2_FS_XATTR
-+
-+struct ext2_xattr_handler {
-+      char *prefix;
-+      size_t (*list)(char *list, struct inode *inode, const char *name,
-+                     int name_len);
-+      int (*get)(struct inode *inode, const char *name, void *buffer,
-+                 size_t size);
-+      int (*set)(struct inode *inode, const char *name, const void *buffer,
-+                 size_t size, int flags);
-+};
-+
-+extern int ext2_xattr_register(int, struct ext2_xattr_handler *);
-+extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *);
-+
-+extern int ext2_setxattr(struct dentry *, const char *, const void *, size_t, int);
-+extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t);
-+extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
-+extern int ext2_removexattr(struct dentry *, const char *);
-+
-+extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
-+extern int ext2_xattr_list(struct inode *, char *, size_t);
-+extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
-+
-+extern void ext2_xattr_delete_inode(struct inode *);
-+extern void ext2_xattr_put_super(struct super_block *);
-+
-+extern int init_ext2_xattr(void) __init;
-+extern void exit_ext2_xattr(void);
-+
-+# else  /* CONFIG_EXT2_FS_XATTR */
-+#  define ext2_setxattr               NULL
-+#  define ext2_getxattr               NULL
-+#  define ext2_listxattr      NULL
-+#  define ext2_removexattr    NULL
-+
-+static inline int
-+ext2_xattr_get(struct inode *inode, int name_index,
-+             const char *name, void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext2_xattr_list(struct inode *inode, char *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext2_xattr_set(struct inode *inode, int name_index, const char *name,
-+             const void *value, size_t size, int flags)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline void
-+ext2_xattr_delete_inode(struct inode *inode)
-+{
-+}
-+
-+static inline void
-+ext2_xattr_put_super(struct super_block *sb)
-+{
-+}
-+
-+static inline int
-+init_ext2_xattr(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext2_xattr(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT2_FS_XATTR */
-+
-+# ifdef CONFIG_EXT2_FS_XATTR_USER
-+
-+extern int init_ext2_xattr_user(void) __init;
-+extern void exit_ext2_xattr_user(void);
-+
-+# else  /* CONFIG_EXT2_FS_XATTR_USER */
-+
-+static inline int
-+init_ext2_xattr_user(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext2_xattr_user(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT2_FS_XATTR_USER */
-+
-+#endif  /* __KERNEL__ */
-+
---- linux-2.4.20/include/linux/ext3_fs.h~linux-2.4.20-xattr-0.8.54     2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/linux/ext3_fs.h 2003-04-08 15:11:05.000000000 +0800
-@@ -63,8 +63,6 @@
-  */
- #define       EXT3_BAD_INO             1      /* Bad blocks inode */
- #define EXT3_ROOT_INO          2      /* Root inode */
--#define EXT3_ACL_IDX_INO       3      /* ACL inode */
--#define EXT3_ACL_DATA_INO      4      /* ACL inode */
- #define EXT3_BOOT_LOADER_INO   5      /* Boot loader inode */
- #define EXT3_UNDEL_DIR_INO     6      /* Undelete directory inode */
- #define EXT3_RESIZE_INO                7      /* Reserved group descriptors inode */
-@@ -94,7 +92,6 @@
- #else
- # define EXT3_BLOCK_SIZE(s)           (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
- #endif
--#define EXT3_ACLE_PER_BLOCK(s)                (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
- #define       EXT3_ADDR_PER_BLOCK(s)          (EXT3_BLOCK_SIZE(s) / sizeof (__u32))
- #ifdef __KERNEL__
- # define EXT3_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
-@@ -129,28 +126,6 @@
- #endif
- /*
-- * ACL structures
-- */
--struct ext3_acl_header        /* Header of Access Control Lists */
--{
--      __u32   aclh_size;
--      __u32   aclh_file_count;
--      __u32   aclh_acle_count;
--      __u32   aclh_first_acle;
--};
--
--struct ext3_acl_entry /* Access Control List Entry */
--{
--      __u32   acle_size;
--      __u16   acle_perms;     /* Access permissions */
--      __u16   acle_type;      /* Type of entry */
--      __u16   acle_tag;       /* User or group identity */
--      __u16   acle_pad1;
--      __u32   acle_next;      /* Pointer on next entry for the */
--                                      /* same inode or on next free entry */
--};
--
--/*
-  * Structure of a blocks group descriptor
-  */
- struct ext3_group_desc
-@@ -344,6 +319,7 @@ struct ext3_inode {
-   #define EXT3_MOUNT_WRITEBACK_DATA   0x0C00  /* No data ordering */
- #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
-@@ -520,7 +496,7 @@ struct ext3_super_block {
- #define EXT3_FEATURE_INCOMPAT_RECOVER         0x0004 /* Needs recovery */
- #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008 /* Journal device */
--#define EXT3_FEATURE_COMPAT_SUPP      0
-+#define EXT3_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
- #define EXT3_FEATURE_INCOMPAT_SUPP    (EXT3_FEATURE_INCOMPAT_FILETYPE| \
-                                        EXT3_FEATURE_INCOMPAT_RECOVER)
- #define EXT3_FEATURE_RO_COMPAT_SUPP   (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-@@ -703,6 +679,7 @@ extern void ext3_check_inodes_bitmap (st
- extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
- /* inode.c */
-+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
-@@ -771,8 +748,10 @@ extern struct address_space_operations e
- /* namei.c */
- extern struct inode_operations ext3_dir_inode_operations;
-+extern struct inode_operations ext3_special_inode_operations;
- /* symlink.c */
-+extern struct inode_operations ext3_symlink_inode_operations;
- extern struct inode_operations ext3_fast_symlink_inode_operations;
---- linux-2.4.20/include/linux/ext3_jbd.h~linux-2.4.20-xattr-0.8.54    2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/linux/ext3_jbd.h        2003-04-08 15:11:05.000000000 +0800
-@@ -30,13 +30,19 @@
- #define EXT3_SINGLEDATA_TRANS_BLOCKS  8
-+/* Extended attributes may touch two data buffers, two bitmap buffers,
-+ * and two group and summaries. */
-+
-+#define EXT3_XATTR_TRANS_BLOCKS               8
-+
- /* Define the minimum size for a transaction which modifies data.  This
-  * needs to take into account the fact that we may end up modifying two
-  * quota files too (one for the group, one for the user quota).  The
-  * superblock only gets updated once, of course, so don't bother
-  * counting that again for the quota updates. */
--#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
-+#define EXT3_DATA_TRANS_BLOCKS                (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
-+                                       EXT3_XATTR_TRANS_BLOCKS - 2)
- extern int ext3_writepage_trans_blocks(struct inode *inode);
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.20-braam/include/linux/ext3_xattr.h      2003-04-08 15:11:05.000000000 +0800
-@@ -0,0 +1,157 @@
-+/*
-+  File: linux/ext3_xattr.h
-+
-+  On-disk format of extended attributes for the ext3 filesystem.
-+
-+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/xattr.h>
-+
-+/* Magic value in attribute blocks */
-+#define EXT3_XATTR_MAGIC              0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT3_XATTR_REFCOUNT_MAX               1024
-+
-+/* Name indexes */
-+#define EXT3_XATTR_INDEX_MAX                  10
-+#define EXT3_XATTR_INDEX_USER                 1
-+#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS     2
-+#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT    3
-+
-+struct ext3_xattr_header {
-+      __u32   h_magic;        /* magic number for identification */
-+      __u32   h_refcount;     /* reference count */
-+      __u32   h_blocks;       /* number of disk blocks used */
-+      __u32   h_hash;         /* hash value of all attributes */
-+      __u32   h_reserved[4];  /* zero right now */
-+};
-+
-+struct ext3_xattr_entry {
-+      __u8    e_name_len;     /* length of name */
-+      __u8    e_name_index;   /* attribute name index */
-+      __u16   e_value_offs;   /* offset in disk block of value */
-+      __u32   e_value_block;  /* disk block attribute is stored on (n/i) */
-+      __u32   e_value_size;   /* size of attribute value */
-+      __u32   e_hash;         /* hash value of name and value */
-+      char    e_name[0];      /* attribute name */
-+};
-+
-+#define EXT3_XATTR_PAD_BITS           2
-+#define EXT3_XATTR_PAD                (1<<EXT3_XATTR_PAD_BITS)
-+#define EXT3_XATTR_ROUND              (EXT3_XATTR_PAD-1)
-+#define EXT3_XATTR_LEN(name_len) \
-+      (((name_len) + EXT3_XATTR_ROUND + \
-+      sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
-+#define EXT3_XATTR_NEXT(entry) \
-+      ( (struct ext3_xattr_entry *)( \
-+        (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
-+#define EXT3_XATTR_SIZE(size) \
-+      (((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
-+
-+#ifdef __KERNEL__
-+
-+# ifdef CONFIG_EXT3_FS_XATTR
-+
-+struct ext3_xattr_handler {
-+      char *prefix;
-+      size_t (*list)(char *list, struct inode *inode, const char *name,
-+                     int name_len);
-+      int (*get)(struct inode *inode, const char *name, void *buffer,
-+                 size_t size);
-+      int (*set)(struct inode *inode, const char *name, const void *buffer,
-+                 size_t size, int flags);
-+};
-+
-+extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
-+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
-+
-+extern int ext3_setxattr(struct dentry *, const char *, const void *, size_t, int);
-+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
-+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
-+extern int ext3_removexattr(struct dentry *, const char *);
-+
-+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
-+extern int ext3_xattr_list(struct inode *, char *, size_t);
-+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
-+
-+extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
-+extern void ext3_xattr_put_super(struct super_block *);
-+
-+extern int init_ext3_xattr(void) __init;
-+extern void exit_ext3_xattr(void);
-+
-+# else  /* CONFIG_EXT3_FS_XATTR */
-+#  define ext3_setxattr               NULL
-+#  define ext3_getxattr               NULL
-+#  define ext3_listxattr      NULL
-+#  define ext3_removexattr    NULL
-+
-+static inline int
-+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-+             void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline int
-+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-+             const char *name, const void *value, size_t size, int flags)
-+{
-+      return -ENOTSUP;
-+}
-+
-+static inline void
-+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
-+{
-+}
-+
-+static inline void
-+ext3_xattr_put_super(struct super_block *sb)
-+{
-+}
-+
-+static inline int
-+init_ext3_xattr(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext3_xattr(void)
-+{
-+}
-+
-+# endif  /* CONFIG_EXT3_FS_XATTR */
-+
-+# ifdef CONFIG_EXT3_FS_XATTR_USER
-+
-+extern int init_ext3_xattr_user(void) __init;
-+extern void exit_ext3_xattr_user(void);
-+
-+# else  /* CONFIG_EXT3_FS_XATTR_USER */
-+
-+static inline int
-+init_ext3_xattr_user(void)
-+{
-+      return 0;
-+}
-+
-+static inline void
-+exit_ext3_xattr_user(void)
-+{
-+}
-+
-+#endif  /* CONFIG_EXT3_FS_XATTR_USER */
-+
-+#endif  /* __KERNEL__ */
-+
---- linux-2.4.20/include/linux/fs.h~linux-2.4.20-xattr-0.8.54  2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/include/linux/fs.h      2003-04-08 15:11:05.000000000 +0800
-@@ -888,7 +888,7 @@ struct inode_operations {
-       int (*setattr) (struct dentry *, struct iattr *);
-       int (*setattr_raw) (struct inode *, struct iattr *);
-       int (*getattr) (struct dentry *, struct iattr *);
--      int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
-+      int (*setxattr) (struct dentry *, const char *, const void *, size_t, int);
-       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-       ssize_t (*listxattr) (struct dentry *, char *, size_t);
-       int (*removexattr) (struct dentry *, const char *);
---- /dev/null  2002-08-31 07:31:37.000000000 +0800
-+++ linux-2.4.20-braam/include/linux/mbcache.h 2003-04-08 15:11:05.000000000 +0800
-@@ -0,0 +1,69 @@
-+/*
-+  File: linux/mbcache.h
-+
-+  (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+/* Hardwire the number of additional indexes */
-+#define MB_CACHE_INDEXES_COUNT 1
-+
-+struct mb_cache_entry;
-+
-+struct mb_cache_op {
-+      int (*free)(struct mb_cache_entry *, int);
-+};
-+
-+struct mb_cache {
-+      struct list_head                c_cache_list;
-+      const char                      *c_name;
-+      struct mb_cache_op              c_op;
-+      atomic_t                        c_entry_count;
-+      int                             c_bucket_count;
-+#ifndef MB_CACHE_INDEXES_COUNT
-+      int                             c_indexes_count;
-+#endif
-+      kmem_cache_t                    *c_entry_cache;
-+      struct list_head                *c_block_hash;
-+      struct list_head                *c_indexes_hash[0];
-+};
-+
-+struct mb_cache_entry_index {
-+      struct list_head                o_list;
-+      unsigned int                    o_key;
-+};
-+
-+struct mb_cache_entry {
-+      struct list_head                e_lru_list;
-+      struct mb_cache                 *e_cache;
-+      atomic_t                        e_used;
-+      kdev_t                          e_dev;
-+      unsigned long                   e_block;
-+      struct list_head                e_block_list;
-+      struct mb_cache_entry_index     e_indexes[0];
-+};
-+
-+/* Functions on caches */
-+
-+struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t,
-+                                int, int);
-+void mb_cache_shrink(struct mb_cache *, kdev_t);
-+void mb_cache_destroy(struct mb_cache *);
-+
-+/* Functions on cache entries */
-+
-+struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
-+int mb_cache_entry_insert(struct mb_cache_entry *, kdev_t, unsigned long,
-+                        unsigned int[]);
-+void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
-+void mb_cache_entry_release(struct mb_cache_entry *);
-+void mb_cache_entry_takeout(struct mb_cache_entry *);
-+void mb_cache_entry_free(struct mb_cache_entry *);
-+struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *);
-+struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, kdev_t,
-+                                        unsigned long);
-+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
-+struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int,
-+                                               kdev_t, unsigned int);
-+struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int,
-+                                              kdev_t, unsigned int);
-+#endif
---- linux-2.4.20/kernel/ksyms.c~linux-2.4.20-xattr-0.8.54      2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/kernel/ksyms.c  2003-04-08 15:11:05.000000000 +0800
-@@ -11,6 +11,7 @@
- #include <linux/config.h>
- #include <linux/slab.h>
-+#include <linux/cache_def.h>
- #include <linux/module.h>
- #include <linux/blkdev.h>
- #include <linux/cdrom.h>
-@@ -89,6 +90,7 @@ EXPORT_SYMBOL(exit_mm);
- EXPORT_SYMBOL(exit_files);
- EXPORT_SYMBOL(exit_fs);
- EXPORT_SYMBOL(exit_sighand);
-+EXPORT_SYMBOL(copy_fs_struct);
- /* internal kernel memory management */
- EXPORT_SYMBOL(_alloc_pages);
-@@ -107,6 +109,8 @@ EXPORT_SYMBOL(kmem_cache_validate);
- EXPORT_SYMBOL(kmem_cache_alloc);
- EXPORT_SYMBOL(kmem_cache_free);
- EXPORT_SYMBOL(kmem_cache_size);
-+EXPORT_SYMBOL(register_cache);
-+EXPORT_SYMBOL(unregister_cache);
- EXPORT_SYMBOL(kmalloc);
- EXPORT_SYMBOL(kfree);
- EXPORT_SYMBOL(vfree);
---- linux-2.4.20/mm/vmscan.c~linux-2.4.20-xattr-0.8.54 2003-04-08 15:11:04.000000000 +0800
-+++ linux-2.4.20-braam/mm/vmscan.c     2003-04-08 15:11:05.000000000 +0800
-@@ -18,6 +18,7 @@
- #include <linux/kernel_stat.h>
- #include <linux/swap.h>
- #include <linux/swapctl.h>
-+#include <linux/cache_def.h>
- #include <linux/smp_lock.h>
- #include <linux/pagemap.h>
- #include <linux/init.h>
-@@ -34,6 +35,39 @@
-  */
- #define DEF_PRIORITY (6)
-+static DECLARE_MUTEX(other_caches_sem);
-+static LIST_HEAD(cache_definitions);
-+
-+void register_cache(struct cache_definition *cache)
-+{
-+      down(&other_caches_sem);
-+      list_add(&cache->link, &cache_definitions);
-+      up(&other_caches_sem);
-+}
-+
-+void unregister_cache(struct cache_definition *cache)
-+{
-+      down(&other_caches_sem);
-+      list_del(&cache->link);
-+      up(&other_caches_sem);
-+}
-+
-+static void shrink_other_caches(unsigned int priority, int gfp_mask)
-+{
-+      struct list_head *p;
-+
-+      if (down_trylock(&other_caches_sem))
-+              return;
-+
-+      list_for_each_prev(p, &cache_definitions) {
-+              struct cache_definition *cache =
-+                      list_entry(p, struct cache_definition, link);
-+
-+              cache->shrink(priority, gfp_mask);
-+      }
-+      up(&other_caches_sem);
-+}
-+
- /*
-  * The swap-out function returns 1 if it successfully
-  * scanned all the pages it was asked to (`count').
-@@ -577,6 +611,7 @@ static int shrink_caches(zone_t * classz
-       shrink_dcache_memory(priority, gfp_mask);
-       shrink_icache_memory(priority, gfp_mask);
-+      shrink_other_caches(priority, gfp_mask);
- #ifdef CONFIG_QUOTA
-       shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
- #endif
-
-_
diff --git a/lustre/kernel_patches/patches/lustre-2.5.63.patch b/lustre/kernel_patches/patches/lustre-2.5.63.patch
deleted file mode 100644 (file)
index 40e6a90..0000000
+++ /dev/null
@@ -1,862 +0,0 @@
- arch/um/kernel/mem.c   |   18 ++++++
- fs/dcache.c            |   12 +++-
- fs/namei.c             |  132 ++++++++++++++++++++++++++++++++++++++-----------
- fs/namespace.c         |    1 
- fs/nfsd/vfs.c          |    2 
- fs/open.c              |   39 ++++++++++++--
- fs/stat.c              |    2 
- fs/sysfs/inode.c       |    2 
- include/linux/dcache.h |   28 ++++++++++
- include/linux/fs.h     |   20 +++++++
- include/linux/namei.h  |    3 -
- include/linux/slab.h   |    1 
- kernel/ksyms.c         |    7 ++
- mm/slab.c              |    5 +
- net/unix/af_unix.c     |    2 
- 15 files changed, 231 insertions(+), 43 deletions(-)
-
---- linux-2.5.63-nointent/arch/um/kernel/mem.c~lustre-2.5.63   Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/arch/um/kernel/mem.c    Tue Mar 18 15:02:10 2003
-@@ -660,6 +660,22 @@ struct page *pte_mem_map(pte_t pte)
-       return(phys_mem_map(pte_val(pte)));
- }
-+struct page *check_get_page(unsigned long kaddr)
-+{
-+        struct page *page;
-+        struct mem_region *mr;
-+        unsigned long phys = __pa(kaddr);
-+      unsigned int n = phys_region_index(phys);
-+
-+      if(regions[n] == NULL) 
-+                return NULL; 
-+
-+        mr = regions[n];
-+        page = (struct page *) mr->mem_map;
-+      return page + ((phys_addr(phys)) >> PAGE_SHIFT);
-+}
-+
-+
- struct mem_region *page_region(struct page *page, int *index_out)
- {
-       int i;
-@@ -747,7 +763,7 @@ extern unsigned long region_pa(void *vir
-                  (addr <= region->start + region->len))
-                       return(mk_phys(addr - region->start, i));
-       }
--      panic("region_pa : no region for virtual address");
-+      //panic("region_pa : no region for virtual address");
-       return(0);
- }
---- linux-2.5.63-nointent/fs/namei.c~lustre-2.5.63     Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/fs/namei.c      Mon Mar 24 17:08:18 2003
-@@ -101,6 +101,14 @@
-  * any extra contention...
-  */
-+void intent_release(struct dentry *de, struct lookup_intent *it)
-+{
-+      if (it && de->d_op && de->d_op->d_intent_release)
-+              de->d_op->d_intent_release(de, it);
-+
-+}
-+
-+
- /* In order to reduce some races, while at the same time doing additional
-  * checking and hopefully speeding things up, we copy filenames to the
-  * kernel data space before using them..
-@@ -273,10 +281,18 @@ void path_release(struct nameidata *nd)
-  * Internal lookup() using the new generic dcache.
-  * SMP-safe
-  */
--static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
- {
-       struct dentry * dentry = d_lookup(parent, name);
-       
-+      if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+              if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
-+                  !d_invalidate(dentry)) {
-+                      dput(dentry);
-+                      dentry = NULL;
-+              }
-+              return dentry;
-+      } else
-       if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-               if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
-                       dput(dentry);
-@@ -330,7 +346,7 @@ ok:
-  * make sure that nobody added the entry to the dcache in the meantime..
-  * SMP-safe
-  */
--static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
- {
-       struct dentry * result;
-       struct inode *dir = parent->d_inode;
-@@ -348,7 +364,10 @@ static struct dentry * real_lookup(struc
-               struct dentry * dentry = d_alloc(parent, name);
-               result = ERR_PTR(-ENOMEM);
-               if (dentry) {
--                      result = dir->i_op->lookup(dir, dentry);
-+                      if (dir->i_op->lookup2)
-+                              result = dir->i_op->lookup2(dir, dentry, it);
-+                      else
-+                                result = dir->i_op->lookup(dir, dentry);
-                       if (result)
-                               dput(dentry);
-                       else {
-@@ -370,6 +389,12 @@ static struct dentry * real_lookup(struc
-                       dput(result);
-                       result = ERR_PTR(-ENOENT);
-               }
-+      } else if (result->d_op && result->d_op->d_revalidate2) {
-+              if (!result->d_op->d_revalidate2(result, flags, it) &&
-+                  !d_invalidate(result)) {
-+                      dput(result);
-+                      result = ERR_PTR(-ENOENT);
-+              }
-       }
-       return result;
- }
-@@ -402,6 +427,7 @@ static inline int do_follow_link(struct 
-       current->link_count--;
-       return err;
- loop:
-+      intent_release(dentry, &nd->it);
-       path_release(nd);
-       return err;
- }
-@@ -447,15 +473,26 @@ static int follow_mount(struct vfsmount 
-       return res;
- }
--static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
-+static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
-+                              struct lookup_intent *it)
- {
-       struct vfsmount *mounted;
-       spin_lock(&dcache_lock);
-       mounted = lookup_mnt(*mnt, *dentry);
-       if (mounted) {
-+              int opc = 0, mode = 0;
-               *mnt = mntget(mounted);
-               spin_unlock(&dcache_lock);
-+              if (it) {
-+                      opc = it->it_op;
-+                      mode = it->it_mode;
-+              }
-+              intent_release(*dentry, it);
-+              if (it) {
-+                      it->it_op = opc;
-+                      it->it_mode = mode;
-+              }
-               dput(*dentry);
-               mntput(mounted->mnt_parent);
-               *dentry = dget(mounted->mnt_root);
-@@ -467,7 +504,7 @@ static inline int __follow_down(struct v
- int follow_down(struct vfsmount **mnt, struct dentry **dentry)
- {
--      return __follow_down(mnt,dentry);
-+      return __follow_down(mnt,dentry,NULL);
- }
-  
- static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry)
-@@ -531,7 +568,7 @@ done:
-       return 0;
- need_lookup:
--      dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE);
-+      dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE, &nd->it);
-       if (IS_ERR(dentry))
-               goto fail;
-       goto done;
-@@ -665,7 +702,7 @@ int link_path_walk(const char * name, st
-                       nd->dentry = next.dentry;
-               }
-               err = -ENOTDIR; 
--              if (!inode->i_op->lookup)
-+              if (!inode->i_op->lookup && !inode->i_op->lookup2)
-                       break;
-               continue;
-               /* here ends the main loop */
-@@ -716,7 +753,8 @@ last_component:
-                       break;
-               if (lookup_flags & LOOKUP_DIRECTORY) {
-                       err = -ENOTDIR; 
--                      if (!inode->i_op || !inode->i_op->lookup)
-+                      if (!inode->i_op || 
-+                            (!inode->i_op->lookup && !inode->i_op->lookup2))
-                               break;
-               }
-               goto return_base;
-@@ -735,6 +773,7 @@ out_dput:
-               dput(next.dentry);
-               break;
-       }
-+      intent_release(nd->dentry, &nd->it);
-       path_release(nd);
- return_err:
-       return err;
-@@ -857,7 +896,8 @@ int path_lookup(const char *name, unsign
-  * needs parent already locked. Doesn't follow mounts.
-  * SMP-safe.
-  */
--struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+struct dentry * lookup_hash(struct qstr *name, struct dentry * base, 
-+                            struct lookup_intent *it)
- {
-       struct dentry * dentry;
-       struct inode *inode;
-@@ -880,13 +920,16 @@ struct dentry * lookup_hash(struct qstr 
-                       goto out;
-       }
--      dentry = cached_lookup(base, name, 0);
-+      dentry = cached_lookup(base, name, 0, it);
-       if (!dentry) {
-               struct dentry *new = d_alloc(base, name);
-               dentry = ERR_PTR(-ENOMEM);
-               if (!new)
-                       goto out;
--              dentry = inode->i_op->lookup(inode, new);
-+                if (inode->i_op->lookup2) 
-+                        dentry = inode->i_op->lookup2(inode, new, it);
-+                else 
-+                        dentry = inode->i_op->lookup(inode, new);
-               if (!dentry) {
-                       dentry = new;
-                       security_inode_post_lookup(inode, dentry);
-@@ -898,7 +941,7 @@ out:
- }
- /* SMP-safe */
--struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
-+struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct lookup_intent *it)
- {
-       unsigned long hash;
-       struct qstr this;
-@@ -918,11 +961,16 @@ struct dentry * lookup_one_len(const cha
-       }
-       this.hash = end_name_hash(hash);
--      return lookup_hash(&this, base);
-+      return lookup_hash(&this, base, it);
- access:
-       return ERR_PTR(-EACCES);
- }
-+struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
-+{
-+        return lookup_one_len_it(name, base, len, NULL);
-+}
-+
- /*
-  *    namei()
-  *
-@@ -1224,6 +1272,9 @@ int open_namei(const char * pathname, in
-       /*
-        * Create - we need to know the parent.
-        */
-+      nd->it.it_mode = mode;
-+      nd->it.it_op |= IT_CREAT;
-+              
-       error = path_lookup(pathname, LOOKUP_PARENT, nd);
-       if (error)
-               return error;
-@@ -1239,7 +1290,7 @@ int open_namei(const char * pathname, in
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash(&nd->last, nd->dentry, &nd->it);
- do_last:
-       error = PTR_ERR(dentry);
-@@ -1247,7 +1298,8 @@ do_last:
-               up(&dir->d_inode->i_sem);
-               goto exit;
-       }
--
-+        
-+      nd->it.it_mode = mode;
-       /* Negative dentry, just create the file */
-       if (!dentry->d_inode) {
-               if (!IS_POSIXACL(dir->d_inode))
-@@ -1277,7 +1329,7 @@ do_last:
-               error = -ELOOP;
-               if (flag & O_NOFOLLOW)
-                       goto exit_dput;
--              while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
-+              while (__follow_down(&nd->mnt,&dentry,&nd->it) && d_mountpoint(dentry));
-       }
-       error = -ENOENT;
-       if (!dentry->d_inode)
-@@ -1297,8 +1349,10 @@ ok:
-       return 0;
- exit_dput:
-+      intent_release(dentry, &nd->it);
-       dput(dentry);
- exit:
-+      intent_release(nd->dentry, &nd->it);
-       path_release(nd);
-       return error;
-@@ -1320,7 +1374,12 @@ do_link:
-       if (error)
-               goto exit_dput;
-       UPDATE_ATIME(dentry->d_inode);
--      error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (dentry->d_inode->i_op->follow_link2)
-+              error = dentry->d_inode->i_op->follow_link2(dentry, nd, &nd->it);
-+      else
-+              error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+        if (error)
-+              intent_release(dentry, &nd->it);
-       dput(dentry);
-       if (error)
-               return error;
-@@ -1342,7 +1401,7 @@ do_link:
-       }
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash(&nd->last, nd->dentry, &nd->it);
-       putname(nd->last.name);
-       goto do_last;
- }
-@@ -1356,7 +1415,7 @@ static struct dentry *lookup_create(stru
-       dentry = ERR_PTR(-EEXIST);
-       if (nd->last_type != LAST_NORM)
-               goto fail;
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash(&nd->last, nd->dentry, &nd->it);
-       if (IS_ERR(dentry))
-               goto fail;
-       if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1588,7 +1647,7 @@ asmlinkage long sys_rmdir(const char * p
-                       goto exit1;
-       }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      dentry = lookup_hash(&nd.last, nd.dentry, &nd.it);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1654,8 +1713,18 @@ asmlinkage long sys_unlink(const char * 
-       error = -EISDIR;
-       if (nd.last_type != LAST_NORM)
-               goto exit1;
-+      if (nd.dentry->d_inode->i_op->unlink2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              error = op->unlink2(nd.dentry->d_inode,
-+                              nd.last.name,
-+                              nd.last.len);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit1;
-+      }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+//    dentry = lookup_hash(&nd.last, nd.dentry, &nd.it);
-+      dentry = lookup_hash(&nd.last, nd.dentry, NULL);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               /* Why not before? Because we want correct error value */
-@@ -1859,7 +1928,8 @@ exit:
-  *       locking].
-  */
- int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+             struct inode *new_dir, struct dentry *new_dentry,
-+                                struct lookup_intent *it)
- {
-       int error = 0;
-       struct inode *target;
-@@ -1887,6 +1957,7 @@ int vfs_rename_dir(struct inode *old_dir
-               error = -EBUSY;
-       else 
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       if (target) {
-               if (!error)
-                       target->i_flags |= S_DEAD;
-@@ -1904,7 +1975,8 @@ int vfs_rename_dir(struct inode *old_dir
- }
- int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+             struct inode *new_dir, struct dentry *new_dentry,
-+               struct lookup_intent *it)
- {
-       struct inode *target;
-       int error;
-@@ -1921,6 +1993,7 @@ int vfs_rename_other(struct inode *old_d
-               error = -EBUSY;
-       else
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+        intent_release(new_dentry, it);
-       if (!error) {
-               /* The following d_move() should become unconditional */
-               if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME))
-@@ -1934,7 +2007,8 @@ int vfs_rename_other(struct inode *old_d
- }
- int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+             struct inode *new_dir, struct dentry *new_dentry, 
-+               struct lookup_intent *it)
- {
-       int error;
-       int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
-@@ -1960,9 +2034,9 @@ int vfs_rename(struct inode *old_dir, st
-       DQUOT_INIT(new_dir);
-       if (is_dir)
--              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry, it);
-       else
--              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry, it);
-       if (!error) {
-               if (old_dir == new_dir)
-                       inode_dir_notify(old_dir, DN_RENAME);
-@@ -2005,7 +2079,7 @@ static inline int do_rename(const char *
-       trap = lock_rename(new_dir, old_dir);
--      old_dentry = lookup_hash(&oldnd.last, old_dir);
-+      old_dentry = lookup_hash(&oldnd.last, old_dir, &oldnd.it);
-       error = PTR_ERR(old_dentry);
-       if (IS_ERR(old_dentry))
-               goto exit3;
-@@ -2025,7 +2099,7 @@ static inline int do_rename(const char *
-       error = -EINVAL;
-       if (old_dentry == trap)
-               goto exit4;
--      new_dentry = lookup_hash(&newnd.last, new_dir);
-+      new_dentry = lookup_hash(&newnd.last, new_dir, &newnd.it);
-       error = PTR_ERR(new_dentry);
-       if (IS_ERR(new_dentry))
-               goto exit4;
-@@ -2035,7 +2109,7 @@ static inline int do_rename(const char *
-               goto exit5;
-       error = vfs_rename(old_dir->d_inode, old_dentry,
--                                 new_dir->d_inode, new_dentry);
-+                                 new_dir->d_inode, new_dentry, NULL);
- exit5:
-       dput(new_dentry);
- exit4:
---- linux-2.5.63-nointent/fs/nfsd/vfs.c~lustre-2.5.63  Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/fs/nfsd/vfs.c   Tue Mar 18 15:02:10 2003
-@@ -1337,7 +1337,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
-                       err = nfserr_perm;
-       } else
- #endif
--      err = vfs_rename(fdir, odentry, tdir, ndentry);
-+      err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
-       if (!err && EX_ISSYNC(tfhp->fh_export)) {
-               nfsd_sync_dir(tdentry);
-               nfsd_sync_dir(fdentry);
---- linux-2.5.63-nointent/fs/sysfs/inode.c~lustre-2.5.63       Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/fs/sysfs/inode.c        Tue Mar 18 15:02:10 2003
-@@ -540,7 +540,7 @@ static struct dentry * get_dentry(struct
-       qstr.name = name;
-       qstr.len = strlen(name);
-       qstr.hash = full_name_hash(name,qstr.len);
--      return lookup_hash(&qstr,parent);
-+      return lookup_hash(&qstr,parent,NULL);
- }
---- linux-2.5.63-nointent/include/linux/dcache.h~lustre-2.5.63 Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/include/linux/dcache.h  Tue Mar 18 15:02:10 2003
-@@ -12,6 +12,27 @@
- struct vfsmount;
-+#define IT_OPEN     (1)
-+#define IT_CREAT    (1<<1)
-+#define IT_READDIR  (1<<2)
-+#define IT_GETATTR  (1<<3)
-+#define IT_LOOKUP   (1<<4)
-+#define IT_UNLINK   (1<<5)
-+
-+
-+struct lookup_intent {
-+       int it_op;
-+       int it_mode;
-+       int it_flags;
-+       int it_disposition;
-+       int it_status;
-+       struct iattr *it_iattr;
-+       __u64 it_lock_handle[2];
-+       int it_lock_mode;
-+       void *it_data;
-+};
-+
-+
- /*
-  * linux/include/linux/dcache.h
-  *
-@@ -34,6 +55,8 @@ struct qstr {
-       char name_str[0];
- };
-+#include <linux/namei.h>
-+
- struct dentry_stat_t {
-       int nr_dentry;
-       int nr_unused;
-@@ -87,6 +110,7 @@ struct dentry {
-       struct list_head d_subdirs;     /* our children */
-       struct list_head d_alias;       /* inode alias list */
-       int d_mounted;
-+        struct lookup_intent *d_it;
-       struct qstr d_name;
-       struct qstr * d_qstr;           /* quick str ptr used in lockless lookup and concurrent d_move */
-       unsigned long d_time;           /* used by d_revalidate */
-@@ -107,6 +131,8 @@ struct dentry_operations {
-       int (*d_delete)(struct dentry *);
-       void (*d_release)(struct dentry *);
-       void (*d_iput)(struct dentry *, struct inode *);
-+      int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
-+      void (*d_intent_release)(struct  dentry *, struct lookup_intent *);
- };
- /* the dentry parameter passed to d_hash and d_compare is the parent
-@@ -147,6 +173,8 @@ d_iput:            no              no              yes
- #define DCACHE_REFERENCED     0x0008  /* Recently used, don't discard. */
- #define DCACHE_UNHASHED               0x0010  
-+#define DCACHE_LUSTRE_INVALID     0x0011  /* Lustre invalidated */
-+
- extern spinlock_t dcache_lock;
- extern rwlock_t dparent_lock;
---- linux-2.5.63-nointent/include/linux/fs.h~lustre-2.5.63     Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/include/linux/fs.h      Tue Mar 18 15:02:10 2003
-@@ -234,6 +234,9 @@ typedef int (get_blocks_t)(struct inode 
- #define ATTR_ATTR_FLAG        1024
- #define ATTR_KILL_SUID        2048
- #define ATTR_KILL_SGID        4096
-+#define ATTR_RAW              8192    /* file system, not vfs will massage attrs */
-+#define ATTR_FROM_OPEN        16384    /* called from open path, ie O_TRUNC */
-+
- /*
-  * This is the Inode Attributes structure, used for notify_change().  It
-@@ -642,7 +645,7 @@ extern int vfs_symlink(struct inode *, s
- extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
- extern int vfs_rmdir(struct inode *, struct dentry *);
- extern int vfs_unlink(struct inode *, struct dentry *);
--extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
-+extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct lookup_intent *it);
- /*
-  * File types
-@@ -728,19 +731,33 @@ struct file_operations {
- struct inode_operations {
-       int (*create) (struct inode *,struct dentry *,int);
-       struct dentry * (*lookup) (struct inode *,struct dentry *);
-+      struct dentry * (*lookup2) (struct inode *,struct dentry *, 
-+                                    struct lookup_intent *);
-       int (*link) (struct dentry *,struct inode *,struct dentry *);
-+      int (*link2) (struct inode *,struct inode *, const char *, int);
-       int (*unlink) (struct inode *,struct dentry *);
-+      int (*unlink2) (struct inode *, const char *, int);
-       int (*symlink) (struct inode *,struct dentry *,const char *);
-+      int (*symlink2) (struct inode *, const char *, int, const char *);
-       int (*mkdir) (struct inode *,struct dentry *,int);
-+      int (*mkdir2) (struct inode *, const char *, int,int);
-       int (*rmdir) (struct inode *,struct dentry *);
-+      int (*rmdir2) (struct inode *, const char *, int);
-       int (*mknod) (struct inode *,struct dentry *,int,dev_t);
-+      int (*mknod2) (struct inode *, const char *, int,int,int);
-       int (*rename) (struct inode *, struct dentry *,
-                       struct inode *, struct dentry *);
-+      int (*rename2) (struct inode *, struct inode *,
-+                      const char *oldname, int oldlen,
-+                      const char *newname, int newlen);
-       int (*readlink) (struct dentry *, char *,int);
-       int (*follow_link) (struct dentry *, struct nameidata *);
-+      int (*follow_link2) (struct dentry *, struct nameidata *,
-+                              struct lookup_intent *it);
-       void (*truncate) (struct inode *);
-       int (*permission) (struct inode *, int);
-       int (*setattr) (struct dentry *, struct iattr *);
-+      int (*setattr_raw) (struct inode *, struct iattr *);
-       int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
-       int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
-       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t,int);
-@@ -953,6 +970,7 @@ extern int register_filesystem(struct fi
- extern int unregister_filesystem(struct file_system_type *);
- extern struct vfsmount *kern_mount(struct file_system_type *);
- extern int may_umount(struct vfsmount *);
-+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
- extern long do_mount(char *, char *, char *, unsigned long, void *);
- extern int vfs_statfs(struct super_block *, struct statfs *);
---- linux-2.5.63-nointent/include/linux/namei.h~lustre-2.5.63  Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/include/linux/namei.h   Tue Mar 18 15:02:10 2003
-@@ -11,6 +11,7 @@ struct nameidata {
-       struct qstr     last;
-       unsigned int    flags;
-       int             last_type;
-+   struct lookup_intent it;
- };
- /*
-@@ -44,7 +45,7 @@ extern int FASTCALL(link_path_walk(const
- extern void path_release(struct nameidata *);
- extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
--extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
-+extern struct dentry * lookup_hash(struct qstr *, struct dentry *, struct lookup_intent *);
- extern int follow_down(struct vfsmount **, struct dentry **);
- extern int follow_up(struct vfsmount **, struct dentry **);
---- linux-2.5.63-nointent/include/linux/slab.h~lustre-2.5.63   Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/include/linux/slab.h    Tue Mar 18 15:02:10 2003
-@@ -55,6 +55,7 @@ extern int kmem_cache_destroy(kmem_cache
- extern int kmem_cache_shrink(kmem_cache_t *);
- extern void *kmem_cache_alloc(kmem_cache_t *, int);
- extern void kmem_cache_free(kmem_cache_t *, void *);
-+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
- extern unsigned int kmem_cache_size(kmem_cache_t *);
- extern void *kmalloc(size_t, int);
---- linux-2.5.63-nointent/kernel/ksyms.c~lustre-2.5.63 Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/kernel/ksyms.c  Tue Mar 18 15:02:10 2003
-@@ -377,6 +377,7 @@ EXPORT_SYMBOL(unregister_filesystem);
- EXPORT_SYMBOL(kern_mount);
- EXPORT_SYMBOL(__mntput);
- EXPORT_SYMBOL(may_umount);
-+EXPORT_SYMBOL(reparent_to_init);
- /* executable format registration */
- EXPORT_SYMBOL(register_binfmt);
-@@ -407,6 +408,12 @@ EXPORT_SYMBOL(request_irq);
- EXPORT_SYMBOL(free_irq);
- EXPORT_SYMBOL(irq_stat);
-+/* lustre */
-+EXPORT_SYMBOL(do_kern_mount);
-+EXPORT_SYMBOL(exit_files);
-+EXPORT_SYMBOL(kmem_cache_validate);
-+
-+
- /* waitqueue handling */
- EXPORT_SYMBOL(add_wait_queue);
- EXPORT_SYMBOL(add_wait_queue_exclusive);
---- linux-2.5.63-nointent/mm/slab.c~lustre-2.5.63      Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/mm/slab.c       Tue Mar 18 15:02:10 2003
-@@ -1792,6 +1792,11 @@ static inline void __cache_free (kmem_ca
-       }
- }
-+int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
-+{
-+      return 1;
-+}
-+
- /**
-  * kmem_cache_alloc - Allocate an object
-  * @cachep: The cache to allocate from.
---- linux-2.5.63-nointent/net/unix/af_unix.c~lustre-2.5.63     Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/net/unix/af_unix.c      Tue Mar 18 15:02:10 2003
-@@ -720,7 +720,7 @@ static int unix_bind(struct socket *sock
-               /*
-                * Do the final lookup.
-                */
--              dentry = lookup_hash(&nd.last, nd.dentry);
-+              dentry = lookup_hash(&nd.last, nd.dentry, NULL);
-               err = PTR_ERR(dentry);
-               if (IS_ERR(dentry))
-                       goto out_mknod_unlock;
---- linux-2.5.63-nointent/fs/dcache.c~lustre-2.5.63    Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/fs/dcache.c     Tue Mar 18 15:02:10 2003
-@@ -1111,15 +1111,21 @@ void d_delete(struct dentry * dentry)
-  * Adds a dentry to the hash according to its name.
-  */
-  
--void d_rehash(struct dentry * entry)
-+void __d_rehash(struct dentry * entry, int lock)
- {
-       struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
--      spin_lock(&dcache_lock);
-+      if (lock) spin_lock(&dcache_lock);
-       if (!list_empty(&entry->d_hash) && !d_unhashed(entry)) BUG();
-       entry->d_vfs_flags &= ~DCACHE_UNHASHED;
-       entry->d_bucket = list;
-       list_add_rcu(&entry->d_hash, list);
--      spin_unlock(&dcache_lock);
-+      if (lock) spin_unlock(&dcache_lock);
-+}
-+EXPORT_SYMBOL(__d_rehash);
-+
-+void d_rehash(struct dentry * entry)
-+{
-+      __d_rehash(entry, 1);
- }
- #define do_switch(x,y) do { \
---- linux-2.5.63-nointent/fs/namespace.c~lustre-2.5.63 Tue Mar 18 15:02:10 2003
-+++ linux-2.5.63-nointent-root/fs/namespace.c  Tue Mar 18 15:02:10 2003
-@@ -925,6 +925,7 @@ void set_fs_pwd(struct fs_struct *fs, st
-               mntput(old_pwdmnt);
-       }
- }
-+EXPORT_SYMBOL(set_fs_pwd);
- static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
- {
---- linux-2.5.63-nointent/fs/open.c~lustre-2.5.63      Thu Mar 20 12:43:39 2003
-+++ linux-2.5.63-nointent-root/fs/open.c       Mon Mar 24 16:25:47 2003
-@@ -97,7 +97,8 @@ static inline long do_sys_truncate(const
-       struct nameidata nd;
-       struct inode * inode;
-       int error;
--
-+        struct lookup_intent it = { .it_op = IT_GETATTR };
-+      nd.it=it;
-       error = -EINVAL;
-       if (length < 0) /* sorry, but loff_t says... */
-               goto out;
-@@ -142,11 +143,13 @@ static inline long do_sys_truncate(const
-       error = locks_verify_truncate(inode, NULL, length);
-       if (!error) {
-               DQUOT_INIT(inode);
-+              intent_release(nd.dentry, &nd.it);
-               error = do_truncate(nd.dentry, length);
-       }
-       put_write_access(inode);
- dput_and_out:
-+      intent_release(nd.dentry, &nd.it);
-       path_release(&nd);
- out:
-       return error;
-@@ -340,6 +343,8 @@ asmlinkage long sys_access(const char * 
-       int old_fsuid, old_fsgid;
-       kernel_cap_t old_cap;
-       int res;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-+      nd.it=it;       
-       if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
-               return -EINVAL;
-@@ -371,6 +376,8 @@ asmlinkage long sys_access(const char * 
-               if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
-                  && !special_file(nd.dentry->d_inode->i_mode))
-                       res = -EROFS;
-+                              
-+              intent_release(nd.dentry, &nd.it);
-               path_release(&nd);
-       }
-@@ -385,6 +392,8 @@ asmlinkage long sys_chdir(const char * f
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-+      nd.it=it;       
-       error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
-       if (error)
-@@ -397,6 +406,7 @@ asmlinkage long sys_chdir(const char * f
-       set_fs_pwd(current->fs, nd.mnt, nd.dentry);
- dput_and_out:
-+      intent_release(nd.dentry, &nd.it);
-       path_release(&nd);
- out:
-       return error;
-@@ -436,6 +446,8 @@ asmlinkage long sys_chroot(const char * 
- {
-       struct nameidata nd;
-       int error;
-+        struct lookup_intent it = { .it_op = IT_GETATTR };
-+      nd.it=it;
-       error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
-       if (error)
-@@ -508,6 +520,18 @@ asmlinkage long sys_chmod(const char * f
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-+      
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_mode = mode;
-+              newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-       error = -EPERM;
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-@@ -619,7 +643,10 @@ asmlinkage long sys_fchown(unsigned int 
- struct file *filp_open(const char * filename, int flags, int mode)
- {
-       int namei_flags, error;
-+      struct file * temp_filp;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
-+      nd.it=it;       
-       namei_flags = flags;
-       if ((namei_flags+1) & O_ACCMODE)
-@@ -628,9 +655,11 @@ struct file *filp_open(const char * file
-               namei_flags |= 2;
-       error = open_namei(filename, namei_flags, mode, &nd);
--      if (!error)
--              return dentry_open(nd.dentry, nd.mnt, flags);
--
-+      if (!error) {
-+              temp_filp = dentry_open(nd.dentry, nd.mnt, flags);
-+              intent_release(nd.dentry,&nd.it);
-+              return temp_filp;
-+      }       
-       return ERR_PTR(error);
- }
-@@ -675,7 +704,7 @@ struct file *dentry_open(struct dentry *
-                               goto cleanup_all;
-               }
-       }
--
-+        
-       return f;
- cleanup_all:
---- linux-2.5.63-nointent/fs/stat.c~lustre-2.5.63      Fri Mar 21 21:15:40 2003
-+++ linux-2.5.63-nointent-root/fs/stat.c       Fri Mar 21 21:16:53 2003
-@@ -65,6 +65,7 @@ int vfs_stat(char *name, struct kstat *s
-       error = user_path_walk(name, &nd);
-       if (!error) {
-               error = vfs_getattr(nd.mnt, nd.dentry, stat);
-+              intent_release(nd.dentry, &nd.it);
-               path_release(&nd);
-       }
-       return error;
-@@ -80,6 +81,7 @@ int vfs_lstat(char *name, struct kstat *
-       error = user_path_walk_link(name, &nd);
-       if (!error) {
-               error = vfs_getattr(nd.mnt, nd.dentry, stat);
-+              intent_release(nd.dentry, &nd.it);
-               path_release(&nd);
-       }
-       return error;
-
-_
diff --git a/lustre/kernel_patches/patches/lustre_version.patch b/lustre/kernel_patches/patches/lustre_version.patch
deleted file mode 100644 (file)
index 2e69e01..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
- 0 files changed
-
---- /dev/null  2002-08-30 16:31:37.000000000 -0700
-+++ linux-2.4.18-17.8.0-zab/include/linux/lustre_version.h     2002-12-06 14:52:30.000000000 -0800
-@@ -0,0 +1 @@
-+#define LUSTRE_KERNEL_VERSION 5
-
-_
diff --git a/lustre/kernel_patches/patches/tcp-zero-copy-2.4.18.patch b/lustre/kernel_patches/patches/tcp-zero-copy-2.4.18.patch
deleted file mode 100644 (file)
index 878e95f..0000000
+++ /dev/null
@@ -1,476 +0,0 @@
-diff -u -r1.1.1.1 linux/include/linux/skbuff.h
---- linux/include/linux/skbuff.h       2 Aug 2002 10:59:25 -0000       1.1.1.1
-+++ linux/include/linux/skbuff.h       2 Aug 2002 14:20:00 -0000
-@@ -116,6 +116,30 @@
-       __u16 size;
- };
-
-+/* Support for callback when skb data has been released */
-+typedef struct zccd                           /* Zero Copy Callback Descriptor */
-+{                                             /* (embed as first member of custom struct) */
-+      atomic_t        zccd_count;             /* reference count */
-+      void           (*zccd_destructor)(struct zccd *); /* callback when refcount reaches zero */
-+} zccd_t;
-+
-+static inline void zccd_init (zccd_t *d, void (*callback)(zccd_t *))
-+{
-+      atomic_set (&d->zccd_count, 1);
-+      d->zccd_destructor = callback;
-+}
-+
-+static inline void zccd_get (zccd_t *d)               /* take a reference */
-+{
-+      atomic_inc (&d->zccd_count);
-+}
-+
-+static inline void zccd_put (zccd_t *d)               /* release a reference */
-+{
-+      if (atomic_dec_and_test (&d->zccd_count))
-+              (d->zccd_destructor)(d);
-+}
-+
- /* This data is invariant across clones and lives at
-  * the end of the header data, ie. at skb->end.
-  */
-@@ -123,6 +147,12 @@
-       atomic_t        dataref;
-       unsigned int    nr_frags;
-       struct sk_buff  *frag_list;
-+      zccd_t          *zccd;                  /* zero copy descriptor */
-+      zccd_t          *zccd2;                 /* 2nd zero copy descriptor */
-+      /* NB we expect zero-copy data to be at least 1 packet, so
-+       * having 2 zccds means we don't unneccessarily split the packet
-+       * where consecutive zero-copy sends abutt.
-+       */
-       skb_frag_t      frags[MAX_SKB_FRAGS];
- };
-
-diff -u -r1.1.1.1 linux/include/net/tcp.h
---- linux/include/net/tcp.h    2 Aug 2002 10:59:29 -0000       1.1.1.1
-+++ linux/include/net/tcp.h    2 Aug 2002 14:03:49 -0000
-@@ -639,6 +639,8 @@
-
- extern int                    tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size);
- extern ssize_t                        tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags);
-+extern ssize_t                        tcp_sendpage_zccd(struct socket *sock, struct page *page, int offset, size_t size,
-+                                                int flags, zccd_t *zccd);
-
- extern int                    tcp_ioctl(struct sock *sk,
-                                         int cmd,
-@@ -732,6 +734,9 @@
-                                           struct msghdr *msg,
-                                           int len, int nonblock,
-                                           int flags, int *addr_len);
-+extern int                    tcp_recvpackets(struct sock *sk,
-+                                              struct sk_buff_head *packets,
-+                                              int len, int nonblock);
-
- extern int                    tcp_listen_start(struct sock *sk);
-
-diff -u -r1.1.1.1 linux/net/netsyms.c
---- linux/net/netsyms.c        2 Aug 2002 10:59:31 -0000       1.1.1.1
-+++ linux/net/netsyms.c        2 Aug 2002 14:21:31 -0000
-@@ -395,6 +395,8 @@
- EXPORT_SYMBOL(sysctl_tcp_ecn);
- EXPORT_SYMBOL(tcp_cwnd_application_limited);
- EXPORT_SYMBOL(tcp_sendpage);
-+EXPORT_SYMBOL(tcp_sendpage_zccd);
-+EXPORT_SYMBOL(tcp_recvpackets);
-
- EXPORT_SYMBOL(tcp_write_xmit);
-
-diff -u -r1.1.1.1 linux/net/core/skbuff.c
---- linux/net/core/net/core/skbuff.c   2 Aug 2002 10:59:32 -0000       1.1.1.1
-+++ linux/net/core/net/core/skbuff.c   2 Aug 2002 14:07:13 -0000
-@@ -208,6 +208,8 @@
-       atomic_set(&(skb_shinfo(skb)->dataref), 1);
-       skb_shinfo(skb)->nr_frags = 0;
-       skb_shinfo(skb)->frag_list = NULL;
-+      skb_shinfo(skb)->zccd = NULL;           /* skbuffs kick off with NO user zero copy descriptors */
-+      skb_shinfo(skb)->zccd2 = NULL;
-       return skb;
-
- nodata:
-@@ -276,6 +278,10 @@
- {
-       if (!skb->cloned ||
-           atomic_dec_and_test(&(skb_shinfo(skb)->dataref))) {
-+              if (skb_shinfo(skb)->zccd != NULL) /* zero copy callback descriptor? */
-+                      zccd_put (skb_shinfo(skb)->zccd); /* release hold */
-+              if (skb_shinfo(skb)->zccd2 != NULL) /* 2nd zero copy callback descriptor? */
-+                      zccd_put (skb_shinfo(skb)->zccd2); /* release hold */
-               if (skb_shinfo(skb)->nr_frags) {
-                       int i;
-                       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-@@ -532,6 +538,8 @@
-       atomic_set(&(skb_shinfo(skb)->dataref), 1);
-       skb_shinfo(skb)->nr_frags = 0;
-       skb_shinfo(skb)->frag_list = NULL;
-+      skb_shinfo(skb)->zccd = NULL;           /* copied data => no user zero copy descriptor */
-+      skb_shinfo(skb)->zccd2 = NULL;
-
-       /* We are no longer a clone, even if we were. */
-       skb->cloned = 0;
-@@ -577,6 +585,14 @@
-
-       n->data_len = skb->data_len;
-       n->len = skb->len;
-+
-+      if (skb_shinfo(skb)->zccd != NULL)      /* user zero copy descriptor? */
-+              zccd_get (skb_shinfo(skb)->zccd); /* 1 more ref (pages are shared) */
-+      skb_shinfo(n)->zccd = skb_shinfo(skb)->zccd;
-+
-+      if (skb_shinfo(skb)->zccd2 != NULL)     /* 2nd user zero copy descriptor? */
-+              zccd_get (skb_shinfo(skb)->zccd2); /* 1 more ref (pages are shared) */
-+      skb_shinfo(n)->zccd2 = skb_shinfo(skb)->zccd2;
-
-       if (skb_shinfo(skb)->nr_frags) {
-               int i;
-@@ -620,6 +636,8 @@
-       u8 *data;
-       int size = nhead + (skb->end - skb->head) + ntail;
-       long off;
-+      zccd_t *zccd = skb_shinfo(skb)->zccd;   /* stash user zero copy descriptor */
-+      zccd_t *zccd2 = skb_shinfo(skb)->zccd2; /* stash 2nd user zero copy descriptor */
-
-       if (skb_shared(skb))
-               BUG();
-@@ -641,6 +659,11 @@
-       if (skb_shinfo(skb)->frag_list)
-               skb_clone_fraglist(skb);
-
-+      if (zccd != NULL)                       /* user zero copy descriptor? */
-+              zccd_get (zccd);                /* extra ref (pages are shared) */
-+      if (zccd2 != NULL)                      /* 2nd user zero copy descriptor? */
-+              zccd_get (zccd2);               /* extra ref (pages are shared) */
-+
-       skb_release_data(skb);
-
-       off = (data+nhead) - skb->head;
-@@ -655,6 +678,8 @@
-       skb->nh.raw += off;
-       skb->cloned = 0;
-       atomic_set(&skb_shinfo(skb)->dataref, 1);
-+      skb_shinfo(skb)->zccd = zccd;
-+      skb_shinfo(skb)->zccd2 = zccd2;
-       return 0;
-
- nodata:
-diff -u -r1.1.1.1 linux/net/ipv4/tcp.c
---- linux/net/ipv4/net/ipv4/tcp.c      2 Aug 2002 10:59:34 -0000       1.1.1.1
-+++ linux/net/ipv4/net/ipv4/tcp.c      2 Aug 2002 14:36:30 -0000
-@@ -745,7 +745,7 @@
-       goto out;
- }
-
--ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags);
-+ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags, zccd_t *zccd);
-
- static inline int
- can_coalesce(struct sk_buff *skb, int i, struct page *page, int off)
-@@ -824,7 +824,8 @@
-       return err;
- }
-
--ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags)
-+/* Extra parameter: user zero copy descriptor (or NULL if not doing that) */
-+ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags, zccd_t *zccd)
- {
-       struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-       int mss_now;
-@@ -872,6 +873,17 @@
-                       copy = size;
-
-               i = skb_shinfo(skb)->nr_frags;
-+
-+              if (zccd != NULL &&             /* this is a zcc I/O */
-+                  skb_shinfo(skb)->zccd != NULL && /* skb is part of a zcc I/O */
-+                  skb_shinfo(skb)->zccd2 != NULL &&
-+                  skb_shinfo(skb)->zccd != zccd && /* not the same one */
-+                  skb_shinfo(skb)->zccd2 != zccd)
-+              {
-+                      tcp_mark_push (tp, skb);
-+                      goto new_segment;
-+              }
-+
-               if (can_coalesce(skb, i, page, offset)) {
-                       skb_shinfo(skb)->frags[i-1].size += copy;
-               } else if (i < MAX_SKB_FRAGS) {
-@@ -881,6 +893,20 @@
-                       tcp_mark_push(tp, skb);
-                       goto new_segment;
-               }
-+
-+              if (zccd != NULL &&     /* this is a zcc I/O */
-+                  skb_shinfo(skb)->zccd != zccd && /* not already referencing this zccd */
-+                  skb_shinfo(skb)->zccd2 != zccd)
-+              {
-+                      zccd_get (zccd);        /* bump ref count */
-+
-+                      BUG_TRAP (skb_shinfo(skb)->zccd2 == NULL);
-+
-+                      if (skb_shinfo(skb)->zccd == NULL) /* reference this zccd */
-+                              skb_shinfo(skb)->zccd = zccd;
-+                      else
-+                              skb_shinfo(skb)->zccd2 = zccd;
-+              }
-
-               skb->len += copy;
-               skb->data_len += copy;
-@@ -945,7 +971,31 @@
-
-       lock_sock(sk);
-       TCP_CHECK_TIMER(sk);
--      res = do_tcp_sendpages(sk, &page, offset, size, flags);
-+      res = do_tcp_sendpages(sk, &page, offset, size, flags, NULL);
-+      TCP_CHECK_TIMER(sk);
-+      release_sock(sk);
-+      return res;
-+}
-+
-+ssize_t tcp_sendpage_zccd(struct socket *sock, struct page *page, int offset, size_t size,
-+                        int flags, zccd_t *zccd)
-+{
-+      ssize_t res;
-+      struct sock *sk = sock->sk;
-+
-+#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
-+
-+      if (!(sk->route_caps & NETIF_F_SG) ||   /* caller shouldn't waste her time */
-+          !(sk->route_caps & TCP_ZC_CSUM_FLAGS)) /* on double mapping */
-+              BUG ();
-+
-+#undef TCP_ZC_CSUM_FLAGS
-+
-+      lock_sock(sk);
-+      TCP_CHECK_TIMER(sk);
-+
-+      res = do_tcp_sendpages(sk, &page, offset, size, flags, zccd);
-+
-       TCP_CHECK_TIMER(sk);
-       release_sock(sk);
-       return res;
-@@ -1767,6 +1817,202 @@
- recv_urg:
-       err = tcp_recv_urg(sk, timeo, msg, len, flags, addr_len);
-       goto out;
-+}
-+
-+int tcp_recvpackets (struct sock *sk, struct sk_buff_head *packets,
-+                   int len, int nonblock)
-+{
-+      struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-+      int copied;
-+      long timeo;
-+
-+      BUG_TRAP (len > 0);
-+      BUG_TRAP ((flags & (MSG_OOB | MSG_PEEK | MSG_TRUNC)) == 0);
-+
-+      lock_sock(sk);
-+
-+      TCP_CHECK_TIMER(sk);
-+
-+      copied = -ENOTCONN;
-+      if (sk->state == TCP_LISTEN)
-+              goto out;
-+
-+      copied = 0;
-+      timeo = sock_rcvtimeo(sk, nonblock);
-+
-+      do {
-+              struct sk_buff * skb;
-+              u32 offset;
-+              unsigned long used;
-+              int exhausted;
-+              int eaten;
-+
-+              /* Are we at urgent data? Stop if we have read anything. */
-+              if (copied && tp->urg_data && tp->urg_seq == tp->copied_seq)
-+                      break;
-+
-+              /* We need to check signals first, to get correct SIGURG
-+               * handling. FIXME: Need to check this doesnt impact 1003.1g
-+               * and move it down to the bottom of the loop
-+               */
-+              if (signal_pending(current)) {
-+                      if (copied)
-+                              break;
-+                      copied = timeo ? sock_intr_errno(timeo) : -EAGAIN;
-+                      break;
-+              }
-+
-+              /* Next get a buffer. */
-+
-+              skb = skb_peek(&sk->receive_queue);
-+
-+              if (skb == NULL)                /* nothing ready */
-+              {
-+                      if (copied) {
-+                              if (sk->err ||
-+                                  sk->state == TCP_CLOSE ||
-+                                  (sk->shutdown & RCV_SHUTDOWN) ||
-+                                  !timeo ||
-+                                  (0))
-+                                      break;
-+                      } else {
-+                              if (sk->done)
-+                                      break;
-+
-+                              if (sk->err) {
-+                                      copied = sock_error(sk);
-+                                      break;
-+                              }
-+
-+                              if (sk->shutdown & RCV_SHUTDOWN)
-+                                      break;
-+
-+                              if (sk->state == TCP_CLOSE) {
-+                                      if (!sk->done) {
-+                                              /* This occurs when user tries to read
-+                                               * from never connected socket.
-+                                               */
-+                                              copied = -ENOTCONN;
-+                                              break;
-+                                      }
-+                                      break;
-+                              }
-+
-+                              if (!timeo) {
-+                                      copied = -EAGAIN;
-+                                      break;
-+                              }
-+                      }
-+
-+                      cleanup_rbuf(sk, copied);
-+                      timeo = tcp_data_wait(sk, timeo);
-+                      continue;
-+              }
-+
-+              BUG_TRAP (atomic_read (&skb->users) == 1);
-+
-+              exhausted = eaten = 0;
-+
-+              offset = tp->copied_seq - TCP_SKB_CB(skb)->seq;
-+              if (skb->h.th->syn)
-+                      offset--;
-+
-+              used = skb->len - offset;
-+
-+              if (tp->urg_data) {
-+                      u32 urg_offset = tp->urg_seq - tp->copied_seq;
-+                      if (urg_offset < used) {
-+                              if (!urg_offset) { /* at urgent date */
-+                                      if (!sk->urginline) {
-+                                              tp->copied_seq++; /* discard the single byte of urgent data */
-+                                              offset++;
-+                                              used--;
-+                                      }
-+                              } else          /* truncate read */
-+                                      used = urg_offset;
-+                      }
-+              }
-+
-+              BUG_TRAP (used >= 0);
-+              if (len < used)
-+                      used = len;
-+
-+              if (used == 0)
-+                      exhausted = 1;
-+              else
-+              {
-+                      if (skb_is_nonlinear (skb))
-+                      {
-+                              int   rc = skb_linearize (skb, GFP_KERNEL);
-+
-+                              printk ("tcp_recvpackets(): linearising: %d\n", rc);
-+
-+                              if (rc)
-+                              {
-+                                      if (!copied)
-+                                              copied = rc;
-+                                      break;
-+                              }
-+                      }
-+
-+                      if ((offset + used) == skb->len) /* consuming the whole packet */
-+                      {
-+                              __skb_unlink (skb, &sk->receive_queue);
-+                              dst_release (skb->dst);
-+                              skb_orphan (skb);
-+                              __skb_pull (skb, offset);
-+                              __skb_queue_tail (packets, skb);
-+                              exhausted = eaten = 1;
-+                      }
-+                      else                    /* consuming only part of the packet */
-+                      {
-+                              struct sk_buff *skb2 = skb_clone (skb, GFP_KERNEL);
-+
-+                              if (skb2 == NULL)
-+                              {
-+                                      if (!copied)
-+                                              copied = -ENOMEM;
-+                                      break;
-+                              }
-+
-+                              dst_release (skb2->dst);
-+                              __skb_pull (skb2, offset);
-+                              __skb_trim (skb2, used);
-+                              __skb_queue_tail (packets, skb2);
-+                      }
-+
-+                      tp->copied_seq += used;
-+                      copied += used;
-+                      len -= used;
-+              }
-+
-+              if (tp->urg_data && after(tp->copied_seq,tp->urg_seq)) {
-+                      tp->urg_data = 0;
-+                      tcp_fast_path_check(sk, tp);
-+              }
-+
-+              if (!exhausted)
-+                      continue;
-+
-+              if (skb->h.th->fin)
-+              {
-+                      tp->copied_seq++;
-+                      if (!eaten)
-+                              tcp_eat_skb (sk, skb);
-+                      break;
-+              }
-+
-+              if (!eaten)
-+                      tcp_eat_skb (sk, skb);
-+
-+      } while (len > 0);
-+
-+ out:
-+      /* Clean up data we have read: This will do ACK frames. */
-+      cleanup_rbuf(sk, copied);
-+      TCP_CHECK_TIMER(sk);
-+      release_sock(sk);
-+      return copied;
- }
-
- /*
-
-
-
-
-------=_NextPart_000_00A5_01C29D5C.787B8C30
-Content-Type: application/ms-tnef;
-       name="winmail.dat"
-Content-Transfer-Encoding: base64
-Content-Disposition: attachment;
-       filename="winmail.dat"
-
-eJ8+IgATAQaQCAAEAAAAAAABAAEAAQeQBgAIAAAA5AQAAAAAAADoAAEIgAcAGAAAAElQTS5NaWNy
-b3NvZnQgTWFpbC5Ob3RlADEIAQ2ABAACAAAAAgACAAEDkAYAJAEAAAkAAAACAR0MAQAAAB0AAABT
-TVRQOkVSSUNAQkFSVE9OU09GVFdBUkUuQ09NAAAAAAsAAQ4BAAAAAwAUDgEAAAACAfgPAQAAABAA
-AAAqejobp4bREYPyAKDJDOioAgH6DwEAAAAQAAAAKno6G6eG0RGD8gCgyQzoqAIB+w8BAAAATgAA
-AAAAAAA4obsQBeUQGqG7CAArKlbCAABtc3BzdC5kbGwAAAAAAE5JVEH5v7gBAKoAN9luAAAARDpc
-aG9tZVxtcy1tYWlsXGVyaWMucHN0AAAAAwD+DwUAAAADAA00/TcAAAIBfwABAAAAMQAAADAwMDAw
-MDAwMkE3QTNBMUJBNzg2RDExMTgzRjIwMEEwQzkwQ0U4QTgwNEQwMTAwMQAAAADQQA==
-
-------=_NextPart_000_00A5_01C29D5C.787B8C30--
-
diff --git a/lustre/kernel_patches/patches/uml_check_get_page.patch b/lustre/kernel_patches/patches/uml_check_get_page.patch
deleted file mode 100644 (file)
index fafdf90..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
- 0 files changed
-
---- linux-2.4.18-17.8.0/arch/um/kernel/mem.c~uml_check_get_page        2002-12-06 14:52:30.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/arch/um/kernel/mem.c       2002-12-06 14:52:30.000000000 -0800
-@@ -529,6 +529,21 @@ struct page *pte_mem_map(pte_t pte)
-       return(phys_mem_map(pte_val(pte)));
- }
-+struct page *check_get_page(unsigned long kaddr)
-+{
-+      struct page *page;
-+      struct mem_region *mr;
-+      unsigned long phys = __pa(kaddr);
-+      unsigned int n = phys_region_index(phys);
-+
-+      if (regions[n] == NULL)
-+                return NULL;
-+
-+      mr = regions[n];
-+      page = (struct page *) mr->mem_map;
-+      return page + ((phys_addr(phys)) >> PAGE_SHIFT);
-+}
-+
- struct mem_region *page_region(struct page *page, int *index_out)
- {
-       int i;
-
-_
diff --git a/lustre/kernel_patches/patches/uml_compile_fixes.patch b/lustre/kernel_patches/patches/uml_compile_fixes.patch
deleted file mode 100644 (file)
index 815bd92..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- 0 files changed
-
---- linux-2.4.18-17.8.0/include/asm-um/pgtable.h~uml_compile_fixes     2002-12-06 15:46:21.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/include/asm-um/pgtable.h   2002-12-06 15:46:21.000000000 -0800
-@@ -200,7 +200,7 @@ static inline void pgd_clear(pgd_t * pgd
-  * called on a highmem page.
-  */
--#define page_address(page) ({ if (!(page)->virtual) BUG(); (page)->virtual; })
-+//#define page_address(page) ({ if (!(page)->virtual) BUG(); (page)->virtual; })
- #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
- extern struct page *pte_mem_map(pte_t pte);
-
-_
diff --git a/lustre/kernel_patches/patches/uml_no_panic.patch b/lustre/kernel_patches/patches/uml_no_panic.patch
deleted file mode 100644 (file)
index b0c305b..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
- 0 files changed
-
---- linux-2.4.18-17.8.0/arch/um/kernel/mem.c~uml_no_panic      2002-12-06 14:52:30.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/arch/um/kernel/mem.c       2002-12-06 14:52:30.000000000 -0800
-@@ -559,7 +559,9 @@ struct mem_region *page_region(struct pa
-                       return(region);
-               }
-       }
--      panic("No region found for page");
-+//    panic("No region found for page");
-+      printk(KERN_ERR "no region foudn for page %p\n, returning NULL\n", 
-+                      page);
-       return(NULL);
- }
-@@ -581,7 +583,9 @@ unsigned long region_pa(void *virt)
-                  (addr <= region->start + region->len))
-                       return(mk_phys(addr - region->start, i));
-       }
--      panic("region_pa : no region for virtual address");
-+      //panic("region_pa : no region for virtual address");
-+      printk(KERN_ERR "no region for virtual address %lu, return pa 0\n",
-+                      addr);
-       return(0);
- }
-
-_
diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch
deleted file mode 100644 (file)
index 906620f..0000000
+++ /dev/null
@@ -1,1472 +0,0 @@
- fs/dcache.c            |   20 ++
- fs/exec.c              |   16 +-
- fs/namei.c             |  356 +++++++++++++++++++++++++++++++++++++++++--------
- fs/nfsd/vfs.c          |    2 
- fs/open.c              |  125 ++++++++++++++---
- fs/stat.c              |    8 -
- include/linux/dcache.h |   28 +++
- include/linux/fs.h     |   31 +++-
- kernel/ksyms.c         |    1 
- 9 files changed, 500 insertions(+), 87 deletions(-)
-
---- linux-rh-2.4.20-8/fs/dcache.c~vfs_intent-2.4.20-rh 2003-04-11 14:04:58.000000000 +0800
-+++ linux-rh-2.4.20-8-root/fs/dcache.c 2003-04-23 18:27:35.000000000 +0800
-@@ -186,6 +186,13 @@ int d_invalidate(struct dentry * dentry)
-               spin_unlock(&dcache_lock);
-               return 0;
-       }
-+
-+      /* network invalidation by Lustre */
-+      if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
-+              spin_unlock(&dcache_lock);
-+              return 0;
-+      }
-+
-       /*
-        * Check whether to do a partial shrink_dcache
-        * to get rid of unused child entries.
-@@ -624,6 +631,7 @@ struct dentry * d_alloc(struct dentry * 
-       dentry->d_fsdata = NULL;
-       dentry->d_extra_attributes = NULL;
-       dentry->d_mounted = 0;
-+      dentry->d_it = NULL;
-       dentry->d_cookie = NULL;
-       INIT_LIST_HEAD(&dentry->d_hash);
-       INIT_LIST_HEAD(&dentry->d_lru);
-@@ -839,13 +847,19 @@ void d_delete(struct dentry * dentry)
-  * Adds a dentry to the hash according to its name.
-  */
-  
--void d_rehash(struct dentry * entry)
-+void __d_rehash(struct dentry * entry, int lock)
- {
-       struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
-       if (!list_empty(&entry->d_hash)) BUG();
--      spin_lock(&dcache_lock);
-+      if (lock) spin_lock(&dcache_lock);
-       list_add(&entry->d_hash, list);
--      spin_unlock(&dcache_lock);
-+      if (lock) spin_unlock(&dcache_lock);
-+}
-+EXPORT_SYMBOL(__d_rehash);
-+
-+void d_rehash(struct dentry * entry)
-+{
-+      __d_rehash(entry, 1);
- }
- #define do_switch(x,y) do { \
---- linux-rh-2.4.20-8/fs/namei.c~vfs_intent-2.4.20-rh  2003-04-11 14:04:57.000000000 +0800
-+++ linux-rh-2.4.20-8-root/fs/namei.c  2003-04-23 18:27:35.000000000 +0800
-@@ -94,6 +94,13 @@
-  * XEmacs seems to be relying on it...
-  */
-+void intent_release(struct dentry *de, struct lookup_intent *it)
-+{
-+      if (it && de->d_op && de->d_op->d_intent_release)
-+              de->d_op->d_intent_release(de, it);
-+
-+}
-+
- /* In order to reduce some races, while at the same time doing additional
-  * checking and hopefully speeding things up, we copy filenames to the
-  * kernel data space before using them..
-@@ -260,10 +267,19 @@ void path_release(struct nameidata *nd)
-  * Internal lookup() using the new generic dcache.
-  * SMP-safe
-  */
--static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
-+                                  int flags, struct lookup_intent *it)
- {
-       struct dentry * dentry = d_lookup(parent, name);
-+      if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+              if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
-+                  !d_invalidate(dentry)) {
-+                      dput(dentry);
-+                      dentry = NULL;
-+              }
-+              return dentry;
-+      } else
-       if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-               if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
-                       dput(dentry);
-@@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str
-  * make sure that nobody added the entry to the dcache in the meantime..
-  * SMP-safe
-  */
--static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
-+                                int flags, struct lookup_intent *it)
- {
-       struct dentry * result;
-       struct inode *dir = parent->d_inode;
-+again:
-+
-       down(&dir->i_sem);
-       /*
-        * First re-do the cached lookup just in case it was created
-@@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc
-               result = ERR_PTR(-ENOMEM);
-               if (dentry) {
-                       lock_kernel();
-+                      if (dir->i_op->lookup2)
-+                              result = dir->i_op->lookup2(dir, dentry, it);
-+                      else
-                       result = dir->i_op->lookup(dir, dentry);
-                       unlock_kernel();
-                       if (result)
-@@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc
-                       dput(result);
-                       result = ERR_PTR(-ENOENT);
-               }
-+      } else if (result->d_op && result->d_op->d_revalidate2) {
-+              if (!result->d_op->d_revalidate2(result, flags, it) &&
-+                  !d_invalidate(result)) {
-+                      dput(result);
-+                      goto again;
-+              }
-       }
-       return result;
- }
-@@ -334,7 +362,8 @@ int max_recursive_link = 5;
-  * Without that kind of total limit, nasty chains of consecutive
-  * symlinks can cause almost arbitrarily long lookups. 
-  */
--static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
-+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
-+                               struct lookup_intent *it)
- {
-       int err;
-       if (current->link_count >= max_recursive_link)
-@@ -348,10 +377,14 @@ static inline int do_follow_link(struct 
-       current->link_count++;
-       current->total_link_count++;
-       UPDATE_ATIME(dentry->d_inode);
--      err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (dentry->d_inode->i_op->follow_link2)
-+              err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
-+      else
-+              err = dentry->d_inode->i_op->follow_link(dentry, nd);
-       current->link_count--;
-       return err;
- loop:
-+      intent_release(dentry, it);
-       path_release(nd);
-       return -ELOOP;
- }
-@@ -381,15 +414,26 @@ int follow_up(struct vfsmount **mnt, str
-       return __follow_up(mnt, dentry);
- }
--static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
-+static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
-+                              struct lookup_intent *it)
- {
-       struct vfsmount *mounted;
-       spin_lock(&dcache_lock);
-       mounted = lookup_mnt(*mnt, *dentry);
-       if (mounted) {
-+              int opc = 0, mode = 0;
-               *mnt = mntget(mounted);
-               spin_unlock(&dcache_lock);
-+              if (it) {
-+                      opc = it->it_op;
-+                      mode = it->it_mode;
-+              }
-+              intent_release(*dentry, it);
-+              if (it) {
-+                      it->it_op = opc;
-+                      it->it_mode = mode;
-+              }
-               dput(*dentry);
-               mntput(mounted->mnt_parent);
-               *dentry = dget(mounted->mnt_root);
-@@ -401,7 +445,7 @@ static inline int __follow_down(struct v
- int follow_down(struct vfsmount **mnt, struct dentry **dentry)
- {
--      return __follow_down(mnt,dentry);
-+      return __follow_down(mnt,dentry,NULL);
- }
-  
- static inline void follow_dotdot(struct nameidata *nd)
-@@ -437,7 +481,7 @@ static inline void follow_dotdot(struct 
-               mntput(nd->mnt);
-               nd->mnt = parent;
-       }
--      while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
-+      while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL))
-               ;
- }
-@@ -449,7 +493,8 @@ static inline void follow_dotdot(struct 
-  *
-  * We expect 'base' to be positive and a directory.
-  */
--int link_path_walk(const char * name, struct nameidata *nd)
-+int link_path_walk_it(const char *name, struct nameidata *nd,
-+                    struct lookup_intent *it)
- {
-       struct dentry *dentry;
-       struct inode *inode;
-@@ -526,18 +571,18 @@ int link_path_walk(const char * name, st
-                               break;
-               }
-               /* This does the actual lookups.. */
--              dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
-+              dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
-               if (!dentry) {
-                       err = -EWOULDBLOCKIO;
-                       if (atomic)
-                               break;
--                      dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
-+                      dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
-                       err = PTR_ERR(dentry);
-                       if (IS_ERR(dentry))
-                               break;
-               }
-               /* Check mountpoints.. */
--              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
-+              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL))
-                       ;
-               err = -ENOENT;
-@@ -548,8 +593,8 @@ int link_path_walk(const char * name, st
-               if (!inode->i_op)
-                       goto out_dput;
--              if (inode->i_op->follow_link) {
--                      err = do_follow_link(dentry, nd);
-+              if (inode->i_op->follow_link || inode->i_op->follow_link2) {
-+                      err = do_follow_link(dentry, nd, NULL);
-                       dput(dentry);
-                       if (err)
-                               goto return_err;
-@@ -565,7 +610,7 @@ int link_path_walk(const char * name, st
-                       nd->dentry = dentry;
-               }
-               err = -ENOTDIR; 
--              if (!inode->i_op->lookup)
-+              if (!inode->i_op->lookup && !inode->i_op->lookup2)
-                       break;
-               continue;
-               /* here ends the main loop */
-@@ -592,22 +637,23 @@ last_component:
-                       if (err < 0)
-                               break;
-               }
--              dentry = cached_lookup(nd->dentry, &this, 0);
-+              dentry = cached_lookup(nd->dentry, &this, 0, it);
-               if (!dentry) {
-                       err = -EWOULDBLOCKIO;
-                       if (atomic)
-                               break;
--                      dentry = real_lookup(nd->dentry, &this, 0);
-+                      dentry = real_lookup(nd->dentry, &this, 0, it);
-                       err = PTR_ERR(dentry);
-                       if (IS_ERR(dentry))
-                               break;
-               }
--              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
-+              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, it))
-                       ;
-               inode = dentry->d_inode;
-               if ((lookup_flags & LOOKUP_FOLLOW)
--                  && inode && inode->i_op && inode->i_op->follow_link) {
--                      err = do_follow_link(dentry, nd);
-+                  && inode && inode->i_op &&
-+                  (inode->i_op->follow_link || inode->i_op->follow_link2)) {
-+                      err = do_follow_link(dentry, nd, it);
-                       dput(dentry);
-                       if (err)
-                               goto return_err;
-@@ -621,7 +667,8 @@ last_component:
-                       goto no_inode;
-               if (lookup_flags & LOOKUP_DIRECTORY) {
-                       err = -ENOTDIR; 
--                      if (!inode->i_op || !inode->i_op->lookup)
-+                      if (!inode->i_op ||
-+                          (!inode->i_op->lookup && !inode->i_op->lookup2))
-                               break;
-               }
-               goto return_base;
-@@ -645,6 +692,23 @@ return_reval:
-                * Check the cached dentry for staleness.
-                */
-               dentry = nd->dentry;
-+        revalidate_again:
-+              if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+                      err = -ESTALE;
-+                      if (!dentry->d_op->d_revalidate2(dentry, 0, it)) {
-+                                struct dentry *new;
-+                                err = permission(dentry->d_parent->d_inode, 
-+                                                 MAY_EXEC);
-+                                if (err)
-+                                        break;
-+                                new = real_lookup(dentry->d_parent,
-+                                                  &dentry->d_name, 0, NULL);
-+                              d_invalidate(dentry);
-+                                dput(dentry);
-+                                dentry = new;
-+                                goto revalidate_again;
-+                        }
-+              } else
-               if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-                       err = -ESTALE;
-                       if (!dentry->d_op->d_revalidate(dentry, 0)) {
-@@ -658,15 +722,28 @@ out_dput:
-               dput(dentry);
-               break;
-       }
-+      if (err)
-+              intent_release(nd->dentry, it);
-       path_release(nd);
- return_err:
-       return err;
- }
-+int link_path_walk(const char * name, struct nameidata *nd)
-+{
-+      return link_path_walk_it(name, nd, NULL);
-+}
-+
-+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
-+{
-+      current->total_link_count = 0;
-+      return link_path_walk_it(name, nd, it);
-+}
-+
- int path_walk(const char * name, struct nameidata *nd)
- {
-       current->total_link_count = 0;
--      return link_path_walk(name, nd);
-+      return link_path_walk_it(name, nd, NULL);
- }
- /* SMP-safe */
-@@ -751,6 +828,17 @@ walk_init_root(const char *name, struct 
- }
- /* SMP-safe */
-+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
-+                 struct lookup_intent *it)
-+{
-+      int error = 0;
-+      if (path_init(path, flags, nd))
-+              error = path_walk_it(path, nd, it);
-+      return error;
-+}
-+
-+
-+/* SMP-safe */
- int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
- {
-       int error = 0;
-@@ -779,7 +867,8 @@ int path_init(const char *name, unsigned
-  * needs parent already locked. Doesn't follow mounts.
-  * SMP-safe.
-  */
--struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
-+                             struct lookup_intent *it)
- {
-       struct dentry * dentry;
-       struct inode *inode;
-@@ -802,13 +891,16 @@ struct dentry * lookup_hash(struct qstr 
-                       goto out;
-       }
--      dentry = cached_lookup(base, name, 0);
-+      dentry = cached_lookup(base, name, 0, it);
-       if (!dentry) {
-               struct dentry *new = d_alloc(base, name);
-               dentry = ERR_PTR(-ENOMEM);
-               if (!new)
-                       goto out;
-               lock_kernel();
-+              if (inode->i_op->lookup2)
-+                      dentry = inode->i_op->lookup2(inode, new, it);
-+              else
-               dentry = inode->i_op->lookup(inode, new);
-               unlock_kernel();
-               if (!dentry)
-@@ -820,6 +912,12 @@ out:
-       return dentry;
- }
-+struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+{
-+      return lookup_hash_it(name, base, NULL);
-+}
-+
-+
- /* SMP-safe */
- struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
- {
-@@ -841,7 +939,7 @@ struct dentry * lookup_one_len(const cha
-       }
-       this.hash = end_name_hash(hash);
--      return lookup_hash(&this, base);
-+      return lookup_hash_it(&this, base, NULL);
- access:
-       return ERR_PTR(-EACCES);
- }
-@@ -872,6 +970,23 @@ int __user_walk(const char *name, unsign
-       return err;
- }
-+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
-+                 struct lookup_intent *it)
-+{
-+      char *tmp;
-+      int err;
-+
-+      tmp = getname(name);
-+      err = PTR_ERR(tmp);
-+      if (!IS_ERR(tmp)) {
-+              err = 0;
-+              if (path_init(tmp, flags, nd))
-+                      err = path_walk_it(tmp, nd, it);
-+              putname(tmp);
-+      }
-+      return err;
-+}
-+
- /*
-  * It's inline, so penalty for filesystems that don't use sticky bit is
-  * minimal.
-@@ -1010,7 +1125,8 @@ exit_lock:
-  * for symlinks (where the permissions are checked later).
-  * SMP-safe
-  */
--int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
-+int open_namei_it(const char *pathname, int flag, int mode,
-+                struct nameidata *nd, struct lookup_intent *it)
- {
-       int acc_mode, error = 0;
-       struct inode *inode;
-@@ -1024,7 +1140,7 @@ int open_namei(const char * pathname, in
-        * The simplest case - just a plain lookup.
-        */
-       if (!(flag & O_CREAT)) {
--              error = path_lookup(pathname, lookup_flags(flag), nd);
-+              error = path_lookup_it(pathname, lookup_flags(flag), nd, it);
-               if (error)
-                       return error;
-               dentry = nd->dentry;
-@@ -1034,6 +1150,10 @@ int open_namei(const char * pathname, in
-       /*
-        * Create - we need to know the parent.
-        */
-+      if (it) {
-+              it->it_mode = mode;
-+              it->it_op |= IT_CREAT;
-+      }
-       error = path_lookup(pathname, LOOKUP_PARENT, nd);
-       if (error)
-               return error;
-@@ -1049,7 +1169,7 @@ int open_namei(const char * pathname, in
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
- do_last:
-       error = PTR_ERR(dentry);
-@@ -1058,6 +1178,7 @@ do_last:
-               goto exit;
-       }
-+      it->it_mode = mode;
-       /* Negative dentry, just create the file */
-       if (!dentry->d_inode) {
-               error = vfs_create(dir->d_inode, dentry,
-@@ -1086,12 +1207,13 @@ do_last:
-               error = -ELOOP;
-               if (flag & O_NOFOLLOW)
-                       goto exit_dput;
--              while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
-+              while (__follow_down(&nd->mnt,&dentry,it) && d_mountpoint(dentry));
-       }
-       error = -ENOENT;
-       if (!dentry->d_inode)
-               goto exit_dput;
--      if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
-+      if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
-+                                    dentry->d_inode->i_op->follow_link2))
-               goto do_link;
-       dput(nd->dentry);
-@@ -1165,7 +1287,7 @@ ok:
-               if (!error) {
-                       DQUOT_INIT(inode);
-                       
--                      error = do_truncate(dentry, 0);
-+                      error = do_truncate(dentry, 0, 1);
-               }
-               put_write_access(inode);
-               if (error)
-@@ -1177,8 +1299,10 @@ ok:
-       return 0;
- exit_dput:
-+      intent_release(dentry, it);
-       dput(dentry);
- exit:
-+      intent_release(nd->dentry, it);
-       path_release(nd);
-       return error;
-@@ -1197,7 +1321,12 @@ do_link:
-        * are done. Procfs-like symlinks just set LAST_BIND.
-        */
-       UPDATE_ATIME(dentry->d_inode);
--      error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (dentry->d_inode->i_op->follow_link2)
-+              error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
-+      else
-+              error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (error)
-+              intent_release(dentry, it);
-       dput(dentry);
-       if (error)
-               return error;
-@@ -1219,13 +1348,20 @@ do_link:
-       }
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
-       putname(nd->last.name);
-       goto do_last;
- }
-+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
-+{
-+      return open_namei_it(pathname, flag, mode, nd, NULL);
-+}
-+
-+
- /* SMP-safe */
--static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
-+static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
-+                                  struct lookup_intent *it)
- {
-       struct dentry *dentry;
-@@ -1233,7 +1369,7 @@ static struct dentry *lookup_create(stru
-       dentry = ERR_PTR(-EEXIST);
-       if (nd->last_type != LAST_NORM)
-               goto fail;
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
-       if (IS_ERR(dentry))
-               goto fail;
-       if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1289,7 +1425,19 @@ asmlinkage long sys_mknod(const char * f
-       error = path_lookup(tmp, LOOKUP_PARENT, &nd);
-       if (error)
-               goto out;
--      dentry = lookup_create(&nd, 0);
-+
-+      if (nd.dentry->d_inode->i_op->mknod2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              error = op->mknod2(nd.dentry->d_inode,
-+                                 nd.last.name,
-+                                 nd.last.len,
-+                                 mode, dev);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto out2;
-+      }
-+
-+      dentry = lookup_create(&nd, 0, NULL);
-       error = PTR_ERR(dentry);
-       mode &= ~current->fs->umask;
-@@ -1310,6 +1458,7 @@ asmlinkage long sys_mknod(const char * f
-               dput(dentry);
-       }
-       up(&nd.dentry->d_inode->i_sem);
-+out2:
-       path_release(&nd);
- out:
-       putname(tmp);
-@@ -1357,7 +1506,17 @@ asmlinkage long sys_mkdir(const char * p
-               error = path_lookup(tmp, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
--              dentry = lookup_create(&nd, 1);
-+              if (nd.dentry->d_inode->i_op->mkdir2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->mkdir2(nd.dentry->d_inode,
-+                                         nd.last.name,
-+                                         nd.last.len,
-+                                         mode);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out2;
-+              }
-+              dentry = lookup_create(&nd, 1, NULL);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_mkdir(nd.dentry->d_inode, dentry,
-@@ -1365,6 +1524,7 @@ asmlinkage long sys_mkdir(const char * p
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-+out2:
-               path_release(&nd);
- out:
-               putname(tmp);
-@@ -1465,8 +1625,33 @@ asmlinkage long sys_rmdir(const char * p
-                       error = -EBUSY;
-                       goto exit1;
-       }
-+      if (nd.dentry->d_inode->i_op->rmdir2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              struct dentry *last;
-+
-+              down(&nd.dentry->d_inode->i_sem);
-+              last = lookup_hash_it(&nd.last, nd.dentry, NULL);
-+              up(&nd.dentry->d_inode->i_sem);
-+              if (IS_ERR(last)) {
-+                      error = PTR_ERR(last);
-+                      goto exit1;
-+              }
-+              if (d_mountpoint(last)) {
-+                      dput(last);
-+                      error = -EBUSY;
-+                      goto exit1;
-+              }
-+              dput(last);
-+
-+              error = op->rmdir2(nd.dentry->d_inode,
-+                                 nd.last.name,
-+                                 nd.last.len);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit1;
-+      }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1524,8 +1709,17 @@ asmlinkage long sys_unlink(const char * 
-       error = -EISDIR;
-       if (nd.last_type != LAST_NORM)
-               goto exit1;
-+      if (nd.dentry->d_inode->i_op->unlink2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              error = op->unlink2(nd.dentry->d_inode,
-+                                  nd.last.name,
-+                                  nd.last.len);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit1;
-+      }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               /* Why not before? Because we want correct error value */
-@@ -1592,15 +1786,26 @@ asmlinkage long sys_symlink(const char *
-               error = path_lookup(to, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
--              dentry = lookup_create(&nd, 0);
-+              if (nd.dentry->d_inode->i_op->symlink2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->symlink2(nd.dentry->d_inode,
-+                                           nd.last.name,
-+                                           nd.last.len,
-+                                           from);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out2;
-+              }
-+              dentry = lookup_create(&nd, 0, NULL);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_symlink(nd.dentry->d_inode, dentry, from);
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-+      out2:
-               path_release(&nd);
--out:
-+      out:
-               putname(to);
-       }
-       putname(from);
-@@ -1676,7 +1881,17 @@ asmlinkage long sys_link(const char * ol
-               error = -EXDEV;
-               if (old_nd.mnt != nd.mnt)
-                       goto out_release;
--              new_dentry = lookup_create(&nd, 0);
-+              if (nd.dentry->d_inode->i_op->link2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->link2(old_nd.dentry->d_inode,
-+                                        nd.dentry->d_inode,
-+                                        nd.last.name,
-+                                        nd.last.len);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out_release;
-+              }
-+              new_dentry = lookup_create(&nd, 0, NULL);
-               error = PTR_ERR(new_dentry);
-               if (!IS_ERR(new_dentry)) {
-                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-@@ -1720,7 +1935,8 @@ exit:
-  *       locking].
-  */
- int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+                 struct inode *new_dir, struct dentry *new_dentry,
-+                 struct lookup_intent *it)
- {
-       int error;
-       struct inode *target;
-@@ -1778,6 +1994,7 @@ int vfs_rename_dir(struct inode *old_dir
-               error = -EBUSY;
-       else 
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       if (target) {
-               if (!error)
-                       target->i_flags |= S_DEAD;
-@@ -1799,7 +2016,8 @@ out_unlock:
- }
- int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+                   struct inode *new_dir, struct dentry *new_dentry,
-+                   struct lookup_intent *it)
- {
-       int error;
-@@ -1830,6 +2048,7 @@ int vfs_rename_other(struct inode *old_d
-               error = -EBUSY;
-       else
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       double_up(&old_dir->i_zombie, &new_dir->i_zombie);
-       if (error)
-               return error;
-@@ -1841,13 +2060,14 @@ int vfs_rename_other(struct inode *old_d
- }
- int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+             struct inode *new_dir, struct dentry *new_dentry,
-+             struct lookup_intent *it)
- {
-       int error;
-       if (S_ISDIR(old_dentry->d_inode->i_mode))
--              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
-       else
--              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
-       if (!error) {
-               if (old_dir == new_dir)
-                       inode_dir_notify(old_dir, DN_RENAME);
-@@ -1889,7 +2109,7 @@ static inline int do_rename(const char *
-       double_lock(new_dir, old_dir);
--      old_dentry = lookup_hash(&oldnd.last, old_dir);
-+      old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL);
-       error = PTR_ERR(old_dentry);
-       if (IS_ERR(old_dentry))
-               goto exit3;
-@@ -1905,16 +2125,37 @@ static inline int do_rename(const char *
-               if (newnd.last.name[newnd.last.len])
-                       goto exit4;
-       }
--      new_dentry = lookup_hash(&newnd.last, new_dir);
-+      new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL);
-       error = PTR_ERR(new_dentry);
-       if (IS_ERR(new_dentry))
-               goto exit4;
-+      if (old_dir->d_inode->i_op->rename2) {
-+              lock_kernel();
-+              /* don't rename mount point. mds will take care of
-+               * the rest sanity checking */
-+              if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) {
-+                      error = -EBUSY;
-+                      goto exit5;
-+              }
-+
-+              error = old_dir->d_inode->i_op->rename2(old_dir->d_inode,
-+                                                      new_dir->d_inode,
-+                                                      oldnd.last.name,
-+                                                      oldnd.last.len,
-+                                                      newnd.last.name,
-+                                                      newnd.last.len);
-+              unlock_kernel();
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit5;
-+      }
-+
-       lock_kernel();
-       error = vfs_rename(old_dir->d_inode, old_dentry,
--                                 new_dir->d_inode, new_dentry);
-+                                 new_dir->d_inode, new_dentry, NULL);
-       unlock_kernel();
--
-+exit5:
-       dput(new_dentry);
- exit4:
-       dput(old_dentry);
-@@ -1965,7 +2206,8 @@ out:
- }
- static inline int
--__vfs_follow_link(struct nameidata *nd, const char *link)
-+__vfs_follow_link(struct nameidata *nd, const char *link,
-+                struct lookup_intent *it)
- {
-       int res = 0;
-       char *name;
-@@ -1978,7 +2220,7 @@ __vfs_follow_link(struct nameidata *nd, 
-                       /* weird __emul_prefix() stuff did it */
-                       goto out;
-       }
--      res = link_path_walk(link, nd);
-+      res = link_path_walk_it(link, nd, it);
- out:
-       if (current->link_count || res || nd->last_type!=LAST_NORM)
-               return res;
-@@ -2002,7 +2244,13 @@ fail:
- int vfs_follow_link(struct nameidata *nd, const char *link)
- {
--      return __vfs_follow_link(nd, link);
-+      return __vfs_follow_link(nd, link, NULL);
-+}
-+
-+int vfs_follow_link_it(struct nameidata *nd, const char *link,
-+                     struct lookup_intent *it)
-+{
-+      return __vfs_follow_link(nd, link, it);
- }
- /* get the link contents into pagecache */
-@@ -2044,7 +2292,7 @@ int page_follow_link(struct dentry *dent
- {
-       struct page *page = NULL;
-       char *s = page_getlink(dentry, &page);
--      int res = __vfs_follow_link(nd, s);
-+      int res = __vfs_follow_link(nd, s, NULL);
-       if (page) {
-               kunmap(page);
-               page_cache_release(page);
---- linux-rh-2.4.20-8/fs/nfsd/vfs.c~vfs_intent-2.4.20-rh       2003-04-11 14:04:48.000000000 +0800
-+++ linux-rh-2.4.20-8-root/fs/nfsd/vfs.c       2003-04-23 18:27:35.000000000 +0800
-@@ -1293,7 +1293,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
-                       err = nfserr_perm;
-       } else
- #endif
--      err = vfs_rename(fdir, odentry, tdir, ndentry);
-+      err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
-       if (!err && EX_ISSYNC(tfhp->fh_export)) {
-               nfsd_sync_dir(tdentry);
-               nfsd_sync_dir(fdentry);
---- linux-rh-2.4.20-8/fs/open.c~vfs_intent-2.4.20-rh   2003-04-11 14:04:57.000000000 +0800
-+++ linux-rh-2.4.20-8-root/fs/open.c   2003-04-23 18:27:35.000000000 +0800
-@@ -19,6 +19,8 @@
- #include <asm/uaccess.h>
- #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
-+extern int path_walk_it(const char *name, struct nameidata *nd,
-+                      struct lookup_intent *it);
- int vfs_statfs(struct super_block *sb, struct statfs *buf)
- {
-@@ -95,9 +97,10 @@ void fd_install(unsigned int fd, struct 
-       write_unlock(&files->file_lock);
- }
--int do_truncate(struct dentry *dentry, loff_t length)
-+int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
- {
-       struct inode *inode = dentry->d_inode;
-+      struct inode_operations *op = dentry->d_inode->i_op;
-       int error;
-       struct iattr newattrs;
-@@ -108,7 +111,14 @@ int do_truncate(struct dentry *dentry, l
-       down(&inode->i_sem);
-       newattrs.ia_size = length;
-       newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
--      error = notify_change(dentry, &newattrs);
-+      if (called_from_open)
-+              newattrs.ia_valid |= ATTR_FROM_OPEN;
-+      if (op->setattr_raw) {
-+              newattrs.ia_valid |= ATTR_RAW;
-+              newattrs.ia_ctime = CURRENT_TIME;
-+              error = op->setattr_raw(inode, &newattrs);
-+      } else 
-+              error = notify_change(dentry, &newattrs);
-       up(&inode->i_sem);
-       return error;
- }
-@@ -118,12 +128,13 @@ static inline long do_sys_truncate(const
-       struct nameidata nd;
-       struct inode * inode;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       error = -EINVAL;
-       if (length < 0) /* sorry, but loff_t says... */
-               goto out;
--      error = user_path_walk(path, &nd);
-+      error = user_path_walk_it(path, &nd, &it);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-@@ -163,11 +174,13 @@ static inline long do_sys_truncate(const
-       error = locks_verify_truncate(inode, NULL, length);
-       if (!error) {
-               DQUOT_INIT(inode);
--              error = do_truncate(nd.dentry, length);
-+              intent_release(nd.dentry, &it);
-+              error = do_truncate(nd.dentry, length, 0);
-       }
-       put_write_access(inode);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi
-       error = locks_verify_truncate(inode, file, length);
-       if (!error)
--              error = do_truncate(dentry, length);
-+              error = do_truncate(dentry, length, 0);
- out_putf:
-       fput(file);
- out:
-@@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam
-       struct inode * inode;
-       struct iattr newattrs;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, NULL);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-+      /* this is safe without a Lustre lock because it only depends
-+         on the super block */
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-@@ -279,11 +294,29 @@ asmlinkage long sys_utime(char * filenam
-                       goto dput_and_out;
-               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
--      } else {
-+      }
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-+      error = -EROFS;
-+      if (IS_RDONLY(inode))
-+              goto dput_and_out;
-+
-+      error = -EPERM;
-+      if (!times) {
-               if (current->fsuid != inode->i_uid &&
-                   (error = permission(inode,MAY_WRITE)) != 0)
-                       goto dput_and_out;
-       }
-+
-       error = notify_change(nd.dentry, &newattrs);
- dput_and_out:
-       path_release(&nd);
-@@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena
-       struct inode * inode;
-       struct iattr newattrs;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, NULL);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-+      /* this is safe without a Lustre lock because it only depends
-+         on the super block */
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-@@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena
-               newattrs.ia_atime = times[0].tv_sec;
-               newattrs.ia_mtime = times[1].tv_sec;
-               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
--      } else {
-+      }
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-+      error = -EPERM;
-+      if (!utimes) {
-               if (current->fsuid != inode->i_uid &&
-                   (error = permission(inode,MAY_WRITE)) != 0)
-                       goto dput_and_out;
-@@ -347,6 +395,7 @@ asmlinkage long sys_access(const char * 
-       int old_fsuid, old_fsgid;
-       kernel_cap_t old_cap;
-       int res;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
-               return -EINVAL;
-@@ -364,13 +413,14 @@ asmlinkage long sys_access(const char * 
-       else
-               current->cap_effective = current->cap_permitted;
--      res = user_path_walk(filename, &nd);
-+      res = user_path_walk_it(filename, &nd, &it);
-       if (!res) {
-               res = permission(nd.dentry->d_inode, mode);
-               /* SuS v2 requires we report a read only fs too */
-               if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
-                  && !special_file(nd.dentry->d_inode->i_mode))
-                       res = -EROFS;
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-@@ -385,8 +435,9 @@ asmlinkage long sys_chdir(const char * f
- {
-       int error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
-+      error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it);
-       if (error)
-               goto out;
-@@ -397,6 +448,7 @@ asmlinkage long sys_chdir(const char * f
-       set_fs_pwd(current->fs, nd.mnt, nd.dentry);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -436,9 +488,10 @@ asmlinkage long sys_chroot(const char * 
- {
-       int error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
--                    LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
-+      error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
-+                    LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
-       if (error)
-               goto out;
-@@ -454,6 +507,7 @@ asmlinkage long sys_chroot(const char * 
-       set_fs_altroot();
-       error = 0;
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -508,6 +562,18 @@ asmlinkage long sys_chmod(const char * f
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_mode = mode;
-+              newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-       error = -EPERM;
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               goto dput_and_out;
-@@ -538,6 +604,20 @@ static int chown_common(struct dentry * 
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto out;
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = dentry->d_inode->i_op;
-+
-+              newattrs.ia_uid = user;
-+              newattrs.ia_gid = group;
-+              newattrs.ia_valid = ATTR_UID | ATTR_GID;
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      return error;
-+      }
-+
-       error = -EPERM;
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               goto out;
-@@ -642,6 +722,7 @@ struct file *filp_open(const char * file
- {
-       int namei_flags, error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
-       
-       flags &= ~O_DIRECT;
-@@ -651,14 +732,15 @@ struct file *filp_open(const char * file
-       if (namei_flags & O_TRUNC)
-               namei_flags |= 2;
--      error = open_namei(filename, namei_flags, mode, &nd);
--      if (!error)
--              return dentry_open(nd.dentry, nd.mnt, flags);
-+      error = open_namei_it(filename, namei_flags, mode, &nd, &it);
-+      if (error)
-+              return ERR_PTR(error);
--      return ERR_PTR(error);
-+      return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
- }
--struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                          int flags, struct lookup_intent *it)
- {
-       struct file * f;
-       struct inode *inode;
-@@ -701,6 +783,7 @@ struct file *dentry_open(struct dentry *
-       }
-       f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
-+      intent_release(dentry, it);
-       return f;
- cleanup_all:
-@@ -715,11 +798,17 @@ cleanup_all:
- cleanup_file:
-       put_filp(f);
- cleanup_dentry:
-+      intent_release(dentry, it);
-       dput(dentry);
-       mntput(mnt);
-       return ERR_PTR(error);
- }
-+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+{
-+      return dentry_open_it(dentry, mnt, flags, NULL);
-+}
-+
- /*
-  * Find an empty file descriptor entry, and mark it busy.
-  */
---- linux-rh-2.4.20-8/fs/stat.c~vfs_intent-2.4.20-rh   2003-04-11 14:05:08.000000000 +0800
-+++ linux-rh-2.4.20-8-root/fs/stat.c   2003-04-23 18:27:35.000000000 +0800
-@@ -110,11 +110,13 @@ static int do_getattr(struct vfsmount *m
- int vfs_stat(char *name, struct kstat *stat)
- {
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       int error;
--      error = user_path_walk(name, &nd);
-+      error = user_path_walk_it(name, &nd, &it);
-       if (!error) {
-               error = do_getattr(nd.mnt, nd.dentry, stat);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -123,11 +125,13 @@ int vfs_stat(char *name, struct kstat *s
- int vfs_lstat(char *name, struct kstat *stat)
- {
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       int error;
--      error = user_path_walk_link(name, &nd);
-+      error = user_path_walk_link_it(name, &nd, &it);
-       if (!error) {
-               error = do_getattr(nd.mnt, nd.dentry, stat);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
---- linux-rh-2.4.20-8/include/linux/dcache.h~vfs_intent-2.4.20-rh      2003-04-12 15:46:39.000000000 +0800
-+++ linux-rh-2.4.20-8-root/include/linux/dcache.h      2003-04-23 18:27:35.000000000 +0800
-@@ -7,6 +7,25 @@
- #include <linux/mount.h>
- #include <linux/kernel.h>
-+#define IT_OPEN     (1)
-+#define IT_CREAT    (1<<1)
-+#define IT_READDIR  (1<<2)
-+#define IT_GETATTR  (1<<3)
-+#define IT_LOOKUP   (1<<4)
-+#define IT_UNLINK   (1<<5)
-+
-+struct lookup_intent {
-+      int it_op;
-+      int it_mode;
-+      int it_flags;
-+      int it_disposition;
-+      int it_status;
-+      struct iattr *it_iattr;
-+      __u64 it_lock_handle[2];
-+      int it_lock_mode;
-+      void *it_data;
-+};
-+
- /*
-  * linux/include/linux/dcache.h
-  *
-@@ -82,6 +101,7 @@ struct dentry {
-       unsigned long d_time;           /* used by d_revalidate */
-       struct dentry_operations  *d_op;
-       struct super_block * d_sb;      /* The root of the dentry tree */
-+      struct lookup_intent *d_it;
-       unsigned long d_vfs_flags;
-       void * d_fsdata;                /* fs-specific data */
-       void * d_extra_attributes;      /* TUX-specific data */
-@@ -96,8 +116,15 @@ struct dentry_operations {
-       int (*d_delete)(struct dentry *);
-       void (*d_release)(struct dentry *);
-       void (*d_iput)(struct dentry *, struct inode *);
-+      int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
-+      void (*d_intent_release)(struct dentry *, struct lookup_intent *);
- };
-+/* defined in fs/namei.c */
-+extern void intent_release(struct dentry *de, struct lookup_intent *it);
-+/* defined in fs/dcache.c */
-+extern void __d_rehash(struct dentry * entry, int lock);
-+
- /* the dentry parameter passed to d_hash and d_compare is the parent
-  * directory of the entries to be compared. It is used in case these
-  * functions need any directory specific information for determining
-@@ -129,6 +156,7 @@ d_iput:            no              no              yes
-                                        * s_nfsd_free_path semaphore will be down
-                                        */
- #define DCACHE_REFERENCED     0x0008  /* Recently used, don't discard. */
-+#define DCACHE_LUSTRE_INVALID 0x0010  /* Lustre invalidated */
- extern spinlock_t dcache_lock;
---- linux-rh-2.4.20-8/include/linux/fs.h~vfs_intent-2.4.20-rh  2003-04-23 18:25:49.000000000 +0800
-+++ linux-rh-2.4.20-8-root/include/linux/fs.h  2003-04-23 18:27:35.000000000 +0800
-@@ -337,6 +337,8 @@ extern void set_bh_page(struct buffer_he
- #define ATTR_MTIME_SET        256
- #define ATTR_FORCE    512     /* Not a change, but a change it */
- #define ATTR_ATTR_FLAG        1024
-+#define ATTR_RAW      2048    /* file system, not vfs will massage attrs */
-+#define ATTR_FROM_OPEN        4096    /* called from open path, ie O_TRUNC */
- /*
-  * This is the Inode Attributes structure, used for notify_change().  It
-@@ -574,6 +576,7 @@ struct file {
-       /* needed for tty driver, and maybe others */
-       void                    *private_data;
-+      struct lookup_intent    *f_intent;
-       /* preallocated helper kiobuf to speedup O_DIRECT */
-       struct kiobuf           *f_iobuf;
-@@ -821,7 +824,9 @@ extern int vfs_symlink(struct inode *, s
- extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
- extern int vfs_rmdir(struct inode *, struct dentry *);
- extern int vfs_unlink(struct inode *, struct dentry *);
--extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
-+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-+              struct inode *new_dir, struct dentry *new_dentry,
-+              struct lookup_intent *it);
- /*
-  * File types
-@@ -882,20 +887,33 @@ struct file_operations {
- struct inode_operations {
-       int (*create) (struct inode *,struct dentry *,int);
-       struct dentry * (*lookup) (struct inode *,struct dentry *);
-+      struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
-       int (*link) (struct dentry *,struct inode *,struct dentry *);
-+      int (*link2) (struct inode *,struct inode *, const char *, int);
-       int (*unlink) (struct inode *,struct dentry *);
-+      int (*unlink2) (struct inode *, const char *, int);
-       int (*symlink) (struct inode *,struct dentry *,const char *);
-+      int (*symlink2) (struct inode *, const char *, int, const char *);
-       int (*mkdir) (struct inode *,struct dentry *,int);
-+      int (*mkdir2) (struct inode *, const char *, int,int);
-       int (*rmdir) (struct inode *,struct dentry *);
-+      int (*rmdir2) (struct inode *, const char *, int);
-       int (*mknod) (struct inode *,struct dentry *,int,int);
-+      int (*mknod2) (struct inode *, const char *, int,int,int);
-       int (*rename) (struct inode *, struct dentry *,
-                       struct inode *, struct dentry *);
-+      int (*rename2) (struct inode *, struct inode *,
-+                      const char *oldname, int oldlen,
-+                      const char *newname, int newlen);
-       int (*readlink) (struct dentry *, char *,int);
-       int (*follow_link) (struct dentry *, struct nameidata *);
-+      int (*follow_link2) (struct dentry *, struct nameidata *,
-+                           struct lookup_intent *it);
-       void (*truncate) (struct inode *);
-       int (*permission) (struct inode *, int);
-       int (*revalidate) (struct dentry *);
-       int (*setattr) (struct dentry *, struct iattr *);
-+      int (*setattr_raw) (struct inode *, struct iattr *);
-       int (*getattr) (struct dentry *, struct iattr *);
-       int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
-       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-@@ -1091,10 +1109,14 @@ static inline int get_lease(struct inode
- asmlinkage long sys_open(const char *, int, int);
- asmlinkage long sys_close(unsigned int);      /* yes, it's really unsigned */
--extern int do_truncate(struct dentry *, loff_t start);
-+extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
- extern struct file *filp_open(const char *, int, int);
- extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
-+extern int open_namei_it(const char *filename, int namei_flags, int mode,
-+                       struct nameidata *nd, struct lookup_intent *it);
-+extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                          int flags, struct lookup_intent *it);
- extern int filp_close(struct file *, fl_owner_t id);
- extern char * getname(const char *);
-@@ -1385,6 +1407,7 @@ typedef int (*read_actor_t)(read_descrip
- extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
- extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
-+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
- extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
- extern int FASTCALL(path_walk(const char *, struct nameidata *));
- extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
-@@ -1396,6 +1419,8 @@ extern struct dentry * lookup_one_len(co
- extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
- #define user_path_walk(name,nd)        __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
- #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
-+#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
-+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
- extern void inode_init_once(struct inode *);
- extern void iput(struct inode *);
-@@ -1495,6 +1520,8 @@ extern struct file_operations generic_ro
- extern int vfs_readlink(struct dentry *, char *, int, const char *);
- extern int vfs_follow_link(struct nameidata *, const char *);
-+extern int vfs_follow_link_it(struct nameidata *, const char *,
-+                            struct lookup_intent *it);
- extern int page_readlink(struct dentry *, char *, int);
- extern int page_follow_link(struct dentry *, struct nameidata *);
- extern struct inode_operations page_symlink_inode_operations;
---- linux-rh-2.4.20-8/kernel/ksyms.c~vfs_intent-2.4.20-rh      2003-04-23 18:25:50.000000000 +0800
-+++ linux-rh-2.4.20-8-root/kernel/ksyms.c      2003-04-23 18:27:35.000000000 +0800
-@@ -298,6 +298,7 @@ EXPORT_SYMBOL(read_cache_page);
- EXPORT_SYMBOL(set_page_dirty);
- EXPORT_SYMBOL(vfs_readlink);
- EXPORT_SYMBOL(vfs_follow_link);
-+EXPORT_SYMBOL(vfs_follow_link_it);
- EXPORT_SYMBOL(page_readlink);
- EXPORT_SYMBOL(page_follow_link);
- EXPORT_SYMBOL(page_symlink_inode_operations);
---- linux-rh-2.4.20-8/fs/exec.c~vfs_intent-2.4.20-rh   2003-04-13 10:07:02.000000000 +0800
-+++ linux-rh-2.4.20-8-root/fs/exec.c   2003-04-23 18:34:24.000000000 +0800
-@@ -114,8 +114,9 @@ asmlinkage long sys_uselib(const char * 
-       struct file * file;
-       struct nameidata nd;
-       int error;
--
--      error = user_path_walk(library, &nd);
-+              struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
-+                                                                                                                                             
-+        error = user_path_walk_it(library, &nd, &it);
-       if (error)
-               goto out;
-@@ -127,7 +128,7 @@ asmlinkage long sys_uselib(const char * 
-       if (error)
-               goto exit;
--      file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
-+      file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);        
-       error = PTR_ERR(file);
-       if (IS_ERR(file))
-               goto out;
-@@ -382,8 +383,9 @@ struct file *open_exec(const char *name)
-       struct inode *inode;
-       struct file *file;
-       int err = 0;
--
--      err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
-+      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
-+                                                                                                                                             
-+      err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
-       file = ERR_PTR(err);
-       if (!err) {
-               inode = nd.dentry->d_inode;
-@@ -395,7 +397,7 @@ struct file *open_exec(const char *name)
-                               err = -EACCES;
-                       file = ERR_PTR(err);
-                       if (!err) {
--                              file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
-+                                file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
-                               if (!IS_ERR(file)) {
-                                       err = deny_write_access(file);
-                                       if (err) {
-@@ -1283,7 +1285,7 @@ int do_coredump(long signr, int exit_cod
-               goto close_fail;
-       if (!file->f_op->write)
-               goto close_fail;
--      if (do_truncate(file->f_dentry, 0) != 0)
-+      if (do_truncate(file->f_dentry, 0, 0) != 0)
-               goto close_fail;
-       retval = binfmt->core_dump(signr, regs, file);
-
-_
diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch
deleted file mode 100644 (file)
index 3dd5357..0000000
+++ /dev/null
@@ -1,1539 +0,0 @@
- fs/dcache.c            |   20 ++
- fs/exec.c              |   12 -
- fs/namei.c             |  356 +++++++++++++++++++++++++++++++++++++++++--------
- fs/nfsd/vfs.c          |    2 
- fs/open.c              |  126 ++++++++++++++---
- fs/stat.c              |   24 ++-
- include/linux/dcache.h |   28 +++
- include/linux/fs.h     |   31 +++-
- kernel/ksyms.c         |    1 
- 9 files changed, 511 insertions(+), 89 deletions(-)
-
---- linux-2.4.20/fs/exec.c~vfs_intent-2.4.20-vanilla   2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-braam/fs/exec.c       2003-04-22 15:39:47.000000000 -0600
-@@ -107,8 +107,9 @@ asmlinkage long sys_uselib(const char * 
-       struct file * file;
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
--      error = user_path_walk(library, &nd);
-+      error = user_path_walk_it(library, &nd, &it);
-       if (error)
-               goto out;
-@@ -120,7 +121,7 @@ asmlinkage long sys_uselib(const char * 
-       if (error)
-               goto exit;
--      file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
-+      file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
-       error = PTR_ERR(file);
-       if (IS_ERR(file))
-               goto out;
-@@ -363,8 +364,9 @@ struct file *open_exec(const char *name)
-       struct inode *inode;
-       struct file *file;
-       int err = 0;
-+      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
--      err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
-+      err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
-       file = ERR_PTR(err);
-       if (!err) {
-               inode = nd.dentry->d_inode;
-@@ -376,7 +378,7 @@ struct file *open_exec(const char *name)
-                               err = -EACCES;
-                       file = ERR_PTR(err);
-                       if (!err) {
--                              file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
-+                              file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
-                               if (!IS_ERR(file)) {
-                                       err = deny_write_access(file);
-                                       if (err) {
-@@ -989,7 +991,7 @@ int do_coredump(long signr, struct pt_re
-               goto close_fail;
-       if (!file->f_op->write)
-               goto close_fail;
--      if (do_truncate(file->f_dentry, 0) != 0)
-+      if (do_truncate(file->f_dentry, 0, 0) != 0)
-               goto close_fail;
-       retval = binfmt->core_dump(signr, regs, file);
---- linux-2.4.20/fs/dcache.c~vfs_intent-2.4.20-vanilla 2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-braam/fs/dcache.c     2003-04-22 15:38:48.000000000 -0600
-@@ -181,6 +181,13 @@ int d_invalidate(struct dentry * dentry)
-               spin_unlock(&dcache_lock);
-               return 0;
-       }
-+
-+      /* network invalidation by Lustre */
-+      if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
-+              spin_unlock(&dcache_lock);
-+              return 0;
-+      }
-+
-       /*
-        * Check whether to do a partial shrink_dcache
-        * to get rid of unused child entries.
-@@ -616,6 +623,7 @@ struct dentry * d_alloc(struct dentry * 
-       dentry->d_op = NULL;
-       dentry->d_fsdata = NULL;
-       dentry->d_mounted = 0;
-+      dentry->d_it = NULL;
-       INIT_LIST_HEAD(&dentry->d_hash);
-       INIT_LIST_HEAD(&dentry->d_lru);
-       INIT_LIST_HEAD(&dentry->d_subdirs);
-@@ -830,13 +838,19 @@ void d_delete(struct dentry * dentry)
-  * Adds a dentry to the hash according to its name.
-  */
-  
--void d_rehash(struct dentry * entry)
-+void __d_rehash(struct dentry * entry, int lock)
- {
-       struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
-       if (!list_empty(&entry->d_hash)) BUG();
--      spin_lock(&dcache_lock);
-+      if (lock) spin_lock(&dcache_lock);
-       list_add(&entry->d_hash, list);
--      spin_unlock(&dcache_lock);
-+      if (lock) spin_unlock(&dcache_lock);
-+}
-+EXPORT_SYMBOL(__d_rehash);
-+
-+void d_rehash(struct dentry * entry)
-+{
-+      __d_rehash(entry, 1);
- }
- #define do_switch(x,y) do { \
---- linux-2.4.20/fs/namei.c~vfs_intent-2.4.20-vanilla  2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-braam/fs/namei.c      2003-04-22 15:38:48.000000000 -0600
-@@ -94,6 +94,13 @@
-  * XEmacs seems to be relying on it...
-  */
-+void intent_release(struct dentry *de, struct lookup_intent *it)
-+{
-+      if (it && de->d_op && de->d_op->d_intent_release)
-+              de->d_op->d_intent_release(de, it);
-+
-+}
-+
- /* In order to reduce some races, while at the same time doing additional
-  * checking and hopefully speeding things up, we copy filenames to the
-  * kernel data space before using them..
-@@ -260,10 +267,19 @@ void path_release(struct nameidata *nd)
-  * Internal lookup() using the new generic dcache.
-  * SMP-safe
-  */
--static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
-+                                  int flags, struct lookup_intent *it)
- {
-       struct dentry * dentry = d_lookup(parent, name);
-+      if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+              if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
-+                  !d_invalidate(dentry)) {
-+                      dput(dentry);
-+                      dentry = NULL;
-+              }
-+              return dentry;
-+      } else
-       if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-               if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
-                       dput(dentry);
-@@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str
-  * make sure that nobody added the entry to the dcache in the meantime..
-  * SMP-safe
-  */
--static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
-+                                int flags, struct lookup_intent *it)
- {
-       struct dentry * result;
-       struct inode *dir = parent->d_inode;
-+again:
-+
-       down(&dir->i_sem);
-       /*
-        * First re-do the cached lookup just in case it was created
-@@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc
-               result = ERR_PTR(-ENOMEM);
-               if (dentry) {
-                       lock_kernel();
-+                      if (dir->i_op->lookup2)
-+                              result = dir->i_op->lookup2(dir, dentry, it);
-+                      else
-                       result = dir->i_op->lookup(dir, dentry);
-                       unlock_kernel();
-                       if (result)
-@@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc
-                       dput(result);
-                       result = ERR_PTR(-ENOENT);
-               }
-+      } else if (result->d_op && result->d_op->d_revalidate2) {
-+              if (!result->d_op->d_revalidate2(result, flags, it) &&
-+                  !d_invalidate(result)) {
-+                      dput(result);
-+                      goto again;
-+              }
-       }
-       return result;
- }
-@@ -332,7 +360,8 @@ static struct dentry * real_lookup(struc
-  * Without that kind of total limit, nasty chains of consecutive
-  * symlinks can cause almost arbitrarily long lookups. 
-  */
--static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
-+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
-+                               struct lookup_intent *it)
- {
-       int err;
-       if (current->link_count >= 5)
-@@ -346,10 +375,14 @@ static inline int do_follow_link(struct 
-       current->link_count++;
-       current->total_link_count++;
-       UPDATE_ATIME(dentry->d_inode);
--      err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (dentry->d_inode->i_op->follow_link2)
-+              err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
-+      else
-+              err = dentry->d_inode->i_op->follow_link(dentry, nd);
-       current->link_count--;
-       return err;
- loop:
-+      intent_release(dentry, it);
-       path_release(nd);
-       return -ELOOP;
- }
-@@ -379,15 +412,26 @@ int follow_up(struct vfsmount **mnt, str
-       return __follow_up(mnt, dentry);
- }
--static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
-+static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
-+                              struct lookup_intent *it)
- {
-       struct vfsmount *mounted;
-       spin_lock(&dcache_lock);
-       mounted = lookup_mnt(*mnt, *dentry);
-       if (mounted) {
-+              int opc = 0, mode = 0;
-               *mnt = mntget(mounted);
-               spin_unlock(&dcache_lock);
-+              if (it) {
-+                      opc = it->it_op;
-+                      mode = it->it_mode;
-+              }
-+              intent_release(*dentry, it);
-+              if (it) {
-+                      it->it_op = opc;
-+                      it->it_mode = mode;
-+              }
-               dput(*dentry);
-               mntput(mounted->mnt_parent);
-               *dentry = dget(mounted->mnt_root);
-@@ -399,7 +443,7 @@ static inline int __follow_down(struct v
- int follow_down(struct vfsmount **mnt, struct dentry **dentry)
- {
--      return __follow_down(mnt,dentry);
-+      return __follow_down(mnt,dentry,NULL);
- }
-  
- static inline void follow_dotdot(struct nameidata *nd)
-@@ -435,7 +479,7 @@ static inline void follow_dotdot(struct 
-               mntput(nd->mnt);
-               nd->mnt = parent;
-       }
--      while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
-+      while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL))
-               ;
- }
-@@ -447,7 +491,8 @@ static inline void follow_dotdot(struct 
-  *
-  * We expect 'base' to be positive and a directory.
-  */
--int link_path_walk(const char * name, struct nameidata *nd)
-+int link_path_walk_it(const char *name, struct nameidata *nd,
-+                    struct lookup_intent *it)
- {
-       struct dentry *dentry;
-       struct inode *inode;
-@@ -520,15 +565,15 @@ int link_path_walk(const char * name, st
-                               break;
-               }
-               /* This does the actual lookups.. */
--              dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
-+              dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
-               if (!dentry) {
--                      dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
-+                      dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
-                       err = PTR_ERR(dentry);
-                       if (IS_ERR(dentry))
-                               break;
-               }
-               /* Check mountpoints.. */
--              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
-+              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL))
-                       ;
-               err = -ENOENT;
-@@ -539,8 +584,8 @@ int link_path_walk(const char * name, st
-               if (!inode->i_op)
-                       goto out_dput;
--              if (inode->i_op->follow_link) {
--                      err = do_follow_link(dentry, nd);
-+              if (inode->i_op->follow_link || inode->i_op->follow_link2) {
-+                      err = do_follow_link(dentry, nd, NULL);
-                       dput(dentry);
-                       if (err)
-                               goto return_err;
-@@ -556,7 +601,7 @@ int link_path_walk(const char * name, st
-                       nd->dentry = dentry;
-               }
-               err = -ENOTDIR; 
--              if (!inode->i_op->lookup)
-+              if (!inode->i_op->lookup && !inode->i_op->lookup2)
-                       break;
-               continue;
-               /* here ends the main loop */
-@@ -583,19 +628,20 @@ last_component:
-                       if (err < 0)
-                               break;
-               }
--              dentry = cached_lookup(nd->dentry, &this, 0);
-+              dentry = cached_lookup(nd->dentry, &this, 0, it);
-               if (!dentry) {
--                      dentry = real_lookup(nd->dentry, &this, 0);
-+                      dentry = real_lookup(nd->dentry, &this, 0, it);
-                       err = PTR_ERR(dentry);
-                       if (IS_ERR(dentry))
-                               break;
-               }
--              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
-+              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, it))
-                       ;
-               inode = dentry->d_inode;
-               if ((lookup_flags & LOOKUP_FOLLOW)
--                  && inode && inode->i_op && inode->i_op->follow_link) {
--                      err = do_follow_link(dentry, nd);
-+                  && inode && inode->i_op &&
-+                  (inode->i_op->follow_link || inode->i_op->follow_link2)) {
-+                      err = do_follow_link(dentry, nd, it);
-                       dput(dentry);
-                       if (err)
-                               goto return_err;
-@@ -609,7 +655,8 @@ last_component:
-                       goto no_inode;
-               if (lookup_flags & LOOKUP_DIRECTORY) {
-                       err = -ENOTDIR; 
--                      if (!inode->i_op || !inode->i_op->lookup)
-+                      if (!inode->i_op ||
-+                          (!inode->i_op->lookup && !inode->i_op->lookup2))
-                               break;
-               }
-               goto return_base;
-@@ -633,6 +680,23 @@ return_reval:
-                * Check the cached dentry for staleness.
-                */
-               dentry = nd->dentry;
-+        revalidate_again:
-+              if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+                      err = -ESTALE;
-+                      if (!dentry->d_op->d_revalidate2(dentry, 0, it)) {
-+                                struct dentry *new;
-+                                err = permission(dentry->d_parent->d_inode, 
-+                                                 MAY_EXEC);
-+                                if (err)
-+                                        break;
-+                                new = real_lookup(dentry->d_parent,
-+                                                  &dentry->d_name, 0, NULL);
-+                              d_invalidate(dentry);
-+                                dput(dentry);
-+                                dentry = new;
-+                                goto revalidate_again;
-+                        }
-+              } else
-               if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-                       err = -ESTALE;
-                       if (!dentry->d_op->d_revalidate(dentry, 0)) {
-@@ -646,15 +710,28 @@ out_dput:
-               dput(dentry);
-               break;
-       }
-+      if (err)
-+              intent_release(nd->dentry, it);
-       path_release(nd);
- return_err:
-       return err;
- }
-+int link_path_walk(const char * name, struct nameidata *nd)
-+{
-+      return link_path_walk_it(name, nd, NULL);
-+}
-+
-+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
-+{
-+      current->total_link_count = 0;
-+      return link_path_walk_it(name, nd, it);
-+}
-+
- int path_walk(const char * name, struct nameidata *nd)
- {
-       current->total_link_count = 0;
--      return link_path_walk(name, nd);
-+      return link_path_walk_it(name, nd, NULL);
- }
- /* SMP-safe */
-@@ -739,6 +816,17 @@ walk_init_root(const char *name, struct 
- }
- /* SMP-safe */
-+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
-+                 struct lookup_intent *it)
-+{
-+      int error = 0;
-+      if (path_init(path, flags, nd))
-+              error = path_walk_it(path, nd, it);
-+      return error;
-+}
-+
-+
-+/* SMP-safe */
- int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
- {
-       int error = 0;
-@@ -767,7 +855,8 @@ int path_init(const char *name, unsigned
-  * needs parent already locked. Doesn't follow mounts.
-  * SMP-safe.
-  */
--struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
-+                             struct lookup_intent *it)
- {
-       struct dentry * dentry;
-       struct inode *inode;
-@@ -790,13 +879,16 @@ struct dentry * lookup_hash(struct qstr 
-                       goto out;
-       }
--      dentry = cached_lookup(base, name, 0);
-+      dentry = cached_lookup(base, name, 0, it);
-       if (!dentry) {
-               struct dentry *new = d_alloc(base, name);
-               dentry = ERR_PTR(-ENOMEM);
-               if (!new)
-                       goto out;
-               lock_kernel();
-+              if (inode->i_op->lookup2)
-+                      dentry = inode->i_op->lookup2(inode, new, it);
-+              else
-               dentry = inode->i_op->lookup(inode, new);
-               unlock_kernel();
-               if (!dentry)
-@@ -808,6 +900,12 @@ out:
-       return dentry;
- }
-+struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+{
-+      return lookup_hash_it(name, base, NULL);
-+}
-+
-+
- /* SMP-safe */
- struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
- {
-@@ -829,7 +927,7 @@ struct dentry * lookup_one_len(const cha
-       }
-       this.hash = end_name_hash(hash);
--      return lookup_hash(&this, base);
-+      return lookup_hash_it(&this, base, NULL);
- access:
-       return ERR_PTR(-EACCES);
- }
-@@ -860,6 +958,23 @@ int __user_walk(const char *name, unsign
-       return err;
- }
-+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
-+                 struct lookup_intent *it)
-+{
-+      char *tmp;
-+      int err;
-+
-+      tmp = getname(name);
-+      err = PTR_ERR(tmp);
-+      if (!IS_ERR(tmp)) {
-+              err = 0;
-+              if (path_init(tmp, flags, nd))
-+                      err = path_walk_it(tmp, nd, it);
-+              putname(tmp);
-+      }
-+      return err;
-+}
-+
- /*
-  * It's inline, so penalty for filesystems that don't use sticky bit is
-  * minimal.
-@@ -996,7 +1111,8 @@ exit_lock:
-  * for symlinks (where the permissions are checked later).
-  * SMP-safe
-  */
--int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
-+int open_namei_it(const char *pathname, int flag, int mode,
-+                struct nameidata *nd, struct lookup_intent *it)
- {
-       int acc_mode, error = 0;
-       struct inode *inode;
-@@ -1010,7 +1126,7 @@ int open_namei(const char * pathname, in
-        * The simplest case - just a plain lookup.
-        */
-       if (!(flag & O_CREAT)) {
--              error = path_lookup(pathname, lookup_flags(flag), nd);
-+              error = path_lookup_it(pathname, lookup_flags(flag), nd, it);
-               if (error)
-                       return error;
-               dentry = nd->dentry;
-@@ -1020,6 +1136,10 @@ int open_namei(const char * pathname, in
-       /*
-        * Create - we need to know the parent.
-        */
-+      if (it) {
-+              it->it_mode = mode;
-+              it->it_op |= IT_CREAT;
-+      }
-       error = path_lookup(pathname, LOOKUP_PARENT, nd);
-       if (error)
-               return error;
-@@ -1035,7 +1155,7 @@ int open_namei(const char * pathname, in
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
- do_last:
-       error = PTR_ERR(dentry);
-@@ -1044,6 +1164,7 @@ do_last:
-               goto exit;
-       }
-+      it->it_mode = mode;
-       /* Negative dentry, just create the file */
-       if (!dentry->d_inode) {
-               error = vfs_create(dir->d_inode, dentry,
-@@ -1072,12 +1193,13 @@ do_last:
-               error = -ELOOP;
-               if (flag & O_NOFOLLOW)
-                       goto exit_dput;
--              while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
-+              while (__follow_down(&nd->mnt,&dentry,it) && d_mountpoint(dentry));
-       }
-       error = -ENOENT;
-       if (!dentry->d_inode)
-               goto exit_dput;
--      if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
-+      if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
-+                                    dentry->d_inode->i_op->follow_link2))
-               goto do_link;
-       dput(nd->dentry);
-@@ -1151,7 +1273,7 @@ ok:
-               if (!error) {
-                       DQUOT_INIT(inode);
-                       
--                      error = do_truncate(dentry, 0);
-+                      error = do_truncate(dentry, 0, 1);
-               }
-               put_write_access(inode);
-               if (error)
-@@ -1163,8 +1285,10 @@ ok:
-       return 0;
- exit_dput:
-+      intent_release(dentry, it);
-       dput(dentry);
- exit:
-+      intent_release(nd->dentry, it);
-       path_release(nd);
-       return error;
-@@ -1183,7 +1307,12 @@ do_link:
-        * are done. Procfs-like symlinks just set LAST_BIND.
-        */
-       UPDATE_ATIME(dentry->d_inode);
--      error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (dentry->d_inode->i_op->follow_link2)
-+              error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
-+      else
-+              error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (error)
-+              intent_release(dentry, it);
-       dput(dentry);
-       if (error)
-               return error;
-@@ -1205,13 +1334,20 @@ do_link:
-       }
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
-       putname(nd->last.name);
-       goto do_last;
- }
-+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
-+{
-+      return open_namei_it(pathname, flag, mode, nd, NULL);
-+}
-+
-+
- /* SMP-safe */
--static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
-+static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
-+                                  struct lookup_intent *it)
- {
-       struct dentry *dentry;
-@@ -1219,7 +1355,7 @@ static struct dentry *lookup_create(stru
-       dentry = ERR_PTR(-EEXIST);
-       if (nd->last_type != LAST_NORM)
-               goto fail;
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
-       if (IS_ERR(dentry))
-               goto fail;
-       if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1275,7 +1411,19 @@ asmlinkage long sys_mknod(const char * f
-       error = path_lookup(tmp, LOOKUP_PARENT, &nd);
-       if (error)
-               goto out;
--      dentry = lookup_create(&nd, 0);
-+
-+      if (nd.dentry->d_inode->i_op->mknod2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              error = op->mknod2(nd.dentry->d_inode,
-+                                 nd.last.name,
-+                                 nd.last.len,
-+                                 mode, dev);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto out2;
-+      }
-+
-+      dentry = lookup_create(&nd, 0, NULL);
-       error = PTR_ERR(dentry);
-       mode &= ~current->fs->umask;
-@@ -1296,6 +1444,7 @@ asmlinkage long sys_mknod(const char * f
-               dput(dentry);
-       }
-       up(&nd.dentry->d_inode->i_sem);
-+out2:
-       path_release(&nd);
- out:
-       putname(tmp);
-@@ -1343,7 +1492,17 @@ asmlinkage long sys_mkdir(const char * p
-               error = path_lookup(tmp, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
--              dentry = lookup_create(&nd, 1);
-+              if (nd.dentry->d_inode->i_op->mkdir2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->mkdir2(nd.dentry->d_inode,
-+                                         nd.last.name,
-+                                         nd.last.len,
-+                                         mode);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out2;
-+              }
-+              dentry = lookup_create(&nd, 1, NULL);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_mkdir(nd.dentry->d_inode, dentry,
-@@ -1351,6 +1510,7 @@ asmlinkage long sys_mkdir(const char * p
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-+out2:
-               path_release(&nd);
- out:
-               putname(tmp);
-@@ -1451,8 +1611,33 @@ asmlinkage long sys_rmdir(const char * p
-                       error = -EBUSY;
-                       goto exit1;
-       }
-+      if (nd.dentry->d_inode->i_op->rmdir2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              struct dentry *last;
-+
-+              down(&nd.dentry->d_inode->i_sem);
-+              last = lookup_hash_it(&nd.last, nd.dentry, NULL);
-+              up(&nd.dentry->d_inode->i_sem);
-+              if (IS_ERR(last)) {
-+                      error = PTR_ERR(last);
-+                      goto exit1;
-+              }
-+              if (d_mountpoint(last)) {
-+                      dput(last);
-+                      error = -EBUSY;
-+                      goto exit1;
-+              }
-+              dput(last);
-+
-+              error = op->rmdir2(nd.dentry->d_inode,
-+                                 nd.last.name,
-+                                 nd.last.len);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit1;
-+      }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1510,8 +1695,17 @@ asmlinkage long sys_unlink(const char * 
-       error = -EISDIR;
-       if (nd.last_type != LAST_NORM)
-               goto exit1;
-+      if (nd.dentry->d_inode->i_op->unlink2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              error = op->unlink2(nd.dentry->d_inode,
-+                                  nd.last.name,
-+                                  nd.last.len);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit1;
-+      }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               /* Why not before? Because we want correct error value */
-@@ -1578,15 +1772,26 @@ asmlinkage long sys_symlink(const char *
-               error = path_lookup(to, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
--              dentry = lookup_create(&nd, 0);
-+              if (nd.dentry->d_inode->i_op->symlink2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->symlink2(nd.dentry->d_inode,
-+                                           nd.last.name,
-+                                           nd.last.len,
-+                                           from);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out2;
-+              }
-+              dentry = lookup_create(&nd, 0, NULL);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_symlink(nd.dentry->d_inode, dentry, from);
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-+      out2:
-               path_release(&nd);
--out:
-+      out:
-               putname(to);
-       }
-       putname(from);
-@@ -1662,7 +1867,17 @@ asmlinkage long sys_link(const char * ol
-               error = -EXDEV;
-               if (old_nd.mnt != nd.mnt)
-                       goto out_release;
--              new_dentry = lookup_create(&nd, 0);
-+              if (nd.dentry->d_inode->i_op->link2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->link2(old_nd.dentry->d_inode,
-+                                        nd.dentry->d_inode,
-+                                        nd.last.name,
-+                                        nd.last.len);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out_release;
-+              }
-+              new_dentry = lookup_create(&nd, 0, NULL);
-               error = PTR_ERR(new_dentry);
-               if (!IS_ERR(new_dentry)) {
-                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-@@ -1706,7 +1921,8 @@ exit:
-  *       locking].
-  */
- int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+                 struct inode *new_dir, struct dentry *new_dentry,
-+                 struct lookup_intent *it)
- {
-       int error;
-       struct inode *target;
-@@ -1764,6 +1980,7 @@ int vfs_rename_dir(struct inode *old_dir
-               error = -EBUSY;
-       else 
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       if (target) {
-               if (!error)
-                       target->i_flags |= S_DEAD;
-@@ -1785,7 +2002,8 @@ out_unlock:
- }
- int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+                   struct inode *new_dir, struct dentry *new_dentry,
-+                   struct lookup_intent *it)
- {
-       int error;
-@@ -1816,6 +2034,7 @@ int vfs_rename_other(struct inode *old_d
-               error = -EBUSY;
-       else
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       double_up(&old_dir->i_zombie, &new_dir->i_zombie);
-       if (error)
-               return error;
-@@ -1827,13 +2046,14 @@ int vfs_rename_other(struct inode *old_d
- }
- int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+             struct inode *new_dir, struct dentry *new_dentry,
-+             struct lookup_intent *it)
- {
-       int error;
-       if (S_ISDIR(old_dentry->d_inode->i_mode))
--              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
-       else
--              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
-       if (!error) {
-               if (old_dir == new_dir)
-                       inode_dir_notify(old_dir, DN_RENAME);
-@@ -1875,7 +2095,7 @@ static inline int do_rename(const char *
-       double_lock(new_dir, old_dir);
--      old_dentry = lookup_hash(&oldnd.last, old_dir);
-+      old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL);
-       error = PTR_ERR(old_dentry);
-       if (IS_ERR(old_dentry))
-               goto exit3;
-@@ -1891,16 +2111,37 @@ static inline int do_rename(const char *
-               if (newnd.last.name[newnd.last.len])
-                       goto exit4;
-       }
--      new_dentry = lookup_hash(&newnd.last, new_dir);
-+      new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL);
-       error = PTR_ERR(new_dentry);
-       if (IS_ERR(new_dentry))
-               goto exit4;
-+      if (old_dir->d_inode->i_op->rename2) {
-+              lock_kernel();
-+              /* don't rename mount point. mds will take care of
-+               * the rest sanity checking */
-+              if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) {
-+                      error = -EBUSY;
-+                      goto exit5;
-+              }
-+
-+              error = old_dir->d_inode->i_op->rename2(old_dir->d_inode,
-+                                                      new_dir->d_inode,
-+                                                      oldnd.last.name,
-+                                                      oldnd.last.len,
-+                                                      newnd.last.name,
-+                                                      newnd.last.len);
-+              unlock_kernel();
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit5;
-+      }
-+
-       lock_kernel();
-       error = vfs_rename(old_dir->d_inode, old_dentry,
--                                 new_dir->d_inode, new_dentry);
-+                                 new_dir->d_inode, new_dentry, NULL);
-       unlock_kernel();
--
-+exit5:
-       dput(new_dentry);
- exit4:
-       dput(old_dentry);
-@@ -1951,7 +2192,8 @@ out:
- }
- static inline int
--__vfs_follow_link(struct nameidata *nd, const char *link)
-+__vfs_follow_link(struct nameidata *nd, const char *link,
-+                struct lookup_intent *it)
- {
-       int res = 0;
-       char *name;
-@@ -1964,7 +2206,7 @@ __vfs_follow_link(struct nameidata *nd, 
-                       /* weird __emul_prefix() stuff did it */
-                       goto out;
-       }
--      res = link_path_walk(link, nd);
-+      res = link_path_walk_it(link, nd, it);
- out:
-       if (current->link_count || res || nd->last_type!=LAST_NORM)
-               return res;
-@@ -1986,7 +2228,13 @@ fail:
- int vfs_follow_link(struct nameidata *nd, const char *link)
- {
--      return __vfs_follow_link(nd, link);
-+      return __vfs_follow_link(nd, link, NULL);
-+}
-+
-+int vfs_follow_link_it(struct nameidata *nd, const char *link,
-+                     struct lookup_intent *it)
-+{
-+      return __vfs_follow_link(nd, link, it);
- }
- /* get the link contents into pagecache */
-@@ -2028,7 +2276,7 @@ int page_follow_link(struct dentry *dent
- {
-       struct page *page = NULL;
-       char *s = page_getlink(dentry, &page);
--      int res = __vfs_follow_link(nd, s);
-+      int res = __vfs_follow_link(nd, s, NULL);
-       if (page) {
-               kunmap(page);
-               page_cache_release(page);
---- linux-2.4.20/fs/nfsd/vfs.c~vfs_intent-2.4.20-vanilla       2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-braam/fs/nfsd/vfs.c   2003-04-22 15:38:48.000000000 -0600
-@@ -1291,7 +1291,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
-                       err = nfserr_perm;
-       } else
- #endif
--      err = vfs_rename(fdir, odentry, tdir, ndentry);
-+      err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
-       if (!err && EX_ISSYNC(tfhp->fh_export)) {
-               nfsd_sync_dir(tdentry);
-               nfsd_sync_dir(fdentry);
---- linux-2.4.20/fs/open.c~vfs_intent-2.4.20-vanilla   2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-braam/fs/open.c       2003-04-22 15:38:48.000000000 -0600
-@@ -19,6 +19,8 @@
- #include <asm/uaccess.h>
- #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
-+extern int path_walk_it(const char *name, struct nameidata *nd,
-+                      struct lookup_intent *it);
- int vfs_statfs(struct super_block *sb, struct statfs *buf)
- {
-@@ -95,9 +97,10 @@ void fd_install(unsigned int fd, struct 
-       write_unlock(&files->file_lock);
- }
--int do_truncate(struct dentry *dentry, loff_t length)
-+int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
- {
-       struct inode *inode = dentry->d_inode;
-+      struct inode_operations *op = dentry->d_inode->i_op;
-       int error;
-       struct iattr newattrs;
-@@ -108,7 +111,14 @@ int do_truncate(struct dentry *dentry, l
-       down(&inode->i_sem);
-       newattrs.ia_size = length;
-       newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
--      error = notify_change(dentry, &newattrs);
-+      if (called_from_open)
-+              newattrs.ia_valid |= ATTR_FROM_OPEN;
-+      if (op->setattr_raw) {
-+              newattrs.ia_valid |= ATTR_RAW;
-+              newattrs.ia_ctime = CURRENT_TIME;
-+              error = op->setattr_raw(inode, &newattrs);
-+      } else 
-+              error = notify_change(dentry, &newattrs);
-       up(&inode->i_sem);
-       return error;
- }
-@@ -118,12 +128,13 @@ static inline long do_sys_truncate(const
-       struct nameidata nd;
-       struct inode * inode;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       error = -EINVAL;
-       if (length < 0) /* sorry, but loff_t says... */
-               goto out;
--      error = user_path_walk(path, &nd);
-+      error = user_path_walk_it(path, &nd, &it);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-@@ -163,11 +174,13 @@ static inline long do_sys_truncate(const
-       error = locks_verify_truncate(inode, NULL, length);
-       if (!error) {
-               DQUOT_INIT(inode);
--              error = do_truncate(nd.dentry, length);
-+              intent_release(nd.dentry, &it);
-+              error = do_truncate(nd.dentry, length, 0);
-       }
-       put_write_access(inode);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi
-       error = locks_verify_truncate(inode, file, length);
-       if (!error)
--              error = do_truncate(dentry, length);
-+              error = do_truncate(dentry, length, 0);
- out_putf:
-       fput(file);
- out:
-@@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam
-       struct inode * inode;
-       struct iattr newattrs;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, NULL);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-+      /* this is safe without a Lustre lock because it only depends
-+         on the super block */
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-@@ -279,11 +294,29 @@ asmlinkage long sys_utime(char * filenam
-                       goto dput_and_out;
-               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
--      } else {
-+      }
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-+      error = -EROFS;
-+      if (IS_RDONLY(inode))
-+              goto dput_and_out;
-+
-+      error = -EPERM;
-+      if (!times) {
-               if (current->fsuid != inode->i_uid &&
-                   (error = permission(inode,MAY_WRITE)) != 0)
-                       goto dput_and_out;
-       }
-+
-       error = notify_change(nd.dentry, &newattrs);
- dput_and_out:
-       path_release(&nd);
-@@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena
-       struct inode * inode;
-       struct iattr newattrs;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, NULL);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-+      /* this is safe without a Lustre lock because it only depends
-+         on the super block */
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-@@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena
-               newattrs.ia_atime = times[0].tv_sec;
-               newattrs.ia_mtime = times[1].tv_sec;
-               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
--      } else {
-+      }
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-+      error = -EPERM;
-+      if (!utimes) {
-               if (current->fsuid != inode->i_uid &&
-                   (error = permission(inode,MAY_WRITE)) != 0)
-                       goto dput_and_out;
-@@ -347,6 +395,7 @@ asmlinkage long sys_access(const char * 
-       int old_fsuid, old_fsgid;
-       kernel_cap_t old_cap;
-       int res;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
-               return -EINVAL;
-@@ -364,13 +413,14 @@ asmlinkage long sys_access(const char * 
-       else
-               current->cap_effective = current->cap_permitted;
--      res = user_path_walk(filename, &nd);
-+      res = user_path_walk_it(filename, &nd, &it);
-       if (!res) {
-               res = permission(nd.dentry->d_inode, mode);
-               /* SuS v2 requires we report a read only fs too */
-               if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
-                  && !special_file(nd.dentry->d_inode->i_mode))
-                       res = -EROFS;
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-@@ -385,8 +435,9 @@ asmlinkage long sys_chdir(const char * f
- {
-       int error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
-+      error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it);
-       if (error)
-               goto out;
-@@ -397,6 +448,7 @@ asmlinkage long sys_chdir(const char * f
-       set_fs_pwd(current->fs, nd.mnt, nd.dentry);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -436,9 +488,10 @@ asmlinkage long sys_chroot(const char * 
- {
-       int error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
--                    LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
-+      error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
-+                    LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
-       if (error)
-               goto out;
-@@ -454,6 +507,7 @@ asmlinkage long sys_chroot(const char * 
-       set_fs_altroot();
-       error = 0;
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -508,6 +562,18 @@ asmlinkage long sys_chmod(const char * f
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_mode = mode;
-+              newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-       error = -EPERM;
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               goto dput_and_out;
-@@ -538,6 +604,20 @@ static int chown_common(struct dentry * 
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto out;
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = dentry->d_inode->i_op;
-+
-+              newattrs.ia_uid = user;
-+              newattrs.ia_gid = group;
-+              newattrs.ia_valid = ATTR_UID | ATTR_GID;
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      return error;
-+      }
-+
-       error = -EPERM;
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               goto out;
-@@ -638,10 +718,12 @@ asmlinkage long sys_fchown(unsigned int 
-  * for the internal routines (ie open_namei()/follow_link() etc). 00 is
-  * used by symlinks.
-  */
-+
- struct file *filp_open(const char * filename, int flags, int mode)
- {
-       int namei_flags, error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
-       namei_flags = flags;
-       if ((namei_flags+1) & O_ACCMODE)
-@@ -649,14 +731,15 @@ struct file *filp_open(const char * file
-       if (namei_flags & O_TRUNC)
-               namei_flags |= 2;
--      error = open_namei(filename, namei_flags, mode, &nd);
--      if (!error)
--              return dentry_open(nd.dentry, nd.mnt, flags);
-+      error = open_namei_it(filename, namei_flags, mode, &nd, &it);
-+      if (error)
-+              return ERR_PTR(error);
--      return ERR_PTR(error);
-+      return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
- }
--struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                          int flags, struct lookup_intent *it)
- {
-       struct file * f;
-       struct inode *inode;
-@@ -699,6 +782,7 @@ struct file *dentry_open(struct dentry *
-       }
-       f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
-+      intent_release(dentry, it);
-       return f;
- cleanup_all:
-@@ -713,11 +797,17 @@ cleanup_all:
- cleanup_file:
-       put_filp(f);
- cleanup_dentry:
-+      intent_release(dentry, it);
-       dput(dentry);
-       mntput(mnt);
-       return ERR_PTR(error);
- }
-+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+{
-+      return dentry_open_it(dentry, mnt, flags, NULL);
-+}
-+
- /*
-  * Find an empty file descriptor entry, and mark it busy.
-  */
---- linux-2.4.20/fs/stat.c~vfs_intent-2.4.20-vanilla   2001-09-13 17:04:43.000000000 -0600
-+++ linux-2.4.20-braam/fs/stat.c       2003-04-22 15:38:48.000000000 -0600
-@@ -135,13 +135,15 @@ static int cp_new_stat(struct inode * in
- asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
- {
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       int error;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_old_stat(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -151,13 +153,15 @@ asmlinkage long sys_stat(char * filename
- asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
- {
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       int error;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_new_stat(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -172,13 +176,15 @@ asmlinkage long sys_newstat(char * filen
- asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
- {
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       int error;
--      error = user_path_walk_link(filename, &nd);
-+      error = user_path_walk_link_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_old_stat(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -189,13 +195,15 @@ asmlinkage long sys_lstat(char * filenam
- asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
- {
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       int error;
--      error = user_path_walk_link(filename, &nd);
-+      error = user_path_walk_link_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_new_stat(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -333,12 +341,14 @@ asmlinkage long sys_stat64(char * filena
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_new_stat64(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -348,12 +358,14 @@ asmlinkage long sys_lstat64(char * filen
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = user_path_walk_link(filename, &nd);
-+      error = user_path_walk_link_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_new_stat64(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
---- linux-2.4.20/include/linux/dcache.h~vfs_intent-2.4.20-vanilla      2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-braam/include/linux/dcache.h  2003-04-22 15:38:48.000000000 -0600
-@@ -7,6 +7,25 @@
- #include <linux/mount.h>
- #include <linux/kernel.h>
-+#define IT_OPEN     (1)
-+#define IT_CREAT    (1<<1)
-+#define IT_READDIR  (1<<2)
-+#define IT_GETATTR  (1<<3)
-+#define IT_LOOKUP   (1<<4)
-+#define IT_UNLINK   (1<<5)
-+
-+struct lookup_intent {
-+      int it_op;
-+      int it_mode;
-+      int it_flags;
-+      int it_disposition;
-+      int it_status;
-+      struct iattr *it_iattr;
-+      __u64 it_lock_handle[2];
-+      int it_lock_mode;
-+      void *it_data;
-+};
-+
- /*
-  * linux/include/linux/dcache.h
-  *
-@@ -79,6 +98,7 @@ struct dentry {
-       unsigned long d_time;           /* used by d_revalidate */
-       struct dentry_operations  *d_op;
-       struct super_block * d_sb;      /* The root of the dentry tree */
-+      struct lookup_intent *d_it;
-       unsigned long d_vfs_flags;
-       void * d_fsdata;                /* fs-specific data */
-       unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
-@@ -91,8 +111,15 @@ struct dentry_operations {
-       int (*d_delete)(struct dentry *);
-       void (*d_release)(struct dentry *);
-       void (*d_iput)(struct dentry *, struct inode *);
-+      int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
-+      void (*d_intent_release)(struct dentry *, struct lookup_intent *);
- };
-+/* defined in fs/namei.c */
-+extern void intent_release(struct dentry *de, struct lookup_intent *it);
-+/* defined in fs/dcache.c */
-+extern void __d_rehash(struct dentry * entry, int lock);
-+
- /* the dentry parameter passed to d_hash and d_compare is the parent
-  * directory of the entries to be compared. It is used in case these
-  * functions need any directory specific information for determining
-@@ -124,6 +151,7 @@ d_iput:            no              no              yes
-                                        * s_nfsd_free_path semaphore will be down
-                                        */
- #define DCACHE_REFERENCED     0x0008  /* Recently used, don't discard. */
-+#define DCACHE_LUSTRE_INVALID 0x0010  /* Lustre invalidated */
- extern spinlock_t dcache_lock;
---- linux-2.4.20/include/linux/fs.h~vfs_intent-2.4.20-vanilla  2003-04-22 15:38:15.000000000 -0600
-+++ linux-2.4.20-braam/include/linux/fs.h      2003-04-22 15:38:48.000000000 -0600
-@@ -338,6 +338,8 @@ extern void set_bh_page(struct buffer_he
- #define ATTR_MTIME_SET        256
- #define ATTR_FORCE    512     /* Not a change, but a change it */
- #define ATTR_ATTR_FLAG        1024
-+#define ATTR_RAW      2048    /* file system, not vfs will massage attrs */
-+#define ATTR_FROM_OPEN        4096    /* called from open path, ie O_TRUNC */
- /*
-  * This is the Inode Attributes structure, used for notify_change().  It
-@@ -542,6 +544,7 @@ struct file {
-       /* needed for tty driver, and maybe others */
-       void                    *private_data;
-+      struct lookup_intent    *f_intent;
-       /* preallocated helper kiobuf to speedup O_DIRECT */
-       struct kiobuf           *f_iobuf;
-@@ -794,7 +797,9 @@ extern int vfs_symlink(struct inode *, s
- extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
- extern int vfs_rmdir(struct inode *, struct dentry *);
- extern int vfs_unlink(struct inode *, struct dentry *);
--extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
-+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-+              struct inode *new_dir, struct dentry *new_dentry,
-+              struct lookup_intent *it);
- /*
-  * File types
-@@ -855,20 +860,33 @@ struct file_operations {
- struct inode_operations {
-       int (*create) (struct inode *,struct dentry *,int);
-       struct dentry * (*lookup) (struct inode *,struct dentry *);
-+      struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
-       int (*link) (struct dentry *,struct inode *,struct dentry *);
-+      int (*link2) (struct inode *,struct inode *, const char *, int);
-       int (*unlink) (struct inode *,struct dentry *);
-+      int (*unlink2) (struct inode *, const char *, int);
-       int (*symlink) (struct inode *,struct dentry *,const char *);
-+      int (*symlink2) (struct inode *, const char *, int, const char *);
-       int (*mkdir) (struct inode *,struct dentry *,int);
-+      int (*mkdir2) (struct inode *, const char *, int,int);
-       int (*rmdir) (struct inode *,struct dentry *);
-+      int (*rmdir2) (struct inode *, const char *, int);
-       int (*mknod) (struct inode *,struct dentry *,int,int);
-+      int (*mknod2) (struct inode *, const char *, int,int,int);
-       int (*rename) (struct inode *, struct dentry *,
-                       struct inode *, struct dentry *);
-+      int (*rename2) (struct inode *, struct inode *,
-+                      const char *oldname, int oldlen,
-+                      const char *newname, int newlen);
-       int (*readlink) (struct dentry *, char *,int);
-       int (*follow_link) (struct dentry *, struct nameidata *);
-+      int (*follow_link2) (struct dentry *, struct nameidata *,
-+                           struct lookup_intent *it);
-       void (*truncate) (struct inode *);
-       int (*permission) (struct inode *, int);
-       int (*revalidate) (struct dentry *);
-       int (*setattr) (struct dentry *, struct iattr *);
-+      int (*setattr_raw) (struct inode *, struct iattr *);
-       int (*getattr) (struct dentry *, struct iattr *);
-       int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
-       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-@@ -1070,10 +1088,14 @@ static inline int get_lease(struct inode
- asmlinkage long sys_open(const char *, int, int);
- asmlinkage long sys_close(unsigned int);      /* yes, it's really unsigned */
--extern int do_truncate(struct dentry *, loff_t start);
-+extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
- extern struct file *filp_open(const char *, int, int);
- extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
-+extern int open_namei_it(const char *filename, int namei_flags, int mode,
-+                       struct nameidata *nd, struct lookup_intent *it);
-+extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                          int flags, struct lookup_intent *it);
- extern int filp_close(struct file *, fl_owner_t id);
- extern char * getname(const char *);
-@@ -1335,6 +1357,7 @@ typedef int (*read_actor_t)(read_descrip
- extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
- extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
-+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
- extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
- extern int FASTCALL(path_walk(const char *, struct nameidata *));
- extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
-@@ -1346,6 +1369,8 @@ extern struct dentry * lookup_one_len(co
- extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
- #define user_path_walk(name,nd)        __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
- #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
-+#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
-+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
- extern void iput(struct inode *);
- extern void force_delete(struct inode *);
-@@ -1455,6 +1480,8 @@ extern struct file_operations generic_ro
- extern int vfs_readlink(struct dentry *, char *, int, const char *);
- extern int vfs_follow_link(struct nameidata *, const char *);
-+extern int vfs_follow_link_it(struct nameidata *, const char *,
-+                            struct lookup_intent *it);
- extern int page_readlink(struct dentry *, char *, int);
- extern int page_follow_link(struct dentry *, struct nameidata *);
- extern struct inode_operations page_symlink_inode_operations;
---- linux-2.4.20/kernel/ksyms.c~vfs_intent-2.4.20-vanilla      2003-04-22 15:38:16.000000000 -0600
-+++ linux-2.4.20-braam/kernel/ksyms.c  2003-04-22 15:38:48.000000000 -0600
-@@ -269,6 +269,7 @@ EXPORT_SYMBOL(read_cache_page);
- EXPORT_SYMBOL(set_page_dirty);
- EXPORT_SYMBOL(vfs_readlink);
- EXPORT_SYMBOL(vfs_follow_link);
-+EXPORT_SYMBOL(vfs_follow_link_it);
- EXPORT_SYMBOL(page_readlink);
- EXPORT_SYMBOL(page_follow_link);
- EXPORT_SYMBOL(page_symlink_inode_operations);
-
-_
diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.20.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.20.patch
deleted file mode 100644 (file)
index 8a5c674..0000000
+++ /dev/null
@@ -1,1468 +0,0 @@
- fs/dcache.c            |   19 ++
- fs/exec.c              |   14 +
- fs/namei.c             |  364 +++++++++++++++++++++++++++++++++++++++++--------
- fs/nfsd/vfs.c          |    2 
- fs/open.c              |  118 ++++++++++++++-
- fs/stat.c              |    8 -
- include/linux/dcache.h |   28 +++
- include/linux/fs.h     |   33 ++++
- kernel/ksyms.c         |    1 
- 9 files changed, 505 insertions(+), 82 deletions(-)
-
---- linux-rh-2.4.20-6/fs/dcache.c~vfs_intent-2.4.20    Tue Apr  1 01:03:23 2003
-+++ linux-rh-2.4.20-6-braam/fs/dcache.c        Tue Apr  1 01:03:23 2003
-@@ -186,6 +186,13 @@ int d_invalidate(struct dentry * dentry)
-               spin_unlock(&dcache_lock);
-               return 0;
-       }
-+
-+      /* network invalidation by Lustre */
-+      if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
-+              spin_unlock(&dcache_lock);
-+              return 0;
-+      }
-+
-       /*
-        * Check whether to do a partial shrink_dcache
-        * to get rid of unused child entries.
-@@ -840,13 +847,19 @@ void d_delete(struct dentry * dentry)
-  * Adds a dentry to the hash according to its name.
-  */
-  
--void d_rehash(struct dentry * entry)
-+void __d_rehash(struct dentry * entry, int lock)
- {
-       struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
-       if (!list_empty(&entry->d_hash)) BUG();
--      spin_lock(&dcache_lock);
-+      if (lock) spin_lock(&dcache_lock);
-       list_add(&entry->d_hash, list);
--      spin_unlock(&dcache_lock);
-+      if (lock) spin_unlock(&dcache_lock);
-+}
-+EXPORT_SYMBOL(__d_rehash);
-+
-+void d_rehash(struct dentry * entry)
-+{
-+      __d_rehash(entry, 1);
- }
- #define do_switch(x,y) do { \
---- linux-rh-2.4.20-6/fs/namei.c~vfs_intent-2.4.20     Tue Apr  1 01:03:23 2003
-+++ linux-rh-2.4.20-6-braam/fs/namei.c Wed Apr  2 02:12:53 2003
-@@ -1,3 +1,4 @@
-+
- /*
-  *  linux/fs/namei.c
-  *
-@@ -94,6 +95,13 @@
-  * XEmacs seems to be relying on it...
-  */
-+void intent_release(struct dentry *de, struct lookup_intent *it)
-+{
-+      if (it && de->d_op && de->d_op->d_intent_release)
-+              de->d_op->d_intent_release(de, it);
-+
-+}
-+
- /* In order to reduce some races, while at the same time doing additional
-  * checking and hopefully speeding things up, we copy filenames to the
-  * kernel data space before using them..
-@@ -260,10 +268,19 @@ void path_release(struct nameidata *nd)
-  * Internal lookup() using the new generic dcache.
-  * SMP-safe
-  */
--static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
-+                                  int flags, struct lookup_intent *it)
- {
-       struct dentry * dentry = d_lookup(parent, name);
-+      if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+              if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
-+                  !d_invalidate(dentry)) {
-+                      dput(dentry);
-+                      dentry = NULL;
-+              }
-+              return dentry;
-+      } else
-       if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-               if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
-                       dput(dentry);
-@@ -281,11 +298,14 @@ static struct dentry * cached_lookup(str
-  * make sure that nobody added the entry to the dcache in the meantime..
-  * SMP-safe
-  */
--static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
-+                                int flags, struct lookup_intent *it)
- {
-       struct dentry * result;
-       struct inode *dir = parent->d_inode;
-+again:
-+
-       down(&dir->i_sem);
-       /*
-        * First re-do the cached lookup just in case it was created
-@@ -300,6 +320,9 @@ static struct dentry * real_lookup(struc
-               result = ERR_PTR(-ENOMEM);
-               if (dentry) {
-                       lock_kernel();
-+                      if (dir->i_op->lookup2)
-+                              result = dir->i_op->lookup2(dir, dentry, it);
-+                      else
-                       result = dir->i_op->lookup(dir, dentry);
-                       unlock_kernel();
-                       if (result)
-@@ -321,6 +344,12 @@ static struct dentry * real_lookup(struc
-                       dput(result);
-                       result = ERR_PTR(-ENOENT);
-               }
-+      } else if (result->d_op && result->d_op->d_revalidate2) {
-+              if (!result->d_op->d_revalidate2(result, flags, it) &&
-+                  !d_invalidate(result)) {
-+                      dput(result);
-+                      goto again;
-+              }
-       }
-       return result;
- }
-@@ -334,7 +363,8 @@ int max_recursive_link = 5;
-  * Without that kind of total limit, nasty chains of consecutive
-  * symlinks can cause almost arbitrarily long lookups. 
-  */
--static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
-+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
-+                               struct lookup_intent *it)
- {
-       int err;
-       if (current->link_count >= max_recursive_link)
-@@ -348,10 +378,14 @@ static inline int do_follow_link(struct 
-       current->link_count++;
-       current->total_link_count++;
-       UPDATE_ATIME(dentry->d_inode);
--      err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (dentry->d_inode->i_op->follow_link2)
-+              err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
-+      else
-+              err = dentry->d_inode->i_op->follow_link(dentry, nd);
-       current->link_count--;
-       return err;
- loop:
-+      intent_release(dentry, it);
-       path_release(nd);
-       return -ELOOP;
- }
-@@ -381,15 +415,26 @@ int follow_up(struct vfsmount **mnt, str
-       return __follow_up(mnt, dentry);
- }
--static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
-+static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
-+                              struct lookup_intent *it)
- {
-       struct vfsmount *mounted;
-       spin_lock(&dcache_lock);
-       mounted = lookup_mnt(*mnt, *dentry);
-       if (mounted) {
-+              int opc = 0, mode = 0;
-               *mnt = mntget(mounted);
-               spin_unlock(&dcache_lock);
-+              if (it) {
-+                      opc = it->it_op;
-+                      mode = it->it_mode;
-+              }
-+              intent_release(*dentry, it);
-+              if (it) {
-+                      it->it_op = opc;
-+                      it->it_mode = mode;
-+              }
-               dput(*dentry);
-               mntput(mounted->mnt_parent);
-               *dentry = dget(mounted->mnt_root);
-@@ -401,7 +446,7 @@ static inline int __follow_down(struct v
- int follow_down(struct vfsmount **mnt, struct dentry **dentry)
- {
--      return __follow_down(mnt,dentry);
-+      return __follow_down(mnt,dentry,NULL);
- }
-  
- static inline void follow_dotdot(struct nameidata *nd)
-@@ -437,7 +482,7 @@ static inline void follow_dotdot(struct 
-               mntput(nd->mnt);
-               nd->mnt = parent;
-       }
--      while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
-+      while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL))
-               ;
- }
-@@ -449,7 +494,8 @@ static inline void follow_dotdot(struct 
-  *
-  * We expect 'base' to be positive and a directory.
-  */
--int link_path_walk(const char * name, struct nameidata *nd)
-+int link_path_walk_it(const char *name, struct nameidata *nd,
-+                    struct lookup_intent *it)
- {
-       struct dentry *dentry;
-       struct inode *inode;
-@@ -526,18 +572,18 @@ int link_path_walk(const char * name, st
-                               break;
-               }
-               /* This does the actual lookups.. */
--              dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
-+              dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
-               if (!dentry) {
-                       err = -EWOULDBLOCKIO;
-                       if (atomic)
-                               break;
--                      dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
-+                      dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
-                       err = PTR_ERR(dentry);
-                       if (IS_ERR(dentry))
-                               break;
-               }
-               /* Check mountpoints.. */
--              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
-+              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL))
-                       ;
-               err = -ENOENT;
-@@ -548,8 +594,8 @@ int link_path_walk(const char * name, st
-               if (!inode->i_op)
-                       goto out_dput;
--              if (inode->i_op->follow_link) {
--                      err = do_follow_link(dentry, nd);
-+              if (inode->i_op->follow_link || inode->i_op->follow_link2) {
-+                      err = do_follow_link(dentry, nd, NULL);
-                       dput(dentry);
-                       if (err)
-                               goto return_err;
-@@ -565,7 +611,7 @@ int link_path_walk(const char * name, st
-                       nd->dentry = dentry;
-               }
-               err = -ENOTDIR; 
--              if (!inode->i_op->lookup)
-+              if (!inode->i_op->lookup && !inode->i_op->lookup2)
-                       break;
-               continue;
-               /* here ends the main loop */
-@@ -592,22 +638,23 @@ last_component:
-                       if (err < 0)
-                               break;
-               }
--              dentry = cached_lookup(nd->dentry, &this, 0);
-+              dentry = cached_lookup(nd->dentry, &this, 0, NULL);
-               if (!dentry) {
-                       err = -EWOULDBLOCKIO;
-                       if (atomic)
-                               break;
--                      dentry = real_lookup(nd->dentry, &this, 0);
-+                      dentry = real_lookup(nd->dentry, &this, 0, NULL);
-                       err = PTR_ERR(dentry);
-                       if (IS_ERR(dentry))
-                               break;
-               }
--              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
-+              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL))
-                       ;
-               inode = dentry->d_inode;
-               if ((lookup_flags & LOOKUP_FOLLOW)
--                  && inode && inode->i_op && inode->i_op->follow_link) {
--                      err = do_follow_link(dentry, nd);
-+                  && inode && inode->i_op && 
-+                    inode->i_op->follow_link || inode->i_op->follow_link2) {
-+                      err = do_follow_link(dentry, nd, it);
-                       dput(dentry);
-                       if (err)
-                               goto return_err;
-@@ -621,7 +668,8 @@ last_component:
-                       goto no_inode;
-               if (lookup_flags & LOOKUP_DIRECTORY) {
-                       err = -ENOTDIR; 
--                      if (!inode->i_op || !inode->i_op->lookup)
-+                      if (!inode->i_op ||
-+                          (!inode->i_op->lookup && !inode->i_op->lookup2))
-                               break;
-               }
-               goto return_base;
-@@ -645,6 +693,30 @@ return_reval:
-                * Check the cached dentry for staleness.
-                */
-               dentry = nd->dentry;
-+        revalidate_again:
-+              if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+                      err = -ESTALE;
-+                      if (!dentry->d_op->d_revalidate2(dentry, 0, it)) {
-+                                struct dentry *new;
-+                                err = permission(dentry->d_parent->d_inode, 
-+                                                 MAY_EXEC);
-+                                if (err)
-+                                        break;
-+                                new = real_lookup(dentry->d_parent,
-+                                                  &dentry->d_name, 0, NULL);
-+                              d_invalidate(dentry);
-+                                dput(dentry);
-+                                dentry = new;
-+                                goto revalidate_again;
-+                        }
-+              } else
-+              if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+                      err = -ESTALE;
-+                      if (!dentry->d_op->d_revalidate2(dentry, 0, it)) {
-+                              d_invalidate(dentry);
-+                              break;
-+                      }
-+              } else 
-               if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-                       err = -ESTALE;
-                       if (!dentry->d_op->d_revalidate(dentry, 0)) {
-@@ -658,15 +730,28 @@ out_dput:
-               dput(dentry);
-               break;
-       }
-+      if (err)
-+              intent_release(nd->dentry, it);
-       path_release(nd);
- return_err:
-       return err;
- }
-+int link_path_walk(const char * name, struct nameidata *nd)
-+{
-+      return link_path_walk_it(name, nd, NULL);
-+}
-+
-+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
-+{
-+      current->total_link_count = 0;
-+      return link_path_walk_it(name, nd, it);
-+}
-+
- int path_walk(const char * name, struct nameidata *nd)
- {
-       current->total_link_count = 0;
--      return link_path_walk(name, nd);
-+      return link_path_walk_it(name, nd, NULL);
- }
- /* SMP-safe */
-@@ -751,6 +836,14 @@ walk_init_root(const char *name, struct 
- }
- /* SMP-safe */
-+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd, struct lookup_intent *it)
-+{
-+      int error = 0;
-+      if (path_init(path, flags, nd))
-+              error = path_walk_it(path, nd, it);
-+      return error;
-+}
-+
- int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
- {
-       int error = 0;
-@@ -779,7 +872,8 @@ int path_init(const char *name, unsigned
-  * needs parent already locked. Doesn't follow mounts.
-  * SMP-safe.
-  */
--struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
-+                             struct lookup_intent *it)
- {
-       struct dentry * dentry;
-       struct inode *inode;
-@@ -802,13 +896,16 @@ struct dentry * lookup_hash(struct qstr 
-                       goto out;
-       }
--      dentry = cached_lookup(base, name, 0);
-+      dentry = cached_lookup(base, name, 0, it);
-       if (!dentry) {
-               struct dentry *new = d_alloc(base, name);
-               dentry = ERR_PTR(-ENOMEM);
-               if (!new)
-                       goto out;
-               lock_kernel();
-+              if (inode->i_op->lookup2)
-+                      dentry = inode->i_op->lookup2(inode, new, it);
-+              else
-               dentry = inode->i_op->lookup(inode, new);
-               unlock_kernel();
-               if (!dentry)
-@@ -820,6 +917,12 @@ out:
-       return dentry;
- }
-+struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+{
-+      return lookup_hash_it(name, base, NULL);
-+}
-+
-+
- /* SMP-safe */
- struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
- {
-@@ -841,7 +944,7 @@ struct dentry * lookup_one_len(const cha
-       }
-       this.hash = end_name_hash(hash);
--      return lookup_hash(&this, base);
-+      return lookup_hash_it(&this, base, NULL);
- access:
-       return ERR_PTR(-EACCES);
- }
-@@ -872,6 +975,23 @@ int __user_walk(const char *name, unsign
-       return err;
- }
-+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
-+                 struct lookup_intent *it)
-+{
-+      char *tmp;
-+      int err;
-+
-+      tmp = getname(name);
-+      err = PTR_ERR(tmp);
-+      if (!IS_ERR(tmp)) {
-+              err = 0;
-+              if (path_init(tmp, flags, nd))
-+                      err = path_walk_it(tmp, nd, it);
-+              putname(tmp);
-+      }
-+      return err;
-+}
-+
- /*
-  * It's inline, so penalty for filesystems that don't use sticky bit is
-  * minimal.
-@@ -1010,7 +1130,8 @@ exit_lock:
-  * for symlinks (where the permissions are checked later).
-  * SMP-safe
-  */
--int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
-+int open_namei_it(const char *pathname, int flag, int mode,
-+                struct nameidata *nd, struct lookup_intent *it)
- {
-       int acc_mode, error = 0;
-       struct inode *inode;
-@@ -1024,7 +1145,7 @@ int open_namei(const char * pathname, in
-        * The simplest case - just a plain lookup.
-        */
-       if (!(flag & O_CREAT)) {
--              error = path_lookup(pathname, lookup_flags(flag), nd);
-+              error = path_lookup_it(pathname, lookup_flags(flag), nd, it);
-               if (error)
-                       return error;
-               dentry = nd->dentry;
-@@ -1034,6 +1155,10 @@ int open_namei(const char * pathname, in
-       /*
-        * Create - we need to know the parent.
-        */
-+      if (it) {
-+              it->it_mode = mode;
-+              it->it_op |= IT_CREAT;
-+      }
-       error = path_lookup(pathname, LOOKUP_PARENT, nd);
-       if (error)
-               return error;
-@@ -1049,7 +1174,7 @@ int open_namei(const char * pathname, in
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
- do_last:
-       error = PTR_ERR(dentry);
-@@ -1058,6 +1183,7 @@ do_last:
-               goto exit;
-       }
-+      it->it_mode = mode;
-       /* Negative dentry, just create the file */
-       if (!dentry->d_inode) {
-               error = vfs_create(dir->d_inode, dentry,
-@@ -1086,12 +1212,13 @@ do_last:
-               error = -ELOOP;
-               if (flag & O_NOFOLLOW)
-                       goto exit_dput;
--              while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
-+              while (__follow_down(&nd->mnt,&dentry,it) && d_mountpoint(dentry));
-       }
-       error = -ENOENT;
-       if (!dentry->d_inode)
-               goto exit_dput;
--      if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
-+      if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
-+                                    dentry->d_inode->i_op->follow_link2))
-               goto do_link;
-       dput(nd->dentry);
-@@ -1165,7 +1292,7 @@ ok:
-               if (!error) {
-                       DQUOT_INIT(inode);
-                       
--                      error = do_truncate(dentry, 0);
-+                      error = do_truncate(dentry, 0, 1);
-               }
-               put_write_access(inode);
-               if (error)
-@@ -1177,8 +1304,10 @@ ok:
-       return 0;
- exit_dput:
-+      intent_release(dentry, it);
-       dput(dentry);
- exit:
-+      intent_release(nd->dentry, it);
-       path_release(nd);
-       return error;
-@@ -1197,7 +1326,12 @@ do_link:
-        * are done. Procfs-like symlinks just set LAST_BIND.
-        */
-       UPDATE_ATIME(dentry->d_inode);
--      error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (dentry->d_inode->i_op->follow_link2)
-+              error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
-+      else
-+              error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (error)
-+              intent_release(dentry, it);
-       dput(dentry);
-       if (error)
-               return error;
-@@ -1219,13 +1353,20 @@ do_link:
-       }
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
-       putname(nd->last.name);
-       goto do_last;
- }
-+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
-+{
-+      return open_namei_it(pathname, flag, mode, nd, NULL);
-+}
-+
-+
- /* SMP-safe */
--static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
-+static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
-+                                  struct lookup_intent *it)
- {
-       struct dentry *dentry;
-@@ -1233,7 +1374,7 @@ static struct dentry *lookup_create(stru
-       dentry = ERR_PTR(-EEXIST);
-       if (nd->last_type != LAST_NORM)
-               goto fail;
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
-       if (IS_ERR(dentry))
-               goto fail;
-       if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1289,7 +1430,19 @@ asmlinkage long sys_mknod(const char * f
-       error = path_lookup(tmp, LOOKUP_PARENT, &nd);
-       if (error)
-               goto out;
--      dentry = lookup_create(&nd, 0);
-+
-+      if (nd.dentry->d_inode->i_op->mknod2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              error = op->mknod2(nd.dentry->d_inode,
-+                                 nd.last.name,
-+                                 nd.last.len,
-+                                 mode, dev);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto out2;
-+      }
-+
-+      dentry = lookup_create(&nd, 0, NULL);
-       error = PTR_ERR(dentry);
-       mode &= ~current->fs->umask;
-@@ -1310,6 +1463,7 @@ asmlinkage long sys_mknod(const char * f
-               dput(dentry);
-       }
-       up(&nd.dentry->d_inode->i_sem);
-+out2:
-       path_release(&nd);
- out:
-       putname(tmp);
-@@ -1357,7 +1511,17 @@ asmlinkage long sys_mkdir(const char * p
-               error = path_lookup(tmp, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
--              dentry = lookup_create(&nd, 1);
-+              if (nd.dentry->d_inode->i_op->mkdir2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->mkdir2(nd.dentry->d_inode,
-+                                         nd.last.name,
-+                                         nd.last.len,
-+                                         mode);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out2;
-+              }
-+              dentry = lookup_create(&nd, 1, NULL);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_mkdir(nd.dentry->d_inode, dentry,
-@@ -1365,6 +1529,8 @@ asmlinkage long sys_mkdir(const char * p
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-+out2:
-+              path_release(&nd);
-               path_release(&nd);
- out:
-               putname(tmp);
-@@ -1465,8 +1631,33 @@ asmlinkage long sys_rmdir(const char * p
-                       error = -EBUSY;
-                       goto exit1;
-       }
-+      if (nd.dentry->d_inode->i_op->rmdir2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              struct dentry *last;
-+
-+              down(&nd.dentry->d_inode->i_sem);
-+              last = lookup_hash_it(&nd.last, nd.dentry, NULL);
-+              up(&nd.dentry->d_inode->i_sem);
-+              if (IS_ERR(last)) {
-+                      error = PTR_ERR(last);
-+                      goto exit1;
-+              }
-+              if (d_mountpoint(last)) {
-+                      dput(last);
-+                      error = -EBUSY;
-+                      goto exit1;
-+              }
-+              dput(last);
-+
-+              error = op->rmdir2(nd.dentry->d_inode,
-+                                 nd.last.name,
-+                                 nd.last.len);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit1;
-+      }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1518,14 +1709,23 @@ asmlinkage long sys_unlink(const char * 
-       if(IS_ERR(name))
-               return PTR_ERR(name);
--      error = path_lookup(name, LOOKUP_PARENT, &nd);
-+      error = path_lookup_it(name, LOOKUP_PARENT, &nd, NULL);
-       if (error)
-               goto exit;
-       error = -EISDIR;
-       if (nd.last_type != LAST_NORM)
-               goto exit1;
-+      if (nd.dentry->d_inode->i_op->unlink2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              error = op->unlink2(nd.dentry->d_inode,
-+                                  nd.last.name,
-+                                  nd.last.len);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit1;
-+      }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               /* Why not before? Because we want correct error value */
-@@ -1592,15 +1792,26 @@ asmlinkage long sys_symlink(const char *
-               error = path_lookup(to, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
--              dentry = lookup_create(&nd, 0);
-+              if (nd.dentry->d_inode->i_op->symlink2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->symlink2(nd.dentry->d_inode,
-+                                           nd.last.name,
-+                                           nd.last.len,
-+                                           from);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out2;
-+              }
-+              dentry = lookup_create(&nd, 0, NULL);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_symlink(nd.dentry->d_inode, dentry, from);
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-+      out2:
-               path_release(&nd);
--out:
-+      out:
-               putname(to);
-       }
-       putname(from);
-@@ -1676,7 +1887,17 @@ asmlinkage long sys_link(const char * ol
-               error = -EXDEV;
-               if (old_nd.mnt != nd.mnt)
-                       goto out_release;
--              new_dentry = lookup_create(&nd, 0);
-+              if (nd.dentry->d_inode->i_op->link2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->link2(old_nd.dentry->d_inode,
-+                                        nd.dentry->d_inode,
-+                                        nd.last.name,
-+                                        nd.last.len);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out_release;
-+              }
-+              new_dentry = lookup_create(&nd, 0, NULL);
-               error = PTR_ERR(new_dentry);
-               if (!IS_ERR(new_dentry)) {
-                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-@@ -1720,7 +1941,8 @@ exit:
-  *       locking].
-  */
- int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+                 struct inode *new_dir, struct dentry *new_dentry,
-+                 struct lookup_intent *it)
- {
-       int error;
-       struct inode *target;
-@@ -1778,6 +2000,7 @@ int vfs_rename_dir(struct inode *old_dir
-               error = -EBUSY;
-       else 
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       if (target) {
-               if (!error)
-                       target->i_flags |= S_DEAD;
-@@ -1799,7 +2022,8 @@ out_unlock:
- }
- int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+                   struct inode *new_dir, struct dentry *new_dentry,
-+                   struct lookup_intent *it)
- {
-       int error;
-@@ -1830,6 +2054,7 @@ int vfs_rename_other(struct inode *old_d
-               error = -EBUSY;
-       else
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       double_up(&old_dir->i_zombie, &new_dir->i_zombie);
-       if (error)
-               return error;
-@@ -1841,13 +2066,14 @@ int vfs_rename_other(struct inode *old_d
- }
- int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+             struct inode *new_dir, struct dentry *new_dentry,
-+             struct lookup_intent *it)
- {
-       int error;
-       if (S_ISDIR(old_dentry->d_inode->i_mode))
--              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
-       else
--              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
-       if (!error) {
-               if (old_dir == new_dir)
-                       inode_dir_notify(old_dir, DN_RENAME);
-@@ -1889,7 +2115,7 @@ static inline int do_rename(const char *
-       double_lock(new_dir, old_dir);
--      old_dentry = lookup_hash(&oldnd.last, old_dir);
-+      old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL);
-       error = PTR_ERR(old_dentry);
-       if (IS_ERR(old_dentry))
-               goto exit3;
-@@ -1905,16 +2131,37 @@ static inline int do_rename(const char *
-               if (newnd.last.name[newnd.last.len])
-                       goto exit4;
-       }
--      new_dentry = lookup_hash(&newnd.last, new_dir);
-+      new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL);
-       error = PTR_ERR(new_dentry);
-       if (IS_ERR(new_dentry))
-               goto exit4;
-+      if (old_dir->d_inode->i_op->rename2) {
-+              lock_kernel();
-+              /* don't rename mount point. mds will take care of
-+               * the rest sanity checking */
-+              if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) {
-+                      error = -EBUSY;
-+                      goto exit5;
-+              }
-+
-+              error = old_dir->d_inode->i_op->rename2(old_dir->d_inode,
-+                                                      new_dir->d_inode,
-+                                                      oldnd.last.name,
-+                                                      oldnd.last.len,
-+                                                      newnd.last.name,
-+                                                      newnd.last.len);
-+              unlock_kernel();
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit5;
-+      }
-+
-       lock_kernel();
-       error = vfs_rename(old_dir->d_inode, old_dentry,
--                                 new_dir->d_inode, new_dentry);
-+                                 new_dir->d_inode, new_dentry, NULL);
-       unlock_kernel();
--
-+exit5:
-       dput(new_dentry);
- exit4:
-       dput(old_dentry);
-@@ -1965,7 +2212,8 @@ out:
- }
- static inline int
--__vfs_follow_link(struct nameidata *nd, const char *link)
-+__vfs_follow_link(struct nameidata *nd, const char *link,
-+                struct lookup_intent *it)
- {
-       int res = 0;
-       char *name;
-@@ -1978,7 +2226,7 @@ __vfs_follow_link(struct nameidata *nd, 
-                       /* weird __emul_prefix() stuff did it */
-                       goto out;
-       }
--      res = link_path_walk(link, nd);
-+      res = link_path_walk_it(link, nd, it);
- out:
-       if (current->link_count || res || nd->last_type!=LAST_NORM)
-               return res;
-@@ -2002,7 +2250,13 @@ fail:
- int vfs_follow_link(struct nameidata *nd, const char *link)
- {
--      return __vfs_follow_link(nd, link);
-+      return __vfs_follow_link(nd, link, NULL);
-+}
-+
-+int vfs_follow_link_it(struct nameidata *nd, const char *link,
-+                     struct lookup_intent *it)
-+{
-+      return __vfs_follow_link(nd, link, it);
- }
- /* get the link contents into pagecache */
-@@ -2044,7 +2298,7 @@ int page_follow_link(struct dentry *dent
- {
-       struct page *page = NULL;
-       char *s = page_getlink(dentry, &page);
--      int res = __vfs_follow_link(nd, s);
-+      int res = __vfs_follow_link(nd, s, NULL);
-       if (page) {
-               kunmap(page);
-               page_cache_release(page);
---- linux-rh-2.4.20-6/fs/nfsd/vfs.c~vfs_intent-2.4.20  Tue Apr  1 01:03:23 2003
-+++ linux-rh-2.4.20-6-braam/fs/nfsd/vfs.c      Tue Apr  1 01:03:23 2003
-@@ -1293,7 +1293,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
-                       err = nfserr_perm;
-       } else
- #endif
--      err = vfs_rename(fdir, odentry, tdir, ndentry);
-+      err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
-       if (!err && EX_ISSYNC(tfhp->fh_export)) {
-               nfsd_sync_dir(tdentry);
-               nfsd_sync_dir(fdentry);
---- linux-rh-2.4.20-6/fs/open.c~vfs_intent-2.4.20      Tue Apr  1 01:03:23 2003
-+++ linux-rh-2.4.20-6-braam/fs/open.c  Tue Apr  1 01:03:23 2003
-@@ -19,6 +19,8 @@
- #include <asm/uaccess.h>
- #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
-+extern int path_walk_it(const char *name, struct nameidata *nd,
-+                      struct lookup_intent *it);
- int vfs_statfs(struct super_block *sb, struct statfs *buf)
- {
-@@ -95,9 +97,10 @@ void fd_install(unsigned int fd, struct 
-       write_unlock(&files->file_lock);
- }
--int do_truncate(struct dentry *dentry, loff_t length)
-+int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
- {
-       struct inode *inode = dentry->d_inode;
-+      struct inode_operations *op = dentry->d_inode->i_op;
-       int error;
-       struct iattr newattrs;
-@@ -108,7 +111,14 @@ int do_truncate(struct dentry *dentry, l
-       down(&inode->i_sem);
-       newattrs.ia_size = length;
-       newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
--      error = notify_change(dentry, &newattrs);
-+      if (called_from_open)
-+              newattrs.ia_valid |= ATTR_FROM_OPEN;
-+      if (op->setattr_raw) {
-+              newattrs.ia_valid |= ATTR_RAW;
-+              newattrs.ia_ctime = CURRENT_TIME;
-+              error = op->setattr_raw(inode, &newattrs);
-+      } else 
-+              error = notify_change(dentry, &newattrs);
-       up(&inode->i_sem);
-       return error;
- }
-@@ -118,12 +128,13 @@ static inline long do_sys_truncate(const
-       struct nameidata nd;
-       struct inode * inode;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       error = -EINVAL;
-       if (length < 0) /* sorry, but loff_t says... */
-               goto out;
--      error = user_path_walk(path, &nd);
-+      error = user_path_walk_it(path, &nd, &it);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-@@ -163,11 +174,13 @@ static inline long do_sys_truncate(const
-       error = locks_verify_truncate(inode, NULL, length);
-       if (!error) {
-               DQUOT_INIT(inode);
--              error = do_truncate(nd.dentry, length);
-+              intent_release(nd.dentry, &it);
-+              error = do_truncate(nd.dentry, length, 0);
-       }
-       put_write_access(inode);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi
-       error = locks_verify_truncate(inode, file, length);
-       if (!error)
--              error = do_truncate(dentry, length);
-+              error = do_truncate(dentry, length, 0);
- out_putf:
-       fput(file);
- out:
-@@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam
-       struct inode * inode;
-       struct iattr newattrs;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, NULL);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-+      /* this is safe without a Lustre lock because it only depends
-+         on the super block */
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-@@ -279,11 +294,29 @@ asmlinkage long sys_utime(char * filenam
-                       goto dput_and_out;
-               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
--      } else {
-+      }
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-+      error = -EROFS;
-+      if (IS_RDONLY(inode))
-+              goto dput_and_out;
-+
-+      error = -EPERM;
-+      if (!times) {
-               if (current->fsuid != inode->i_uid &&
-                   (error = permission(inode,MAY_WRITE)) != 0)
-                       goto dput_and_out;
-       }
-+
-       error = notify_change(nd.dentry, &newattrs);
- dput_and_out:
-       path_release(&nd);
-@@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena
-       struct inode * inode;
-       struct iattr newattrs;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, NULL);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-+      /* this is safe without a Lustre lock because it only depends
-+         on the super block */
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-@@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena
-               newattrs.ia_atime = times[0].tv_sec;
-               newattrs.ia_mtime = times[1].tv_sec;
-               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
--      } else {
-+      }
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-+      error = -EPERM;
-+      if (!utimes) {
-               if (current->fsuid != inode->i_uid &&
-                   (error = permission(inode,MAY_WRITE)) != 0)
-                       goto dput_and_out;
-@@ -347,6 +395,7 @@ asmlinkage long sys_access(const char * 
-       int old_fsuid, old_fsgid;
-       kernel_cap_t old_cap;
-       int res;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
-               return -EINVAL;
-@@ -364,13 +413,14 @@ asmlinkage long sys_access(const char * 
-       else
-               current->cap_effective = current->cap_permitted;
--      res = user_path_walk(filename, &nd);
-+      res = user_path_walk_it(filename, &nd, &it);
-       if (!res) {
-               res = permission(nd.dentry->d_inode, mode);
-               /* SuS v2 requires we report a read only fs too */
-               if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
-                  && !special_file(nd.dentry->d_inode->i_mode))
-                       res = -EROFS;
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-@@ -385,8 +435,11 @@ asmlinkage long sys_chdir(const char * f
- {
-       int error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
-+      error = __user_walk_it(filename,
-+                             LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,
-+                             &nd, &it);
-       if (error)
-               goto out;
-@@ -397,6 +450,7 @@ asmlinkage long sys_chdir(const char * f
-       set_fs_pwd(current->fs, nd.mnt, nd.dentry);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -436,9 +490,10 @@ asmlinkage long sys_chroot(const char * 
- {
-       int error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
--                    LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
-+      error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
-+                             LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
-       if (error)
-               goto out;
-@@ -454,6 +509,7 @@ asmlinkage long sys_chroot(const char * 
-       set_fs_altroot();
-       error = 0;
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -508,6 +564,18 @@ asmlinkage long sys_chmod(const char * f
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_mode = mode;
-+              newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-       error = -EPERM;
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               goto dput_and_out;
-@@ -538,6 +606,20 @@ static int chown_common(struct dentry * 
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto out;
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = dentry->d_inode->i_op;
-+
-+              newattrs.ia_uid = user;
-+              newattrs.ia_gid = group;
-+              newattrs.ia_valid = ATTR_UID | ATTR_GID;
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      return error;
-+      }
-+
-       error = -EPERM;
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               goto out;
-@@ -658,7 +740,8 @@ struct file *filp_open(const char * file
-       return ERR_PTR(error);
- }
--struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                          int flags, struct lookup_intent *it)
- {
-       struct file * f;
-       struct inode *inode;
-@@ -701,6 +784,7 @@ struct file *dentry_open(struct dentry *
-       }
-       f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
-+      intent_release(dentry, it);
-       return f;
- cleanup_all:
-@@ -715,11 +799,17 @@ cleanup_all:
- cleanup_file:
-       put_filp(f);
- cleanup_dentry:
-+      intent_release(dentry, it);
-       dput(dentry);
-       mntput(mnt);
-       return ERR_PTR(error);
- }
-+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+{
-+      return dentry_open_it(dentry, mnt, flags, NULL);
-+}
-+
- /*
-  * Find an empty file descriptor entry, and mark it busy.
-  */
---- linux-rh-2.4.20-6/fs/stat.c~vfs_intent-2.4.20      Tue Apr  1 01:03:23 2003
-+++ linux-rh-2.4.20-6-braam/fs/stat.c  Tue Apr  1 01:03:23 2003
-@@ -111,10 +111,12 @@ int vfs_stat(char *name, struct kstat *s
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = user_path_walk(name, &nd);
-+      error = user_path_walk_it(name, &nd, &it);
-       if (!error) {
-               error = do_getattr(nd.mnt, nd.dentry, stat);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -124,10 +126,12 @@ int vfs_lstat(char *name, struct kstat *
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = user_path_walk_link(name, &nd);
-+      error = user_path_walk_link_it(name, &nd, &it);
-       if (!error) {
-               error = do_getattr(nd.mnt, nd.dentry, stat);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
---- linux-rh-2.4.20-6/fs/exec.c~vfs_intent-2.4.20      Tue Apr  1 01:03:23 2003
-+++ linux-rh-2.4.20-6-braam/fs/exec.c  Wed Apr  2 00:29:56 2003
-@@ -114,8 +114,9 @@ asmlinkage long sys_uselib(const char * 
-       struct file * file;
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
--      error = user_path_walk(library, &nd);
-+      error = user_path_walk_it(library, &nd, &it);
-       if (error)
-               goto out;
-@@ -127,7 +128,8 @@ asmlinkage long sys_uselib(const char * 
-       if (error)
-               goto exit;
--      file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
-+      file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
-+      intent_release(nd.dentry, &it);
-       error = PTR_ERR(file);
-       if (IS_ERR(file))
-               goto out;
-@@ -382,8 +384,9 @@ struct file *open_exec(const char *name)
-       struct inode *inode;
-       struct file *file;
-       int err = 0;
-+      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
--      err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
-+      err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
-       file = ERR_PTR(err);
-       if (!err) {
-               inode = nd.dentry->d_inode;
-@@ -395,7 +398,8 @@ struct file *open_exec(const char *name)
-                               err = -EACCES;
-                       file = ERR_PTR(err);
-                       if (!err) {
--                              file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
-+                              file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
-+                              intent_release(nd.dentry, &it);
-                               if (!IS_ERR(file)) {
-                                       err = deny_write_access(file);
-                                       if (err) {
-@@ -1279,7 +1283,7 @@ int do_coredump(long signr, int exit_cod
-               goto close_fail;
-       if (!file->f_op->write)
-               goto close_fail;
--      if (do_truncate(file->f_dentry, 0) != 0)
-+      if (do_truncate(file->f_dentry, 0, 0) != 0)
-               goto close_fail;
-       retval = binfmt->core_dump(signr, regs, file);
---- linux-rh-2.4.20-6/include/linux/dcache.h~vfs_intent-2.4.20 Tue Apr  1 01:03:23 2003
-+++ linux-rh-2.4.20-6-braam/include/linux/dcache.h     Tue Apr  1 01:03:23 2003
-@@ -7,6 +7,25 @@
- #include <linux/mount.h>
- #include <linux/kernel.h>
-+#define IT_OPEN     (1)
-+#define IT_CREAT    (1<<1)
-+#define IT_READDIR  (1<<2)
-+#define IT_GETATTR  (1<<3)
-+#define IT_LOOKUP   (1<<4)
-+#define IT_UNLINK   (1<<5)
-+
-+struct lookup_intent {
-+      int it_op;
-+      int it_mode;
-+      int it_flags;
-+      int it_disposition;
-+      int it_status;
-+      struct iattr *it_iattr;
-+      __u64 it_lock_handle[2];
-+      int it_lock_mode;
-+      void *it_data;
-+};
-+
- /*
-  * linux/include/linux/dcache.h
-  *
-@@ -82,6 +101,7 @@ struct dentry {
-       unsigned long d_time;           /* used by d_revalidate */
-       struct dentry_operations  *d_op;
-       struct super_block * d_sb;      /* The root of the dentry tree */
-+      struct lookup_intent *d_it;
-       unsigned long d_vfs_flags;
-       void * d_fsdata;                /* fs-specific data */
-       void * d_extra_attributes;      /* TUX-specific data */
-@@ -96,8 +116,15 @@ struct dentry_operations {
-       int (*d_delete)(struct dentry *);
-       void (*d_release)(struct dentry *);
-       void (*d_iput)(struct dentry *, struct inode *);
-+      int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
-+      void (*d_intent_release)(struct dentry *, struct lookup_intent *);
- };
-+/* defined in fs/namei.c */
-+extern void intent_release(struct dentry *de, struct lookup_intent *it);
-+/* defined in fs/dcache.c */
-+extern void __d_rehash(struct dentry * entry, int lock);
-+
- /* the dentry parameter passed to d_hash and d_compare is the parent
-  * directory of the entries to be compared. It is used in case these
-  * functions need any directory specific information for determining
-@@ -129,6 +156,7 @@ d_iput:            no              no              yes
-                                        * s_nfsd_free_path semaphore will be down
-                                        */
- #define DCACHE_REFERENCED     0x0008  /* Recently used, don't discard. */
-+#define DCACHE_LUSTRE_INVALID 0x0010  /* Lustre invalidated */
- extern spinlock_t dcache_lock;
---- linux-rh-2.4.20-6/include/linux/fs.h~vfs_intent-2.4.20     Tue Apr  1 01:03:23 2003
-+++ linux-rh-2.4.20-6-braam/include/linux/fs.h Wed Apr  2 02:13:01 2003
-@@ -1,3 +1,6 @@
-+
-+
-+
- #ifndef _LINUX_FS_H
- #define _LINUX_FS_H
-@@ -337,6 +340,8 @@ extern void set_bh_page(struct buffer_he
- #define ATTR_MTIME_SET        256
- #define ATTR_FORCE    512     /* Not a change, but a change it */
- #define ATTR_ATTR_FLAG        1024
-+#define ATTR_RAW      2048    /* file system, not vfs will massage attrs */
-+#define ATTR_FROM_OPEN        4096    /* called from open path, ie O_TRUNC */
- /*
-  * This is the Inode Attributes structure, used for notify_change().  It
-@@ -574,6 +579,7 @@ struct file {
-       /* needed for tty driver, and maybe others */
-       void                    *private_data;
-+      struct lookup_intent    *f_intent;
-       /* preallocated helper kiobuf to speedup O_DIRECT */
-       struct kiobuf           *f_iobuf;
-@@ -821,7 +827,9 @@ extern int vfs_symlink(struct inode *, s
- extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
- extern int vfs_rmdir(struct inode *, struct dentry *);
- extern int vfs_unlink(struct inode *, struct dentry *);
--extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
-+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-+              struct inode *new_dir, struct dentry *new_dentry,
-+              struct lookup_intent *it);
- /*
-  * File types
-@@ -882,20 +890,33 @@ struct file_operations {
- struct inode_operations {
-       int (*create) (struct inode *,struct dentry *,int);
-       struct dentry * (*lookup) (struct inode *,struct dentry *);
-+      struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
-       int (*link) (struct dentry *,struct inode *,struct dentry *);
-+      int (*link2) (struct inode *,struct inode *, const char *, int);
-       int (*unlink) (struct inode *,struct dentry *);
-+      int (*unlink2) (struct inode *, const char *, int);
-       int (*symlink) (struct inode *,struct dentry *,const char *);
-+      int (*symlink2) (struct inode *, const char *, int, const char *);
-       int (*mkdir) (struct inode *,struct dentry *,int);
-+      int (*mkdir2) (struct inode *, const char *, int,int);
-       int (*rmdir) (struct inode *,struct dentry *);
-+      int (*rmdir2) (struct inode *, const char *, int);
-       int (*mknod) (struct inode *,struct dentry *,int,int);
-+      int (*mknod2) (struct inode *, const char *, int,int,int);
-       int (*rename) (struct inode *, struct dentry *,
-                       struct inode *, struct dentry *);
-+      int (*rename2) (struct inode *, struct inode *,
-+                      const char *oldname, int oldlen,
-+                      const char *newname, int newlen);
-       int (*readlink) (struct dentry *, char *,int);
-       int (*follow_link) (struct dentry *, struct nameidata *);
-+      int (*follow_link2) (struct dentry *, struct nameidata *,
-+                           struct lookup_intent *it);
-       void (*truncate) (struct inode *);
-       int (*permission) (struct inode *, int);
-       int (*revalidate) (struct dentry *);
-       int (*setattr) (struct dentry *, struct iattr *);
-+      int (*setattr_raw) (struct inode *, struct iattr *);
-       int (*getattr) (struct dentry *, struct iattr *);
-       int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
-       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-@@ -1091,10 +1112,13 @@ static inline int get_lease(struct inode
- asmlinkage long sys_open(const char *, int, int);
- asmlinkage long sys_close(unsigned int);      /* yes, it's really unsigned */
--extern int do_truncate(struct dentry *, loff_t start);
-+extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
- extern struct file *filp_open(const char *, int, int);
- extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
-+extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                          int flags, struct lookup_intent *it);
-+extern int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd, struct lookup_intent *it);
- extern int filp_close(struct file *, fl_owner_t id);
- extern char * getname(const char *);
-@@ -1385,6 +1409,7 @@ typedef int (*read_actor_t)(read_descrip
- extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
- extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
-+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
- extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
- extern int FASTCALL(path_walk(const char *, struct nameidata *));
- extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
-@@ -1396,6 +1421,8 @@ extern struct dentry * lookup_one_len(co
- extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
- #define user_path_walk(name,nd)        __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
- #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
-+#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
-+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
- extern void inode_init_once(struct inode *);
- extern void iput(struct inode *);
-@@ -1495,6 +1522,8 @@ extern struct file_operations generic_ro
- extern int vfs_readlink(struct dentry *, char *, int, const char *);
- extern int vfs_follow_link(struct nameidata *, const char *);
-+extern int vfs_follow_link_it(struct nameidata *, const char *,
-+                            struct lookup_intent *it);
- extern int page_readlink(struct dentry *, char *, int);
- extern int page_follow_link(struct dentry *, struct nameidata *);
- extern struct inode_operations page_symlink_inode_operations;
---- linux-rh-2.4.20-6/kernel/ksyms.c~vfs_intent-2.4.20 Tue Apr  1 01:03:23 2003
-+++ linux-rh-2.4.20-6-braam/kernel/ksyms.c     Tue Apr  1 01:03:23 2003
-@@ -298,6 +298,7 @@ EXPORT_SYMBOL(read_cache_page);
- EXPORT_SYMBOL(set_page_dirty);
- EXPORT_SYMBOL(vfs_readlink);
- EXPORT_SYMBOL(vfs_follow_link);
-+EXPORT_SYMBOL(vfs_follow_link_it);
- EXPORT_SYMBOL(page_readlink);
- EXPORT_SYMBOL(page_follow_link);
- EXPORT_SYMBOL(page_symlink_inode_operations);
-
-_
diff --git a/lustre/kernel_patches/patches/vfs_intent.patch b/lustre/kernel_patches/patches/vfs_intent.patch
deleted file mode 100644 (file)
index 54c498a..0000000
+++ /dev/null
@@ -1,1157 +0,0 @@
-
-
-
- 0 files changed
-
---- linux-2.4.18-17.8.0/fs/dcache.c~vfs_intent 2002-12-06 14:52:31.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/fs/dcache.c        2002-12-06 14:52:31.000000000 -0800
-@@ -150,6 +150,8 @@ repeat:
- unhash_it:
-       list_del_init(&dentry->d_hash);
-+
-+
- kill_it: {
-               struct dentry *parent;
-               list_del(&dentry->d_child);
-@@ -645,6 +647,7 @@ struct dentry * d_alloc(struct dentry * 
-       dentry->d_fsdata = NULL;
-       dentry->d_extra_attributes = NULL;
-       dentry->d_mounted = 0;
-+      dentry->d_it = NULL;
-       INIT_LIST_HEAD(&dentry->d_hash);
-       INIT_LIST_HEAD(&dentry->d_lru);
-       INIT_LIST_HEAD(&dentry->d_subdirs);
---- linux-2.4.18-17.8.0/fs/namei.c~vfs_intent  2002-12-06 14:52:31.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/fs/namei.c 2002-12-06 14:52:31.000000000 -0800
-@@ -1,3 +1,6 @@
-+
-+
-+
- /*
-  *  linux/fs/namei.c
-  *
-@@ -94,6 +97,14 @@
-  * XEmacs seems to be relying on it...
-  */
-+void intent_release(struct dentry *de, struct lookup_intent *it)
-+{
-+      if (it && de->d_op && de->d_op->d_intent_release)
-+              de->d_op->d_intent_release(de, it);
-+
-+}
-+
-+
- /* In order to reduce some races, while at the same time doing additional
-  * checking and hopefully speeding things up, we copy filenames to the
-  * kernel data space before using them..
-@@ -260,10 +271,19 @@ void path_release(struct nameidata *nd)
-  * Internal lookup() using the new generic dcache.
-  * SMP-safe
-  */
--static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
-+                                  int flags, struct lookup_intent *it)
- {
-       struct dentry * dentry = d_lookup(parent, name);
-+      if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+              if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
-+                  !d_invalidate(dentry)) {
-+                      dput(dentry);
-+                      dentry = NULL;
-+              }
-+              return dentry;
-+      } else
-       if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-               if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
-                       dput(dentry);
-@@ -281,7 +301,8 @@ static struct dentry * cached_lookup(str
-  * make sure that nobody added the entry to the dcache in the meantime..
-  * SMP-safe
-  */
--static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
-+                                int flags, struct lookup_intent *it)
- {
-       struct dentry * result;
-       struct inode *dir = parent->d_inode;
-@@ -300,6 +321,9 @@ static struct dentry * real_lookup(struc
-               result = ERR_PTR(-ENOMEM);
-               if (dentry) {
-                       lock_kernel();
-+                      if (dir->i_op->lookup2)
-+                              result = dir->i_op->lookup2(dir, dentry, it);
-+                      else
-                       result = dir->i_op->lookup(dir, dentry);
-                       unlock_kernel();
-                       if (result)
-@@ -321,6 +345,12 @@ static struct dentry * real_lookup(struc
-                       dput(result);
-                       result = ERR_PTR(-ENOENT);
-               }
-+      } else if (result->d_op && result->d_op->d_revalidate2) {
-+              if (!result->d_op->d_revalidate2(result, flags, it) &&
-+                  !d_invalidate(result)) {
-+                      dput(result);
-+                      result = ERR_PTR(-ENOENT);
-+              }
-       }
-       return result;
- }
-@@ -334,7 +364,8 @@ int max_recursive_link = 5;
-  * Without that kind of total limit, nasty chains of consecutive
-  * symlinks can cause almost arbitrarily long lookups. 
-  */
--static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
-+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, 
-+                                 struct lookup_intent *it)
- {
-       int err;
-       if (current->link_count >= max_recursive_link)
-@@ -348,10 +379,14 @@ static inline int do_follow_link(struct 
-       current->link_count++;
-       current->total_link_count++;
-       UPDATE_ATIME(dentry->d_inode);
--      err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+        if (dentry->d_inode->i_op->follow_link2)
-+                err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
-+        else 
-+                err = dentry->d_inode->i_op->follow_link(dentry, nd);
-       current->link_count--;
-       return err;
- loop:
-+        intent_release(dentry, it);
-       path_release(nd);
-       return -ELOOP;
- }
-@@ -449,7 +484,8 @@ static inline void follow_dotdot(struct 
-  *
-  * We expect 'base' to be positive and a directory.
-  */
--int link_path_walk(const char * name, struct nameidata *nd)
-+int link_path_walk_it(const char *name, struct nameidata *nd,
-+                    struct lookup_intent *it)
- {
-       struct dentry *dentry;
-       struct inode *inode;
-@@ -526,12 +562,12 @@ int link_path_walk(const char * name, st
-                               break;
-               }
-               /* This does the actual lookups.. */
--              dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
-+              dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
-               if (!dentry) {
-                       err = -EWOULDBLOCKIO;
-                       if (atomic)
-                               break;
--                      dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
-+                      dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
-                       err = PTR_ERR(dentry);
-                       if (IS_ERR(dentry))
-                               break;
-@@ -548,8 +584,8 @@ int link_path_walk(const char * name, st
-               if (!inode->i_op)
-                       goto out_dput;
--              if (inode->i_op->follow_link) {
--                      err = do_follow_link(dentry, nd);
-+              if (inode->i_op->follow_link || inode->i_op->follow_link2) {
-+                      err = do_follow_link(dentry, nd, NULL);
-                       dput(dentry);
-                       if (err)
-                               goto return_err;
-@@ -565,7 +601,7 @@ int link_path_walk(const char * name, st
-                       nd->dentry = dentry;
-               }
-               err = -ENOTDIR; 
--              if (!inode->i_op->lookup)
-+              if (!inode->i_op->lookup && !inode->i_op->lookup2)
-                       break;
-               continue;
-               /* here ends the main loop */
-@@ -592,12 +628,12 @@ last_component:
-                       if (err < 0)
-                               break;
-               }
--              dentry = cached_lookup(nd->dentry, &this, 0);
-+              dentry = cached_lookup(nd->dentry, &this, 0, it);
-               if (!dentry) {
-                       err = -EWOULDBLOCKIO;
-                       if (atomic)
-                               break;
--                      dentry = real_lookup(nd->dentry, &this, 0);
-+                      dentry = real_lookup(nd->dentry, &this, 0, it);
-                       err = PTR_ERR(dentry);
-                       if (IS_ERR(dentry))
-                               break;
-@@ -606,8 +642,10 @@ last_component:
-                       ;
-               inode = dentry->d_inode;
-               if ((lookup_flags & LOOKUP_FOLLOW)
--                  && inode && inode->i_op && inode->i_op->follow_link) {
--                      err = do_follow_link(dentry, nd);
-+                  && inode && inode->i_op && 
-+                    (inode->i_op->follow_link || 
-+                     inode->i_op->follow_link2)) {
-+                      err = do_follow_link(dentry, nd, it);
-                       dput(dentry);
-                       if (err)
-                               goto return_err;
-@@ -621,7 +659,8 @@ last_component:
-                       goto no_inode;
-               if (lookup_flags & LOOKUP_DIRECTORY) {
-                       err = -ENOTDIR; 
--                      if (!inode->i_op || !inode->i_op->lookup)
-+                      if (!inode->i_op || (!inode->i_op->lookup &&
-+                                           !inode->i_op->lookup2))
-                               break;
-               }
-               goto return_base;
-@@ -663,10 +702,21 @@ return_err:
-       return err;
- }
-+int link_path_walk(const char * name, struct nameidata *nd)
-+{
-+      return link_path_walk_it(name, nd, NULL);
-+}
-+
-+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
-+{
-+      current->total_link_count = 0;
-+      return link_path_walk_it(name, nd, it);
-+}
-+
- int path_walk(const char * name, struct nameidata *nd)
- {
-       current->total_link_count = 0;
--      return link_path_walk(name, nd);
-+      return link_path_walk_it(name, nd, NULL);
- }
- /* SMP-safe */
-@@ -751,6 +801,17 @@ walk_init_root(const char *name, struct 
- }
- /* SMP-safe */
-+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
-+                 struct lookup_intent *it)
-+{
-+      int error = 0;
-+      if (path_init(path, flags, nd))
-+              error = path_walk_it(path, nd, it);
-+      return error;
-+}
-+
-+
-+/* SMP-safe */
- int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
- {
-       int error = 0;
-@@ -779,7 +840,8 @@ int path_init(const char *name, unsigned
-  * needs parent already locked. Doesn't follow mounts.
-  * SMP-safe.
-  */
--struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
-+                             struct lookup_intent *it)
- {
-       struct dentry * dentry;
-       struct inode *inode;
-@@ -802,13 +864,16 @@ struct dentry * lookup_hash(struct qstr 
-                       goto out;
-       }
--      dentry = cached_lookup(base, name, 0);
-+      dentry = cached_lookup(base, name, 0, it);
-       if (!dentry) {
-               struct dentry *new = d_alloc(base, name);
-               dentry = ERR_PTR(-ENOMEM);
-               if (!new)
-                       goto out;
-               lock_kernel();
-+              if (inode->i_op->lookup2)
-+                      dentry = inode->i_op->lookup2(inode, new, it);
-+              else
-               dentry = inode->i_op->lookup(inode, new);
-               unlock_kernel();
-               if (!dentry)
-@@ -820,6 +885,12 @@ out:
-       return dentry;
- }
-+struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+{
-+      return lookup_hash_it(name, base, NULL);
-+}
-+
-+
- /* SMP-safe */
- struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
- {
-@@ -841,7 +912,7 @@ struct dentry * lookup_one_len(const cha
-       }
-       this.hash = end_name_hash(hash);
--      return lookup_hash(&this, base);
-+      return lookup_hash_it(&this, base, NULL);
- access:
-       return ERR_PTR(-EACCES);
- }
-@@ -872,6 +943,23 @@ int __user_walk(const char *name, unsign
-       return err;
- }
-+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
-+                 struct lookup_intent *it)
-+{
-+      char *tmp;
-+      int err;
-+
-+      tmp = getname(name);
-+      err = PTR_ERR(tmp);
-+      if (!IS_ERR(tmp)) {
-+              err = 0;
-+              if (path_init(tmp, flags, nd))
-+                      err = path_walk_it(tmp, nd, it);
-+              putname(tmp);
-+      }
-+      return err;
-+}
-+
- /*
-  * It's inline, so penalty for filesystems that don't use sticky bit is
-  * minimal.
-@@ -1010,7 +1098,8 @@ exit_lock:
-  * for symlinks (where the permissions are checked later).
-  * SMP-safe
-  */
--int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
-+int open_namei_it(const char *pathname, int flag, int mode,
-+                struct nameidata *nd, struct lookup_intent *it)
- {
-       int acc_mode, error = 0;
-       struct inode *inode;
-@@ -1024,7 +1113,7 @@ int open_namei(const char * pathname, in
-        * The simplest case - just a plain lookup.
-        */
-       if (!(flag & O_CREAT)) {
--              error = path_lookup(pathname, lookup_flags(flag), nd);
-+              error = path_lookup_it(pathname, lookup_flags(flag), nd, it);
-               if (error)
-                       return error;
-               dentry = nd->dentry;
-@@ -1034,6 +1123,10 @@ int open_namei(const char * pathname, in
-       /*
-        * Create - we need to know the parent.
-        */
-+      if (it) {
-+              it->it_mode = mode;
-+              it->it_op |= IT_CREAT;
-+      }
-       error = path_lookup(pathname, LOOKUP_PARENT, nd);
-       if (error)
-               return error;
-@@ -1049,7 +1142,7 @@ int open_namei(const char * pathname, in
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
- do_last:
-       error = PTR_ERR(dentry);
-@@ -1058,6 +1151,7 @@ do_last:
-               goto exit;
-       }
-+      it->it_mode = mode;
-       /* Negative dentry, just create the file */
-       if (!dentry->d_inode) {
-               error = vfs_create(dir->d_inode, dentry,
-@@ -1091,7 +1185,8 @@ do_last:
-       error = -ENOENT;
-       if (!dentry->d_inode)
-               goto exit_dput;
--      if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
-+      if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || 
-+                                      dentry->d_inode->i_op->follow_link2))
-               goto do_link;
-       dput(nd->dentry);
-@@ -1177,8 +1272,10 @@ ok:
-       return 0;
- exit_dput:
-+      intent_release(dentry, it);
-       dput(dentry);
- exit:
-+      intent_release(nd->dentry, it);
-       path_release(nd);
-       return error;
-@@ -1197,7 +1294,12 @@ do_link:
-        * are done. Procfs-like symlinks just set LAST_BIND.
-        */
-       UPDATE_ATIME(dentry->d_inode);
--      error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+        if (dentry->d_inode->i_op->follow_link2) 
-+                error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
-+        else 
-+                error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (error)
-+              intent_release(dentry, it);
-       dput(dentry);
-       if (error)
-               return error;
-@@ -1219,13 +1321,20 @@ do_link:
-       }
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
-       putname(nd->last.name);
-       goto do_last;
- }
-+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
-+{
-+      return open_namei_it(pathname, flag, mode, nd, NULL);
-+}
-+
-+
- /* SMP-safe */
--static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
-+static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
-+                                  struct lookup_intent *it)
- {
-       struct dentry *dentry;
-@@ -1233,7 +1342,7 @@ static struct dentry *lookup_create(stru
-       dentry = ERR_PTR(-EEXIST);
-       if (nd->last_type != LAST_NORM)
-               goto fail;
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
-       if (IS_ERR(dentry))
-               goto fail;
-       if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1279,6 +1388,7 @@ asmlinkage long sys_mknod(const char * f
-       char * tmp;
-       struct dentry * dentry;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
-       if (S_ISDIR(mode))
-               return -EPERM;
-@@ -1289,7 +1399,7 @@ asmlinkage long sys_mknod(const char * f
-       error = path_lookup(tmp, LOOKUP_PARENT, &nd);
-       if (error)
-               goto out;
--      dentry = lookup_create(&nd, 0);
-+      dentry = lookup_create(&nd, 0, &it);
-       error = PTR_ERR(dentry);
-       mode &= ~current->fs->umask;
-@@ -1307,6 +1417,7 @@ asmlinkage long sys_mknod(const char * f
-               default:
-                       error = -EINVAL;
-               }
-+              intent_release(dentry, &it);
-               dput(dentry);
-       }
-       up(&nd.dentry->d_inode->i_sem);
-@@ -1347,6 +1458,7 @@ asmlinkage long sys_mkdir(const char * p
- {
-       int error = 0;
-       char * tmp;
-+      struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
-       tmp = getname(pathname);
-       error = PTR_ERR(tmp);
-@@ -1357,11 +1469,12 @@ asmlinkage long sys_mkdir(const char * p
-               error = path_lookup(tmp, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
--              dentry = lookup_create(&nd, 1);
-+              dentry = lookup_create(&nd, 1, &it);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_mkdir(nd.dentry->d_inode, dentry,
-                                         mode & ~current->fs->umask);
-+                      intent_release(dentry, &it);
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-@@ -1445,6 +1558,7 @@ asmlinkage long sys_rmdir(const char * p
-       char * name;
-       struct dentry *dentry;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_RMDIR };
-       name = getname(pathname);
-       if(IS_ERR(name))
-@@ -1466,10 +1580,11 @@ asmlinkage long sys_rmdir(const char * p
-                       goto exit1;
-       }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               error = vfs_rmdir(nd.dentry->d_inode, dentry);
-+              intent_release(dentry, &it);
-               dput(dentry);
-       }
-       up(&nd.dentry->d_inode->i_sem);
-@@ -1513,6 +1628,7 @@ asmlinkage long sys_unlink(const char * 
-       char * name;
-       struct dentry *dentry;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_UNLINK };
-       name = getname(pathname);
-       if(IS_ERR(name))
-@@ -1525,7 +1641,7 @@ asmlinkage long sys_unlink(const char * 
-       if (nd.last_type != LAST_NORM)
-               goto exit1;
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               /* Why not before? Because we want correct error value */
-@@ -1533,6 +1649,7 @@ asmlinkage long sys_unlink(const char * 
-                       goto slashes;
-               error = vfs_unlink(nd.dentry->d_inode, dentry);
-       exit2:
-+              intent_release(dentry, &it);
-               dput(dentry);
-       }
-       up(&nd.dentry->d_inode->i_sem);
-@@ -1579,6 +1696,7 @@ asmlinkage long sys_symlink(const char *
-       int error = 0;
-       char * from;
-       char * to;
-+      struct lookup_intent it = { .it_op = IT_SYMLINK };
-       from = getname(oldname);
-       if(IS_ERR(from))
-@@ -1592,10 +1710,12 @@ asmlinkage long sys_symlink(const char *
-               error = path_lookup(to, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
--              dentry = lookup_create(&nd, 0);
-+              it.it_data = from;
-+              dentry = lookup_create(&nd, 0, &it);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_symlink(nd.dentry->d_inode, dentry, from);
-+                      intent_release(dentry, &it);
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-@@ -1660,6 +1780,7 @@ asmlinkage long sys_link(const char * ol
- {
-       int error;
-       char * to;
-+      struct lookup_intent it = { .it_op = IT_LINK };
-       to = getname(newname);
-       error = PTR_ERR(to);
-@@ -1667,7 +1788,7 @@ asmlinkage long sys_link(const char * ol
-               struct dentry *new_dentry;
-               struct nameidata nd, old_nd;
--              error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd);
-+              error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, &it);
-               if (error)
-                       goto exit;
-               error = path_lookup(to, LOOKUP_PARENT, &nd);
-@@ -1676,10 +1797,12 @@ asmlinkage long sys_link(const char * ol
-               error = -EXDEV;
-               if (old_nd.mnt != nd.mnt)
-                       goto out_release;
--              new_dentry = lookup_create(&nd, 0);
-+              it.it_op = IT_LINK2;
-+              new_dentry = lookup_create(&nd, 0, &it);
-               error = PTR_ERR(new_dentry);
-               if (!IS_ERR(new_dentry)) {
-                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-+                      intent_release(new_dentry, &it);
-                       dput(new_dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-@@ -1720,7 +1843,8 @@ exit:
-  *       locking].
-  */
- int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+                 struct inode *new_dir, struct dentry *new_dentry,
-+                 struct lookup_intent *it)
- {
-       int error;
-       struct inode *target;
-@@ -1778,6 +1902,7 @@ int vfs_rename_dir(struct inode *old_dir
-               error = -EBUSY;
-       else 
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       if (target) {
-               if (!error)
-                       target->i_flags |= S_DEAD;
-@@ -1799,7 +1924,8 @@ out_unlock:
- }
- int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+                   struct inode *new_dir, struct dentry *new_dentry,
-+                   struct lookup_intent *it)
- {
-       int error;
-@@ -1830,6 +1956,7 @@ int vfs_rename_other(struct inode *old_d
-               error = -EBUSY;
-       else
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       double_up(&old_dir->i_zombie, &new_dir->i_zombie);
-       if (error)
-               return error;
-@@ -1841,13 +1968,14 @@ int vfs_rename_other(struct inode *old_d
- }
- int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+             struct inode *new_dir, struct dentry *new_dentry,
-+             struct lookup_intent *it)
- {
-       int error;
-       if (S_ISDIR(old_dentry->d_inode->i_mode))
--              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
-       else
--              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
-       if (!error) {
-               if (old_dir == new_dir)
-                       inode_dir_notify(old_dir, DN_RENAME);
-@@ -1864,6 +1992,7 @@ static inline int do_rename(const char *
-       int error = 0;
-       struct dentry * old_dir, * new_dir;
-       struct dentry * old_dentry, *new_dentry;
-+      struct lookup_intent it = { .it_op = IT_RENAME };
-       struct nameidata oldnd, newnd;
-       error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
-@@ -1889,7 +2018,7 @@ static inline int do_rename(const char *
-       double_lock(new_dir, old_dir);
--      old_dentry = lookup_hash(&oldnd.last, old_dir);
-+      old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
-       error = PTR_ERR(old_dentry);
-       if (IS_ERR(old_dentry))
-               goto exit3;
-@@ -1905,18 +2034,21 @@ static inline int do_rename(const char *
-               if (newnd.last.name[newnd.last.len])
-                       goto exit4;
-       }
--      new_dentry = lookup_hash(&newnd.last, new_dir);
-+      it.it_op = IT_RENAME2;
-+      new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
-       error = PTR_ERR(new_dentry);
-       if (IS_ERR(new_dentry))
-               goto exit4;
-       lock_kernel();
-       error = vfs_rename(old_dir->d_inode, old_dentry,
--                                 new_dir->d_inode, new_dentry);
-+                                 new_dir->d_inode, new_dentry, &it);
-       unlock_kernel();
-+      intent_release(new_dentry, &it);
-       dput(new_dentry);
- exit4:
-+      intent_release(old_dentry, &it);
-       dput(old_dentry);
- exit3:
-       double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
-@@ -1965,7 +2097,8 @@ out:
- }
- static inline int
--__vfs_follow_link(struct nameidata *nd, const char *link)
-+__vfs_follow_link(struct nameidata *nd, const char *link, 
-+                     struct lookup_intent *it)
- {
-       int res = 0;
-       char *name;
-@@ -1978,7 +2111,7 @@ __vfs_follow_link(struct nameidata *nd, 
-                       /* weird __emul_prefix() stuff did it */
-                       goto out;
-       }
--      res = link_path_walk(link, nd);
-+      res = link_path_walk_it(link, nd, it);
- out:
-       if (current->link_count || res || nd->last_type!=LAST_NORM)
-               return res;
-@@ -2000,7 +2133,13 @@ fail:
- int vfs_follow_link(struct nameidata *nd, const char *link)
- {
--      return __vfs_follow_link(nd, link);
-+      return __vfs_follow_link(nd, link, NULL);
-+}
-+
-+int vfs_follow_link_it(struct nameidata *nd, const char *link, 
-+                       struct lookup_intent *it)
-+{
-+      return __vfs_follow_link(nd, link, it);
- }
- /* get the link contents into pagecache */
-@@ -2042,7 +2181,7 @@ int page_follow_link(struct dentry *dent
- {
-       struct page *page = NULL;
-       char *s = page_getlink(dentry, &page);
--      int res = __vfs_follow_link(nd, s);
-+      int res = __vfs_follow_link(nd, s, NULL);
-       if (page) {
-               kunmap(page);
-               page_cache_release(page);
---- linux-2.4.18-17.8.0/fs/nfsd/vfs.c~vfs_intent       2002-12-06 14:52:31.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/fs/nfsd/vfs.c      2002-12-06 14:52:31.000000000 -0800
-@@ -1298,7 +1298,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
-                       err = nfserr_perm;
-       } else
- #endif
--      err = vfs_rename(fdir, odentry, tdir, ndentry);
-+      err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
-       unlock_kernel();
-       if (!err && EX_ISSYNC(tfhp->fh_export)) {
-               nfsd_sync_dir(tdentry);
---- linux-2.4.18-17.8.0/fs/open.c~vfs_intent   2002-12-06 14:52:31.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/fs/open.c  2002-12-06 14:52:31.000000000 -0800
-@@ -19,6 +19,9 @@
- #include <asm/uaccess.h>
- #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
-+extern int path_walk_it(const char *name, struct nameidata *nd,
-+                      struct lookup_intent *it);
-+extern void intent_release(struct dentry *de, struct lookup_intent *it);
- int vfs_statfs(struct super_block *sb, struct statfs *buf)
- {
-@@ -118,12 +121,13 @@ static inline long do_sys_truncate(const
-       struct nameidata nd;
-       struct inode * inode;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
-       error = -EINVAL;
-       if (length < 0) /* sorry, but loff_t says... */
-               goto out;
--      error = user_path_walk(path, &nd);
-+      error = user_path_walk_it(path, &nd, &it);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-@@ -168,6 +172,7 @@ static inline long do_sys_truncate(const
-       put_write_access(inode);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -259,8 +264,9 @@ asmlinkage long sys_utime(char * filenam
-       struct nameidata nd;
-       struct inode * inode;
-       struct iattr newattrs;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-@@ -286,6 +292,7 @@ asmlinkage long sys_utime(char * filenam
-       }
-       error = notify_change(nd.dentry, &newattrs);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -303,8 +310,9 @@ asmlinkage long sys_utimes(char * filena
-       struct nameidata nd;
-       struct inode * inode;
-       struct iattr newattrs;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (error)
-               goto out;
-@@ -331,6 +339,7 @@ asmlinkage long sys_utimes(char * filena
-       }
-       error = notify_change(nd.dentry, &newattrs);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -347,6 +356,7 @@ asmlinkage long sys_access(const char * 
-       int old_fsuid, old_fsgid;
-       kernel_cap_t old_cap;
-       int res;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
-               return -EINVAL;
-@@ -364,13 +374,14 @@ asmlinkage long sys_access(const char * 
-       else
-               current->cap_effective = current->cap_permitted;
--      res = user_path_walk(filename, &nd);
-+      res = user_path_walk_it(filename, &nd, &it);
-       if (!res) {
-               res = permission(nd.dentry->d_inode, mode);
-               /* SuS v2 requires we report a read only fs too */
-               if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
-                  && !special_file(nd.dentry->d_inode->i_mode))
-                       res = -EROFS;
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-@@ -385,8 +396,11 @@ asmlinkage long sys_chdir(const char * f
- {
-       int error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
-+      error = __user_walk_it(filename,
-+                             LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,
-+                             &nd, &it);
-       if (error)
-               goto out;
-@@ -397,6 +411,7 @@ asmlinkage long sys_chdir(const char * f
-       set_fs_pwd(current->fs, nd.mnt, nd.dentry);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -436,9 +451,10 @@ asmlinkage long sys_chroot(const char * 
- {
-       int error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
--                    LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
-+      error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
-+                             LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
-       if (error)
-               goto out;
-@@ -454,6 +470,7 @@ asmlinkage long sys_chroot(const char * 
-       set_fs_altroot();
-       error = 0;
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -498,8 +515,9 @@ asmlinkage long sys_chmod(const char * f
-       struct inode * inode;
-       int error;
-       struct iattr newattrs;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-@@ -519,6 +537,7 @@ asmlinkage long sys_chmod(const char * f
-       error = notify_change(nd.dentry, &newattrs);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -588,10 +607,12 @@ asmlinkage long sys_chown(const char * f
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (!error) {
-               error = chown_common(nd.dentry, user, group);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -601,10 +622,12 @@ asmlinkage long sys_lchown(const char * 
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
--      error = user_path_walk_link(filename, &nd);
-+      error = user_path_walk_link_it(filename, &nd, &it);
-       if (!error) {
-               error = chown_common(nd.dentry, user, group);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -638,10 +661,16 @@ asmlinkage long sys_fchown(unsigned int 
-  * for the internal routines (ie open_namei()/follow_link() etc). 00 is
-  * used by symlinks.
-  */
-+extern int open_namei_it(const char *filename, int namei_flags, int mode,
-+                       struct nameidata *nd, struct lookup_intent *it);
-+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                          int flags, struct lookup_intent *it);
-+
- struct file *filp_open(const char * filename, int flags, int mode)
- {
-       int namei_flags, error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_OPEN };
-       namei_flags = flags;
-       if ((namei_flags+1) & O_ACCMODE)
-@@ -649,18 +678,19 @@ struct file *filp_open(const char * file
-       if (namei_flags & O_TRUNC)
-               namei_flags |= 2;
--      error = open_namei(filename, namei_flags, mode, &nd);
--      if (!error)
--              return dentry_open(nd.dentry, nd.mnt, flags);
-+      error = open_namei_it(filename, namei_flags, mode, &nd, &it);
-+      if (error)
-+              return ERR_PTR(error);
--      return ERR_PTR(error);
-+      return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
- }
- extern ssize_t do_readahead(struct file *file, unsigned long index, unsigned long nr);
- /* for files over a certains size it doesn't pay to do readahead on open */
- #define READAHEAD_CUTOFF 48000
--struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                          int flags, struct lookup_intent *it)
- {
-       struct file * f;
-       struct inode *inode;
-@@ -711,6 +741,7 @@ struct file *dentry_open(struct dentry *
-               do_readahead(f, 0, (48 * 1024) >> PAGE_SHIFT);
-       
-+      intent_release(dentry, it);
-       return f;
- cleanup_all:
-@@ -725,11 +756,17 @@ cleanup_all:
- cleanup_file:
-       put_filp(f);
- cleanup_dentry:
-+      intent_release(dentry, it);
-       dput(dentry);
-       mntput(mnt);
-       return ERR_PTR(error);
- }
-+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+{
-+      return dentry_open_it(dentry, mnt, flags, NULL);
-+}
-+
- /*
-  * Find an empty file descriptor entry, and mark it busy.
-  */
---- linux-2.4.18-17.8.0/fs/stat.c~vfs_intent   2002-12-06 14:52:31.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/fs/stat.c  2002-12-06 14:52:31.000000000 -0800
-@@ -13,6 +13,7 @@
- #include <asm/uaccess.h>
-+extern void intent_release(struct dentry *de, struct lookup_intent *it);
- /*
-  * Revalidate the inode. This is required for proper NFS attribute caching.
-  */
-@@ -104,10 +105,12 @@ int vfs_stat(char *name, struct kstat *s
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = user_path_walk(name, &nd);
-+      error = user_path_walk_it(name, &nd, &it);
-       if (!error) {
-               error = do_getattr(nd.mnt, nd.dentry, stat);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -117,10 +120,12 @@ int vfs_lstat(char *name, struct kstat *
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = user_path_walk_link(name, &nd);
-+      error = user_path_walk_link_it(name, &nd, &it);
-       if (!error) {
-               error = do_getattr(nd.mnt, nd.dentry, stat);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
---- linux-2.4.18-17.8.0/include/linux/dcache.h~vfs_intent      2002-12-06 14:52:31.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/include/linux/dcache.h     2002-12-06 14:52:31.000000000 -0800
-@@ -6,6 +6,34 @@
- #include <asm/atomic.h>
- #include <linux/mount.h>
-+#define IT_OPEN  (1)
-+#define IT_CREAT  (1<<1)
-+#define IT_MKDIR  (1<<2)
-+#define IT_LINK  (1<<3)
-+#define IT_LINK2  (1<<4)
-+#define IT_SYMLINK  (1<<5)
-+#define IT_UNLINK  (1<<6)
-+#define IT_RMDIR  (1<<7)
-+#define IT_RENAME  (1<<8)
-+#define IT_RENAME2  (1<<9)
-+#define IT_READDIR  (1<<10)
-+#define IT_GETATTR  (1<<11)
-+#define IT_SETATTR  (1<<12)
-+#define IT_READLINK  (1<<13)
-+#define IT_MKNOD  (1<<14)
-+#define IT_LOOKUP  (1<<15)
-+
-+struct lookup_intent {
-+      int it_op;
-+      int it_mode;
-+      int it_disposition;
-+      int it_status;
-+      struct iattr *it_iattr;
-+      __u64 it_lock_handle[2];
-+      int it_lock_mode;
-+      void *it_data;
-+};
-+
- /*
-  * linux/include/linux/dcache.h
-  *
-@@ -78,6 +106,7 @@ struct dentry {
-       unsigned long d_time;           /* used by d_revalidate */
-       struct dentry_operations  *d_op;
-       struct super_block * d_sb;      /* The root of the dentry tree */
-+      struct lookup_intent *d_it;
-       unsigned long d_vfs_flags;
-       void * d_fsdata;                /* fs-specific data */
-       void * d_extra_attributes;      /* TUX-specific data */
-@@ -91,6 +120,8 @@ struct dentry_operations {
-       int (*d_delete)(struct dentry *);
-       void (*d_release)(struct dentry *);
-       void (*d_iput)(struct dentry *, struct inode *);
-+      int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
-+      void (*d_intent_release)(struct dentry *, struct lookup_intent *);
- };
- /* the dentry parameter passed to d_hash and d_compare is the parent
---- linux-2.4.18-17.8.0/include/linux/fs.h~vfs_intent  2002-12-06 14:52:31.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/include/linux/fs.h 2002-12-06 14:52:31.000000000 -0800
-@@ -576,6 +576,7 @@ struct file {
-       /* needed for tty driver, and maybe others */
-       void                    *private_data;
-+      struct lookup_intent    *f_intent;
-       /* preallocated helper kiobuf to speedup O_DIRECT */
-       struct kiobuf           *f_iobuf;
-@@ -836,7 +837,9 @@ extern int vfs_symlink(struct inode *, s
- extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
- extern int vfs_rmdir(struct inode *, struct dentry *);
- extern int vfs_unlink(struct inode *, struct dentry *);
--extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
-+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-+              struct inode *new_dir, struct dentry *new_dentry,
-+              struct lookup_intent *it);
- /*
-  * File types
-@@ -897,6 +900,7 @@ struct file_operations {
- struct inode_operations {
-       int (*create) (struct inode *,struct dentry *,int);
-       struct dentry * (*lookup) (struct inode *,struct dentry *);
-+      struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
-       int (*link) (struct dentry *,struct inode *,struct dentry *);
-       int (*unlink) (struct inode *,struct dentry *);
-       int (*symlink) (struct inode *,struct dentry *,const char *);
-@@ -907,6 +911,8 @@ struct inode_operations {
-                       struct inode *, struct dentry *);
-       int (*readlink) (struct dentry *, char *,int);
-       int (*follow_link) (struct dentry *, struct nameidata *);
-+      int (*follow_link2) (struct dentry *, struct nameidata *, 
-+                            struct lookup_intent *it);
-       void (*truncate) (struct inode *);
-       int (*permission) (struct inode *, int);
-       int (*revalidate) (struct dentry *);
-@@ -1381,6 +1387,7 @@ typedef int (*read_actor_t)(read_descrip
- extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
- extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
-+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
- extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
- extern int FASTCALL(path_walk(const char *, struct nameidata *));
- extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
-@@ -1392,6 +1399,8 @@ extern struct dentry * lookup_one_len(co
- extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
- #define user_path_walk(name,nd)        __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
- #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
-+#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
-+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
- extern void inode_init_once(struct inode *);
- extern void iput(struct inode *);
-@@ -1492,6 +1501,8 @@ extern struct file_operations generic_ro
- extern int vfs_readlink(struct dentry *, char *, int, const char *);
- extern int vfs_follow_link(struct nameidata *, const char *);
-+extern int vfs_follow_link_it(struct nameidata *, const char *, 
-+                              struct lookup_intent *it);
- extern int page_readlink(struct dentry *, char *, int);
- extern int page_follow_link(struct dentry *, struct nameidata *);
- extern struct inode_operations page_symlink_inode_operations;
---- linux-2.4.18-17.8.0/kernel/ksyms.c~vfs_intent      2002-12-06 14:52:31.000000000 -0800
-+++ linux-2.4.18-17.8.0-zab/kernel/ksyms.c     2002-12-06 14:52:31.000000000 -0800
-@@ -293,6 +293,7 @@ EXPORT_SYMBOL(read_cache_page);
- EXPORT_SYMBOL(set_page_dirty);
- EXPORT_SYMBOL(vfs_readlink);
- EXPORT_SYMBOL(vfs_follow_link);
-+EXPORT_SYMBOL(vfs_follow_link_it);
- EXPORT_SYMBOL(page_readlink);
- EXPORT_SYMBOL(page_follow_link);
- EXPORT_SYMBOL(page_symlink_inode_operations);
-
-_
diff --git a/lustre/kernel_patches/patches/vfs_intent_hp_2.4.19.patch b/lustre/kernel_patches/patches/vfs_intent_hp_2.4.19.patch
deleted file mode 100644 (file)
index adf311f..0000000
+++ /dev/null
@@ -1,1546 +0,0 @@
- fs/dcache.c            |   20 ++
- fs/exec.c              |   16 +-
- fs/namei.c             |  351 +++++++++++++++++++++++++++++++++++++++++--------
- fs/nfsd/vfs.c          |    2 
- fs/open.c              |  144 +++++++++++++++-----
- fs/stat.c              |   24 ++-
- include/linux/dcache.h |   28 +++
- include/linux/fs.h     |   31 ++++
- kernel/ksyms.c         |    1 
- 9 files changed, 506 insertions(+), 111 deletions(-)
-
---- linux-2.4.19-hp3_pnnl1/fs/dcache.c~vfs_intent_hp_2.4.19    2003-04-23 16:52:44.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/dcache.c    2003-04-23 17:07:19.000000000 +0800
-@@ -181,6 +181,13 @@ int d_invalidate(struct dentry * dentry)
-               spin_unlock(&dcache_lock);
-               return 0;
-       }
-+
-+      /* network invalidation by Lustre */
-+      if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
-+              spin_unlock(&dcache_lock);
-+              return 0;
-+      }
-+
-       /*
-        * Check whether to do a partial shrink_dcache
-        * to get rid of unused child entries.
-@@ -616,6 +623,7 @@ struct dentry * d_alloc(struct dentry * 
-       dentry->d_op = NULL;
-       dentry->d_fsdata = NULL;
-       dentry->d_mounted = 0;
-+      dentry->d_it = NULL;
-       INIT_LIST_HEAD(&dentry->d_hash);
-       INIT_LIST_HEAD(&dentry->d_lru);
-       INIT_LIST_HEAD(&dentry->d_subdirs);
-@@ -830,13 +838,19 @@ void d_delete(struct dentry * dentry)
-  * Adds a dentry to the hash according to its name.
-  */
-  
--void d_rehash(struct dentry * entry)
-+void __d_rehash(struct dentry * entry, int lock)
- {
-       struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
-       if (!list_empty(&entry->d_hash)) BUG();
--      spin_lock(&dcache_lock);
-+      if (lock) spin_lock(&dcache_lock);
-       list_add(&entry->d_hash, list);
--      spin_unlock(&dcache_lock);
-+      if (lock) spin_unlock(&dcache_lock);
-+}
-+EXPORT_SYMBOL(__d_rehash);
-+
-+void d_rehash(struct dentry * entry)
-+{
-+      __d_rehash(entry, 1);
- }
- #define do_switch(x,y) do { \
---- linux-2.4.19-hp3_pnnl1/fs/namei.c~vfs_intent_hp_2.4.19     2003-04-11 17:41:45.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/namei.c     2003-04-23 17:07:19.000000000 +0800
-@@ -94,6 +94,13 @@
-  * XEmacs seems to be relying on it...
-  */
-+void intent_release(struct dentry *de, struct lookup_intent *it)
-+{
-+      if (it && de->d_op && de->d_op->d_intent_release)
-+              de->d_op->d_intent_release(de, it);
-+
-+}
-+
- /* In order to reduce some races, while at the same time doing additional
-  * checking and hopefully speeding things up, we copy filenames to the
-  * kernel data space before using them..
-@@ -260,10 +267,19 @@ void path_release(struct nameidata *nd)
-  * Internal lookup() using the new generic dcache.
-  * SMP-safe
-  */
--static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
-+                                  int flags, struct lookup_intent *it)
- {
-       struct dentry * dentry = d_lookup(parent, name);
-+      if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+              if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
-+                  !d_invalidate(dentry)) {
-+                      dput(dentry);
-+                      dentry = NULL;
-+              }
-+              return dentry;
-+      } else
-       if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-               if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
-                       dput(dentry);
-@@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str
-  * make sure that nobody added the entry to the dcache in the meantime..
-  * SMP-safe
-  */
--static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
-+                                int flags, struct lookup_intent *it)
- {
-       struct dentry * result;
-       struct inode *dir = parent->d_inode;
-+again:
-+
-       down(&dir->i_sem);
-       /*
-        * First re-do the cached lookup just in case it was created
-@@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc
-               result = ERR_PTR(-ENOMEM);
-               if (dentry) {
-                       lock_kernel();
-+                      if (dir->i_op->lookup2)
-+                              result = dir->i_op->lookup2(dir, dentry, it);
-+                      else
-                       result = dir->i_op->lookup(dir, dentry);
-                       unlock_kernel();
-                       if (result)
-@@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc
-                       dput(result);
-                       result = ERR_PTR(-ENOENT);
-               }
-+      } else if (result->d_op && result->d_op->d_revalidate2) {
-+              if (!result->d_op->d_revalidate2(result, flags, it) &&
-+                  !d_invalidate(result)) {
-+                      dput(result);
-+                      goto again;
-+              }
-       }
-       return result;
- }
-@@ -332,7 +360,8 @@ static struct dentry * real_lookup(struc
-  * Without that kind of total limit, nasty chains of consecutive
-  * symlinks can cause almost arbitrarily long lookups. 
-  */
--static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
-+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
-+                               struct lookup_intent *it)
- {
-       int err;
-       if (current->link_count >= 5)
-@@ -346,10 +375,14 @@ static inline int do_follow_link(struct 
-       current->link_count++;
-       current->total_link_count++;
-       UPDATE_ATIME(dentry->d_inode);
--      err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (dentry->d_inode->i_op->follow_link2)
-+              err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
-+      else
-+              err = dentry->d_inode->i_op->follow_link(dentry, nd);
-       current->link_count--;
-       return err;
- loop:
-+      intent_release(dentry, it);
-       path_release(nd);
-       return -ELOOP;
- }
-@@ -379,15 +412,26 @@ int follow_up(struct vfsmount **mnt, str
-       return __follow_up(mnt, dentry);
- }
--static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
-+static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
-+                              struct lookup_intent *it)
- {
-       struct vfsmount *mounted;
-       spin_lock(&dcache_lock);
-       mounted = lookup_mnt(*mnt, *dentry);
-       if (mounted) {
-+              int opc = 0, mode = 0;
-               *mnt = mntget(mounted);
-               spin_unlock(&dcache_lock);
-+              if (it) {
-+                      opc = it->it_op;
-+                      mode = it->it_mode;
-+              }
-+              intent_release(*dentry, it);
-+              if (it) {
-+                      it->it_op = opc;
-+                      it->it_mode = mode;
-+              }
-               dput(*dentry);
-               mntput(mounted->mnt_parent);
-               *dentry = dget(mounted->mnt_root);
-@@ -399,7 +443,7 @@ static inline int __follow_down(struct v
- int follow_down(struct vfsmount **mnt, struct dentry **dentry)
- {
--      return __follow_down(mnt,dentry);
-+      return __follow_down(mnt,dentry,NULL);
- }
-  
- static inline void follow_dotdot(struct nameidata *nd)
-@@ -435,7 +479,7 @@ static inline void follow_dotdot(struct 
-               mntput(nd->mnt);
-               nd->mnt = parent;
-       }
--      while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
-+      while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL))
-               ;
- }
-@@ -447,7 +491,8 @@ static inline void follow_dotdot(struct 
-  *
-  * We expect 'base' to be positive and a directory.
-  */
--int link_path_walk(const char * name, struct nameidata *nd)
-+int link_path_walk_it(const char *name, struct nameidata *nd,
-+                    struct lookup_intent *it)
- {
-       struct dentry *dentry;
-       struct inode *inode;
-@@ -520,15 +565,15 @@ int link_path_walk(const char * name, st
-                               break;
-               }
-               /* This does the actual lookups.. */
--              dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
-+              dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
-               if (!dentry) {
--                      dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
-+                      dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
-                       err = PTR_ERR(dentry);
-                       if (IS_ERR(dentry))
-                               break;
-               }
-               /* Check mountpoints.. */
--              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
-+              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL))
-                       ;
-               err = -ENOENT;
-@@ -539,8 +584,8 @@ int link_path_walk(const char * name, st
-               if (!inode->i_op)
-                       goto out_dput;
--              if (inode->i_op->follow_link) {
--                      err = do_follow_link(dentry, nd);
-+              if (inode->i_op->follow_link || inode->i_op->follow_link2) {
-+                      err = do_follow_link(dentry, nd, NULL);
-                       dput(dentry);
-                       if (err)
-                               goto return_err;
-@@ -556,7 +601,7 @@ int link_path_walk(const char * name, st
-                       nd->dentry = dentry;
-               }
-               err = -ENOTDIR; 
--              if (!inode->i_op->lookup)
-+              if (!inode->i_op->lookup && !inode->i_op->lookup2)
-                       break;
-               continue;
-               /* here ends the main loop */
-@@ -583,19 +628,20 @@ last_component:
-                       if (err < 0)
-                               break;
-               }
--              dentry = cached_lookup(nd->dentry, &this, 0);
-+              dentry = cached_lookup(nd->dentry, &this, 0, it);
-               if (!dentry) {
--                      dentry = real_lookup(nd->dentry, &this, 0);
-+                      dentry = real_lookup(nd->dentry, &this, 0, it);
-                       err = PTR_ERR(dentry);
-                       if (IS_ERR(dentry))
-                               break;
-               }
--              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
-+              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, it))
-                       ;
-               inode = dentry->d_inode;
-               if ((lookup_flags & LOOKUP_FOLLOW)
--                  && inode && inode->i_op && inode->i_op->follow_link) {
--                      err = do_follow_link(dentry, nd);
-+                  && inode && inode->i_op &&
-+                  (inode->i_op->follow_link || inode->i_op->follow_link2)) {
-+                      err = do_follow_link(dentry, nd, it);
-                       dput(dentry);
-                       if (err)
-                               goto return_err;
-@@ -609,7 +655,8 @@ last_component:
-                       goto no_inode;
-               if (lookup_flags & LOOKUP_DIRECTORY) {
-                       err = -ENOTDIR; 
--                      if (!inode->i_op || !inode->i_op->lookup)
-+                      if (!inode->i_op ||
-+                          (!inode->i_op->lookup && !inode->i_op->lookup2))
-                               break;
-               }
-               goto return_base;
-@@ -633,6 +680,23 @@ return_reval:
-                * Check the cached dentry for staleness.
-                */
-               dentry = nd->dentry;
-+        revalidate_again:
-+              if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
-+                      err = -ESTALE;
-+                      if (!dentry->d_op->d_revalidate2(dentry, 0, it)) {
-+                                struct dentry *new;
-+                                err = permission(dentry->d_parent->d_inode, 
-+                                                 MAY_EXEC);
-+                                if (err)
-+                                        break;
-+                                new = real_lookup(dentry->d_parent,
-+                                                  &dentry->d_name, 0, NULL);
-+                              d_invalidate(dentry);
-+                                dput(dentry);
-+                                dentry = new;
-+                                goto revalidate_again;
-+                        }
-+              } else
-               if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-                       err = -ESTALE;
-                       if (!dentry->d_op->d_revalidate(dentry, 0)) {
-@@ -646,15 +710,28 @@ out_dput:
-               dput(dentry);
-               break;
-       }
-+      if (err)
-+              intent_release(nd->dentry, it);
-       path_release(nd);
- return_err:
-       return err;
- }
-+int link_path_walk(const char * name, struct nameidata *nd)
-+{
-+      return link_path_walk_it(name, nd, NULL);
-+}
-+
-+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
-+{
-+      current->total_link_count = 0;
-+      return link_path_walk_it(name, nd, it);
-+}
-+
- int path_walk(const char * name, struct nameidata *nd)
- {
-       current->total_link_count = 0;
--      return link_path_walk(name, nd);
-+      return link_path_walk_it(name, nd, NULL);
- }
- /* SMP-safe */
-@@ -757,7 +834,8 @@ int path_init(const char *name, unsigned
-  * needs parent already locked. Doesn't follow mounts.
-  * SMP-safe.
-  */
--struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
-+                             struct lookup_intent *it)
- {
-       struct dentry * dentry;
-       struct inode *inode;
-@@ -780,13 +858,16 @@ struct dentry * lookup_hash(struct qstr 
-                       goto out;
-       }
--      dentry = cached_lookup(base, name, 0);
-+      dentry = cached_lookup(base, name, 0, it);
-       if (!dentry) {
-               struct dentry *new = d_alloc(base, name);
-               dentry = ERR_PTR(-ENOMEM);
-               if (!new)
-                       goto out;
-               lock_kernel();
-+              if (inode->i_op->lookup2)
-+                      dentry = inode->i_op->lookup2(inode, new, it);
-+              else
-               dentry = inode->i_op->lookup(inode, new);
-               unlock_kernel();
-               if (!dentry)
-@@ -798,6 +879,12 @@ out:
-       return dentry;
- }
-+struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+{
-+      return lookup_hash_it(name, base, NULL);
-+}
-+
-+
- /* SMP-safe */
- struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
- {
-@@ -819,7 +906,7 @@ struct dentry * lookup_one_len(const cha
-       }
-       this.hash = end_name_hash(hash);
--      return lookup_hash(&this, base);
-+      return lookup_hash_it(&this, base, NULL);
- access:
-       return ERR_PTR(-EACCES);
- }
-@@ -851,6 +938,23 @@ int __user_walk(const char *name, unsign
-       return err;
- }
-+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
-+                 struct lookup_intent *it)
-+{
-+      char *tmp;
-+      int err;
-+
-+      tmp = getname(name);
-+      err = PTR_ERR(tmp);
-+      if (!IS_ERR(tmp)) {
-+              err = 0;
-+              if (path_init(tmp, flags, nd))
-+                      err = path_walk_it(tmp, nd, it);
-+              putname(tmp);
-+      }
-+      return err;
-+}
-+
- /*
-  * It's inline, so penalty for filesystems that don't use sticky bit is
-  * minimal.
-@@ -987,7 +1091,8 @@ exit_lock:
-  * for symlinks (where the permissions are checked later).
-  * SMP-safe
-  */
--int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
-+int open_namei_it(const char *pathname, int flag, int mode,
-+                struct nameidata *nd, struct lookup_intent *it)
- {
-       int acc_mode, error = 0;
-       struct inode *inode;
-@@ -1002,7 +1107,7 @@ int open_namei(const char * pathname, in
-        */
-       if (!(flag & O_CREAT)) {
-               if (path_init(pathname, lookup_flags(flag), nd))
--                      error = path_walk(pathname, nd);
-+                      error = path_walk_it(pathname, nd, it);
-               if (error)
-                       return error;
-               dentry = nd->dentry;
-@@ -1012,6 +1117,11 @@ int open_namei(const char * pathname, in
-       /*
-        * Create - we need to know the parent.
-        */
-+      if (it) {
-+              it->it_mode = mode;
-+              it->it_op |= IT_CREAT;
-+      }
-+
-       if (path_init(pathname, LOOKUP_PARENT, nd))
-               error = path_walk(pathname, nd);
-       if (error)
-@@ -1028,7 +1138,7 @@ int open_namei(const char * pathname, in
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
- do_last:
-       error = PTR_ERR(dentry);
-@@ -1037,6 +1147,7 @@ do_last:
-               goto exit;
-       }
-+      it->it_mode = mode;
-       /* Negative dentry, just create the file */
-       if (!dentry->d_inode) {
-               if (!IS_POSIXACL(dir->d_inode))
-@@ -1066,12 +1177,13 @@ do_last:
-               error = -ELOOP;
-               if (flag & O_NOFOLLOW)
-                       goto exit_dput;
--              while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
-+              while (__follow_down(&nd->mnt,&dentry,it) && d_mountpoint(dentry));
-       }
-       error = -ENOENT;
-       if (!dentry->d_inode)
-               goto exit_dput;
--      if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
-+      if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
-+                                    dentry->d_inode->i_op->follow_link2))
-               goto do_link;
-       dput(nd->dentry);
-@@ -1145,7 +1257,7 @@ ok:
-               if (!error) {
-                       DQUOT_INIT(inode);
-                       
--                      error = do_truncate(dentry, 0);
-+                      error = do_truncate(dentry, 0, 1);
-               }
-               put_write_access(inode);
-               if (error)
-@@ -1157,8 +1269,10 @@ ok:
-       return 0;
- exit_dput:
-+      intent_release(dentry, it);
-       dput(dentry);
- exit:
-+      intent_release(nd->dentry, it);
-       path_release(nd);
-       return error;
-@@ -1177,7 +1291,12 @@ do_link:
-        * are done. Procfs-like symlinks just set LAST_BIND.
-        */
-       UPDATE_ATIME(dentry->d_inode);
--      error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (dentry->d_inode->i_op->follow_link2)
-+              error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
-+      else
-+              error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+      if (error)
-+              intent_release(dentry, it);
-       dput(dentry);
-       if (error)
-               return error;
-@@ -1199,13 +1318,20 @@ do_link:
-       }
-       dir = nd->dentry;
-       down(&dir->d_inode->i_sem);
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
-       putname(nd->last.name);
-       goto do_last;
- }
-+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
-+{
-+      return open_namei_it(pathname, flag, mode, nd, NULL);
-+}
-+
-+
- /* SMP-safe */
--static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
-+static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
-+                                  struct lookup_intent *it)
- {
-       struct dentry *dentry;
-@@ -1213,7 +1339,7 @@ static struct dentry *lookup_create(stru
-       dentry = ERR_PTR(-EEXIST);
-       if (nd->last_type != LAST_NORM)
-               goto fail;
--      dentry = lookup_hash(&nd->last, nd->dentry);
-+      dentry = lookup_hash_it(&nd->last, nd->dentry, it);
-       if (IS_ERR(dentry))
-               goto fail;
-       if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1270,7 +1396,19 @@ asmlinkage long sys_mknod(const char * f
-               error = path_walk(tmp, &nd);
-       if (error)
-               goto out;
--      dentry = lookup_create(&nd, 0);
-+
-+      if (nd.dentry->d_inode->i_op->mknod2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              error = op->mknod2(nd.dentry->d_inode,
-+                                 nd.last.name,
-+                                 nd.last.len,
-+                                 mode, dev);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto out2;
-+      }
-+
-+      dentry = lookup_create(&nd, 0, NULL);
-       error = PTR_ERR(dentry);
-       if (!IS_POSIXACL(nd.dentry->d_inode))
-@@ -1292,6 +1430,7 @@ asmlinkage long sys_mknod(const char * f
-               dput(dentry);
-       }
-       up(&nd.dentry->d_inode->i_sem);
-+out2:
-       path_release(&nd);
- out:
-       putname(tmp);
-@@ -1340,15 +1479,25 @@ asmlinkage long sys_mkdir(const char * p
-                       error = path_walk(tmp, &nd);
-               if (error)
-                       goto out;
--              dentry = lookup_create(&nd, 1);
-+              if (nd.dentry->d_inode->i_op->mkdir2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->mkdir2(nd.dentry->d_inode,
-+                                         nd.last.name,
-+                                         nd.last.len,
-+                                         mode);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out2;
-+              }
-+              dentry = lookup_create(&nd, 1, NULL);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
--                      if (!IS_POSIXACL(nd.dentry->d_inode))
--                              mode &= ~current->fs->umask;
--                      error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
-+                      error = vfs_mkdir(nd.dentry->d_inode, dentry,
-+                                        mode & ~current->fs->umask);
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-+out2:
-               path_release(&nd);
- out:
-               putname(tmp);
-@@ -1450,8 +1599,33 @@ asmlinkage long sys_rmdir(const char * p
-                       error = -EBUSY;
-                       goto exit1;
-       }
-+      if (nd.dentry->d_inode->i_op->rmdir2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              struct dentry *last;
-+
-+              down(&nd.dentry->d_inode->i_sem);
-+              last = lookup_hash_it(&nd.last, nd.dentry, NULL);
-+              up(&nd.dentry->d_inode->i_sem);
-+              if (IS_ERR(last)) {
-+                      error = PTR_ERR(last);
-+                      goto exit1;
-+              }
-+              if (d_mountpoint(last)) {
-+                      dput(last);
-+                      error = -EBUSY;
-+                      goto exit1;
-+              }
-+              dput(last);
-+
-+              error = op->rmdir2(nd.dentry->d_inode,
-+                                 nd.last.name,
-+                                 nd.last.len);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit1;
-+      }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1510,8 +1684,17 @@ asmlinkage long sys_unlink(const char * 
-       error = -EISDIR;
-       if (nd.last_type != LAST_NORM)
-               goto exit1;
-+      if (nd.dentry->d_inode->i_op->unlink2) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+              error = op->unlink2(nd.dentry->d_inode,
-+                                  nd.last.name,
-+                                  nd.last.len);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit1;
-+      }
-       down(&nd.dentry->d_inode->i_sem);
--      dentry = lookup_hash(&nd.last, nd.dentry);
-+      dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
-       error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               /* Why not before? Because we want correct error value */
-@@ -1579,15 +1762,26 @@ asmlinkage long sys_symlink(const char *
-                       error = path_walk(to, &nd);
-               if (error)
-                       goto out;
--              dentry = lookup_create(&nd, 0);
-+              if (nd.dentry->d_inode->i_op->symlink2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->symlink2(nd.dentry->d_inode,
-+                                           nd.last.name,
-+                                           nd.last.len,
-+                                           from);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out2;
-+              }
-+              dentry = lookup_create(&nd, 0, NULL);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_symlink(nd.dentry->d_inode, dentry, from);
-                       dput(dentry);
-               }
-               up(&nd.dentry->d_inode->i_sem);
-+      out2:
-               path_release(&nd);
--out:
-+      out:
-               putname(to);
-       }
-       putname(from);
-@@ -1670,7 +1864,17 @@ asmlinkage long sys_link(const char * ol
-               error = -EXDEV;
-               if (old_nd.mnt != nd.mnt)
-                       goto out_release;
--              new_dentry = lookup_create(&nd, 0);
-+              if (nd.dentry->d_inode->i_op->link2) {
-+                      struct inode_operations *op = nd.dentry->d_inode->i_op;
-+                      error = op->link2(old_nd.dentry->d_inode,
-+                                        nd.dentry->d_inode,
-+                                        nd.last.name,
-+                                        nd.last.len);
-+                      /* the file system wants to use normal vfs path now */
-+                      if (error != -EOPNOTSUPP)
-+                              goto out_release;
-+              }
-+              new_dentry = lookup_create(&nd, 0, NULL);
-               error = PTR_ERR(new_dentry);
-               if (!IS_ERR(new_dentry)) {
-                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-@@ -1716,7 +1920,8 @@ exit:
-  *       locking].
-  */
- int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+                 struct inode *new_dir, struct dentry *new_dentry,
-+                 struct lookup_intent *it)
- {
-       int error;
-       struct inode *target;
-@@ -1774,6 +1979,7 @@ int vfs_rename_dir(struct inode *old_dir
-               error = -EBUSY;
-       else 
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       if (target) {
-               if (!error)
-                       target->i_flags |= S_DEAD;
-@@ -1795,7 +2001,8 @@ out_unlock:
- }
- int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+                   struct inode *new_dir, struct dentry *new_dentry,
-+                   struct lookup_intent *it)
- {
-       int error;
-@@ -1826,6 +2033,7 @@ int vfs_rename_other(struct inode *old_d
-               error = -EBUSY;
-       else
-               error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-+      intent_release(new_dentry, it);
-       double_up(&old_dir->i_zombie, &new_dir->i_zombie);
-       if (error)
-               return error;
-@@ -1837,13 +2045,14 @@ int vfs_rename_other(struct inode *old_d
- }
- int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
--             struct inode *new_dir, struct dentry *new_dentry)
-+             struct inode *new_dir, struct dentry *new_dentry,
-+             struct lookup_intent *it)
- {
-       int error;
-       if (S_ISDIR(old_dentry->d_inode->i_mode))
--              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
-       else
--              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
-+              error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
-       if (!error) {
-               if (old_dir == new_dir)
-                       inode_dir_notify(old_dir, DN_RENAME);
-@@ -1888,7 +2097,7 @@ static inline int do_rename(const char *
-       double_lock(new_dir, old_dir);
--      old_dentry = lookup_hash(&oldnd.last, old_dir);
-+      old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL);
-       error = PTR_ERR(old_dentry);
-       if (IS_ERR(old_dentry))
-               goto exit3;
-@@ -1904,16 +2113,37 @@ static inline int do_rename(const char *
-               if (newnd.last.name[newnd.last.len])
-                       goto exit4;
-       }
--      new_dentry = lookup_hash(&newnd.last, new_dir);
-+      new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL);
-       error = PTR_ERR(new_dentry);
-       if (IS_ERR(new_dentry))
-               goto exit4;
-+      if (old_dir->d_inode->i_op->rename2) {
-+              lock_kernel();
-+              /* don't rename mount point. mds will take care of
-+               * the rest sanity checking */
-+              if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) {
-+                      error = -EBUSY;
-+                      goto exit5;
-+              }
-+
-+              error = old_dir->d_inode->i_op->rename2(old_dir->d_inode,
-+                                                      new_dir->d_inode,
-+                                                      oldnd.last.name,
-+                                                      oldnd.last.len,
-+                                                      newnd.last.name,
-+                                                      newnd.last.len);
-+              unlock_kernel();
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit5;
-+      }
-+
-       lock_kernel();
-       error = vfs_rename(old_dir->d_inode, old_dentry,
--                                 new_dir->d_inode, new_dentry);
-+                                 new_dir->d_inode, new_dentry, NULL);
-       unlock_kernel();
--
-+exit5:
-       dput(new_dentry);
- exit4:
-       dput(old_dentry);
-@@ -1964,7 +2194,8 @@ out:
- }
- static inline int
--__vfs_follow_link(struct nameidata *nd, const char *link)
-+__vfs_follow_link(struct nameidata *nd, const char *link,
-+                struct lookup_intent *it)
- {
-       int res = 0;
-       char *name;
-@@ -1977,7 +2208,7 @@ __vfs_follow_link(struct nameidata *nd, 
-                       /* weird __emul_prefix() stuff did it */
-                       goto out;
-       }
--      res = link_path_walk(link, nd);
-+      res = link_path_walk_it(link, nd, it);
- out:
-       if (current->link_count || res || nd->last_type!=LAST_NORM)
-               return res;
-@@ -1999,7 +2230,13 @@ fail:
- int vfs_follow_link(struct nameidata *nd, const char *link)
- {
--      return __vfs_follow_link(nd, link);
-+      return __vfs_follow_link(nd, link, NULL);
-+}
-+
-+int vfs_follow_link_it(struct nameidata *nd, const char *link,
-+                     struct lookup_intent *it)
-+{
-+      return __vfs_follow_link(nd, link, it);
- }
- /* get the link contents into pagecache */
-@@ -2041,7 +2278,7 @@ int page_follow_link(struct dentry *dent
- {
-       struct page *page = NULL;
-       char *s = page_getlink(dentry, &page);
--      int res = __vfs_follow_link(nd, s);
-+      int res = __vfs_follow_link(nd, s, NULL);
-       if (page) {
-               kunmap(page);
-               page_cache_release(page);
---- linux-2.4.19-hp3_pnnl1/fs/nfsd/vfs.c~vfs_intent_hp_2.4.19  2002-08-03 08:39:45.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/nfsd/vfs.c  2003-04-23 17:07:19.000000000 +0800
-@@ -1295,7 +1295,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
-                       err = nfserr_perm;
-       } else
- #endif
--      err = vfs_rename(fdir, odentry, tdir, ndentry);
-+      err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
-       if (!err && EX_ISSYNC(tfhp->fh_export)) {
-               nfsd_sync_dir(tdentry);
-               nfsd_sync_dir(fdentry);
---- linux-2.4.19-hp3_pnnl1/fs/open.c~vfs_intent_hp_2.4.19      2002-08-03 08:39:45.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/open.c      2003-04-23 17:07:19.000000000 +0800
-@@ -19,6 +19,8 @@
- #include <asm/uaccess.h>
- #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
-+extern int path_walk_it(const char *name, struct nameidata *nd,
-+                      struct lookup_intent *it);
- int vfs_statfs(struct super_block *sb, struct statfs *buf)
- {
-@@ -95,9 +97,10 @@ void fd_install(unsigned int fd, struct 
-       write_unlock(&files->file_lock);
- }
--int do_truncate(struct dentry *dentry, loff_t length)
-+int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
- {
-       struct inode *inode = dentry->d_inode;
-+      struct inode_operations *op = dentry->d_inode->i_op;
-       int error;
-       struct iattr newattrs;
-@@ -108,7 +111,14 @@ int do_truncate(struct dentry *dentry, l
-       down(&inode->i_sem);
-       newattrs.ia_size = length;
-       newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
--      error = notify_change(dentry, &newattrs);
-+      if (called_from_open)
-+              newattrs.ia_valid |= ATTR_FROM_OPEN;
-+      if (op->setattr_raw) {
-+              newattrs.ia_valid |= ATTR_RAW;
-+              newattrs.ia_ctime = CURRENT_TIME;
-+              error = op->setattr_raw(inode, &newattrs);
-+      } else 
-+              error = notify_change(dentry, &newattrs);
-       up(&inode->i_sem);
-       return error;
- }
-@@ -118,12 +128,13 @@ static inline long do_sys_truncate(const
-       struct nameidata nd;
-       struct inode * inode;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       error = -EINVAL;
-       if (length < 0) /* sorry, but loff_t says... */
-               goto out;
--      error = user_path_walk(path, &nd);
-+      error = user_path_walk_it(path, &nd, &it);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-@@ -163,11 +174,13 @@ static inline long do_sys_truncate(const
-       error = locks_verify_truncate(inode, NULL, length);
-       if (!error) {
-               DQUOT_INIT(inode);
--              error = do_truncate(nd.dentry, length);
-+              intent_release(nd.dentry, &it);
-+              error = do_truncate(nd.dentry, length, 0);
-       }
-       put_write_access(inode);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi
-       error = locks_verify_truncate(inode, file, length);
-       if (!error)
--              error = do_truncate(dentry, length);
-+              error = do_truncate(dentry, length, 0);
- out_putf:
-       fput(file);
- out:
-@@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam
-       struct inode * inode;
-       struct iattr newattrs;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, NULL);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-+      /* this is safe without a Lustre lock because it only depends
-+         on the super block */
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-@@ -279,11 +294,29 @@ asmlinkage long sys_utime(char * filenam
-                       goto dput_and_out;
-               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
--      } else {
-+      }
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-+      error = -EROFS;
-+      if (IS_RDONLY(inode))
-+              goto dput_and_out;
-+
-+      error = -EPERM;
-+      if (!times) {
-               if (current->fsuid != inode->i_uid &&
-                   (error = permission(inode,MAY_WRITE)) != 0)
-                       goto dput_and_out;
-       }
-+
-       error = notify_change(nd.dentry, &newattrs);
- dput_and_out:
-       path_release(&nd);
-@@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena
-       struct inode * inode;
-       struct iattr newattrs;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, NULL);
-       if (error)
-               goto out;
-       inode = nd.dentry->d_inode;
-+      /* this is safe without a Lustre lock because it only depends
-+         on the super block */
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-@@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena
-               newattrs.ia_atime = times[0].tv_sec;
-               newattrs.ia_mtime = times[1].tv_sec;
-               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
--      } else {
-+      }
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-+      error = -EPERM;
-+      if (!utimes) {
-               if (current->fsuid != inode->i_uid &&
-                   (error = permission(inode,MAY_WRITE)) != 0)
-                       goto dput_and_out;
-@@ -347,6 +395,7 @@ asmlinkage long sys_access(const char * 
-       int old_fsuid, old_fsgid;
-       kernel_cap_t old_cap;
-       int res;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
-               return -EINVAL;
-@@ -364,13 +413,14 @@ asmlinkage long sys_access(const char * 
-       else
-               current->cap_effective = current->cap_permitted;
--      res = user_path_walk(filename, &nd);
-+      res = user_path_walk_it(filename, &nd, &it);
-       if (!res) {
-               res = permission(nd.dentry->d_inode, mode);
-               /* SuS v2 requires we report a read only fs too */
-               if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
-                  && !special_file(nd.dentry->d_inode->i_mode))
-                       res = -EROFS;
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-@@ -385,17 +435,10 @@ asmlinkage long sys_chdir(const char * f
- {
-       int error;
-       struct nameidata nd;
--      char *name;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-+  
-+      error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it);
--      name = getname(filename);
--      error = PTR_ERR(name);
--      if (IS_ERR(name))
--              goto out;
--
--      error = 0;
--      if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
--              error = path_walk(name, &nd);
--      putname(name);
-       if (error)
-               goto out;
-@@ -406,6 +449,7 @@ asmlinkage long sys_chdir(const char * f
-       set_fs_pwd(current->fs, nd.mnt, nd.dentry);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -445,17 +489,10 @@ asmlinkage long sys_chroot(const char * 
- {
-       int error;
-       struct nameidata nd;
--      char *name;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-+  
-+      error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it);
--      name = getname(filename);
--      error = PTR_ERR(name);
--      if (IS_ERR(name))
--              goto out;
--
--      path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
--                    LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
--      error = path_walk(name, &nd);   
--      putname(name);
-       if (error)
-               goto out;
-@@ -471,6 +508,7 @@ asmlinkage long sys_chroot(const char * 
-       set_fs_altroot();
-       error = 0;
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -525,6 +563,18 @@ asmlinkage long sys_chmod(const char * f
-       if (IS_RDONLY(inode))
-               goto dput_and_out;
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
-+              newattrs.ia_mode = mode;
-+              newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto dput_and_out;
-+      }
-+
-       error = -EPERM;
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               goto dput_and_out;
-@@ -555,6 +605,20 @@ static int chown_common(struct dentry * 
-       error = -EROFS;
-       if (IS_RDONLY(inode))
-               goto out;
-+
-+      if (inode->i_op->setattr_raw) {
-+              struct inode_operations *op = dentry->d_inode->i_op;
-+
-+              newattrs.ia_uid = user;
-+              newattrs.ia_gid = group;
-+              newattrs.ia_valid = ATTR_UID | ATTR_GID;
-+              newattrs.ia_valid |= ATTR_RAW;
-+              error = op->setattr_raw(inode, &newattrs);
-+              /* the file system wants to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      return error;
-+      }
-+
-       error = -EPERM;
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               goto out;
-@@ -655,10 +719,12 @@ asmlinkage long sys_fchown(unsigned int 
-  * for the internal routines (ie open_namei()/follow_link() etc). 00 is
-  * used by symlinks.
-  */
-+
- struct file *filp_open(const char * filename, int flags, int mode)
- {
-       int namei_flags, error;
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
-       namei_flags = flags;
-       if ((namei_flags+1) & O_ACCMODE)
-@@ -666,14 +732,15 @@ struct file *filp_open(const char * file
-       if (namei_flags & O_TRUNC)
-               namei_flags |= 2;
--      error = open_namei(filename, namei_flags, mode, &nd);
--      if (!error)
--              return dentry_open(nd.dentry, nd.mnt, flags);
-+      error = open_namei_it(filename, namei_flags, mode, &nd, &it);
-+      if (error)
-+              return ERR_PTR(error);
--      return ERR_PTR(error);
-+      return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
- }
--struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                          int flags, struct lookup_intent *it)
- {
-       struct file * f;
-       struct inode *inode;
-@@ -716,6 +783,7 @@ struct file *dentry_open(struct dentry *
-       }
-       f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
-+      intent_release(dentry, it);
-       return f;
- cleanup_all:
-@@ -730,11 +798,17 @@ cleanup_all:
- cleanup_file:
-       put_filp(f);
- cleanup_dentry:
-+      intent_release(dentry, it);
-       dput(dentry);
-       mntput(mnt);
-       return ERR_PTR(error);
- }
-+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+{
-+      return dentry_open_it(dentry, mnt, flags, NULL);
-+}
-+
- /*
-  * Find an empty file descriptor entry, and mark it busy.
-  */
---- linux-2.4.19-hp3_pnnl1/fs/stat.c~vfs_intent_hp_2.4.19      2003-04-23 17:06:53.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/stat.c      2003-04-23 17:07:19.000000000 +0800
-@@ -135,13 +135,15 @@ static int cp_new_stat(struct inode * in
- asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
- {
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       int error;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_old_stat(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -151,13 +153,15 @@ asmlinkage long sys_stat(char * filename
- asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
- {
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       int error;
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_new_stat(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -172,13 +176,15 @@ asmlinkage long sys_newstat(char * filen
- asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
- {
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       int error;
--      error = user_path_walk_link(filename, &nd);
-+      error = user_path_walk_link_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_old_stat(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -189,13 +195,15 @@ asmlinkage long sys_lstat(char * filenam
- asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
- {
-       struct nameidata nd;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
-       int error;
--      error = user_path_walk_link(filename, &nd);
-+      error = user_path_walk_link_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_new_stat(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -333,12 +341,14 @@ asmlinkage long sys_stat64(char * filena
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_new_stat64(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -348,12 +358,14 @@ asmlinkage long sys_lstat64(char * filen
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_GETATTR };
--      error = user_path_walk_link(filename, &nd);
-+      error = user_path_walk_link_it(filename, &nd, &it);
-       if (!error) {
-               error = do_revalidate(nd.dentry);
-               if (!error)
-                       error = cp_new_stat64(nd.dentry->d_inode, statbuf);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
---- linux-2.4.19-hp3_pnnl1/include/linux/dcache.h~vfs_intent_hp_2.4.19 2002-08-03 08:39:45.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/include/linux/dcache.h 2003-04-23 17:07:19.000000000 +0800
-@@ -6,6 +6,25 @@
- #include <asm/atomic.h>
- #include <linux/mount.h>
-+#define IT_OPEN     (1)
-+#define IT_CREAT    (1<<1)
-+#define IT_READDIR  (1<<2)
-+#define IT_GETATTR  (1<<3)
-+#define IT_LOOKUP   (1<<4)
-+#define IT_UNLINK   (1<<5)
-+
-+struct lookup_intent {
-+      int it_op;
-+      int it_mode;
-+      int it_flags;
-+      int it_disposition;
-+      int it_status;
-+      struct iattr *it_iattr;
-+      __u64 it_lock_handle[2];
-+      int it_lock_mode;
-+      void *it_data;
-+};
-+
- /*
-  * linux/include/linux/dcache.h
-  *
-@@ -78,6 +97,7 @@ struct dentry {
-       unsigned long d_time;           /* used by d_revalidate */
-       struct dentry_operations  *d_op;
-       struct super_block * d_sb;      /* The root of the dentry tree */
-+      struct lookup_intent *d_it;
-       unsigned long d_vfs_flags;
-       void * d_fsdata;                /* fs-specific data */
-       unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
-@@ -90,8 +110,15 @@ struct dentry_operations {
-       int (*d_delete)(struct dentry *);
-       void (*d_release)(struct dentry *);
-       void (*d_iput)(struct dentry *, struct inode *);
-+      int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
-+      void (*d_intent_release)(struct dentry *, struct lookup_intent *);
- };
-+/* defined in fs/namei.c */
-+extern void intent_release(struct dentry *de, struct lookup_intent *it);
-+/* defined in fs/dcache.c */
-+extern void __d_rehash(struct dentry * entry, int lock);
-+
- /* the dentry parameter passed to d_hash and d_compare is the parent
-  * directory of the entries to be compared. It is used in case these
-  * functions need any directory specific information for determining
-@@ -123,6 +150,7 @@ d_iput:            no              no              yes
-                                        * s_nfsd_free_path semaphore will be down
-                                        */
- #define DCACHE_REFERENCED     0x0008  /* Recently used, don't discard. */
-+#define DCACHE_LUSTRE_INVALID 0x0010  /* Lustre invalidated */
- extern spinlock_t dcache_lock;
---- linux-2.4.19-hp3_pnnl1/include/linux/fs.h~vfs_intent_hp_2.4.19     2003-04-23 16:25:28.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/include/linux/fs.h     2003-04-23 17:07:19.000000000 +0800
-@@ -339,6 +339,8 @@ extern void set_bh_page(struct buffer_he
- #define ATTR_MTIME_SET        256
- #define ATTR_FORCE    512     /* Not a change, but a change it */
- #define ATTR_ATTR_FLAG        1024
-+#define ATTR_RAW      2048    /* file system, not vfs will massage attrs */
-+#define ATTR_FROM_OPEN        4096    /* called from open path, ie O_TRUNC */
- /*
-  * This is the Inode Attributes structure, used for notify_change().  It
-@@ -575,6 +577,7 @@ struct file {
-       /* needed for tty driver, and maybe others */
-       void                    *private_data;
-+      struct lookup_intent    *f_intent;
-       /* preallocated helper kiobuf to speedup O_DIRECT */
-       struct kiobuf           *f_iobuf;
-@@ -815,7 +818,9 @@ extern int vfs_symlink(struct inode *, s
- extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
- extern int vfs_rmdir(struct inode *, struct dentry *);
- extern int vfs_unlink(struct inode *, struct dentry *);
--extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
-+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-+              struct inode *new_dir, struct dentry *new_dentry,
-+              struct lookup_intent *it);
- /*
-  * File types
-@@ -876,20 +881,33 @@ struct file_operations {
- struct inode_operations {
-       int (*create) (struct inode *,struct dentry *,int);
-       struct dentry * (*lookup) (struct inode *,struct dentry *);
-+      struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
-       int (*link) (struct dentry *,struct inode *,struct dentry *);
-+      int (*link2) (struct inode *,struct inode *, const char *, int);
-       int (*unlink) (struct inode *,struct dentry *);
-+      int (*unlink2) (struct inode *, const char *, int);
-       int (*symlink) (struct inode *,struct dentry *,const char *);
-+      int (*symlink2) (struct inode *, const char *, int, const char *);
-       int (*mkdir) (struct inode *,struct dentry *,int);
-+      int (*mkdir2) (struct inode *, const char *, int,int);
-       int (*rmdir) (struct inode *,struct dentry *);
-+      int (*rmdir2) (struct inode *, const char *, int);
-       int (*mknod) (struct inode *,struct dentry *,int,int);
-+      int (*mknod2) (struct inode *, const char *, int,int,int);
-       int (*rename) (struct inode *, struct dentry *,
-                       struct inode *, struct dentry *);
-+      int (*rename2) (struct inode *, struct inode *,
-+                      const char *oldname, int oldlen,
-+                      const char *newname, int newlen);
-       int (*readlink) (struct dentry *, char *,int);
-       int (*follow_link) (struct dentry *, struct nameidata *);
-+      int (*follow_link2) (struct dentry *, struct nameidata *,
-+                           struct lookup_intent *it);
-       void (*truncate) (struct inode *);
-       int (*permission) (struct inode *, int);
-       int (*revalidate) (struct dentry *);
-       int (*setattr) (struct dentry *, struct iattr *);
-+      int (*setattr_raw) (struct inode *, struct iattr *);
-       int (*getattr) (struct dentry *, struct iattr *);
-       int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
-       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-@@ -1086,10 +1104,14 @@ static inline int get_lease(struct inode
- asmlinkage long sys_open(const char *, int, int);
- asmlinkage long sys_close(unsigned int);      /* yes, it's really unsigned */
--extern int do_truncate(struct dentry *, loff_t start);
-+extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
- extern struct file *filp_open(const char *, int, int);
- extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
-+extern int open_namei_it(const char *filename, int namei_flags, int mode,
-+                       struct nameidata *nd, struct lookup_intent *it);
-+extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
-+                          int flags, struct lookup_intent *it);
- extern int filp_close(struct file *, fl_owner_t id);
- extern char * getname(const char *);
-@@ -1354,6 +1376,7 @@ typedef int (*read_actor_t)(read_descrip
- extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
- extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
-+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
- extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
- extern int FASTCALL(path_walk(const char *, struct nameidata *));
- extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
-@@ -1364,6 +1387,8 @@ extern struct dentry * lookup_one_len(co
- extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
- #define user_path_walk(name,nd)        __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
- #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
-+#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
-+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
- extern void inode_init_once(struct inode *);
- extern void iput(struct inode *);
-@@ -1499,6 +1524,8 @@ extern struct file_operations generic_ro
- extern int vfs_readlink(struct dentry *, char *, int, const char *);
- extern int vfs_follow_link(struct nameidata *, const char *);
-+extern int vfs_follow_link_it(struct nameidata *, const char *,
-+                            struct lookup_intent *it);
- extern int page_readlink(struct dentry *, char *, int);
- extern int page_follow_link(struct dentry *, struct nameidata *);
- extern struct inode_operations page_symlink_inode_operations;
---- linux-2.4.19-hp3_pnnl1/kernel/ksyms.c~vfs_intent_hp_2.4.19 2003-04-23 16:25:29.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/kernel/ksyms.c 2003-04-23 17:07:19.000000000 +0800
-@@ -293,6 +293,7 @@ EXPORT_SYMBOL(read_cache_page);
- EXPORT_SYMBOL(set_page_dirty);
- EXPORT_SYMBOL(vfs_readlink);
- EXPORT_SYMBOL(vfs_follow_link);
-+EXPORT_SYMBOL(vfs_follow_link_it);
- EXPORT_SYMBOL(page_readlink);
- EXPORT_SYMBOL(page_follow_link);
- EXPORT_SYMBOL(page_symlink_inode_operations);
---- linux-2.4.19-hp3_pnnl1/fs/exec.c~vfs_intent_hp_2.4.19      2003-04-23 16:12:58.000000000 +0800
-+++ linux-2.4.19-hp3_pnnl1-root/fs/exec.c      2003-04-23 17:21:09.000000000 +0800
-@@ -109,8 +109,9 @@ asmlinkage long sys_uselib(const char * 
-       struct file * file;
-       struct nameidata nd;
-       int error;
--
--      error = user_path_walk(library, &nd);
-+      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
-+                                                                                                                                             
-+      error = user_path_walk_it(library, &nd, &it);
-       if (error)
-               goto out;
-@@ -122,7 +123,7 @@ asmlinkage long sys_uselib(const char * 
-       if (error)
-               goto exit;
--      file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
-+      file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
-       error = PTR_ERR(file);
-       if (IS_ERR(file))
-               goto out;
-@@ -344,9 +345,10 @@ struct file *open_exec(const char *name)
-       struct inode *inode;
-       struct file *file;
-       int err = 0;
--
-+      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
-+                                                                                                                                             
-       if (path_init(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
--              err = path_walk(name, &nd);
-+              err = path_walk_it(name, &nd, &it);
-       file = ERR_PTR(err);
-       if (!err) {
-               inode = nd.dentry->d_inode;
-@@ -358,7 +360,7 @@ struct file *open_exec(const char *name)
-                               err = -EACCES;
-                       file = ERR_PTR(err);
-                       if (!err) {
--                              file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
-+                              file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
-                               if (!IS_ERR(file)) {
-                                       err = deny_write_access(file);
-                                       if (err) {
-@@ -1058,7 +1060,7 @@ int do_coredump(long signr, struct pt_re
-               goto close_fail;
-       if (!file->f_op->write)
-               goto close_fail;
--      if (do_truncate(file->f_dentry, 0) != 0)
-+      if (do_truncate(file->f_dentry, 0, 0) != 0)
-               goto close_fail;
-       retval = binfmt->core_dump(signr, regs, file);
-
-_
diff --git a/lustre/kernel_patches/pc/dev_read_only.pc b/lustre/kernel_patches/pc/dev_read_only.pc
deleted file mode 100644 (file)
index 4760ad1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-drivers/block/blkpg.c
-drivers/block/loop.c
-drivers/ide/ide-disk.c
diff --git a/lustre/kernel_patches/pc/dev_read_only_2.4.20.pc b/lustre/kernel_patches/pc/dev_read_only_2.4.20.pc
deleted file mode 100644 (file)
index 4760ad1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-drivers/block/blkpg.c
-drivers/block/loop.c
-drivers/ide/ide-disk.c
diff --git a/lustre/kernel_patches/pc/dev_read_only_hp-2.4.19.pc b/lustre/kernel_patches/pc/dev_read_only_hp-2.4.19.pc
deleted file mode 100644 (file)
index 4760ad1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-drivers/block/blkpg.c
-drivers/block/loop.c
-drivers/ide/ide-disk.c
diff --git a/lustre/kernel_patches/pc/export-truncate.pc b/lustre/kernel_patches/pc/export-truncate.pc
deleted file mode 100644 (file)
index bd58c82..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-include/linux/mm.h
-mm/filemap.c
diff --git a/lustre/kernel_patches/pc/exports.pc b/lustre/kernel_patches/pc/exports.pc
deleted file mode 100644 (file)
index 6472a11..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/super.c
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/exports_2.4.20.pc b/lustre/kernel_patches/pc/exports_2.4.20.pc
deleted file mode 100644 (file)
index 6472a11..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/super.c
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/exports_hp-2.4.19.pc b/lustre/kernel_patches/pc/exports_hp-2.4.19.pc
deleted file mode 100644 (file)
index 6472a11..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/super.c
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/exports_hp_2.4.20.pc b/lustre/kernel_patches/pc/exports_hp_2.4.20.pc
deleted file mode 100644 (file)
index 6472a11..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/super.c
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/ext-2.4-patch-1-chaos.pc b/lustre/kernel_patches/pc/ext-2.4-patch-1-chaos.pc
deleted file mode 100644 (file)
index 634b944..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/dir.c
-fs/ext3/file.c
-fs/ext3/hash.c
-fs/ext3/namei.c
-fs/ext3/super.c
-include/linux/ext3_fs.h
-include/linux/ext3_fs_sb.h
-include/linux/ext3_jbd.h
-include/linux/rbtree.h
-lib/rbtree.c
diff --git a/lustre/kernel_patches/pc/ext-2.4-patch-1-hp-2.4.19.pc b/lustre/kernel_patches/pc/ext-2.4-patch-1-hp-2.4.19.pc
deleted file mode 100644 (file)
index 634b944..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/dir.c
-fs/ext3/file.c
-fs/ext3/hash.c
-fs/ext3/namei.c
-fs/ext3/super.c
-include/linux/ext3_fs.h
-include/linux/ext3_fs_sb.h
-include/linux/ext3_jbd.h
-include/linux/rbtree.h
-lib/rbtree.c
diff --git a/lustre/kernel_patches/pc/ext-2.4-patch-1.pc b/lustre/kernel_patches/pc/ext-2.4-patch-1.pc
deleted file mode 100644 (file)
index 634b944..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/dir.c
-fs/ext3/file.c
-fs/ext3/hash.c
-fs/ext3/namei.c
-fs/ext3/super.c
-include/linux/ext3_fs.h
-include/linux/ext3_fs_sb.h
-include/linux/ext3_jbd.h
-include/linux/rbtree.h
-lib/rbtree.c
diff --git a/lustre/kernel_patches/pc/ext-2.4-patch-2.pc b/lustre/kernel_patches/pc/ext-2.4-patch-2.pc
deleted file mode 100644 (file)
index 9b16759..0000000
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/namei.c
diff --git a/lustre/kernel_patches/pc/ext-2.4-patch-3.pc b/lustre/kernel_patches/pc/ext-2.4-patch-3.pc
deleted file mode 100644 (file)
index 65d4845..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/dir.c
-fs/ext3/namei.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/ext-2.4-patch-4.pc b/lustre/kernel_patches/pc/ext-2.4-patch-4.pc
deleted file mode 100644 (file)
index 9b16759..0000000
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/namei.c
diff --git a/lustre/kernel_patches/pc/ext3-2.4-ino_t.pc b/lustre/kernel_patches/pc/ext3-2.4-ino_t.pc
deleted file mode 100644 (file)
index 4cef979..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/ialloc.c
-fs/ext3/namei.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/ext3-2.4.18-fixes.pc b/lustre/kernel_patches/pc/ext3-2.4.18-fixes.pc
deleted file mode 100644 (file)
index 0822c5e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-fs/ext3/balloc.c
-fs/ext3/file.c
-fs/ext3/fsync.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/namei.c
-fs/ext3/super.c
diff --git a/lustre/kernel_patches/pc/ext3-2.4.18-ino_sb_macro.pc b/lustre/kernel_patches/pc/ext3-2.4.18-ino_sb_macro.pc
deleted file mode 100644 (file)
index cd21583..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-fs/ext3/balloc.c
-fs/ext3/dir.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/ioctl.c
-fs/ext3/namei.c
-fs/ext3/super.c
-fs/ext3/symlink.c
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
diff --git a/lustre/kernel_patches/pc/ext3-2.4.20-fixes.pc b/lustre/kernel_patches/pc/ext3-2.4.20-fixes.pc
deleted file mode 100644 (file)
index 441ced8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/balloc.c
diff --git a/lustre/kernel_patches/pc/ext3-2.5-noread.pc b/lustre/kernel_patches/pc/ext3-2.5-noread.pc
deleted file mode 100644 (file)
index 9c3cea8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/ext3-delete_thread-2.4.20.pc b/lustre/kernel_patches/pc/ext3-delete_thread-2.4.20.pc
deleted file mode 100644 (file)
index 5770132..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/super.c
-include/linux/ext3_fs.h
-include/linux/ext3_fs_sb.h
diff --git a/lustre/kernel_patches/pc/ext3-largefile.pc b/lustre/kernel_patches/pc/ext3-largefile.pc
deleted file mode 100644 (file)
index 76d683f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/inode.c
diff --git a/lustre/kernel_patches/pc/ext3-noread-2.4.20.pc b/lustre/kernel_patches/pc/ext3-noread-2.4.20.pc
deleted file mode 100644 (file)
index 9c3cea8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/ext3-orphan_lock.pc b/lustre/kernel_patches/pc/ext3-orphan_lock.pc
deleted file mode 100644 (file)
index 98aebb0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/namei.c
-fs/ext3/super.c
-include/linux/ext3_fs_sb.h
diff --git a/lustre/kernel_patches/pc/ext3-san-2.4.20-hp.pc b/lustre/kernel_patches/pc/ext3-san-2.4.20-hp.pc
deleted file mode 100644 (file)
index 9ed5141..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-fs/ext3/inode.c
-fs/ext3/ext3-exports.c
diff --git a/lustre/kernel_patches/pc/ext3-truncate_blocks-chaos.patch.pc b/lustre/kernel_patches/pc/ext3-truncate_blocks-chaos.patch.pc
deleted file mode 100644 (file)
index 76d683f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/inode.c
diff --git a/lustre/kernel_patches/pc/ext3-truncate_blocks.pc b/lustre/kernel_patches/pc/ext3-truncate_blocks.pc
deleted file mode 100644 (file)
index 76d683f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/inode.c
diff --git a/lustre/kernel_patches/pc/ext3-unmount_sync.pc b/lustre/kernel_patches/pc/ext3-unmount_sync.pc
deleted file mode 100644 (file)
index 08795de..0000000
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/super.c
diff --git a/lustre/kernel_patches/pc/ext3-use-after-free-hp-2.4.19.pc b/lustre/kernel_patches/pc/ext3-use-after-free-hp-2.4.19.pc
deleted file mode 100644 (file)
index daf8787..0000000
+++ /dev/null
@@ -1 +0,0 @@
-./fs/ext3/namei.c
diff --git a/lustre/kernel_patches/pc/ext3-use-after-free.pc b/lustre/kernel_patches/pc/ext3-use-after-free.pc
deleted file mode 100644 (file)
index daf8787..0000000
+++ /dev/null
@@ -1 +0,0 @@
-./fs/ext3/namei.c
diff --git a/lustre/kernel_patches/pc/extN-2.4.18-ino_sb_fixup.pc b/lustre/kernel_patches/pc/extN-2.4.18-ino_sb_fixup.pc
deleted file mode 100644 (file)
index 7191405..0000000
+++ /dev/null
@@ -1 +0,0 @@
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/extN-delete_thread.pc b/lustre/kernel_patches/pc/extN-delete_thread.pc
deleted file mode 100644 (file)
index bc81732..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-include/linux/ext3_fs.h
-include/linux/ext3_fs_sb.h
-fs/ext3/super.c
diff --git a/lustre/kernel_patches/pc/extN-iget-debug.pc b/lustre/kernel_patches/pc/extN-iget-debug.pc
deleted file mode 100644 (file)
index e9fe01e..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-fs/ext3/namei.c
-fs/ext3/inode.c
diff --git a/lustre/kernel_patches/pc/extN-misc-fixup.pc b/lustre/kernel_patches/pc/extN-misc-fixup.pc
deleted file mode 100644 (file)
index 08795de..0000000
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/super.c
diff --git a/lustre/kernel_patches/pc/extN-noread.pc b/lustre/kernel_patches/pc/extN-noread.pc
deleted file mode 100644 (file)
index 9c3cea8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/extN-san.pc b/lustre/kernel_patches/pc/extN-san.pc
deleted file mode 100644 (file)
index 76d683f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/inode.c
diff --git a/lustre/kernel_patches/pc/extN-wantedi.pc b/lustre/kernel_patches/pc/extN-wantedi.pc
deleted file mode 100644 (file)
index 31901ee..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/ext3/namei.c
-fs/ext3/ialloc.c
-fs/ext3/ioctl.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/htree-ext3-2.4.18.pc b/lustre/kernel_patches/pc/htree-ext3-2.4.18.pc
deleted file mode 100644 (file)
index 6499778..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/ext3/super.c
-fs/ext3/namei.c
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
diff --git a/lustre/kernel_patches/pc/iod-rmap-exports-2.4.20.pc b/lustre/kernel_patches/pc/iod-rmap-exports-2.4.20.pc
deleted file mode 100644 (file)
index 1218f55..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-fs/inode.c
-fs/Makefile
-mm/filemap.c
-mm/vmscan.c
-mm/Makefile
-mm/page_alloc.c
diff --git a/lustre/kernel_patches/pc/iod-rmap-exports.pc b/lustre/kernel_patches/pc/iod-rmap-exports.pc
deleted file mode 100644 (file)
index 1218f55..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-fs/inode.c
-fs/Makefile
-mm/filemap.c
-mm/vmscan.c
-mm/Makefile
-mm/page_alloc.c
diff --git a/lustre/kernel_patches/pc/iod-stock-24-exports.pc b/lustre/kernel_patches/pc/iod-stock-24-exports.pc
deleted file mode 100644 (file)
index e4eceee..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/inode.c
-fs/Makefile
-mm/page_alloc.c
diff --git a/lustre/kernel_patches/pc/iod-stock-24-exports_hp.pc b/lustre/kernel_patches/pc/iod-stock-24-exports_hp.pc
deleted file mode 100644 (file)
index e4eceee..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/inode.c
-fs/Makefile
-mm/page_alloc.c
diff --git a/lustre/kernel_patches/pc/jbd-transno-cb.pc b/lustre/kernel_patches/pc/jbd-transno-cb.pc
deleted file mode 100644 (file)
index cde73d8..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/jbd/commit.c
-fs/jbd/journal.c
-fs/jbd/transaction.c
-include/linux/jbd.h
diff --git a/lustre/kernel_patches/pc/kmem_cache_validate.pc b/lustre/kernel_patches/pc/kmem_cache_validate.pc
deleted file mode 100644 (file)
index 12f8816..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-arch/i386/mm/init.c
-arch/ia64/mm/init.c
-include/linux/slab.h
-kernel/ksyms.c
-kernel/ksyms.c.validate
-mm/slab.c
diff --git a/lustre/kernel_patches/pc/kmem_cache_validate_2.4.20-rh.pc b/lustre/kernel_patches/pc/kmem_cache_validate_2.4.20-rh.pc
deleted file mode 100644 (file)
index a0a6297..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-arch/i386/mm/init.c
-arch/ia64/mm/init.c
-include/linux/slab.h
-kernel/ksyms.c
-mm/slab.c
diff --git a/lustre/kernel_patches/pc/lin-2.5.44.pc b/lustre/kernel_patches/pc/lin-2.5.44.pc
deleted file mode 100644 (file)
index ca773d5..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-arch/um/kernel/mem.c
-fs/Config.help
-fs/Config.in
-fs/dcache.c
-fs/driverfs/inode.c
-fs/ext3/file.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/Makefile
-fs/ext3/namei.c
-fs/ext3/super.c
-fs/ext3/symlink.c
-fs/ext3/xattr.c
-fs/ext3/xattr.h
-fs/ext3/xattr_user.c
-fs/Makefile
-fs/mbcache.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/open.c
-fs/stat.c
-fs/sysfs/inode.c
-include/linux/dcache.h
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
-include/linux/fs.h
-include/linux/lustre_version.h
-include/linux/mbcache.h
-include/linux/namei.h
-include/linux/slab.h
-kernel/ksyms.c
-mm/slab.c
-net/unix/af_unix.c
diff --git a/lustre/kernel_patches/pc/linux-2.4.18ea-0.8.26.pc b/lustre/kernel_patches/pc/linux-2.4.18ea-0.8.26.pc
deleted file mode 100644 (file)
index b647d5a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/namei.c
-fs/ext3/super.c
-fs/ext3/xattr.c
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
-include/linux/ext3_xattr.h
-include/linux/xattr.h
-fs/ext3/Makefile
diff --git a/lustre/kernel_patches/pc/linux-2.4.19-xattr-0.8.54-hp.pc b/lustre/kernel_patches/pc/linux-2.4.19-xattr-0.8.54-hp.pc
deleted file mode 100644 (file)
index f0b7796..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-Documentation/Configure.help
-arch/alpha/defconfig
-arch/alpha/kernel/entry.S
-arch/arm/defconfig
-arch/arm/kernel/calls.S
-arch/i386/defconfig
-arch/ia64/defconfig
-arch/m68k/defconfig
-arch/mips/defconfig
-arch/mips64/defconfig
-arch/ppc/defconfig
-arch/ppc64/kernel/misc.S
-arch/s390/defconfig
-arch/s390/kernel/entry.S
-arch/s390x/defconfig
-arch/s390x/kernel/entry.S
-arch/s390x/kernel/wrapper32.S
-arch/sparc/defconfig
-arch/sparc/kernel/systbls.S
-arch/sparc64/defconfig
-arch/sparc64/kernel/systbls.S
-fs/Config.in
-fs/Makefile
-fs/ext2/Makefile
-fs/ext2/file.c
-fs/ext2/ialloc.c
-fs/ext2/inode.c
-fs/ext2/namei.c
-fs/ext2/super.c
-fs/ext2/symlink.c
-fs/ext2/xattr.c
-fs/ext2/xattr_user.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/namei.c
-fs/ext3/symlink.c
-fs/ext3/xattr.c
-fs/ext3/xattr_user.c
-fs/mbcache.c
-include/asm-arm/unistd.h
-include/asm-ppc64/unistd.h
-include/asm-s390/unistd.h
-include/asm-s390x/unistd.h
-include/asm-sparc/unistd.h
-include/asm-sparc64/unistd.h
-include/linux/cache_def.h
-include/linux/errno.h
-include/linux/ext2_fs.h
-include/linux/ext2_xattr.h
-include/linux/ext3_fs.h
-include/linux/ext3_xattr.h
-include/linux/fs.h
-include/linux/mbcache.h
-kernel/ksyms.c
-mm/vmscan.c
diff --git a/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-chaos.pc b/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-chaos.pc
deleted file mode 100644 (file)
index 32344f6..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-Documentation/Configure.help
-arch/alpha/defconfig
-arch/alpha/kernel/entry.S
-arch/arm/defconfig
-arch/arm/kernel/calls.S
-arch/i386/defconfig
-arch/ia64/defconfig
-arch/ia64/kernel/entry.S
-arch/m68k/defconfig
-arch/mips/defconfig
-arch/mips64/defconfig
-arch/ppc/defconfig
-arch/ppc64/kernel/misc.S
-arch/s390/defconfig
-arch/s390/kernel/entry.S
-arch/s390x/defconfig
-arch/s390x/kernel/entry.S
-arch/s390x/kernel/wrapper32.S
-arch/sparc/defconfig
-arch/sparc/kernel/systbls.S
-arch/sparc64/defconfig
-arch/sparc64/kernel/systbls.S
-fs/Config.in
-fs/Makefile
-fs/ext2/Makefile
-fs/ext2/file.c
-fs/ext2/ialloc.c
-fs/ext2/inode.c
-fs/ext2/namei.c
-fs/ext2/super.c
-fs/ext2/symlink.c
-fs/ext2/xattr.c
-fs/ext2/xattr_user.c
-fs/ext3/Makefile
-fs/ext3/file.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/namei.c
-fs/ext3/super.c
-fs/ext3/symlink.c
-fs/ext3/xattr.c
-fs/ext3/xattr_user.c
-fs/jfs/jfs_xattr.h
-fs/jfs/xattr.c
-fs/mbcache.c
-include/asm-arm/unistd.h
-include/asm-ia64/unistd.h
-include/asm-ppc64/unistd.h
-include/asm-s390/unistd.h
-include/asm-s390x/unistd.h
-include/asm-sparc/unistd.h
-include/asm-sparc64/unistd.h
-include/linux/cache_def.h
-include/linux/errno.h
-include/linux/ext2_fs.h
-include/linux/ext2_xattr.h
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
-include/linux/ext3_xattr.h
-include/linux/fs.h
-include/linux/mbcache.h
-kernel/ksyms.c
-mm/vmscan.c
diff --git a/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-hp.pc b/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-hp.pc
deleted file mode 100644 (file)
index 1e8cf75..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-Documentation/Configure.help
-arch/alpha/defconfig
-arch/alpha/kernel/entry.S
-arch/arm/defconfig
-arch/arm/kernel/calls.S
-arch/i386/defconfig
-arch/ia64/defconfig
-arch/m68k/defconfig
-arch/mips/defconfig
-arch/mips64/defconfig
-arch/ppc/defconfig
-arch/ppc64/kernel/misc.S
-arch/s390/defconfig
-arch/s390/kernel/entry.S
-arch/s390x/defconfig
-arch/s390x/kernel/entry.S
-arch/s390x/kernel/wrapper32.S
-arch/sparc/defconfig
-arch/sparc/kernel/systbls.S
-arch/sparc64/defconfig
-arch/sparc64/kernel/systbls.S
-fs/Config.in
-fs/Makefile
-fs/ext2/Makefile
-fs/ext2/file.c
-fs/ext2/ialloc.c
-fs/ext2/inode.c
-fs/ext2/namei.c
-fs/ext2/super.c
-fs/ext2/symlink.c
-fs/ext2/xattr.c
-fs/ext2/xattr_user.c
-fs/ext3/Makefile
-fs/ext3/file.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/namei.c
-fs/ext3/super.c
-fs/ext3/symlink.c
-fs/ext3/xattr.c
-fs/ext3/xattr_user.c
-fs/ext3/ext3-exports.c
-fs/jfs/jfs_xattr.h
-fs/jfs/xattr.c
-fs/mbcache.c
-include/asm-arm/unistd.h
-include/asm-ppc64/unistd.h
-include/asm-s390/unistd.h
-include/asm-s390x/unistd.h
-include/asm-sparc/unistd.h
-include/asm-sparc64/unistd.h
-include/linux/cache_def.h
-include/linux/errno.h
-include/linux/ext2_fs.h
-include/linux/ext2_xattr.h
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
-include/linux/ext3_xattr.h
-include/linux/fs.h
-include/linux/mbcache.h
-kernel/ksyms.c
-mm/vmscan.c
diff --git a/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54.pc b/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54.pc
deleted file mode 100644 (file)
index 32344f6..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-Documentation/Configure.help
-arch/alpha/defconfig
-arch/alpha/kernel/entry.S
-arch/arm/defconfig
-arch/arm/kernel/calls.S
-arch/i386/defconfig
-arch/ia64/defconfig
-arch/ia64/kernel/entry.S
-arch/m68k/defconfig
-arch/mips/defconfig
-arch/mips64/defconfig
-arch/ppc/defconfig
-arch/ppc64/kernel/misc.S
-arch/s390/defconfig
-arch/s390/kernel/entry.S
-arch/s390x/defconfig
-arch/s390x/kernel/entry.S
-arch/s390x/kernel/wrapper32.S
-arch/sparc/defconfig
-arch/sparc/kernel/systbls.S
-arch/sparc64/defconfig
-arch/sparc64/kernel/systbls.S
-fs/Config.in
-fs/Makefile
-fs/ext2/Makefile
-fs/ext2/file.c
-fs/ext2/ialloc.c
-fs/ext2/inode.c
-fs/ext2/namei.c
-fs/ext2/super.c
-fs/ext2/symlink.c
-fs/ext2/xattr.c
-fs/ext2/xattr_user.c
-fs/ext3/Makefile
-fs/ext3/file.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/namei.c
-fs/ext3/super.c
-fs/ext3/symlink.c
-fs/ext3/xattr.c
-fs/ext3/xattr_user.c
-fs/jfs/jfs_xattr.h
-fs/jfs/xattr.c
-fs/mbcache.c
-include/asm-arm/unistd.h
-include/asm-ia64/unistd.h
-include/asm-ppc64/unistd.h
-include/asm-s390/unistd.h
-include/asm-s390x/unistd.h
-include/asm-sparc/unistd.h
-include/asm-sparc64/unistd.h
-include/linux/cache_def.h
-include/linux/errno.h
-include/linux/ext2_fs.h
-include/linux/ext2_xattr.h
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
-include/linux/ext3_xattr.h
-include/linux/fs.h
-include/linux/mbcache.h
-kernel/ksyms.c
-mm/vmscan.c
diff --git a/lustre/kernel_patches/pc/lustre-2.5.63.pc b/lustre/kernel_patches/pc/lustre-2.5.63.pc
deleted file mode 100644 (file)
index daeea17..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-arch/um/kernel/mem.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/sysfs/inode.c
-include/linux/dcache.h
-include/linux/fs.h
-include/linux/namei.h
-include/linux/slab.h
-kernel/ksyms.c
-mm/slab.c
-net/unix/af_unix.c
-fs/dcache.c
diff --git a/lustre/kernel_patches/pc/lustre-2.5.pc b/lustre/kernel_patches/pc/lustre-2.5.pc
deleted file mode 100644 (file)
index 71434ea..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-arch/um/kernel/mem.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/sysfs/inode.c
-include/linux/dcache.h
-include/linux/fs.h
-include/linux/namei.h
-include/linux/slab.h
-kernel/ksyms.c
-mm/slab.c
-net/unix/af_unix.c
diff --git a/lustre/kernel_patches/pc/lustre_version.pc b/lustre/kernel_patches/pc/lustre_version.pc
deleted file mode 100644 (file)
index 898bebd..0000000
+++ /dev/null
@@ -1 +0,0 @@
-include/linux/lustre_version.h
diff --git a/lustre/kernel_patches/pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc b/lustre/kernel_patches/pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc
deleted file mode 100644 (file)
index 44d4abf..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-./include/linux/lustre_version.h
-./arch/ia64/mm/init.c
-./arch/i386/mm/init.c
-./drivers/block/blkpg.c
-./drivers/block/loop.c
-./drivers/ide/ide-disk.c
-./fs/ext3/Makefile
-./fs/ext3/super.c
-./fs/jbd/commit.c
-./fs/jbd/journal.c
-./fs/jbd/transaction.c
-./include/linux/blkdev.h
-./include/linux/slab.h
-./include/linux/jbd.h
-./kernel/ksyms.c
-./include/linux/dcache.h
-./include/linux/fs.h
-./fs/dcache.c
-./fs/nfsd/vfs.c
-./fs/namei.c
-./fs/open.c
-./fs/stat.c
-./mm/slab.c
diff --git a/lustre/kernel_patches/pc/uml-patch-2.4.20-3.pc b/lustre/kernel_patches/pc/uml-patch-2.4.20-3.pc
deleted file mode 100644 (file)
index 887e3fa..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-CREDITS
-Documentation/Configure.help
-MAINTAINERS
-Makefile
-arch/um/Makefile
-arch/um/Makefile-i386
-arch/um/Makefile-ia64
-arch/um/Makefile-os-Linux
-arch/um/Makefile-ppc
-arch/um/Makefile-skas
-arch/um/Makefile-tt
-arch/um/common.ld.in
-arch/um/config.in
-arch/um/config.release
-arch/um/config_block.in
-arch/um/config_char.in
-arch/um/config_net.in
-arch/um/config_scsi.in
-arch/um/defconfig
-arch/um/drivers/Makefile
-arch/um/drivers/chan_kern.c
-arch/um/drivers/chan_user.c
-arch/um/drivers/daemon.h
-arch/um/drivers/daemon_kern.c
-arch/um/drivers/daemon_user.c
-arch/um/drivers/fd.c
-arch/um/drivers/harddog_kern.c
-arch/um/drivers/harddog_user.c
-arch/um/drivers/hostaudio_kern.c
-arch/um/drivers/hostaudio_user.c
-arch/um/drivers/line.c
-arch/um/drivers/mcast.h
-arch/um/drivers/mcast_kern.c
-arch/um/drivers/mcast_user.c
-arch/um/drivers/mconsole_kern.c
-arch/um/drivers/mconsole_user.c
-arch/um/drivers/mmapper_kern.c
-arch/um/drivers/net_kern.c
-arch/um/drivers/net_user.c
-arch/um/drivers/null.c
-arch/um/drivers/pcap_kern.c
-arch/um/drivers/pcap_user.c
-arch/um/drivers/pcap_user.h
-arch/um/drivers/port.h
-arch/um/drivers/port_kern.c
-arch/um/drivers/port_user.c
-arch/um/drivers/pty.c
-arch/um/drivers/slip.h
-arch/um/drivers/slip_kern.c
-arch/um/drivers/slip_proto.h
-arch/um/drivers/slip_user.c
-arch/um/drivers/slirp.h
-arch/um/drivers/slirp_kern.c
-arch/um/drivers/slirp_user.c
-arch/um/drivers/ssl.c
-arch/um/drivers/ssl.h
-arch/um/drivers/stdio_console.c
-arch/um/drivers/stdio_console.h
-arch/um/drivers/tty.c
-arch/um/drivers/ubd_kern.c
-arch/um/drivers/ubd_user.c
-arch/um/drivers/xterm.c
-arch/um/drivers/xterm.h
-arch/um/drivers/xterm_kern.c
-arch/um/dyn_link.ld.in
-arch/um/fs/Makefile
-arch/um/fs/hostfs/Makefile
-arch/um/fs/hostfs/hostfs.h
-arch/um/fs/hostfs/hostfs_kern.c
-arch/um/fs/hostfs/hostfs_user.c
-arch/um/fs/hppfs/Makefile
-arch/um/fs/hppfs/hppfs_kern.c
-arch/um/include/2_5compat.h
-arch/um/include/Makefile
-arch/um/include/chan_kern.h
-arch/um/include/chan_user.h
-arch/um/include/choose-mode.h
-arch/um/include/frame.h
-arch/um/include/frame_kern.h
-arch/um/include/frame_user.h
-arch/um/include/helper.h
-arch/um/include/hostaudio.h
-arch/um/include/init.h
-arch/um/include/initrd.h
-arch/um/include/irq_user.h
-arch/um/include/kern.h
-arch/um/include/kern_util.h
-arch/um/include/line.h
-arch/um/include/mconsole.h
-arch/um/include/mconsole_kern.h
-arch/um/include/mem.h
-arch/um/include/mem_user.h
-arch/um/include/mode.h
-arch/um/include/mode_kern.h
-arch/um/include/net_kern.h
-arch/um/include/net_user.h
-arch/um/include/os.h
-arch/um/include/process.h
-arch/um/include/ptrace_user.h
-arch/um/include/sigcontext.h
-arch/um/include/sigio.h
-arch/um/include/signal_kern.h
-arch/um/include/signal_user.h
-arch/um/include/skas_ptrace.h
-arch/um/include/syscall_user.h
-arch/um/include/sysdep-i386/checksum.h
-arch/um/include/sysdep-i386/frame.h
-arch/um/include/sysdep-i386/frame_kern.h
-arch/um/include/sysdep-i386/frame_user.h
-arch/um/include/sysdep-i386/ptrace.h
-arch/um/include/sysdep-i386/ptrace_user.h
-arch/um/include/sysdep-i386/sigcontext.h
-arch/um/include/sysdep-i386/syscalls.h
-arch/um/include/sysdep-ia64/ptrace.h
-arch/um/include/sysdep-ia64/sigcontext.h
-arch/um/include/sysdep-ia64/syscalls.h
-arch/um/include/sysdep-ppc/ptrace.h
-arch/um/include/sysdep-ppc/sigcontext.h
-arch/um/include/sysdep-ppc/syscalls.h
-arch/um/include/sysrq.h
-arch/um/include/tempfile.h
-arch/um/include/time_user.h
-arch/um/include/tlb.h
-arch/um/include/ubd_user.h
-arch/um/include/um_mmu.h
-arch/um/include/um_uaccess.h
-arch/um/include/umid.h
-arch/um/include/uml_uaccess.h
-arch/um/include/umn.h
-arch/um/include/user.h
-arch/um/include/user_util.h
-arch/um/kernel/Makefile
-arch/um/kernel/checksum.c
-arch/um/kernel/config.c.in
-arch/um/kernel/exec_kern.c
-arch/um/kernel/exitcode.c
-arch/um/kernel/frame.c
-arch/um/kernel/frame_kern.c
-arch/um/kernel/gmon_syms.c
-arch/um/kernel/gprof_syms.c
-arch/um/kernel/helper.c
-arch/um/kernel/init_task.c
-arch/um/kernel/initrd_kern.c
-arch/um/kernel/initrd_user.c
-arch/um/kernel/irq.c
-arch/um/kernel/irq_user.c
-arch/um/kernel/ksyms.c
-arch/um/kernel/mem.c
-arch/um/kernel/mem_user.c
-arch/um/kernel/mprot.h
-arch/um/kernel/process.c
-arch/um/kernel/process_kern.c
-arch/um/kernel/ptrace.c
-arch/um/kernel/reboot.c
-arch/um/kernel/resource.c
-arch/um/kernel/sigio_kern.c
-arch/um/kernel/sigio_user.c
-arch/um/kernel/signal_kern.c
-arch/um/kernel/signal_user.c
-arch/um/kernel/skas/Makefile
-arch/um/kernel/skas/exec_kern.c
-arch/um/kernel/skas/exec_user.c
-arch/um/kernel/skas/include/mmu.h
-arch/um/kernel/skas/include/mode.h
-arch/um/kernel/skas/include/mode_kern.h
-arch/um/kernel/skas/include/proc_mm.h
-arch/um/kernel/skas/include/ptrace-skas.h
-arch/um/kernel/skas/include/skas.h
-arch/um/kernel/skas/include/uaccess.h
-arch/um/kernel/skas/mem.c
-arch/um/kernel/skas/mem_user.c
-arch/um/kernel/skas/mmu.c
-arch/um/kernel/skas/process.c
-arch/um/kernel/skas/process_kern.c
-arch/um/kernel/skas/sys-i386/Makefile
-arch/um/kernel/skas/sys-i386/sigcontext.c
-arch/um/kernel/skas/syscall_kern.c
-arch/um/kernel/skas/syscall_user.c
-arch/um/kernel/skas/time.c
-arch/um/kernel/skas/tlb.c
-arch/um/kernel/skas/trap_user.c
-arch/um/kernel/skas/util/Makefile
-arch/um/kernel/skas/util/mk_ptregs.c
-arch/um/kernel/smp.c
-arch/um/kernel/sys_call_table.c
-arch/um/kernel/syscall_kern.c
-arch/um/kernel/syscall_user.c
-arch/um/kernel/sysrq.c
-arch/um/kernel/tempfile.c
-arch/um/kernel/time.c
-arch/um/kernel/time_kern.c
-arch/um/kernel/tlb.c
-arch/um/kernel/trap_kern.c
-arch/um/kernel/trap_user.c
-arch/um/kernel/tt/Makefile
-arch/um/kernel/tt/exec_kern.c
-arch/um/kernel/tt/exec_user.c
-arch/um/kernel/tt/gdb.c
-arch/um/kernel/tt/gdb_kern.c
-arch/um/kernel/tt/include/debug.h
-arch/um/kernel/tt/include/mmu.h
-arch/um/kernel/tt/include/mode.h
-arch/um/kernel/tt/include/mode_kern.h
-arch/um/kernel/tt/include/ptrace-tt.h
-arch/um/kernel/tt/include/tt.h
-arch/um/kernel/tt/include/uaccess.h
-arch/um/kernel/tt/ksyms.c
-arch/um/kernel/tt/mem.c
-arch/um/kernel/tt/mem_user.c
-arch/um/kernel/tt/process_kern.c
-arch/um/kernel/tt/ptproxy/Makefile
-arch/um/kernel/tt/ptproxy/proxy.c
-arch/um/kernel/tt/ptproxy/ptproxy.h
-arch/um/kernel/tt/ptproxy/ptrace.c
-arch/um/kernel/tt/ptproxy/sysdep.c
-arch/um/kernel/tt/ptproxy/sysdep.h
-arch/um/kernel/tt/ptproxy/wait.c
-arch/um/kernel/tt/ptproxy/wait.h
-arch/um/kernel/tt/sys-i386/Makefile
-arch/um/kernel/tt/sys-i386/sigcontext.c
-arch/um/kernel/tt/syscall_kern.c
-arch/um/kernel/tt/syscall_user.c
-arch/um/kernel/tt/time.c
-arch/um/kernel/tt/tlb.c
-arch/um/kernel/tt/tracer.c
-arch/um/kernel/tt/trap_user.c
-arch/um/kernel/tt/uaccess_user.c
-arch/um/kernel/tt/unmap.c
-arch/um/kernel/tty_log.c
-arch/um/kernel/uaccess_user.c
-arch/um/kernel/um_arch.c
-arch/um/kernel/umid.c
-arch/um/kernel/user_syms.c
-arch/um/kernel/user_util.c
-arch/um/link.ld.in
-arch/um/main.c
-arch/um/os-Linux/Makefile
-arch/um/os-Linux/drivers/Makefile
-arch/um/os-Linux/drivers/etap.h
-arch/um/os-Linux/drivers/ethertap_kern.c
-arch/um/os-Linux/drivers/ethertap_user.c
-arch/um/os-Linux/drivers/tuntap.h
-arch/um/os-Linux/drivers/tuntap_kern.c
-arch/um/os-Linux/drivers/tuntap_user.c
-arch/um/os-Linux/file.c
-arch/um/os-Linux/include/file.h
-arch/um/os-Linux/process.c
-arch/um/os-Linux/tty.c
-arch/um/sys-i386/Makefile
-arch/um/sys-i386/bugs.c
-arch/um/sys-i386/checksum.S
-arch/um/sys-i386/fault.c
-arch/um/sys-i386/ksyms.c
-arch/um/sys-i386/ldt.c
-arch/um/sys-i386/ptrace.c
-arch/um/sys-i386/ptrace_user.c
-arch/um/sys-i386/sigcontext.c
-arch/um/sys-i386/syscalls.c
-arch/um/sys-i386/sysrq.c
-arch/um/sys-i386/util/Makefile
-arch/um/sys-i386/util/mk_sc.c
-arch/um/sys-i386/util/mk_thread_kern.c
-arch/um/sys-i386/util/mk_thread_user.c
-arch/um/sys-ia64/Makefile
-arch/um/sys-ppc/Makefile
-arch/um/sys-ppc/misc.S
-arch/um/sys-ppc/miscthings.c
-arch/um/sys-ppc/ptrace.c
-arch/um/sys-ppc/ptrace_user.c
-arch/um/sys-ppc/sigcontext.c
-arch/um/sys-ppc/sysrq.c
-arch/um/util/Makefile
-arch/um/util/mk_constants_kern.c
-arch/um/util/mk_constants_user.c
-arch/um/util/mk_task_kern.c
-arch/um/util/mk_task_user.c
-drivers/char/Makefile
-drivers/char/tty_io.c
-drivers/net/setup.c
-include/asm-i386/hardirq.h
-include/asm-um/a.out.h
-include/asm-um/arch-signal-i386.h
-include/asm-um/archparam-i386.h
-include/asm-um/archparam-ppc.h
-include/asm-um/atomic.h
-include/asm-um/bitops.h
-include/asm-um/boot.h
-include/asm-um/bugs.h
-include/asm-um/byteorder.h
-include/asm-um/cache.h
-include/asm-um/checksum.h
-include/asm-um/cobalt.h
-include/asm-um/current.h
-include/asm-um/delay.h
-include/asm-um/desc.h
-include/asm-um/div64.h
-include/asm-um/dma.h
-include/asm-um/elf.h
-include/asm-um/errno.h
-include/asm-um/fcntl.h
-include/asm-um/fixmap.h
-include/asm-um/floppy.h
-include/asm-um/hardirq.h
-include/asm-um/hdreg.h
-include/asm-um/highmem.h
-include/asm-um/hw_irq.h
-include/asm-um/ide.h
-include/asm-um/init.h
-include/asm-um/io.h
-include/asm-um/ioctl.h
-include/asm-um/ioctls.h
-include/asm-um/ipc.h
-include/asm-um/ipcbuf.h
-include/asm-um/irq.h
-include/asm-um/keyboard.h
-include/asm-um/kmap_types.h
-include/asm-um/linux_logo.h
-include/asm-um/locks.h
-include/asm-um/mca_dma.h
-include/asm-um/mman.h
-include/asm-um/mmu.h
-include/asm-um/mmu_context.h
-include/asm-um/module.h
-include/asm-um/msgbuf.h
-include/asm-um/mtrr.h
-include/asm-um/namei.h
-include/asm-um/page.h
-include/asm-um/page_offset.h
-include/asm-um/param.h
-include/asm-um/pci.h
-include/asm-um/pgalloc.h
-include/asm-um/pgtable.h
-include/asm-um/poll.h
-include/asm-um/posix_types.h
-include/asm-um/processor-generic.h
-include/asm-um/processor-i386.h
-include/asm-um/processor-ppc.h
-include/asm-um/ptrace-generic.h
-include/asm-um/ptrace-i386.h
-include/asm-um/resource.h
-include/asm-um/rwlock.h
-include/asm-um/rwsem.h
-include/asm-um/scatterlist.h
-include/asm-um/segment.h
-include/asm-um/semaphore.h
-include/asm-um/sembuf.h
-include/asm-um/serial.h
-include/asm-um/shmbuf.h
-include/asm-um/shmparam.h
-include/asm-um/sigcontext-generic.h
-include/asm-um/sigcontext-i386.h
-include/asm-um/sigcontext-ppc.h
-include/asm-um/siginfo.h
-include/asm-um/signal.h
-include/asm-um/smp.h
-include/asm-um/smplock.h
-include/asm-um/socket.h
-include/asm-um/sockios.h
-include/asm-um/softirq.h
-include/asm-um/spinlock.h
-include/asm-um/stat.h
-include/asm-um/statfs.h
-include/asm-um/string.h
-include/asm-um/system-generic.h
-include/asm-um/system-i386.h
-include/asm-um/system-ppc.h
-include/asm-um/termbits.h
-include/asm-um/termios.h
-include/asm-um/timex.h
-include/asm-um/tlb.h
-include/asm-um/types.h
-include/asm-um/uaccess.h
-include/asm-um/ucontext.h
-include/asm-um/unaligned.h
-include/asm-um/unistd.h
-include/asm-um/user.h
-include/asm-um/vga.h
-include/asm-um/xor.h
-include/linux/blk.h
-include/linux/fs.h
-include/linux/hostfs_fs_i.h
-include/linux/hppfs_fs_i.h
-include/linux/kernel.h
-include/linux/kernel_stat.h
-include/linux/mm.h
-include/linux/proc_mm.h
-include/linux/tty.h
-init/do_mounts.c
-kernel/panic.c
-mm/Makefile
-mm/mmap.c
-mm/mprotect.c
-mm/proc_mm.c
-mm/slab.c
diff --git a/lustre/kernel_patches/pc/uml-patch-2.4.20-tmp.pc b/lustre/kernel_patches/pc/uml-patch-2.4.20-tmp.pc
deleted file mode 100644 (file)
index f8a0fb6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-arch/um/kernel/process.c
diff --git a/lustre/kernel_patches/pc/uml_check_get_page.pc b/lustre/kernel_patches/pc/uml_check_get_page.pc
deleted file mode 100644 (file)
index 3dbf042..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-arch/um/kernel/mem.c
-arch/um/kernel/mem.c.uml-fixes
diff --git a/lustre/kernel_patches/pc/uml_compile_fixes.pc b/lustre/kernel_patches/pc/uml_compile_fixes.pc
deleted file mode 100644 (file)
index c1caa12..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-include/asm-um/pgtable.h
-include/asm-um/pgtable.h.orig
diff --git a/lustre/kernel_patches/pc/uml_no_panic.pc b/lustre/kernel_patches/pc/uml_no_panic.pc
deleted file mode 100644 (file)
index 3dbf042..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-arch/um/kernel/mem.c
-arch/um/kernel/mem.c.uml-fixes
diff --git a/lustre/kernel_patches/pc/vanilla-2.4.18.pc b/lustre/kernel_patches/pc/vanilla-2.4.18.pc
deleted file mode 100644 (file)
index c1ed719..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-include/linux/lustre_version.h
-arch/ia64/mm/init.c
-arch/i386/mm/init.c
-drivers/block/blkpg.c
-drivers/block/loop.c
-drivers/ide/ide-disk.c
-fs/ext3/Makefile
-fs/ext3/super.c
-fs/jbd/commit.c
-fs/jbd/journal.c
-fs/jbd/transaction.c
-include/linux/blkdev.h
-include/linux/slab.h
-include/linux/jbd.h
-kernel/ksyms.c
-include/linux/dcache.h
-include/linux/fs.h
-fs/dcache.c
-fs/nfsd/vfs.c
-fs/namei.c
-fs/open.c
-fs/stat.c
-mm/slab.c
diff --git a/lustre/kernel_patches/pc/vanilla-2.4.19.pc b/lustre/kernel_patches/pc/vanilla-2.4.19.pc
deleted file mode 100644 (file)
index bb5c390..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-include/linux/lustre_version.h
-arch/ia64/mm/init.c
-arch/i386/mm/init.c
-drivers/block/blkpg.c
-drivers/block/loop.c
-drivers/ide/ide-disk.c
-fs/ext3/Makefile
-fs/ext3/super.c
-include/linux/blkdev.h
-include/linux/slab.h
-kernel/ksyms.c
-include/linux/dcache.h
-include/linux/fs.h
-fs/dcache.c
-fs/nfsd/vfs.c
-fs/namei.c
-fs/open.c
-fs/stat.c
-mm/slab.c
diff --git a/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc b/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc
deleted file mode 100644 (file)
index 881576c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-fs/dcache.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/open.c
-fs/stat.c
-include/linux/dcache.h
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/vfs_intent-2.4.20-rh.pc b/lustre/kernel_patches/pc/vfs_intent-2.4.20-rh.pc
deleted file mode 100644 (file)
index 036a743..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-fs/dcache.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/open.c
-fs/stat.c
-include/linux/dcache.h
-include/linux/fs.h
-kernel/ksyms.c
-fs/exec.c
diff --git a/lustre/kernel_patches/pc/vfs_intent-2.4.20-vanilla.pc b/lustre/kernel_patches/pc/vfs_intent-2.4.20-vanilla.pc
deleted file mode 100644 (file)
index 9e57a63..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-fs/exec.c
-fs/dcache.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/open.c
-fs/stat.c
-include/linux/dcache.h
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/vfs_intent-2.4.20.pc b/lustre/kernel_patches/pc/vfs_intent-2.4.20.pc
deleted file mode 100644 (file)
index dd2b1c8..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-fs/dcache.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/open.c
-fs/stat.c
-fs/exec.c
-include/linux/dcache.h
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/vfs_intent.pc b/lustre/kernel_patches/pc/vfs_intent.pc
deleted file mode 100644 (file)
index 881576c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-fs/dcache.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/open.c
-fs/stat.c
-include/linux/dcache.h
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/vfs_intent_hp_2.4.19.pc b/lustre/kernel_patches/pc/vfs_intent_hp_2.4.19.pc
deleted file mode 100644 (file)
index 036a743..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-fs/dcache.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/open.c
-fs/stat.c
-include/linux/dcache.h
-include/linux/fs.h
-kernel/ksyms.c
-fs/exec.c
diff --git a/lustre/kernel_patches/prepare_tree.sh b/lustre/kernel_patches/prepare_tree.sh
deleted file mode 100755 (executable)
index f512132..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/bin/bash
-
-die() {
-       echo -e $* >&2
-       echo aborting.. >&2
-       exit 1
-}
-
-canon() {
-       cd $1
-       CANON=$PWD
-       cd -
-}
-
-canon $(dirname $0)
-MYDIR=$CANON
-
-while [ ${#*} -gt 1 ]; do
-        case "$1" in
-                -t)
-                        shift;
-                        TREE=$1
-                        ;;
-                -s)
-                        shift;
-                        SERIES=$1
-                        ;;
-                *)
-                       die "unknown argument $1"
-                        break;
-                        ;;
-        esac
-        shift;
-done
-
-[ -z "$TREE" -o -z "$SERIES" ] && die "I need a tree and series:\n\t$0 -t kernel_dir -s series_name"
-[ ! -d $TREE ] && die "kernel tree '$TREE' isn't a directory"
-SERIES=$(basename $SERIES)
-[ ! -f $MYDIR/series/$SERIES ] && die "no series file '$SERIES'"
-
-canon $TREE
-TREE=$CANON
-
-# patch scripts wants a relative path from the linux tree to
-# its patch pile :(
-
-MY=$(echo $MYDIR | sed -e 's_^/__')
-TR=$(echo $TREE | sed -e 's_^/__')
-
-while true ; do
-       M=$(echo $MY | cut -d/ -f 1)
-       T=$(echo $TR | cut -d/ -f 1)
-
-       if [ $M != $T ]; then
-               break;
-       fi
-
-       MY=$(echo $MY | cut -d/ -f 2-)
-       TR=$(echo $TR | cut -d/ -f 2-)
-done
-
-[ $MY == $MYDIR ] && die "bad! $MY == $MYDIR" 
-
-REVERSE=$(revpath $TR)${MY}
-ABSINO=$(stat $MYDIR | awk '($3 == "Inode:") {print $4}')
-REVINO=`(cd $TREE ; stat $REVERSE | awk '($3 == "Inode:") {print $4}')`
-
-[ $ABSINO != $REVINO ] && die "inodes differ, my reverse path is bad?"
-
-echo export PATCHSCRIPTS=$REVERSE
-
-cd $TREE
-ln -sf $REVERSE/series/$SERIES series
-
-PATH_ELEMENTS=$(echo $PATH | sed -e 's/:/ /g')
-
-NEW_PATH=$MYDIR/scripts
-
-for p in $PATH_ELEMENTS; do
-       if echo $p | grep kernel_patches/scripts > /dev/null 2>&1 ; then
-               continue;
-       fi
-       NEW_PATH="$NEW_PATH:$p"
-done
-
-echo export PATH=$NEW_PATH
-
-echo "'$TREE' successfully setup" >&2
diff --git a/lustre/kernel_patches/scripts/added-by-patch b/lustre/kernel_patches/scripts/added-by-patch
deleted file mode 100755 (executable)
index e9ccef6..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-# Extract names of new files from a patch, print them out
-
-PATCHFILE=$1
-case "$PATCHFILE" in
-*.gz) CMD="gzip -d < $PATCHFILE";;
-*)    CMD="cat $PATCHFILE";;
-esac
-
-TMP=$(mktemp /tmp/abp.XXXXXX)
-
-eval $CMD | egrep '^--- .*1969|^--- .*1970' > $TMP
-sed -e 's@[^/]*/\([^   ]*\).*@\1@' < $TMP | sed -e 's@^linux/@@' | sort
-rm -f $TMP
diff --git a/lustre/kernel_patches/scripts/apatch b/lustre/kernel_patches/scripts/apatch
deleted file mode 100755 (executable)
index 4b63598..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-
-do_apply()
-{
-       FILES=$(cat $P/pc/$PATCH_NAME.pc)
-       for file in $FILES
-       do
-               copy_file_to_bup $file $PATCH_NAME
-       done
-
-       silent=-s
-       if [ $opt_force != 0 ]
-       then
-               silent=
-       fi
-
-       if patch -p1 $silent -i "$1" || [ $opt_force != 0 ]
-       then
-               true
-       else
-               echo SOMETHING WENT WRONG
-               exit 1
-       fi
-}
-
-add_to_db()
-{
-       basename "$1" >> "$DB"
-}
-
-usage()
-{
-       echo "Usage: apatch patchname"
-       exit 1
-}
-
-opt_force=0
-PATCH_NAMES=""
-
-for i in $*
-do
-       case "$i" in
-       -f)
-               opt_force=1;;
-       *)
-               PATCH_NAMES="$PATCH_NAMES $i"
-       esac
-done
-
-if [ x"$PATCH_NAMES" == x ]
-then
-       usage
-fi
-
-apatch()
-{
-       PATCH_NAME=$(stripit $1)
-
-       need_file_there $P/pc/$PATCH_NAME.pc
-
-       if is_applied "$PATCH_NAME"
-       then
-               echo "$PATCH_NAME" is already applied
-               exit 1
-       fi
-
-       if [ $opt_force != 0 ]
-       then
-               echo FORCING PATCH
-       fi
-
-       if [ $opt_force != 0 ] || can_apply $P/patches/"$PATCH_NAME".patch
-       then
-               do_apply $P/patches/"$PATCH_NAME".patch
-               add_to_db "$PATCH_NAME"
-               echo applied $PATCH_NAME
-               echo
-       else
-               echo "$PATCH_NAME" does not apply
-               exit 1
-       fi
-}
-
-for i in $PATCH_NAMES
-do
-       if ! apatch $i
-       then
-               exit 1
-       fi
-done
-
diff --git a/lustre/kernel_patches/scripts/cat-series b/lustre/kernel_patches/scripts/cat-series
deleted file mode 100755 (executable)
index c38b1a8..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-. patchfns 2>/dev/null ||
-. /usr/lib/patch-scripts/patchfns 2>/dev/null ||
-. $PATCHSCRIPTS_LIBDIR/patchfns 2>/dev/null ||
-{
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-if [ $# -eq 0 ]
-then
-       cat_series
-else
-       __cat_series $1
-fi
diff --git a/lustre/kernel_patches/scripts/combine-applied b/lustre/kernel_patches/scripts/combine-applied
deleted file mode 100755 (executable)
index 8768b29..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-
-#
-# Make superpatch from currently applied patches using combinediff.
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: combine-applied output-file"
-       exit 1
-}
-
-if [ $# -ne 1 ] 
-then
-       usage
-fi
-
-need_file_there applied-patches
-CURRENT=$(mktemp /tmp/cmbd-XXXXXXXX)
-for FILE in `cat applied-patches`
-do
-       NEXT=$(mktemp /tmp/cmbd-XXXXXXXX)
-       if [ -f $P/patches/$FILE ] 
-       then
-               combinediff $CURRENT $P/patches/$FILE > $NEXT
-       elif [ -f $P/patches/$FILE.patch ]
-       then
-               combinediff $CURRENT $P/patches/$FILE.patch > $NEXT
-       elif [ -f $FILE ]
-       then
-               combinediff $CURRENT $FILE > $NEXT
-       fi
-       rm $CURRENT
-       CURRENT=$NEXT
-done
-
-mv $NEXT "$1"
diff --git a/lustre/kernel_patches/scripts/combine-series b/lustre/kernel_patches/scripts/combine-series
deleted file mode 100755 (executable)
index d00ba36..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-
-#
-# Make superpatch from current series using combinediff.
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: combine-series output-file"
-       exit 1
-}
-
-if [ $# -ne 1 ] 
-then
-       usage
-fi
-
-need_file_there series
-CURRENT=$(mktemp /tmp/cmbd-XXXXXXXX)
-for FILE in $(cat series)
-do
-       NEXT=$(mktemp /tmp/cmbd-XXXXXXXX)
-       if [ -f $P/patches/$FILE ] 
-       then
-               combinediff $CURRENT $P/patches/$FILE > $NEXT
-       elif [ -f $P/patches/$FILE.patch ]
-       then
-               combinediff $CURRENT $P/patches/$FILE.patch > $NEXT
-       elif [ -f $FILE ]
-       then
-               combinediff $CURRENT $FILE > $NEXT
-       fi
-       rm $CURRENT
-       CURRENT=$NEXT
-done
-
-mv $NEXT "$1"
diff --git a/lustre/kernel_patches/scripts/cvs-take-patch b/lustre/kernel_patches/scripts/cvs-take-patch
deleted file mode 100755 (executable)
index c6a6a2a..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/sh
-
-doit()
-{
-       echo $*
-       $*
-}
-
-usage()
-{
-       echo "Usage: cvs-take-patch patch_file_name"
-       exit 1
-}
-
-#
-# Find the highest level directory in $1 which does not
-# contain the directory $2.  Return it in $MISSING
-#
-highest_missing()
-{
-       START_DIR="$1"
-       NAME="$2"
-       MISSING=""
-       WHERE=$(dirname "$START_DIR")
-       PREV_WHERE=$START_DIR
-       while [ x"$WHERE" != x"$PREV_WHERE" ]
-       do
-               WHERE="$PREV_WHERE"
-               if [ ! -d "$WHERE"/"$NAME" ]
-               then
-                       MISSING="$WHERE"
-               fi
-               PREV_WHERE=$(dirname "$WHERE")
-       done
-       echo highest_missing returns $MISSING
-}
-
-#
-# Add all new directries to CVS, top-down
-# $1: name of a directory
-# $2: name of the CVS directory
-#
-add_cvs_dirs()
-{
-       MISSING=foo
-       while [ "$MISSING" != "" ]
-       do
-               highest_missing $1 $2
-               if [ x"$MISSING" != "x" ]
-               then
-                       if [ ! -d "$MISSING"/"$2" ]
-                       then
-                               doit cvs add $MISSING
-                       fi
-               fi
-       done
-}
-
-PATCHFILE=$1
-
-REMOVEDFILES=$(removed-by-patch $PATCHFILE)
-if [ "$REMOVEDFILES" != "" ]
-then
-       doit cvs remove $REMOVEDFILES
-fi
-
-NEWFILES=$(added-by-patch $PATCHFILE)
-for i in $NEWFILES
-do
-       DIRNAME=$(dirname $i)
-       echo "Looking at $DIRNAME"
-       add_cvs_dirs $DIRNAME CVS
-done
-
-if [ "$NEWFILES" != "" ]
-then
-       doit cvs add $NEWFILES
-fi
diff --git a/lustre/kernel_patches/scripts/docco.txt b/lustre/kernel_patches/scripts/docco.txt
deleted file mode 100644 (file)
index 7d4c4b6..0000000
+++ /dev/null
@@ -1,708 +0,0 @@
-Patch management scripts
-Andrew Morton <akpm@digeo.com>
-18 October 2002
-
-This is a description of a bunch of shell scripts which I use for
-managing kernel patches.  They are quite powerful.  They can be used on
-projects other than the linux kernel.  They are easy to use, and fast.
-
-You end up doing a ton of recompiling with these scripts, because
-you're pushing and popping all the time.  ccache takes away the pain of
-all that.  http://ccache.samba.org/ - be sure to put the cache
-directory on the same fs as where you're working so that ccache can use
-hardlinks.
-
-The key philosophical concept is that your primary output is patches. 
-Not ".c" files, not ".h" files.  But patches.  So patches are the
-first-class object here.
-
-Installation
-============
-
-You place all the scripts somewhere in your path, or in
-/usr/lib/patch-scripts.
-
-Terminology
-===========
-
-The patch scripts require three special directories called "pc",
-"patches" and "txt".
-
-If the environment variable PATCHSCRIPTS is set, it is taken to to be
-the directory in which those three directories reside.  Typically, it
-would be a relative pathname.  So
-
-       setenv PATCHSCRIPTS ./i-put-them-here
-
-would tell the patch scripts to look in ./i-put-them-here/pc, etc.
-
-If PATCHSCRIPTS is not set, and the directory ./patch-scripts is
-present then the patch scripts will us ./patch-scripts/pc/,
-./patch-scripts/patches/ and ./patch-scripts/txt/.
-
-Otherwise, the patch scripts use ./pc, ./patches and ./txt.
-
-In this document, the symbol $P is used to describe the directory which
-holds the pc/, patches/ and txt/ directories, as determined by the
-above search.
-
-It is expected that $P will always expand to a relative path.
-
-Concepts
-========
-
-All work occurs with a single directory tree.  All commands are invoked
-within the root of that tree.  The scripts manage a "stack" of patches.
-
-Each patch is a changeset against the base tree plus the preceding patches.
-
-All patches are listed, in order, in the file ./series.  You manage the
-series file.
-
-Any currently-applied patches are described in the file
-./applied-patches.  The patch scripts manage this file.
-
-Each patch affects a number of files in the tree.  These files are
-listed in a "patch control" file.  These .pc files live in the
-directory $P/pc/
-
-Patches are placed in the directory $P/patches/
-
-Documentation for the patches is placed in $P/txt/
-
-So for a particular patch "my-first-patch" the following will exist:
-
-- An entry "my-first-patch.patch" in ./series
-
-- An entry "my-first-patch" in ./applied-patches (if it's currently applied)
-
-- A file $P/pc/my-first-patch.pc which contains the names of the
-  files which my-first-patch modifies, adds or removes
-
-- A file $P/txt/my-first-patch.txt which contains the patch's
-  changelog.
-
-- A file $P/patches/my-first-patch.patch, which is the output of the
-  patch scripts.
-
-Operation
-=========
-
-When a patch "my-patch" is applied with apatch, or with pushpatch
-(which calls apatch), all the affected files (from $P/pc/my-patch.pc)
-are copied to files with ~my-patch appended.  So if $P/pc/my-patch.pc
-contained
-
-       kernel/sched.c
-       fs/inode.c
-
-then apatch will copy those files into kernel/sched.c~my-patch and
-fs/inode.c~my-patch.  It will then apply the patch to kernel/sched.c
-and fs/inode.c
-
-When a diff is regenerated by refpatch (which calls mpatch), the diff
-is made between kernel/sched.c and kernel/sched.c~my-patch.  How do the
-scripts know to use "~my-patch"?  Because my-patch is the current
-topmost patch.  It's the last line in ./applied-patches.
-
-In this way, the whole thing is stackable.  If you have four patches
-applied, say "patch-1", "patch-2", "patch-3" and "patch-4", and if
-patch-2 and patch-4 both touch kernel/sched.c then you will have:
-
-       kernel/sched.c~patch-2          Original copy, before patch-2
-       kernel/sched.c~patch-4          Copy before patch-4.  Contains changes
-                                       from patch-2
-       kernel/sched.c                  Current working copy.  Contains changes
-                                       from patch-4.
-
-This means that your diff headers contain "~patch-name" in them, which
-is convenient documentation.
-
-Walkthrough
-===========
-
-Let's start.
-
-Go into /usr/src/linux (or wherever)
-
-       mkdir pc patches txt
-
-Now let's generate a patch
-
-       fpatch my-patch kernel/sched.c
-
-OK, we've copied kernel/sched.c to kernel/sched.c~my-patch.  We've
-appended "my-patch" to ./applied-patches and we've put "kernel/sched.c"
-into the patch control file, pc/my-patch.pc.
-
-       Now edit kernel/sched.c a bit.
-
-Now we're ready to document the patch
-
-       Now write txt/my-patch.txt
-
-Now generate the patch
-
-       refpatch
-
-This will generate patches/my-patch.patch.  Take a look.
-
-Now remove the patch
-
-       poppatch
-
-applied-patches is now empty, and the patch is removed.
-
-Now let's add a file to my-patch and then generate my-second-patch:
-
-       Add "my-patch.patch" to ./series (no blank lines in that file please)
-
-       pushpatch
-
-OK, the patch is applied again.  Let's add another file
-
-       fpatch kernel/printk.c
-
-Note that here we gave fpatch a single argument.  So rather than
-opening a new patch, it adds kernel/printk.c to the existing topmost
-patch.  That's my-patch.
-
-       Edit kernel/printk.c
-
-Refresh my-patch (you end up running refpatch a lot)
-
-       refpatch
-
-Now start a second patch:
-
-       fpatch my-second-patch kernel/sched.c
-
-Now take a look at applied-patches.  Also do an `ls kernel/sched*'.
-
-       Edit kernel/sched.c, to make some changes for my-second-patch
-
-Generate my-second-patch:
-
-       refpatch
-
-Take a look in patches/my-second-patch.patch
-
-Don't forget to add "my-second-patch.patch" to the series file.
-
-And remove both patches:
-
-       poppatch
-       poppatch
-
-
-That's pretty much it, really.
-
-
-Command reference
-=================
-
-Generally, where any of these commands take a "patch-name", that can be
-of the form txt/patch-name.txt, patch-name.pc, just patch-name or
-whatever.  The scripts will strip off a leading "txt/", "patches/" or
-"pc/" and any trailing extension.  This is so you can do
-
-       apatch patches/a<tab>
-
-to conveniently use shell tabbing to select patch names.
-
-
-
-added-by-patch
-
-  Some internal thing.
-
-apatch [-f] patch-name
-
-  This is the low-level function which adds patches.  It does the
-  copying into ~-files and updates the applied-patches file.  It
-  applies the actual patch.
-
-  apatch will do a patch --dry-run first and will refuse to apply the
-  patch if the dryrun fails.
-
-  So when you are getting rejects you do this:
-
-       pushpatch               # This fails, due to rejects.  Drat.
-       apatch -f patch-name    # Force the patch
-  (or)  pushpatch -f           # Force the patch
-
-  OK, you've now applied patch-name, but you have rejects.  Go fix
-  those up and do
-
-       refpatch
-
-  And you're ready to move on.
-
-combine-series output-file
-
-  It incrementally combinediffs all the patches in series to make a
-  complete patch for the series.  Requires combinediff frmo patchutils.
-
-  See http://cyberelk.net/tim/patchutils/ (Don't download the
-  "experimental" patchutils - it seems to only have half of the
-  commands in it.  Go for "stable")
-
-cvs-take-patch
-
-  I forget.
-
-export_patch
-
-  export the patches listed in ./series to a set of files which
-  are named in such a way that the sort order is the same as the
-  order of the series file. 
-
-  Usage:  export_patch directory [prefix]
-
-  Example:
-       
-       Suppose ./series contains
-       
-       mango.patch
-       orange.patch
-       banana.patch
-       apple.patch
-       pear.patch
-
-       export_patch ../mypatches fruit 
-       
-       The patches would be copied to
-
-       ../mypatches/p00001_fruit_mango.patch
-       ../mypatches/p00002_fruit_orange.patch
-       ../mypatches/p00003_fruit_banana.patch
-       ../mypatches/p00003_fruit_banana.patch
-       ../mypatches/p00003_fruit_banana.patch
-
-       Named in this way, someone may easily apply them:
-
-       cat mypatches/p*fruit* | patch -p1
-
-       If prefix is omitted, the patchnames will be transformed
-       such that "original.patch" becomes "pXXXXX_original.patch".
-
-fpatch [patch-name] foo.c
-
-  If patch-name is given, fpatch will start a new patch which
-  modifies (or adds, or removes) the single file foo.c.  It updates
-  ./applied-patches and creates pc/patch-name.pc.  fpatch will copy
-  foo.c to foo.c~patch-name in preparation for edits of foo.c.
-
-  If patch-name is not given then fpatch will add foo.c to the
-  current topmost patch.  It will add "foo.c" to $P/pc/$(toppatch).pc. 
-  It will copy foo.c to foo.c~$(toppatch).
-
-import_patch
-
-  Imports a set of patch files, creating $P/pc, $P/txt, $P/patches and
-  ./series as necessary.  It also creates $P/txt/*.txt by stripping 
-  off the top of the patches (and removes any diffstat output it finds, 
-  so that it can eat refpatch output and export_patch output.)  The 
-  imported patch names are appended to the series file.
-
-  In creating the $P/txt/*.txt files, mail headers are stripped with 
-  formail, preserving the "From:" and "Subject:" lines.  "DESC" and
-  "EDESC" markers are added if they are not already present, using the
-  "From:" and "Subject:" lines for the DESC portion, if they are present.
-  (See "patchdesc" command, below, for more on these markers.)
-
-  Also, it can rename the patch file as it is imported by stripping out
-  a pattern.  This is useful if, as often is the case, you have patch 
-  sets with filenames designed to help sort the patches into the correct 
-  order, such as "p001_xxx_funky_stuff.patch" you can have it automatically
-  renamed to funky_stuff.patch on import, and let the series file manage
-  the ordering.
-
-  Import_patch will uncompress patches (*.Z, *.bz2, *.gz) as necessary.
-
-  Usage:
-
-  import_patch [-p pattern] patchfile ...
-
-  Example:
-
-       % ls ../fruit/p*patch
-       ../fruit/p00001_northern_apple.patch
-       ../fruit/p00001_tropical_mango.patch
-       ../fruit/p00002_northern_pear.patch
-       ../fruit/p00002_tropical_orange.patch
-       ../fruit/p00003_tropical_banana.patch
-       % import_patch -p 'p[0-9]*_tropical_' ../fruit/p*tropical*
-       Recreated pc/mango.pc
-       Recreated pc/orange.pc
-       Recreated pc/banana.pc
-       % import_patch -p 'p[0-9]*_northern_' ../fruit/p*northern*
-       Recreated pc/apple.pc
-       Recreated pc/pear.pc
-
-  Then you can "pushpatch; refpatch" 5 times.
-
-inpatch
-
-  List the names of ths files which are affected by the current
-  topmost patch.
-
-  This is basically
-
-       cat pc/$(toppatch).pc
-
-mpatch
-
-  A low-level thing to generate patches
-
-new-kernel
-
-  Some thing I use for importing a new kernel from kernel.org
-
-p0-2-p1
-
-  Internal thing to convert patch -p0 form into patch -p1
-
-patchdesc
-
-  Generates a single-line description of a patch.
-
-  The txt/my-patch.txt files have the following format:
-
-  <start of file>
-  DESC
-  some short description
-  EDESC
-
-  The long description
-  <end of file>
-
-  I use
-
-       patchdesc $(cat series)
-
-  to generate short-form summaries of the patch series.
-
-patchfns
-
-  Internal utilities
-
-pcpatch
-
-  Standalone tool to generate a .pc file from a patch.
-
-  Say someone sends you "his-patch.diff".  What you do is:
-
-       cp ~/his-patch.diff patches/his-patch.patch
-       pcpatch his-patch
-
-  This generates $P/pc/his-patch.pc and you're all set.  Add
-  "his-patch.patch" to ./series in the right place and start pushing.
-
-p_diff
-
-  I forget
-
-poppatch
-
-  Remove one or more patches from the current stack.  This command
-  does *not* use the series file.  It works purely against
-  applied-patches.
-
-  Usage:
-
-       poppatch
-               Remove the topmost patch
-       poppatch 10
-               Remove ten patches
-       poppatch some-patch-name[.patch]
-               Remove patches until "some-patch-name" is top patch
-
-pstatus
-
-       Shows status of patches
-
-  Usage:
-       pstatus [patchfile ...]
-       
-       One line per patch is output showing:
-       1: Patch number in the series file
-       2: Whether the patch is currently applied
-       3: Name of patch
-       4: Status of the patch (needs pcpatch, changelog, refpatch)
-
-       If no patchfiles are specified, $P/patches/*.patch
-       are assumed.
-
-  Caveats:
-       A patch set which contains separate patches to add a file
-       and modify that same file may give spurious "Needs refpatch"
-       status for the patch which adds the file or the topmost patch.
-
-ptkdiff
-
-  Two modes:
-
-       ptkdiff -
-
-               Run tkdiff against all the file affected
-               by $(toppatch).  The diff is only for the changes made
-               by the top patch! ie: it's between "filename" and
-               "filename~toppatch-name".
-
-       ptkdiff filename
-
-               Just run tkdiff against that file,
-               showing the changes which are due to toppatch.
-
-pushpatch [-f]
-
-  Apply the next patch, from the series file.
-
-  This consults ./applied-patches to find out the top patch, then
-  consults ./series to find the next patch.  And pushes it.
-
-    pushpatch
-
-      Apply the next patch
-
-    pushpatch 10
-      Apply the next ten patches
-
-    pushpatch some-patch-name
-
-      Keep pushing patches until "some-patch-name" is toppatch
-
-    pushpatch -f
-
-      Push the next patch, ignoring rejects.
-
-refpatch
-
-    regnerates the topmost patch.  Reads all the affected files
-    from pc/$(toppatch).pc and diffs them against their tilde-files.
-
-    Also pastes into the patch your patch documentation and
-    generates a diffstat summary.
-
-removed-by-patch
-
-  Some thing.
-
-rename-patch
-
-  CVS rename for patches.
-
-rolled-up-patch
-
-  Bit of a hack.  Is designed to generate a rolled-up diff of all
-  currently-applied patches.  But it requires a ../linux-2.x.y tree to
-  diff against.  Needs to be redone.
-
-rpatch
-
-  Internal command
-
-split-patch
-
-  Some thing someone write to split patches up.  I don't use it.
-
-tag-series
-
-  Assuming you keep pc/*, patches/* and txt/* under CVS revision
-  control, tag-series allows you to tag a patchset's individual
-  components.  I use
-
-       tag-series s2_5_44-mm3 pc/2.5.44-mm3-series
-
-  which will attach the cvs tag "s2_5_44-mm3" to every .pc, .patch
-  and .txt file which is mentioned in the series file
-  "pc/2.5.44-mm3-series".
-
-  It will also tag pc/2.5.44-mm3-series, which is a bit redundant
-  given that I use a different series file for each patchset release..
-
-
-toppatch
-
-  Print the name of the topmost patch.  From ./applied-patches
-
-touched-by-patch patch-filename
-
-  List the names of files which are affected by a diff.
-
-unitdiff.py
-
-  Rasmus Andersen's script to convert a diff into minimum-context
-  form.  This form has a better chance of applying if you're getting
-  nasty rejects.  But patch can and will make mistakes when fed
-  small-context input.
-
-
-Work Practices
-==============
-
-I keep the kernel tree, the $P/pc/, $P/patches/ and $P/txt/ contents under
-CVS control.  This is important...
-
-I have several "series" files.  I keep these in $P/pc/foo-series and use
-
-       ln -s pc/foo-series series
-
-when I'm working on foo.
-
-If someone sends me a patch I'll do:
-
-       cp ~/whatever patches/his-patch.patch
-       pcpatch his-patch
-       apatch his-patch
-
-  If apatch fails then run `apatch -f his-patch' and fix the rejects.
-
-       refpatch
-
-  to clean up any fuzz.
-
-       poppatch
-       cvs add pc/his-patch.pc patches/his-patch.patch
-       cvs commit pc patches
-
-  Now edit ./series and place "his-patch.patch" in the appropriate place.
-
-
-If you're working on a particular patch (say, "dud-patch") and you
-balls something up, just run:
-
-       refpatch        # Generate the crap patch
-       poppatch        # Remove it all
-       rm patches/dud-patch.patch
-       cvs up patches/dud-patch.patch
-
-and all is well.
-
-
-Getting updates from Linus
-==========================
-
-What I do is to grab the latest -bk diff from
-http://www.kernel.org/pub/linux/kernel/people/dwmw2/bk-2.5/
-and do:
-
-       gzip -d < cs<tab> > patches/linus.patch
-       pcpatch linus
-       apatch linus | grep diff
-
-               Now fix up all the files which got deleted,
-               because there's something wrong with bitkeeper diffs:
-
-       cvs up -ko <missing files from the above diff>
-
-       apatch linus
-       $EDITOR linus/linus.txt
-       
-               Add the changeset number to txt/linus.txt
-
-       refpatch
-       poppatch
-
-  Now add "linus.patch" as the first entry in your ./series file and
-  start pushing your other patches on top of that.
-
-BUGS
-====
-
-Tons and tons.  The scripts are fragile, the error handling is ungraceful and
-if you do something silly you can end up in a pickle.
-
-Generally the scripts are very careful to not wreck your files or your
-patches.  But they can get the ./applied-patches and ~-files into an
-awkward state.
-
-Usually you can sort it out by copying the ~-files back onto the originals
-and removing the last line from ./applied-patches.  Or do a "refpatch ;
-poppatch ; rm patches/troublesome-patch.patch ; cvs up patches".
-
-If it's really bad, just blow away the entire tree and do a new CVS checkout.
-
-
-Working on non-kernel projects
-==============================
-
-Well it's the same thing.  Say you've downloaded a copy of util-linux
-and you want to make a change:
-
-       cd /usr/src
-       tar xvfz ~/util-linux.tar.gz
-       cd util-linux
-       mkdir pc patches txt
-       fpatch my-patch sys-utils/rdev.c
-       fpatch sys-utils/ipcs.8
-       <edit, edit>
-       refpatch
-       <ship patches/my-patch.patch>
-
-How to balls things up
-======================
-
-Well here's one way.  Suppose you have 20 patches applied, and three of
-them (say, "p1", "p6" and "p11") all modify "foo.c".
-
-Now you go and change foo.c.
-
-Well, to which patch does that change belong?  You need to decide. 
-Let's say you decide "p6".
-
-If you run `refpatch' when "p11" is toppatch then you lose.  The diff
-went into p11.
-
-What you can do is:
-
-1:
-       poppatch p6
-       <edit>
-       refpatch
-       pushpatch p11
-       <test>
-
-  (See why ccache is looking good?)
-
-or
-
-2:
-       <edit>
-       <test>
-       poppatch p6     <hope like hell that the other patches remove cleanly>
-       refpatch
-
-
-Another good way of ballsing up is to cheat.  Say "oh I just want to make
-this one-line change".  And "oh, and this one".
-
-Now you're getting in a mess.  It's much, much better to just use the system:
-
-       fpatch junk file1
-       fpatch file2
-       <edit>
-       <play>
-       refpatch
-       poppatch
-       rm pc/junk.pc patches/junk.patch
-
-Merging with -mm kernels
-========================
-
-Haven't tried this, but it should work:
-
-- Grab all the patches from broken-out/, place them in your $P/patches/
-
-- Copy my series file into ./series (or $P/pc/akpm-series and symlink it)
-
-- pushpatch 99
-
-And you're off and running.  The nice thing about this is that you can
-send me incremental diffs to diffs which I already have.
-
-Or whatever.  I'm fairly handy with diffs nowadays.  Rejects are
-expected.  I just prefer to have "one concept per diff".
-
diff --git a/lustre/kernel_patches/scripts/export_patch b/lustre/kernel_patches/scripts/export_patch
deleted file mode 100755 (executable)
index d378417..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "export_patch: export the patches listed in ./series" 1>&2
-       echo "usage: export_patch destination-directory [prefix] " 1>&2
-       exit 1
-}
-
-DIR="$1"
-PREFIX="$2""_"
-
-if [ "$DIR" = "" ]
-then
-       usage
-fi
-
-if [ -e "$DIR" -a ! -d "$DIR" ]
-then
-       echo "$DIR exists already, but is not a directory." 1>&2
-       exit 1
-fi
-
-if [ ! -r ./series ]
-then
-       echo "./series is not readable." 1>&2
-       exit 1
-fi
-
-mkdir -p "$DIR" || exit 1
-
-count=1
-for x in `cat ./series`
-do
-       fname=`echo "$count" "$PREFIX" "$x" |\
-                awk '{ if ( $2 != "_" )
-                               printf("p%05d_%s%s\n", $1, $2, $3); 
-                       else
-                               printf("p%05d_%s\n", $1, $3); 
-               }'`
-       if [ ! -r $P/patches/"$x" ]
-       then
-               echo "$P/patches/"$x" is not readable. skipping." 1>&2
-               continue;
-       fi
-       cp -f $P/patches/"$x" "$DIR"/"$fname" || continue; 
-       count=`expr $count + 1`
-done
-
diff --git a/lustre/kernel_patches/scripts/extract_description b/lustre/kernel_patches/scripts/extract_description
deleted file mode 100755 (executable)
index 6fa0e68..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/bin/sh
-
-insert_line()
-{
-       PATTERN="$1"
-       LINE="$2"
-       FILE="$3"
-       awk ' BEGIN { found=0; }
-               /'"$PATTERN"'/ { 
-                       print; 
-                       if (!found)
-                               printf("%s\n", "'$LINE'"); 
-                       found=1; 
-                       next;
-               }
-               { print; }
-       ' < "$FILE"
-}
-
-# extract the description from the top of a patch
-# filter stdin
-# collapse adjacent blank lines to a single blank line
-# remove any lines that look like diffstat output
-# stop output on encountering a line beginning with '---' (beginning of patch)
-
-       TMPFILE=`mktemp /tmp/xdtmp.XXXXXX` || exit 1
-       formail -kfcb -X 'From:' -X 'Subject:' |\
-       awk '
-               BEGIN { found_end=0; lastone="x"; }
-               /^ .* [|] +[0-9]+ [+-]+$/ { 
-                       #/* we found something like diffstat output... */
-                       if (found_end == 1) {
-                               /* we are past end of diffstat, let it pass */
-                               print;
-                       }
-                       next;
-               }
-               /^ [1-9][0-9]* files changed/ {
-                       #/* end of diffstat output, stop filtering diffstat */
-                       found_end=1;
-                       next;
-               }
-               /^--- / { exit; }
-               {
-                       #/* collapse adjacent blank lines to 1 blank line */ 
-                       if ( $0 == "" && lastone == "" )
-                               next;
-                       else 
-                               print; 
-                       lastone=$0;
-               }
-       ' | awk '{ if ($0 == "" && FNR == 1)  next; print; }' > "$TMPFILE"
-
-       descs=`head -10 $TMPFILE | grep -c '^[  ]*DESC[         ]*$'`
-       if [ "$descs" = "0" ]
-       then
-               # DESC is not 1st non blank line in the file
-               echo "DESC"
-               descs=0
-       fi
-       edescs=`grep -c '^EDESC$' "$TMPFILE"`
-       subjects=`grep -c '^[   ]*Subject[:]' "$TMPFILE"`
-       froms=`grep -c '^[      ]*From[:]' "$TMPFILE"`
-       if [ "$edescs" = "0" ]
-       then
-               if [ "$subjects" != "0" ]
-               then
-                       insert_line '^Subject[:]' 'EDESC' "$TMPFILE"
-               else
-                       if [ "$froms" != "0" ]
-                       then
-                               insert_line '^From[:]' 'EDESC' "$TMPFILE"
-                       else
-                               if [ "$descs" = "0" ]
-                               then
-                                       # blank DESC line...
-                                       echo '(undescribed patch)'
-                                       echo EDESC
-                                       cat "$TMPFILE"
-                               else
-                                       insert_line '^DESC$' "EDESC" "$TMPFILE"
-                               fi
-                       fi
-               fi
-       else
-               cat $TMPFILE
-       fi
diff --git a/lustre/kernel_patches/scripts/forkpatch b/lustre/kernel_patches/scripts/forkpatch
deleted file mode 100755 (executable)
index cef297c..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/sh
-
-#
-# Fork the next patch in the series
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: forkpatch <newname>"
-       exit 1
-}
-
-if [ $# -ne 1 ]
-then
-       usage
-fi
-
-NEW=$1
-BASE=`stripit $NEW`
-SERIES=series
-
-if [ ! -e $SERIES ]
-then
-       echo 'File "series" not found'
-       exit 1
-fi
-
-if [ -f $P/$BASE.patch ] ; then 
-        echo "Patch $NEW already exists as a file"
-        exit 1
-fi
-
-if  grep $BASE $SERIES >& /dev/null ; then 
-        echo "Patch $NEW already exists in series"
-        exit 1
-fi
-
-TMPSERIES=$(mktemp /tmp/series-XXXXXXXX)
-top=$(toppatch)
-if [ x"$top" == x ]
-then
-       todo=$(head -1 $SERIES)
-else
-       last_in_series=$(stripit $(tail -1 $SERIES))
-       if [ $last_in_series == $top ]
-       then
-               echo "Series fully applied.  Ends at $top"
-               exit 0
-       fi
-       todo=$(grep -C1 "^$top\.patch" $SERIES | tail -1)
-       if [ x$todo = x ]
-       then
-               todo=$(head -1 $SERIES)
-       fi
-fi
-
-basetodo=`stripit $todo`
-
-sed "s/$todo/$BASE.patch/" < $SERIES > $TMPSERIES
-cat $TMPSERIES > $SERIES
-rm -f $TMPSERIES
-cp -f $P/patches/$todo $P/patches/$BASE.patch
-cp -f $P/pc/$basetodo.pc $P/pc/$BASE.pc
-if [ -f $P/txt/$basetodo.txt ]; then 
-     cp -f $P/txt/$basetodo.txt $P/txt/$BASE.txt
-else 
-     echo "Warning no documentation for $BASE"
-fi
-
-echo "Cloned $todo to $BASE"
diff --git a/lustre/kernel_patches/scripts/fpatch b/lustre/kernel_patches/scripts/fpatch
deleted file mode 100755 (executable)
index 0cafa65..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/sh
-
-#
-# Add a file to a patch.
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: fpatch patchname filename"
-       echo "       fpatch filename"
-       exit 1
-}
-
-if [ $# == 1 ]
-then
-       PATCH_NAME=$(top_patch)
-       FILENAME=$1
-elif [ $# == 2 ]
-then
-       PATCH_NAME=$(stripit $1)
-       FILENAME=$2
-else
-       usage
-fi
-
-
-if is_applied_last $PATCH_NAME
-then
-       true
-else
-       if is_applied $PATCH_NAME
-       then
-               echo $PATCH_NAME is not the last-applied patch
-               exit 1
-       else
-               echo $PATCH_NAME >> $DB
-       fi
-fi
-
-if file_in_patch $FILENAME $PATCH_NAME
-then
-       echo File $FILENAME is already in patch $PATCH_NAME
-       exit 1
-fi
-
-install_file_in_patch $FILENAME $PATCH_NAME
-
diff --git a/lustre/kernel_patches/scripts/import_patch b/lustre/kernel_patches/scripts/import_patch
deleted file mode 100755 (executable)
index f818f19..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "usage: import_patch [ -p prefix-pattern ] patchfile [...]" 1>&2
-       exit 1
-}
-
-XPATTERN=""
-if [ "$1" = "-p" ]
-then
-       XPATTERN="$2"
-       shift; 
-       shift;
-fi
-
-if [ "$1" = "" ]
-then
-       usage
-fi
-
-if [ ! -e applied-patches ]
-then
-       touch applied-patches
-fi
-
-mkdir -p patches || exit 1
-mkdir -p txt || exit 1
-mkdir -p pc || exit 1
-
-if [ ! -e ./series ]
-then
-       touch ./series
-       if [ "$?" != "0" ]
-       then
-               echo "Cannot create ./series" 1>&2
-               exit 1
-       fi
-fi
-
-if [ ! -w ./series ]
-then
-       echo "./series is not writable." 1>&2
-       exit 1
-fi
-
-PATTERN='s/^'"$XPATTERN"'//'
-for x in $* 
-do
-       if [ ! -r "$x" ]
-       then
-               echo "$x does not exist, skipping." 1>&2
-               continue
-       fi
-       patchname=`basename $x .bz2`
-       patchname=`basename $patchname .gz`
-       patchname=`basename $patchname .Z`
-       patchname=`basename $patchname .patch`
-       if is_applied $patchname
-       then
-               echo $patchname is currently applied
-               exit 1
-       fi
-       if [ "$XPATTERN" != "" ]
-       then
-               patchname=`echo $patchname | sed -e "$PATTERN"`
-       fi
-       pname=$P/patches/"$patchname".patch
-       if [ -r "$pname" ]
-       then
-               echo "$pname exists already, skipping." 1>&2
-               continue
-       fi
-       case "$x" in
-       *.bz2) 
-               bunzip2 < "$x" > "$pname"
-               ;;
-       *.gz)
-               gunzip < "$x" > "$pname"
-               ;;
-       *.Z)    zcat < "$z" > "$pname"
-               ;;
-       *)      
-               cat "$x" > "$pname" || continue 
-               ;;
-       esac
-       echo "$patchname".patch >> series
-       pcpatch "$pname"
-       extract_description < "$pname" >$P/txt/"$patchname".txt
-       grep '^[(]undescribed patch[)]$' < $P/txt/"$patchname".txt > /dev/null
-       if [ "$?" = "0" ]
-       then
-               echo "Warning: $patchname has no description." 1>&2
-       fi
-done
-
diff --git a/lustre/kernel_patches/scripts/inpatch b/lustre/kernel_patches/scripts/inpatch
deleted file mode 100755 (executable)
index edb2c20..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: inpatch"
-       exit 1
-}
-
-if [ $# != 0 ]
-then
-       usage
-fi
-
-if [ -e $DB ]
-then
-       TOP_PATCH=$(top_patch)
-       if [ x$TOP_PATCH != x ]
-       then
-               cat $P/pc/$TOP_PATCH.pc
-       fi
-fi
diff --git a/lustre/kernel_patches/scripts/join-patch b/lustre/kernel_patches/scripts/join-patch
deleted file mode 100755 (executable)
index 065ea73..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-usage()
-{
-       echo "Usage: join-patch patchname"
-       exit 1
-}
-
-if [ $# -ne 1 ]
-then
-       usage
-fi
-
-PATCHNAME=$(stripit $1)
-
-if ! can_apply $PATCHNAME
-then
-       echo Patch $PATCHNAME does not apply
-       exit 1
-fi
-
-pcpatch $PATCHNAME
-for i in $(cat $P/pc/$PATCHNAME.pc)
-do
-       fpatch $i
-done
-
-patch -p1 -i "$P/patches/$PATCHNAME.patch" -f
diff --git a/lustre/kernel_patches/scripts/linus-patch b/lustre/kernel_patches/scripts/linus-patch
deleted file mode 100755 (executable)
index 290b9cf..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-#
-# Grab a patch frmo kernel.org, install it.
-#
-# Usage: linus-patch http://www.kernel.org/pub/linux/kernel/people/dwmw2/bk-2.5/cset-1.786.152.7-to-1.798.txt.gz
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-poppatch 999 || die poppatch
-wget $1 || die wget
-FILE=$(basename $1)
-gzip -d < $FILE > $P/patches/linus.patch
-pcpatch linus || die pcpatch
-(
-       echo DESC
-       echo $FILE
-       echo EDESC
-       echo
-       echo $FILE
-) > $P/txt/linus.txt
-rm $FILE
diff --git a/lustre/kernel_patches/scripts/mpatch b/lustre/kernel_patches/scripts/mpatch
deleted file mode 100755 (executable)
index 16d4eb7..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: mpatch patchname [output_dir]"
-       exit 1
-}
-
-doit()
-{
-       echo $* 1>&2
-       $* || {
-               echo oops
-               exit 1 
-       }
-}
-
-epoch()
-{
-#      doit touch -t 7001011000.00 $1
-       doit touch -t 7001010000.00 $1
-}
-
-dirfor()
-{
-       dir=$(dirname $1)
-       if [ ! -d $dir ]
-       then
-               doit mkdir -p $dir
-               RMDIRS="$RMDIRS $dir"
-       fi
-}
-
-if [ $# == 0 ]
-then
-       usage
-fi
-
-PATCH_NAME=$(stripit $1)
-OUTPUT_DIR=$2
-
-FILES=$(cat $P/pc/$PATCH_NAME.pc)
-OUT=$P/patches/$PATCH_NAME.patch
-TMPOUT=$(mktemp /tmp/patch-$PATCH_NAME-XXXXXX)
-TXT=$P/txt/$PATCH_NAME.txt
-OLDDIR=$(basename $(/bin/pwd))
-NEWDIR=$OLDDIR-$LOGNAME
-
-if is_applied_last $PATCH_NAME
-then
-       true
-else
-       echo $PATCH_NAME is not the last-applied patch
-       exit 1
-fi
-
-doit rm -f $OUT
-echo "Placing patch in " $OUT
-
-if [ -e $TXT -a -s $TXT ]
-then
-       echo >> $OUT
-       body $TXT >> $OUT
-       echo >> $OUT
-       echo >> $OUT
-else
-       echo "**** No patch description for $PATCH_NAME ****"
-fi
-
-rm -f $TMPOUT
-
-for file in $FILES
-do
-       OLD_FILE="$file"~"$PATCH_NAME"
-       if [ ! -e $OLD_FILE ]
-       then
-               OLD_FILE=/dev/null
-       fi
-       NEW_FILE=$file
-       XDIFF_OPTS=""
-       if [ ! -e $NEW_FILE ]
-       then
-               NEW_FILE=/dev/null
-               XDIFF_OPTS="-L $file"
-       fi
-
-       echo diff -puN $XDIFF_OPTS $DIFF_OPTS $OLD_FILE $NEW_FILE
-       diff -puN $XDIFF_OPTS $DIFF_OPTS $OLD_FILE $NEW_FILE | p0-2-p1 $OLDDIR $NEWDIR >> $TMPOUT
-done
-diffstat -p1 $TMPOUT >> $OUT 2>/dev/null
-echo >> $OUT
-cat $TMPOUT >> $OUT
-echo >> $OUT
-echo "_" >> $OUT
-rm -f $TMPOUT
diff --git a/lustre/kernel_patches/scripts/new-kernel b/lustre/kernel_patches/scripts/new-kernel
deleted file mode 100755 (executable)
index 2b065a6..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/bin/sh
-
-usage()
-{
-       echo "Usage: new-kernel linux-2.4.2-pre2 linux-2.4.3-pre3 linux-2.4.3 patch.gz cvs-dir"
-       exit 1
-}
-
-wantdir()
-{
-       if [ x$1 = x ]
-       then
-               usage
-       fi
-       if [ ! -d $1 ]
-       then
-               echo "directory $1 does not exist"
-               usage
-       fi
-}
-
-wantfile()
-{
-       if [ x$1 = x ]
-       then
-               usage
-       fi
-       if [ ! -f $1 ]
-       then
-               echo "file $1 does not exist"
-               usage
-       fi
-}
-
-doit()
-{
-       echo $* 1>&2
-       $* || {
-               echo oops
-               exit 1 
-       }
-}
-
-
-CURRENT_KERNEL=$1
-NEXT_KERNEL=$2
-BASE_KERNEL=$3
-PATCH_FILE=$4
-CVS_DIR=$5
-
-TEMP_PATCH=$(mktemp /tmp/patch-XXXXXX)
-MY_DIFF="$CURRENT_KERNEL"--"$NEXT_KERNEL"
-
-wantdir $CURRENT_KERNEL
-wantdir $BASE_KERNEL
-wantdir $CVS_DIR
-wantfile $PATCH_FILE
-
-doit rm -rf $NEXT_KERNEL
-doit cp -a $BASE_KERNEL $NEXT_KERNEL
-doit rm -f $TEMP_PATCH
-doit gunzip < $PATCH_FILE > $TEMP_PATCH
-cd $NEXT_KERNEL
-doit patch -p1 --dry-run -i $TEMP_PATCH
-doit patch -p1 -s -i $TEMP_PATCH
-echo cd ..
-cd ..
-
-echo diff -uNrp $CURRENT_KERNEL $NEXT_KERNEL
-diff -uNrp $CURRENT_KERNEL $NEXT_KERNEL > $MY_DIFF
-
-echo cd $CVS_DIR
-cd $CVS_DIR
-doit patch -p1 --dry-run -s -i ../$MY_DIFF
-doit patch -p1 -s -i ../$MY_DIFF
-cvs-take-patch ../$MY_DIFF
-cvs commit -m "'doing $NEXT_KERNEL'"
-cvs update -ko -d -P
-
-TAG=$(echo $NEXT_KERNEL | sed -e 's@\.@_@g')
-cvs tag $TAG
-rm -f $TEMP_PATCH
diff --git a/lustre/kernel_patches/scripts/p0-2-p1 b/lustre/kernel_patches/scripts/p0-2-p1
deleted file mode 100755 (executable)
index 266c698..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-#
-# Usage: p0-2-p1 olddir newdir
-#
-OLDDIR=$1
-NEWDIR=$2
-
-sed -e "s/^--- \([^\/].*\)/--- $OLDDIR\/\1/" |
-sed -e "s/^+++ \([^\/].*\)/+++ $NEWDIR\/\1/"
-
diff --git a/lustre/kernel_patches/scripts/p_diff b/lustre/kernel_patches/scripts/p_diff
deleted file mode 100755 (executable)
index 1ad3e09..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-
-#
-# Bring up a patched file in diff.  We show the diffs
-# in the topmost patch, unless it was specified
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: pdiff [patchname] filename"
-       echo "       pdiff [patchname] -"
-       exit 1
-}
-
-if [ $# == 1 ]
-then
-       PATCH_NAME=$(top_patch)
-       FILENAME=$1
-elif [ $# == 2 ]
-then
-       PATCH_NAME=$(stripit $1)
-       FILENAME=$2
-else
-       usage
-fi
-
-if ! is_applied $PATCH_NAME
-then
-       echo $PATCH_NAME is not applied
-       exit 1
-fi
-
-doit()
-{
-       filename=$1
-       unpatched_file=$filename"~"$PATCH_NAME
-       need_file_there $filename
-       if [ -e $unpatched_file ]
-       then
-               diff -u $unpatched_file $filename
-       else
-               echo pdiff: $filename appears to not be in $PATCH_NAME
-       fi
-}
-
-if [ x"$FILENAME" = "x-" ]
-then
-       FILENAME=$(cat $P/pc/$PATCH_NAME.pc)
-fi
-
-for i in $FILENAME
-do
-       doit $i
-done
diff --git a/lustre/kernel_patches/scripts/patchdesc b/lustre/kernel_patches/scripts/patchdesc
deleted file mode 100755 (executable)
index 9a886fd..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-desc1()
-{
-       PATCH=$(stripit $1)
-       TXT=$P/txt/$PATCH.txt
-       echo $PATCH.patch
-       desc < $TXT
-       echo
-}
-
-for i in $*
-do
-       desc1 $i
-done
diff --git a/lustre/kernel_patches/scripts/patchfns b/lustre/kernel_patches/scripts/patchfns
deleted file mode 100644 (file)
index b6cc468..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-DB=applied-patches
-
-#
-# Work out where the user's pc/, patch/ and txt/ directories live.
-#
-# If the user specified PATCHSCRIPTS in environment then use that (it's
-# probably a relative path)
-#
-# If there is a directory ./patch-scripts then use that
-#
-# Otherwise use "."
-#
-
-if [ x$PATCHSCRIPTS != x ]
-then
-       P=$PATCHSCRIPTS
-elif [ -d ./patch-scripts ]
-then
-       P=./patch-scripts
-elif [ -d ./patches ]
-then
-       P=.
-else
-       echo "could not locate your pc/ and patches/ directories"
-       exit 1
-fi
-
-top_patch()
-{
-       tail -1 $DB
-}
-
-die()
-{
-       echo error: $*
-       exit 1
-}
-
-is_numeric()
-{
-       if echo $1 | egrep '^[0-9]*$' > /dev/null
-       then
-               return 0
-       fi
-       return 1
-}
-
-is_applied_last()
-{
-       name="$(stripit $1)"
-       top_patch >$DB.1
-       if grep "^$name$" "$DB.1" > /dev/null 2>&1
-       then
-               rm $DB.1
-               return 0
-       else
-               rm $DB.1
-               return 1
-       fi
-}
-
-is_applied()
-{
-       name=$(stripit "$1")
-       if grep "^$name$" "$DB" > /dev/null 2>&1
-       then
-               return 0
-       else
-               return 1
-       fi
-}
-
-can_apply()
-{
-       if patch -p1 --dry-run -i "$1" -f
-       then
-               return 0
-       else
-               return 1
-       fi
-}
-
-can_remove()
-{
-       if patch -R -p1 --dry-run -i $P/patches/"$1".patch -f
-       then
-               return 0
-       else
-               return 1
-       fi
-}
-
-remove_from_db()
-{
-       tmpfile=$(mktemp /tmp/p_XXXXXX)
-       name="$1"
-       sed -e "/^$name$/d" < "$DB" > $tmpfile
-       mv $tmpfile "$DB"
-}
-
-stripit()
-{
-       ret=$(basename $1)
-       ret=$(echo $ret | sed -e 's/\.patch$//')
-       ret=$(echo $ret | sed -e 's/\.pc$//')
-       ret=$(echo $ret | sed -e 's/\.txt$//')
-       echo $ret
-}
-
-top_is_current()
-{
-       patch_name=$(top_patch)
-       if [ x$patch_name == x ]
-       then
-               return 1
-       else
-               patch_file=$P/patches/"$patch_name".patch
-               files=$(cat $P/pc/$patch_name.pc)
-               for file in $files
-               do
-                       if [ $file -nt $patch_file ]
-                       then
-                               echo $file newer than $patch_file
-                               return 0
-                       fi
-               done
-       fi
-       return 1
-}
-
-need_top_current()
-{
-       if top_is_current
-       then
-               echo "Error: Top patch is not up-to-date"
-               exit 1
-       fi
-}
-
-warn_top_current()
-{
-       if top_is_current
-       then
-               echo "Warning: Top patch is not up-to-date"
-       fi
-}
-
-file_in_patch()
-{
-       file=$1
-       patch=$2
-
-       if [ -e $P/pc/$patch.pc ]
-       then
-               if grep "^"$file"$" $P/pc/$patch.pc > /dev/null
-               then
-                       return 0
-               fi
-       fi
-       return 1
-}
-
-# copy_file_to_bup filename patchname
-copy_file_to_bup()
-{
-       file=$1
-       patch=$2
-       bup="$file"~"$patch"
-
-       if [ -e $bup ]
-       then
-               echo "Cannot install file $file in patch $patch: backup $bup exists"
-               exit 1
-       fi
-
-       if [ -e $file ]
-       then
-               cp $file "$file"~"$patch"
-       else
-               echo "file $file appears to be newly added"
-       fi
-}
-
-install_file_in_patch()
-{
-       file=$1
-       patch=$2
-
-       copy_file_to_bup $file $patch
-       echo $file >> $P/pc/$patch.pc
-#      touch $P/txt/$patch.txt
-}
-
-need_file_there()
-{
-       if [ ! -e $1 ]
-       then
-               echo "File $1 does not exist"
-               exit 1
-       fi
-}
-
-desc()
-{
-       state=0
-       while read x
-       do
-               if [ x"$x" = xDESC ]
-               then
-                       state=1
-               elif [ x"$x" = xEDESC ]
-               then
-                       state=0
-               elif [ $state = 1 ]
-               then
-                       echo "  $x"
-               fi
-       done
-}
-
-body()
-{
-       file=$1
-
-       did_stuff=0
-       while read x
-       do
-               if [ x"$x" = xEDESC ]
-               then
-                       cat
-                       did_stuff=1
-               fi
-       done < $file
-
-       if [ $did_stuff = 0 ]
-       then
-               cat $file
-       fi
-}
diff --git a/lustre/kernel_patches/scripts/pcpatch b/lustre/kernel_patches/scripts/pcpatch
deleted file mode 100755 (executable)
index fa53385..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "pcpatch: recreate the pc file from patches/{patchname}.patch"
-       exit 1
-}
-
-doit()
-{
-       echo $* 1>&2
-       $* || {
-               echo oops
-               exit 1 
-       }
-}
-
-if [ $# != 1 -o "$1" = "help" ]
-then
-       usage
-fi
-PATCH=$1
-PATCH_NAME=$(stripit $PATCH)
-PC=$P/pc/$PATCH_NAME.pc
-
-if [ ! -e $P/patches/$PATCH_NAME.patch ] 
-then
-       echo "$P/patches/$PATCH_NAME.patch does not exist"
-       exit 1
-fi
-
-if is_applied "$PATCH"
-then
-       echo $PATCH is applied!
-       exit 1
-fi
-
-touched-by-patch $P/patches/$PATCH_NAME.patch > $PC
-echo Recreated $PC
diff --git a/lustre/kernel_patches/scripts/poppatch b/lustre/kernel_patches/scripts/poppatch
deleted file mode 100755 (executable)
index 792cb9b..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: poppatch [npatches]"
-       exit 1
-}
-
-doit()
-{
-       echo $* 1>&2
-       $* || {
-               echo oops
-               exit 1 
-       }
-}
-
-if [ $# -gt 1 ]
-then
-       usage
-fi
-
-NR=1
-STOP_AT=""
-if [ $# -eq 1 ]
-then
-       if is_numeric $1
-       then
-               NR=$1
-       else
-               NR=1000
-               STOP_AT=$(stripit $1)
-       fi
-fi
-
-pop_one()
-{
-       TOP_PATCH=$(top_patch)
-       if [ x$TOP_PATCH == x ]
-       then
-               echo "no patches applied"
-               exit 0
-       else
-               popped_patch="$(top_patch)"
-               if ! rpatch $(top_patch)
-               then
-                       echo still at $(top_patch)
-                       exit 1
-               fi
-               echo
-       fi
-}
-
-for i in $(seq 1 $NR)
-do
-       pop_one
-       if [ x$STOP_AT != "x" ]
-       then
-               if [ $STOP_AT == $(toppatch) ]
-               then
-                       exit 0
-               fi
-       fi
-done
diff --git a/lustre/kernel_patches/scripts/prep-patch b/lustre/kernel_patches/scripts/prep-patch
deleted file mode 100755 (executable)
index 1d60ea9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-if [ $# -ne 1 ]
-then
-       echo "Usage prep-patch patchname"
-       exit 1
-fi
-
-PATCHNAME=$(stripit $1)
-
-xcb -s 2 < $P/patches/$PATCHNAME.patch
-head -2 $P/txt/$PATCHNAME.txt | tail -1 | tr -d '\n' | xcb -s 1
diff --git a/lustre/kernel_patches/scripts/pstatus b/lustre/kernel_patches/scripts/pstatus
deleted file mode 100755 (executable)
index f735d8d..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-#!/bin/sh
-
-# print out patch status.  Usage: pstatus [ patchfile ... ]
-#
-# Stephen Cameron <steve.cameron@hp.com>
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-if [ ! -f ./series ]
-then
-       echo "./series does not exist." 1>&2
-       exit 1
-fi
-
-if [ ! -d ./patches ]
-then
-       echo "Directory ./patches does not exist." 1>&2
-       exit 1
-fi
-
-
-PATCHLIST="$*"
-if [ "$PATCHLIST" = "" ]
-then
-       series_optimize=yes
-       PATCHLIST=`cat series | sed -e 's/[.]patch[     ]*$//'`
-       SORTSERIES=`mktemp /tmp/ser.XXXXXX` || exit 1 
-       SORTPATCHES=`mktemp /tmp/pat.XXXXXX` || exit 1
-       sed -e 's/^[    ]//' -e 's/[.]patch[    ]*$//' < series | \
-               sort > $SORTSERIES 
-       exists="`echo $P/patches/*.patch 2>/dev/null`"
-       if [ "$exists" != "$P/patches/*.patch" ]
-       then
-               ls -1 $P/patches/*.patch | sed -e 's/^.*\/patches\///' \
-                       -e 's/[.]patch[         ]*$//' | sort > $SORTPATCHES
-               PATCHLIST="$PATCHLIST"" `comm -1 -3 $SORTSERIES $SORTPATCHES`"
-       fi
-       rm -f $SORTPATCHES $SORTSERIES
-else
-       series_optimize=no
-fi
-
-NSERIES=`wc -l series | awk '{ print $1; }'`
-series=1
-for PATCH_NAME in $PATCHLIST 
-do
-       PATCH_NAME=$(stripit $PATCH_NAME)
-       # see if this patch even exists
-       if [ ! -f $P/patches/"$PATCH_NAME".patch ]
-       then
-               echo "$PATCH_NAME does not exist."
-               continue
-       fi
-       # see if this patch is applied
-       applied="-"
-       if [ -f applied-patches ]
-       then 
-               grep '^'"$PATCH_NAME"'$' applied-patches > /dev/null
-               if [ "$?" = "0" ]
-               then
-                       applied="a"
-               fi
-       fi
-
-       # figure the status of this patch, that is, 
-       # if it needs changelog, pcpatch, refpatch
-
-       stat=""
-       if [ ! -f $P/txt/"$PATCH_NAME".txt ]
-       then
-               stat="changelog "
-       fi
-       if [ ! -f $P/pc/"$PATCH_NAME".pc ]
-       then
-               stat="$stat""pcpatch "
-       elif [ "$applied" != '-' ]
-       then
-               rpatch=n
-
-               # for each file this patch touches
-               for y in `cat $P/pc/"$PATCH_NAME".pc`
-               do
-                       # is the patch adding the file?
-                       if [ ! -e "$y"'~'"$PATCH_NAME" -a -f "$y" ]
-                       then
-                               # file is newer than the patch?
-                               if [ "$y" -nt $P/patches/"$PATCH_NAME".patch ]
-                               then
-                                       rpatch=y
-                                       stat="$stat""refpatch "
-                                       break
-                               fi
-                       else
-                               # modified file is newer than the patch?
-                               if [ "$y"'~'"$PATCH_NAME" -nt \
-                                       $P/patches/"$PATCH_NAME".patch ]
-                               then
-                                       rpatch=y
-                                       stat="$stat""refpatch "
-                                       break
-                               fi
-                               if [ "`toppatch`" = "$PATCH_NAME" -a \
-                                       "$y" -nt $P/patches/"$PATCH_NAME".patch ]
-                               then
-                                       # toppatch, so check if the file 
-                                       # is newer than the patch?
-                                       rpatch=y
-                                       stat="$stat""refpatch "
-                                       break
-                               fi
-                       fi
-               done
-       fi
-       # check if they changed the changelog recently
-       if [ "$rpatch" = "n" -a -f $P/txt/"$PATCH_NAME".txt \
-               -a $P/txt/"$PATCH_NAME".txt -nt \
-               $P/patches/"$PATCH_NAME".patch ]
-       then
-               rpatch=y
-               stat="$stat""refpatch "
-       fi
-       if [ "$stat" != "" ]
-       then
-               stat="Needs ""$stat"
-       fi
-
-       if [ "$series_optimize" != "yes" ]
-       then
-               # have to find the series number the hard way.
-               series=`grep -n '^'"$PATCH_NAME"'\.patch$' series |\
-                       awk -F: '{ printf "%d", $1}' `
-               if [ "$series" = "" ]
-               then
-                       series="?"
-               fi
-       fi
-
-       echo "$series":"$applied":"$PATCH_NAME $stat"
-
-       if [ "$series_optimize" = "yes" ]
-       then
-               if [ "$series" != "?" ]
-               then
-                       series=`expr $series + 1`
-                       if [ $series -gt $NSERIES ]
-                       then 
-                               series="?"
-                       fi
-               fi
-       fi
-done 
diff --git a/lustre/kernel_patches/scripts/ptkdiff b/lustre/kernel_patches/scripts/ptkdiff
deleted file mode 100755 (executable)
index 97c9982..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-
-#
-# Bring up a patched file in tkdiff.  We show the diffs
-# in the topmost patch, unless it was specified
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: ptkdiff filename ..."
-       echo "       ptkdiff -"
-       exit 1
-}
-
-PATCH_NAME=$(top_patch)
-
-doit()
-{
-       filename=$1
-       unpatched_file=$filename"~"$PATCH_NAME
-       need_file_there $filename
-       if [ -e $unpatched_file ]
-       then
-               tkdiff $unpatched_file $filename
-       else
-               echo ptkdiff: $filename appears to not be in $PATCH_NAME
-       fi
-}
-
-if [ x"$1" = "x-" ]
-then
-       FILENAME=$(cat $P/pc/$PATCH_NAME.pc)
-else
-       FILENAME="$*"
-fi
-
-for i in $FILENAME
-do
-       doit $i &
-done
diff --git a/lustre/kernel_patches/scripts/pushpatch b/lustre/kernel_patches/scripts/pushpatch
deleted file mode 100755 (executable)
index 018716d..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/bin/sh
-
-#
-# Add next patch in series
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: pushpatch [npatches]"
-       exit 1
-}
-
-opt_force=0
-
-for i in $*
-do
-       case "$i" in
-       -f)
-               opt_force=1;;
-       *)
-               if [ -n "$NR" -o -n "$STOP_AT" ]
-               then
-                       usage
-               fi
-               if is_numeric $i
-               then
-                       NR=$i
-               else
-                       NR=1000
-                       STOP_AT=$(stripit $i)
-               fi;;
-       esac
-done
-
-[ $opt_force = 1 ] && force="-f"
-
-SERIES=series
-
-if [ ! -e $SERIES ]
-then
-       echo 'File "series" not found'
-       exit 1
-fi
-
-push_one()
-{
-       top=$(toppatch)
-       if [ x"$top" == x ]
-       then
-               todo=$(head -1 $SERIES)
-       else
-               last_in_series=$(stripit $(tail -1 $SERIES))
-               if [ $last_in_series == $top ]
-               then
-                       echo "Series fully applied.  Ends at $top"
-                       exit 0
-               fi
-               todo=$(grep -C1 "^$top\.patch" $SERIES | tail -1)
-               if [ x$todo = x ]
-               then
-                       todo=$(head -1 $SERIES)
-               fi
-       fi
-
-       apatch $force $todo
-}
-
-for i in $(seq 1 $NR)
-do
-       push_one
-       if [ x$STOP_AT != "x" ]
-       then
-               if [ $STOP_AT == $(toppatch) ]
-               then
-                       exit 0
-               fi
-       fi
-done
diff --git a/lustre/kernel_patches/scripts/refpatch b/lustre/kernel_patches/scripts/refpatch
deleted file mode 100755 (executable)
index 88f3caf..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: refpatch"
-       exit 1
-}
-
-doit()
-{
-       echo $* 1>&2
-       $* || {
-               echo oops
-               exit 1 
-       }
-}
-
-if [ $# != 0 ]
-then
-       usage
-fi
-
-TOP_PATCH=$(top_patch)
-mpatch $* $(top_patch)
-echo "Refreshed $TOP_PATCH"
diff --git a/lustre/kernel_patches/scripts/removed-by-patch b/lustre/kernel_patches/scripts/removed-by-patch
deleted file mode 100755 (executable)
index ff12970..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-# Extract names of new files from a patch, print them out
-
-PATCHFILE=$1
-case "$PATCHFILE" in
-*.gz) CMD="gzip -d < $PATCHFILE";;
-*)    CMD="cat $PATCHFILE";;
-esac
-
-TMP=$(mktemp /tmp/rbp-XXXXXX)
-
-eval $CMD | egrep '^\+\+\+.*1970|\+\+\+.*1969' > $TMP
-sed -e 's@[^/]*/\([^   ]*\).*@\1@' < $TMP | sed -e 's@^linux/@@' | sort
-rm -f $TMP
diff --git a/lustre/kernel_patches/scripts/rename-patch b/lustre/kernel_patches/scripts/rename-patch
deleted file mode 100755 (executable)
index 8334f1e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-OLD=$(stripit $1)
-NEW=$(stripit $2)
-
-mv $P/pc/$OLD.pc $P/pc/$NEW.pc
-mv $P/patches/$OLD.patch $P/patches/$NEW.patch
-mv $P/txt/$OLD.txt $P/txt/$NEW.txt
-
-cvs remove $P/pc/$OLD.pc
-cvs remove $P/patches/$OLD.patch
-cvs remove $P/txt/$OLD.txt
-
-cvs add $P/pc/$NEW.pc
-cvs add $P/patches/$NEW.patch
-cvs add $P/txt/$NEW.txt
diff --git a/lustre/kernel_patches/scripts/rolled-up-patch b/lustre/kernel_patches/scripts/rolled-up-patch
deleted file mode 100755 (executable)
index 52676dc..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: rolled-up-patch"
-       exit 1
-}
-
-if [ $# != 0 ]
-then
-       usage
-fi
-
-RUP=$(mktemp /tmp/rup-XXXXXX)
-rm -f $RUP
-
-for i in $(cat applied-patches)
-do
-       patch_name=$(stripit $i)
-       cat $P/pc/$patch_name.pc
-done | sort | uniq > $RUP
-
-kdiff $(cat $RUP)
-rm -f $RUP
diff --git a/lustre/kernel_patches/scripts/rpatch b/lustre/kernel_patches/scripts/rpatch
deleted file mode 100755 (executable)
index 42e1533..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-do_remove()
-{
-       if patch -R -p1 -s -i $P/patches/"$1".patch
-       then
-               true
-       else
-               echo SOMETHING WENT WRONG
-               exit 1
-       fi
-}
-
-kill_old_ones()
-{
-       FILES=$(cat $P/pc/$1.pc)
-       for file in $FILES
-       do
-               rm -f "$file"~"$1"
-       done
-}
-
-usage()
-{
-       echo "Usage: rpatch patchname"
-       exit 1
-}
-
-if [ $# == 0 ]
-then
-       usage
-fi
-
-PATCH_NAME=$(stripit $1)
-
-warn_top_current
-
-if is_applied "$PATCH_NAME"
-then
-       if can_remove "$PATCH_NAME"
-       then
-               do_remove "$PATCH_NAME"
-               kill_old_ones "$PATCH_NAME"
-               remove_from_db "$PATCH_NAME"
-       else
-               echo "$PATCH_NAME" does not remove cleanly
-               exit 1
-       fi
-else
-       echo "$PATCH_NAME" is not applied
-       exit 1
-fi
-
-top=$(top_patch)
-if [ x"$top" == x ]
-then
-       msg="no patches applied"
-else
-       msg="now at $top"
-fi
-
-echo Removed $PATCH_NAME, $msg
-
diff --git a/lustre/kernel_patches/scripts/split-patch b/lustre/kernel_patches/scripts/split-patch
deleted file mode 100755 (executable)
index 08ce431..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/perl -w
-$out = "";
-while (<>) {
-       next if (/^Only/);
-       next if (/^Binary/);
-       if (/^diff/ || /^Index/) {
-               if ($out) {
-                       close OUT;
-               }
-               (@out) = split(' ', $_);
-               shift(@out) if (/^diff/);
-               $out = pop(@out);
-               $out =~ s:/*usr/:/:;
-               $out =~ s:/*src/:/:;
-               $out =~ s:^/*linux[^/]*::;
-               $out =~ s:\(w\)::;
-               next if ($out eq "");
-               $out = "/var/tmp/patches/$out";
-               $dir = $out;
-               $dir =~ s:/[^/]*$::;
-               print STDERR "$out\n";
-               system("mkdir -p $dir");
-               open(OUT, ">$out") || die("cannot open $out");
-       }
-       if ($out) {
-               print OUT $_;
-       }
-}
-
diff --git a/lustre/kernel_patches/scripts/sum-series b/lustre/kernel_patches/scripts/sum-series
deleted file mode 100755 (executable)
index 5b628fb..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-
-#
-# Make superpatch from current series using combinediff.
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: sum-series output-file"
-       exit 1
-}
-
-if [ $# -ne 1 ] 
-then
-       usage
-fi
-
-need_file_there applied-patches
-CURRENT=$(mktemp /tmp/cmbd-XXXXXXXX)
-for FILE in $(cat applied-patches)
-do
-#    echo "Adding patch $FILE...."
-       if [ -f $P/patches/$FILE ] 
-       then
-               cat  $P/patches/$FILE >> $CURRENT
-       elif [ -f $P/patches/$FILE.patch ]
-       then
-               cat $P/patches/$FILE.patch >> $CURRENT
-       elif [ -f $FILE ]
-       then
-               cat $FILE >> $CURRENT
-       fi
-done
-
-mv $CURRENT "$1"
diff --git a/lustre/kernel_patches/scripts/tag-series b/lustre/kernel_patches/scripts/tag-series
deleted file mode 100755 (executable)
index 17f3dfe..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-
-# tag-series tagname series-file-name
-#
-# Does a `cvs tag tagname' of all the .pc, .txt and .patch files mentioned
-# in series-file-name.  Also tags series-file-name.
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-# tag_one tag patchname
-#
-tag_one()
-{
-       PN=$(stripit $2)
-       if [ -r $P/txt/$PN.txt ]
-       then
-               cvs tag $1 $P/pc/$PN.pc $P/patches/$PN.patch $P/txt/$PN.txt
-       else
-               cvs tag $1 $P/pc/$PN.pc $P/patches/$PN.patch
-       fi
-}
-
-if [ $# -ne 2 ]
-then
-       echo Usage: tag-series tagname series-file-name
-       exit 1
-fi
-
-TAG=$1
-SERIES=$2
-
-for p in $(cat $SERIES)
-do
-       tag_one $TAG $p
-done
-cvs tag $TAG $SERIES
diff --git a/lustre/kernel_patches/scripts/toppatch b/lustre/kernel_patches/scripts/toppatch
deleted file mode 100755 (executable)
index 6df239d..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: toppatch"
-       exit 1
-}
-
-if [ $# != 0 ]
-then
-       usage
-fi
-
-if [ -e $DB ]
-then
-       TOP_PATCH=$(top_patch)
-       if [ x$TOP_PATCH != x ]
-       then
-               echo $TOP_PATCH
-       fi
-fi
diff --git a/lustre/kernel_patches/scripts/touched-by-patch b/lustre/kernel_patches/scripts/touched-by-patch
deleted file mode 100755 (executable)
index df5b387..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-# Extract names of new files from a patch, print them out
-
-PATCHFILE=$1
-case "$PATCHFILE" in
-*.gz) CMD="gzip -d < $PATCHFILE";;
-*)    CMD="cat $PATCHFILE";;
-esac
-
-TMP=$(mktemp /tmp/tbp-XXXXXX) || exit 1
-TMP2=$(mktemp /tmp/tbp2-XXXXXX) || exit 1
-
-eval $CMD | egrep '^\+\+\+ |^\-\-\- ' > $TMP
-
-cat $TMP | sed -e 's@[^/]*/\([^        ]*\).*@\1@' \
-        | grep -v '^dev\/null$' \
-        | sort \
-        | uniq \
-        > $TMP2
-
-rm -f $TMP
-grep < $TMP2 '^[+][+][+]' > /dev/null
-if [ "$?" = "0" ]
-then
-       echo "WARNING: $PATCHFILE appears to be -p0 form rather than -p1." 1>&2
-       echo "         Use "\'"p0-2-p1 . . < $PATCHFILE"\'" to fix" 1>&2
-       awk '{ print $2 }' < $TMP2
-else
-       cat $TMP2
-fi | grep -v '~'
-
-rm -f $TMP2
diff --git a/lustre/kernel_patches/scripts/trypatch b/lustre/kernel_patches/scripts/trypatch
deleted file mode 100755 (executable)
index 2e3cd15..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/bin/sh
-
-#
-# Fork the next patch in the series
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: trypatch <newname>"
-       exit 1
-}
-
-if [ $# -ne 1 ]
-then
-       usage
-fi
-
-NEW=$1
-BASE=`stripit $NEW`
-SERIES=series
-
-if [ ! -e $SERIES ]
-then
-       echo 'File "series" not found'
-       exit 1
-fi
-
-if  grep $BASE $SERIES >& /dev/null  ; then 
-        echo "Patch $NEW already exists in series"
-        exit 1
-fi
-
-if [ ! -f $P/patches/$BASE.patch ] ; then 
-        echo "Patch $NEW doesn't exist as a file"
-        exit 1
-fi
-
-$TMPSERIES=$(mktemp /tmp/series-XXXXXXXX)
-top=$(toppatch)
-if [ x"$top" == x ]
-then
-       todo=$(head -1 $SERIES)
-else
-       last_in_series=$(stripit $(tail -1 $SERIES))
-       if [ $last_in_series == $top ]
-       then
-               echo "Series fully applied.  Ends at $top"
-               exit 0
-       fi
-       todo=$(grep -C1 "^$top\.patch" $SERIES | tail -1)
-       if [ x$todo = x ]
-       then
-               todo=$(head -1 $SERIES)
-       fi
-fi
-
-if  patch -p1 -i $P/patches/$BASE.patch ; then 
-    patch -R -p1 -i $P/patches/$BASE.patch
-
-    $basetodo=$(basename $todo)
-    sed "s/$todo/$BASE/" < $SERIES > $TMPSERIES
-    mv -f $TMPSERIES $SERIES
-    echo "Replaced $todo with $BASE"
-else 
-    echo "Failed to replace $todo with $BASE"
-fi
diff --git a/lustre/kernel_patches/scripts/unitdiff.py b/lustre/kernel_patches/scripts/unitdiff.py
deleted file mode 100755 (executable)
index d19d5e7..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-#!/usr/bin/python
-
-import sys
-import re
-import string
-
-#TODO
-# clean up rest/file
-# clean up +6 and like (assumptions). should be turned into 'find'
-# make regession tests for all cases (Only in, etc)
-
-try:
-        filename = sys.argv[1]
-except:
-        print 'requires a file name'
-        sys.exit(1)
-
-filefd = open(filename)
-file = filefd.read()
-filefd.close()
-
-rest = file
-pat = "(^(?:diff .*\n)?--- .*\n\+\+\+ .*)?\n@@ -(\d+),?(\d+)? \+(\d+),?(\d+)? @@|^(Only in .*)"
-startpat = re.compile(pat, re.M)
-
-pos = 0
-oldpos = 0
-filelen = len(rest)
-oldrest = ""
-while(1):
-        rexp = startpat.search(rest)
-        if not rexp:
-                break
-
-       if rexp.group(6):
-               print rexp.group(6)
-               rest = rest[rexp.end(6)+1:]
-               continue
-               
-       header = rexp.group(1)
-        orgfile_start = string.atoi(rexp.group(2))
-       if rexp.group(3):
-               orgfile_len = string.atoi(rexp.group(3))
-       else:
-               orgfile_len = -1
-        newfile_start = string.atoi(rexp.group(4))
-       if rexp.group(5):
-               newfile_len = string.atoi(rexp.group(5))
-       else:
-               newfile_len = -1
-        rest = rest[rexp.start(2):]
-        rest = rest[string.find(rest, "\n")+1:]
-
-       rexp2 = startpat.search(rest)
-       if rexp2:
-               if rexp2.start(6) != -1:
-                       oldrest = rest[rexp2.start(6)-1:]
-                       rest = rest[:rexp2.start(6)]
-               elif rexp2.start(1) == -1:
-                       oldrest = rest[rexp2.start(2)-5:]
-                       rest = rest[:rexp2.start(2)-4]
-               else:
-                       oldrest = rest[rexp2.start(1)-1:]
-                       rest = rest[:rexp2.start(1)]
-       else:
-               oldrest = rest
-
-#      pos = filelen - len(oldrest)
-#      if pos - oldpos > 100:
-#              sys.stderr.write(`pos`+'/'+`filelen`+'\n')
-#              oldpos = pos
-
-       first = 1
-       oldminuses = 0
-       oldplusses = 0
-       oldoffset = 0
-       while(1):
-               #erstat early line stuff med lookbehind paa {1,2}-dims
-               #nedenfor RAA
-               linepat = "^([^-+\n]*)\n?(((^[-+].*\n)|^(.*\n){1,2}(?=^[-+].*\n))+)(.*)\n?"
-               compat = re.compile(linepat, re.M)
-               rexp = compat.search(rest)
-               if not rexp:
-                       break
-
-               prematch = rexp.group(1)
-               match = rexp.group(2)
-               muddle = len(match)
-
-#              print rest
-#              print 'prematch ', rexp.start(1), rexp.end(1), prematch
-#              print 'match ---------'
-#              print match
-#              print 'match --------'
-
-               # dump unwanted early lines...
-               if match[0] != "+" and match[0] != "-":
-                       while(1):
-                               next = string.find(match, '\n')
-                               if next == -1:
-                                       break
-                               if match[next+1] == "+" or match[next+1] == "-":
-                                       prematch = match[:next]
-                                       match = match[next+1:]
-                                       break
-                               match = match[next+1:]
-
-
-#              print 'prematch ', rexp.start(1), rexp.end(1), len(prematch)
-#              print '('+prematch+')'
-#              if prematch == ' ':
-#                      print 'space'
-               muddle = muddle - len(match)
-
-               lines = string.count(match, "\n")
-               compat = re.compile("^-", re.M)
-               minuses = len(compat.findall(match))
-               compat = re.compile("^\+", re.M)
-               plusses = len(compat.findall(match))
-               orgsize = minuses + 2 + (lines - minuses - plusses)
-               newsize = plusses + 2 + (lines - minuses - plusses)
-
-               noeol = "^(\\\ No newline at end of file)$"
-               compnoeol = re.compile(noeol, re.M)
-               if compnoeol.search(match) or compnoeol.search(rexp.group(6)):
-                       orgsize = orgsize - 1
-                       newsize = newsize - 1
-                       
-               coherent = 0
-               if lines - plusses == 0:
-                       coherent = 1
-               elif lines - minuses == 0:
-                       coherent = 1
-
-               # RAA FIXME
-               if not len(prematch):#or len(prematch) == 1 and prematch == ' ':
-                       orgsize = orgsize -1
-                       newsize = newsize -1
-               if rexp.start(6) == rexp.end(6):
-                       orgsize = orgsize -1
-                       newsize = newsize -1
-
-#              print "lines in match: ", lines
-#              print "number of minuses: ", minuses
-#              print "number of plusses: ", plusses
-       
-               matchpos = rexp.start(2) + muddle
-               offset =  string.count(rest[:matchpos], "\n")
-
-#              print 'offset/oldoffset: ', offset,oldoffset
-#              print 'oldplusses/oldminuses: ', oldplusses, oldminuses
-#              print 'orgfile_start/newfile_start: ', orgfile_start, newfile_start
-
-               orgstart = orgfile_start + offset + oldoffset - oldplusses
-               newstart = newfile_start + offset - oldminuses + oldoffset
-
-               # RAA: Bwadr. Fix antagelse om prematch paa en anden
-               # maade
-               orgstartmod = 0
-               newstartmod = 0
-               if orgfile_start == 1 and not len(prematch):
-                       orgstartmod = 1
-               if newfile_start == 1 and not len(prematch):
-                       newstartmod = 1
-               if orgfile_start == 0 and orgfile_len == 0:
-                       orgstartmod = 1
-                       # RAA Hack!
-                       plusses = plusses + 1
-                       minuses = minuses +1
-               if newfile_start == 0 and newfile_len == 0:
-                       newstartmod = 1
-                       # RAA Hack!
-                       plusses = plusses + 1
-                       minuses = minuses +1
-               
-               if header and first:
-                       print header
-                       first = 0
-
-               # should the start(1) == 0 be orgstart == 1? RAA
-               if orgstart == 1 and newstart == 1 and plusses == 0 and coherent:
-                       print "@@ -"+`orgstart`+","+`orgsize`+" +"+`newstart`+" @@"
-                       print match[:string.rfind(match, "\n")]
-                       print rexp.group(6)
-               elif rexp.start(6) == rexp.end(6) and plusses == 0 and coherent:
-                       if orgstartmod:
-                               orgstart = orgstart + 1
-                       if newstartmod:
-                               newstart = newstart + 1
-                       print "@@ -"+`orgstart-1`+","+`orgsize`+" +"+`newstart-1`+" @@"
-                       print prematch
-                       print match[:string.rfind(match, "\n")]
-               elif orgstart == 1 and orgstart == 1 and minuses == 0 and coherent:
-                       print "@@ -"+`orgstart`+" +"+`newstart`+","+`newsize`+" @@"
-                       print match[:string.rfind(match, "\n")]
-                       print rexp.group(6)
-               elif rexp.start(6) == rexp.end(6) and minuses == 0 and coherent:
-                       if orgstartmod:
-                               orgstart = orgstart + 1
-                       if newstartmod:
-                               newstart = newstart + 1
-                       print "@@ -"+`orgstart-1`+" +"+`newstart-1`+","+`newsize`+" @@"
-                       print prematch
-                       print match[:string.rfind(match, "\n")]
-               else:
-                       if orgstartmod:
-                               orgstart = orgstart + 1
-                       if newstartmod:
-                               newstart = newstart + 1
-                       print "@@ -"+`orgstart-1`+","+`orgsize`+" +"+`newstart-1`+","+`newsize`+" @@"
-                       if len(prematch):
-                               print prematch
-                       print match[:string.rfind(match, "\n")]
-                       if rexp.start(6) != rexp.end(6):
-                               print rexp.group(6)
-       
-               rest = rest[rexp.end(6):]
-               oldminuses = minuses + oldminuses
-               oldplusses = plusses + oldplusses
-               oldoffset = oldoffset + offset + lines #include match()-lines
-
-
-       rest = oldrest
diff --git a/lustre/kernel_patches/scripts/unused-patches b/lustre/kernel_patches/scripts/unused-patches
deleted file mode 100755 (executable)
index 2f3a70a..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-
-#
-# List unused patches
-#
-
-. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \
-       echo "Impossible to find my library 'patchfns'."
-       echo "Check your install, or go to the right directory"
-       exit 1
-}
-
-usage()
-{
-       echo "Usage: unused-patches"
-       exit 1
-}
-
-if [ $# -ne 0 ] 
-then
-       usage
-fi
-
-for FILE in $(ls $P/patches)
-do
-        BASE=`stripit $FILE`
-#       echo checking $BASE in $P/patches
-       if  grep $FILE $P/series/*  >&  /dev/null ; then 
-                true
-#                echo $FILE found in $P/series
-        else 
-            if [ $BASE != CVS ]; then
-                echo patches/$FILE
-                echo txt/$BASE.txt
-                echo pc/$BASE.pc
-            fi
-       fi
-done
-
diff --git a/lustre/kernel_patches/series/chaos b/lustre/kernel_patches/series/chaos
deleted file mode 100644 (file)
index 913ae18..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-dev_read_only.patch
-exports.patch
-kmem_cache_validate.patch
-lustre_version.patch
-vfs_intent-2.4.18-18.patch
-invalidate_show.patch
-iod-rmap-exports.patch
diff --git a/lustre/kernel_patches/series/chaos-2.4.20 b/lustre/kernel_patches/series/chaos-2.4.20
deleted file mode 100644 (file)
index db8237e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-dev_read_only_2.4.20.patch
-exports_2.4.20.patch
-kmem_cache_validate_hp.patch
-lustre_version.patch
-vfs_intent-2.4.20.patch
-invalidate_show.patch
-iod-rmap-exports-2.4.20.patch
-export-truncate.patch
-ext-2.4-patch-1.patch
-ext-2.4-patch-2.patch
-ext-2.4-patch-3.patch
-ext-2.4-patch-4.patch
-linux-2.4.20-xattr-0.8.54.patch
-ext3-2.4.20-fixes.patch
-ext3-2.4-ino_t.patch
-ext3-largefile.patch
-ext3-truncate_blocks.patch
-ext3-unmount_sync.patch
-ext3-use-after-free.patch
-extN-wantedi.patch
-extN-san.patch
diff --git a/lustre/kernel_patches/series/hp-pnnl b/lustre/kernel_patches/series/hp-pnnl
deleted file mode 100644 (file)
index 6723ab6..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-dev_read_only_hp.patch
-exports_hp.patch
-kmem_cache_validate_hp.patch
-jbd-transno-cb.patch
-lustre_version.patch
-vfs_intent_hp.patch
-invalidate_show.patch
diff --git a/lustre/kernel_patches/series/hp-pnnl-2.4.20 b/lustre/kernel_patches/series/hp-pnnl-2.4.20
deleted file mode 100644 (file)
index c5a895d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-dev_read_only_hp.patch
-exports_hp.patch
-kmem_cache_validate_hp.patch
-lustre_version.patch
-vfs_intent_hp.patch
-invalidate_show.patch
-export-truncate.patch
-iod-stock-24-exports_hp.patch
diff --git a/lustre/kernel_patches/series/hp-pnnl-2.4.20.orig b/lustre/kernel_patches/series/hp-pnnl-2.4.20.orig
deleted file mode 100644 (file)
index bf276fb..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-dev_read_only_hp.patch
-exports_hp.patch
-kmem_cache_validate_hp.patch
-jbd-transno-cb.patch
-lustre_version.patch
-vfs_intent_hp.patch
-invalidate_show.patch
-iod-stock-24-exports_hp.patch
diff --git a/lustre/kernel_patches/series/lin-2.5.44 b/lustre/kernel_patches/series/lin-2.5.44
deleted file mode 100644 (file)
index 1bc028b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-lin-2.5.44.patch
diff --git a/lustre/kernel_patches/series/rh-2.4.18-18 b/lustre/kernel_patches/series/rh-2.4.18-18
deleted file mode 100644 (file)
index ec72618..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-dev_read_only.patch
-exports.patch
-kmem_cache_validate.patch
-lustre_version.patch
-uml_check_get_page.patch
-uml_no_panic.patch
-vfs_intent-2.4.18-18.patch
-uml_compile_fixes.patch
diff --git a/lustre/kernel_patches/series/rh-2.4.20 b/lustre/kernel_patches/series/rh-2.4.20
deleted file mode 100644 (file)
index 0d8331d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-dev_read_only_2.4.20.patch
-exports_2.4.20.patch
-kmem_cache_validate_hp.patch
-lustre_version.patch
-vfs_intent-2.4.20.patch
-invalidate_show.patch
-iod-rmap-exports-2.4.20.patch
-export-truncate.patch
-uml_check_get_page.patch
-uml_no_panic.patch
diff --git a/lustre/kernel_patches/series/rh-8.0 b/lustre/kernel_patches/series/rh-8.0
deleted file mode 100644 (file)
index 4c64ad2..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-dev_read_only.patch
-exports.patch
-kmem_cache_validate.patch
-lustre_version.patch
-uml_check_get_page.patch
-uml_no_panic.patch
-vfs_intent.patch
-uml_compile_fixes.patch
diff --git a/lustre/kernel_patches/series/vanilla-2.4.18 b/lustre/kernel_patches/series/vanilla-2.4.18
deleted file mode 100644 (file)
index 5d2ab68..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-vanilla-2.4.18
-invalidate_show.patch
diff --git a/lustre/kernel_patches/series/vanilla-2.4.19 b/lustre/kernel_patches/series/vanilla-2.4.19
deleted file mode 100644 (file)
index 37cb65e..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-vanilla-2.4.19.patch
-jbd-transno-cb.patch
-invalidate_show.patch
diff --git a/lustre/kernel_patches/series/vanilla-2.4.20 b/lustre/kernel_patches/series/vanilla-2.4.20
deleted file mode 100644 (file)
index bd6d77d..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-uml-patch-2.4.20-4.patch
-dev_read_only_hp.patch
-exports_hp.patch
-kmem_cache_validate_hp.patch
-lustre_version.patch
-vfs_intent-2.4.20-vanilla.patch
-invalidate_show.patch
-export-truncate.patch
-iod-stock-24-exports.patch
-uml_check_get_page.patch
-uml_no_panic.patch
-ext-2.4-patch-1.patch
-ext-2.4-patch-2.patch
-ext-2.4-patch-3.patch
-ext-2.4-patch-4.patch
-linux-2.4.20-xattr-0.8.54.patch
-ext3-2.4.20-fixes.patch
-ext3-2.4-ino_t.patch
-ext3-largefile.patch
-ext3-truncate_blocks.patch
-ext3-unmount_sync.patch
-ext3-use-after-free.patch
-ext3-noread-2.4.20.patch
-extN-wantedi.patch
-extN-san.patch
diff --git a/lustre/kernel_patches/series/vanilla-2.5 b/lustre/kernel_patches/series/vanilla-2.5
deleted file mode 100644 (file)
index 2dcc98f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-lustre-2.5.patch
diff --git a/lustre/kernel_patches/series/vanilla-2.5.63 b/lustre/kernel_patches/series/vanilla-2.5.63
deleted file mode 100644 (file)
index b77c77b..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-lustre_version.patch
-lustre-2.5.63.patch
diff --git a/lustre/kernel_patches/txt/dev_read_only.txt b/lustre/kernel_patches/txt/dev_read_only.txt
deleted file mode 100644 (file)
index 010cdb7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-DESC
-(undescribed patch)
-EDESC
diff --git a/lustre/kernel_patches/txt/exports.txt b/lustre/kernel_patches/txt/exports.txt
deleted file mode 100644 (file)
index 010cdb7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-DESC
-(undescribed patch)
-EDESC
diff --git a/lustre/kernel_patches/txt/ext3-2.4.20-fixes.txt b/lustre/kernel_patches/txt/ext3-2.4.20-fixes.txt
deleted file mode 100644 (file)
index b890cbd..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-DESC
-Fix for block allocation errors if block bitmap or inode block list is corrupt.
-EDESC
diff --git a/lustre/kernel_patches/txt/kmem_cache_validate.txt b/lustre/kernel_patches/txt/kmem_cache_validate.txt
deleted file mode 100644 (file)
index 010cdb7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-DESC
-(undescribed patch)
-EDESC
diff --git a/lustre/kernel_patches/txt/lin-2.5.44.txt b/lustre/kernel_patches/txt/lin-2.5.44.txt
deleted file mode 100644 (file)
index 694303d..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-DESC
-patches for making kernel 2.5.44 ready for mounting Lustre, and some basic
-sys_call.
-EDESC
diff --git a/lustre/kernel_patches/txt/lustre_version.txt b/lustre/kernel_patches/txt/lustre_version.txt
deleted file mode 100644 (file)
index 010cdb7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-DESC
-(undescribed patch)
-EDESC
diff --git a/lustre/kernel_patches/txt/uml_check_get_page.txt b/lustre/kernel_patches/txt/uml_check_get_page.txt
deleted file mode 100644 (file)
index 010cdb7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-DESC
-(undescribed patch)
-EDESC
diff --git a/lustre/kernel_patches/txt/uml_compile_fixes.txt b/lustre/kernel_patches/txt/uml_compile_fixes.txt
deleted file mode 100644 (file)
index 010cdb7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-DESC
-(undescribed patch)
-EDESC
diff --git a/lustre/kernel_patches/txt/uml_no_panic.txt b/lustre/kernel_patches/txt/uml_no_panic.txt
deleted file mode 100644 (file)
index 010cdb7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-DESC
-(undescribed patch)
-EDESC
diff --git a/lustre/kernel_patches/txt/vfs_intent.txt b/lustre/kernel_patches/txt/vfs_intent.txt
deleted file mode 100644 (file)
index 010cdb7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-DESC
-(undescribed patch)
-EDESC
diff --git a/lustre/kernel_patches/which_patch b/lustre/kernel_patches/which_patch
deleted file mode 100644 (file)
index 1f5c168..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-series/rh-8.0: 
-   redhat 2.4.18-14
-   redhat 2.4.18-17
-series/rh-2.4.18-18
-   redhat 2.4.18-18
diff --git a/lustre/liblustre/.cvsignore b/lustre/liblustre/.cvsignore
deleted file mode 100644 (file)
index fb1a186..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-.Xrefs
-config.log
-config.status
-configure
-Makefile
-Makefile.in
-.deps
-TAGS
-libtest
diff --git a/lustre/liblustre/Makefile.am b/lustre/liblustre/Makefile.am
deleted file mode 100644 (file)
index c761a22..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# Administration utilities Makefile
-DEFS=
-
-CFLAGS:=-g -O2 -I$(top_srcdir)/utils -I$(PORTALS)/include  -I$(srcdir)/../include -Wall -L$(PORTALSLIB)
-
-KFLAGS:=
-CPPFLAGS = $(HAVE_LIBREADLINE)
-LIBS=
-LLIBS= ../lov/liblov.a ../obdecho/libobdecho.a ../osc/libosc.a ../ldlm/libldlm.a  ../ptlrpc/libptlrpc.a ../obdclass/liblustreclass.a
-
-libtest_LDADD := $(LIBREADLINE)  $(LLIBS) \
-                 $(PORTALS)/user/procbridge/libprocbridge.a  $(PORTALS)/user/tcpnal/libtcpnal.a \
-                $(PORTALS)/user/util/libtcpnalutil.a $(PORTALS)/user/$(PORTALS)/api/libptlapi.a \
-                 $(PORTALS)/lib/libptllib.a -lptlctl -lpthread -lefence
-bin_PROGRAMS = libtest
-libtest_SOURCES = libtest.c
-
-include $(top_srcdir)/Rules
diff --git a/lustre/liblustre/file.c b/lustre/liblustre/file.c
deleted file mode 100644 (file)
index d656918..0000000
+++ /dev/null
@@ -1,551 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Lustre Light Super operations
- *
- *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define DEBUG_SUBSYSTEM S_LLITE
-
-#include <stdlib.h>
-#include <string.h>
-#include <error.h>
-#include <assert.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-
-#include <sysio.h>
-#include <fs.h>
-#include <mount.h>
-#include <inode.h>
-#include <file.h>
-
-#include "llite_lib.h"
-
-void llu_prepare_mdc_op_data(struct mdc_op_data *data,
-                             struct inode *i1,
-                             struct inode *i2,
-                             const char *name,
-                             int namelen,
-                             int mode)
-{
-        struct llu_inode_info *lli1, *lli2;
-
-        LASSERT(i1);
-
-        lli1 = llu_i2info(i1);
-        data->ino1 = lli1->lli_st_ino;
-        data->gen1 = lli1->lli_st_generation;
-        data->typ1 = lli1->lli_st_mode & S_IFMT;
-        data->gid1 = lli1->lli_st_gid;
-
-        if (i2) {
-                lli2 = llu_i2info(i2);
-                data->ino2 = lli2->lli_st_ino;
-                data->gen2 = lli2->lli_st_generation;
-                data->typ2 = lli2->lli_st_mode & S_IFMT;
-                data->gid2 = lli2->lli_st_gid;
-        } else
-                data->ino2 = 0;
-
-        data->name = name;
-        data->namelen = namelen;
-        data->mode = mode;
-}
-
-static struct inode *llu_create_node(struct inode *dir, const char *name,
-                                     int namelen, const void *data, int datalen,
-                                     int mode, __u64 extra,
-                                     struct lookup_intent *it)
-{
-        struct inode *inode;
-        struct ptlrpc_request *request = NULL;
-        struct mds_body *body;
-        time_t time = 123456;//time(NULL);
-        struct llu_sb_info *sbi = llu_i2sbi(dir);
-
-        if (it && it->it_disposition) {
-                LBUG();
-#if 0
-                ll_invalidate_inode_pages(dir);
-#endif
-                request = it->it_data;
-                body = lustre_msg_buf(request->rq_repmsg, 1, sizeof(*body));
-        } else {
-                struct mdc_op_data op_data;
-                struct llu_inode_info *lli_dir = llu_i2info(dir);
-                int gid = current->fsgid;
-                int rc;
-
-                if (lli_dir->lli_st_mode & S_ISGID) {
-                        gid = lli_dir->lli_st_gid;
-                        if (S_ISDIR(mode))
-                                mode |= S_ISGID;
-                }
-
-                llu_prepare_mdc_op_data(&op_data, dir, NULL, name, namelen, 0);
-                rc = mdc_create(&sbi->ll_mdc_conn, &op_data,
-                                data, datalen, mode, current->fsuid, gid,
-                                time, extra, &request);
-                if (rc) {
-                        inode = (struct inode*)rc;
-                        goto out;
-                }
-                body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*body));
-        }
-
-        inode = llu_new_inode(dir->i_fs, body->ino, body->mode);
-        if (!inode) {
-                /* FIXME more cleanup needed? */
-                goto out;
-        }
-
-        llu_update_inode(inode, body, NULL);
-
-        if (it && it->it_disposition) {
-                /* We asked for a lock on the directory, but were
-                 * granted a lock on the inode.  Since we finally have
-                 * an inode pointer, stuff it in the lock. */
-#if 0
-                ll_mdc_lock_set_inode((struct lustre_handle *)it->it_lock_handle,
-                                      inode);
-#endif
-        }
-
- out:
-        ptlrpc_req_finished(request);
-        return inode;
-}
-
-int llu_create(struct inode *dir, struct pnode_base *pnode, int mode)
-{
-        struct inode *inode;
-#if 0
-        int rc = 0;
-
-        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu,intent=%s\n",
-               dentry->d_name.name, dir->i_ino, LL_IT2STR(dentry->d_it));
-
-        it = dentry->d_it;
-
-        rc = ll_it_open_error(IT_OPEN_CREATE, it);
-        if (rc) {
-                LL_GET_INTENT(dentry, it);
-                ptlrpc_req_finished(it->it_data);
-                RETURN(rc);
-        }
-#endif
-        inode = llu_create_node(dir, pnode->pb_name.name, pnode->pb_name.len,
-                                NULL, 0, mode, 0, NULL);
-
-        if (IS_ERR(inode))
-                RETURN(PTR_ERR(inode));
-
-        pnode->pb_ino = inode;
-
-        return 0;
-}
-
-static int llu_create_obj(struct lustre_handle *conn, struct inode *inode,
-                          struct lov_stripe_md *lsm)
-{
-        struct ptlrpc_request *req = NULL;
-        struct llu_inode_info *lli = llu_i2info(inode);
-        struct lov_mds_md *lmm = NULL;
-        struct obdo *oa;
-        struct iattr iattr;
-        struct mdc_op_data op_data;
-        int rc, err, lmm_size = 0;;
-        ENTRY;
-
-        oa = obdo_alloc();
-        if (!oa)
-                RETURN(-ENOMEM);
-
-        oa->o_mode = S_IFREG | 0600;
-        oa->o_id = lli->lli_st_ino;
-        /* Keep these 0 for now, because chown/chgrp does not change the
-         * ownership on the OST, and we don't want to allow BA OST NFS
-         * users to access these objects by mistake.
-         */
-        oa->o_uid = 0;
-        oa->o_gid = 0;
-        oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE |
-                OBD_MD_FLUID | OBD_MD_FLGID;
-
-        rc = obd_create(conn, oa, &lsm, NULL);
-        if (rc) {
-                CERROR("error creating objects for inode %lu: rc = %d\n",
-                       lli->lli_st_ino, rc);
-                if (rc > 0) {
-                        CERROR("obd_create returned invalid rc %d\n", rc);
-                        rc = -EIO;
-                }
-                GOTO(out_oa, rc);
-        }
-
-        LASSERT(lsm && lsm->lsm_object_id);
-        rc = obd_packmd(conn, &lmm, lsm);
-        if (rc < 0)
-                GOTO(out_destroy, rc);
-
-        lmm_size = rc;
-
-        /* Save the stripe MD with this file on the MDS */
-        memset(&iattr, 0, sizeof(iattr));
-        iattr.ia_valid = ATTR_FROM_OPEN;
-
-        llu_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
-
-        rc = mdc_setattr(&llu_i2sbi(inode)->ll_mdc_conn, &op_data,
-                         &iattr, lmm, lmm_size, &req);
-        ptlrpc_req_finished(req);
-
-        obd_free_diskmd(conn, &lmm);
-
-        /* If we couldn't complete mdc_open() and store the stripe MD on the
-         * MDS, we need to destroy the objects now or they will be leaked.
-         */
-        if (rc) {
-                CERROR("error: storing stripe MD for %lu: rc %d\n",
-                       lli->lli_st_ino, rc);
-                GOTO(out_destroy, rc);
-        }
-        lli->lli_smd = lsm;
-
-        EXIT;
-out_oa:
-        obdo_free(oa);
-        return rc;
-
-out_destroy:
-        obdo_from_inode(oa, inode, OBD_MD_FLTYPE);
-        oa->o_id = lsm->lsm_object_id;
-        oa->o_valid |= OBD_MD_FLID;
-        err = obd_destroy(conn, oa, lsm, NULL);
-        obd_free_memmd(conn, &lsm);
-        if (err) {
-                CERROR("error uncreating inode %lu objects: rc %d\n",
-                       lli->lli_st_ino, err);
-        }
-        goto out_oa;
-}
-
-/* FIXME currently no "it" passed in */
-static int llu_local_open(struct llu_inode_info *lli, struct lookup_intent *it)
-{
-        struct ll_file_data *fd;
-#if 0
-        struct ptlrpc_request *req = it->it_data;
-        struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 1);
-        ENTRY;
-#endif
-        LASSERT(!lli->lli_file_data);
-
-        fd = malloc(sizeof(struct ll_file_data));
-        /* We can't handle this well without reorganizing ll_file_open and
-         * ll_mdc_close, so don't even try right now. */
-        LASSERT(fd != NULL);
-
-        memset(fd, 0, sizeof(*fd));
-#if 0
-        memcpy(&fd->fd_mds_och.och_fh, &body->handle, sizeof(body->handle));
-        fd->fd_mds_och.och_req = it->it_data;
-#endif
-        lli->lli_file_data = fd;
-
-        RETURN(0);
-}
-
-static int llu_osc_open(struct lustre_handle *conn, struct inode *inode,
-                        struct lov_stripe_md *lsm)
-{
-        struct ll_file_data *fd = llu_i2info(inode)->lli_file_data;
-        struct obdo *oa;
-        int rc;
-        ENTRY;
-
-        oa = obdo_alloc();
-        if (!oa)
-                RETURN(-ENOMEM);
-        oa->o_id = lsm->lsm_object_id;
-        oa->o_mode = S_IFREG;
-        oa->o_valid = (OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLBLOCKS |
-                       OBD_MD_FLMTIME | OBD_MD_FLCTIME);
-        rc = obd_open(conn, oa, lsm, NULL, &fd->fd_ost_och);
-        if (rc)
-                GOTO(out, rc);
-
-//        file->f_flags &= ~O_LOV_DELAY_CREATE;
-        obdo_to_inode(inode, oa, OBD_MD_FLBLOCKS | OBD_MD_FLMTIME |
-                      OBD_MD_FLCTIME);
-
-        EXIT;
-out:
-        obdo_free(oa);
-        return rc;
-}
-
-static int llu_file_open(struct inode *inode)
-{
-#if 0
-        struct llu_sb_info *sbi = llu_i2sbi(inode);
-#endif
-        struct llu_inode_info *lli = llu_i2info(inode);
-        struct lustre_handle *conn = llu_i2obdconn(inode);
-        struct lookup_intent *it;
-        struct lov_stripe_md *lsm;
-        int rc = 0;
-
-#if 0
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
-        LL_GET_INTENT(file->f_dentry, it);
-        rc = ll_it_open_error(IT_OPEN_OPEN, it);
-        if (rc)
-                RETURN(rc);
-#endif
-        rc = llu_local_open(lli, it);
-        if (rc)
-                LBUG();
-#if 0
-        mdc_set_open_replay_data(&((struct ll_file_data *)
-                                 file->private_data)->fd_mds_och);
-#endif
-        lsm = lli->lli_smd;
-        if (lsm == NULL) {
-#if 0
-                if (file->f_flags & O_LOV_DELAY_CREATE) {
-                        CDEBUG(D_INODE, "delaying object creation\n");
-                        RETURN(0);
-                }
-#endif
-                if (!lli->lli_smd) {
-                        rc = llu_create_obj(conn, inode, NULL);
-                        if (rc)
-                                GOTO(out_close, rc);
-                } else {
-                        CERROR("warning: stripe already set on ino %lu\n",
-                               lli->lli_st_ino);
-                }
-                lsm = lli->lli_smd;
-        }
-
-        rc = llu_osc_open(conn, inode, lsm);
-        if (rc)
-                GOTO(out_close, rc);
-        RETURN(0);
-
- out_close:
-//        ll_mdc_close(&sbi->ll_mdc_conn, inode, file);
-        return rc;
-}
-
-int llu_iop_open(struct pnode *pnode, int flags, mode_t mode)
-{
-        struct inode *dir = pnode->p_parent->p_base->pb_ino;
-        int rc;
-        /* FIXME later we must add the ldlm here */
-
-        LASSERT(dir);
-
-        /* libsysio forgot to guarentee mode is valid XXX */
-        mode |= S_IFREG;
-
-        if (!pnode->p_base->pb_ino) {
-                rc = llu_create(dir, pnode->p_base, mode);
-                if (rc)
-                        return rc;
-        }
-
-        LASSERT(pnode->p_base->pb_ino);
-        return llu_file_open(pnode->p_base->pb_ino);
-}
-
-
-static int llu_mdc_close(struct lustre_handle *mdc_conn, struct inode *inode)
-{
-        struct llu_inode_info *lli = llu_i2info(inode);
-        struct ll_file_data *fd = lli->lli_file_data;
-        struct ptlrpc_request *req = NULL;
-        unsigned long flags;
-        struct obd_import *imp;
-        int rc;
-
-        /* FIXME add following code later FIXME */
-#if 0
-        /* Complete the open request and remove it from replay list */
-        rc = mdc_close(&ll_i2sbi(inode)->ll_mdc_conn, lli->lli_st_ino,
-                       inode->i_mode, &fd->fd_mds_och.och_fh, &req);
-        if (rc)
-                CERROR("inode %lu close failed: rc = %d\n",
-                                lli->lli_st_ino, rc);
-
-        imp = fd->fd_mds_och.och_req->rq_import;
-        LASSERT(imp != NULL);
-        spin_lock_irqsave(&imp->imp_lock, flags);
-
-        DEBUG_REQ(D_HA, fd->fd_mds_och.och_req, "matched open req %p", 
-                 fd->fd_mds_och.och_req);
-
-        /* We held on to the request for replay until we saw a close for that
-         * file.  Now that we've closed it, it gets replayed on the basis of
-         * its transno only. */
-        fd->fd_mds_och.och_req->rq_replay = 0;
-
-        if (fd->fd_mds_och.och_req->rq_transno) {
-                /* This open created a file, so it needs replay as a
-                 * normal transaction now.  Our reference to it now
-                 * effectively owned by the imp_replay_list, and it'll
-                 * be committed just like other transno-having
-                 * requests from here on out. */
-
-                /* We now retain this close request, so that it is
-                 * replayed if the open is replayed.  We duplicate the
-                 * transno, so that we get freed at the right time,
-                 * and rely on the difference in xid to keep
-                 * everything ordered correctly.
-                 *
-                 * But! If this close was already given a transno
-                 * (because it caused real unlinking of an
-                 * open-unlinked file, f.e.), then we'll be ordered on
-                 * the basis of that and we don't need to do anything
-                 * magical here. */
-                if (!req->rq_transno) {
-                        req->rq_transno = fd->fd_mds_och.och_req->rq_transno;
-                        ptlrpc_retain_replayable_request(req, imp);
-                }
-                spin_unlock_irqrestore(&imp->imp_lock, flags);
-
-                /* Should we free_committed now? we always free before
-                 * replay, so it's probably a wash.  We could check to
-                 * see if the fd_req should already be committed, in
-                 * which case we can avoid the whole retain_replayable
-                 * dance. */
-        } else {
-                /* No transno means that we can just drop our ref. */
-                spin_unlock_irqrestore(&imp->imp_lock, flags);
-        }
-        ptlrpc_req_finished(fd->fd_mds_och.och_req);
-
-        /* Do this after the fd_req->rq_transno check, because we don't want
-         * to bounce off zero references. */
-        ptlrpc_req_finished(req);
-        fd->fd_mds_och.och_fh.cookie = DEAD_HANDLE_MAGIC;
-#endif
-        lli->lli_file_data = NULL;
-        free(fd);
-
-        RETURN(-abs(rc));
-}
-
-static int llu_file_release(struct inode *inode)
-{
-        struct llu_sb_info *sbi = llu_i2sbi(inode);
-        struct llu_inode_info *lli = llu_i2info(inode);
-        struct lov_stripe_md *lsm = lli->lli_smd;
-        struct ll_file_data *fd;
-        struct obdo oa;
-        int rc = 0, rc2;
-
-        fd = lli->lli_file_data;
-        if (!fd) /* no process opened the file after an mcreate */
-                RETURN(rc = 0);
-
-        /* we might not be able to get a valid handle on this file
-         * again so we really want to flush our write cache.. */
-        if (S_ISREG(inode->i_mode) && lsm) {
-                memset(&oa, 0, sizeof(oa));
-                oa.o_id = lsm->lsm_object_id;
-                oa.o_mode = S_IFREG;
-                oa.o_valid = OBD_MD_FLTYPE | OBD_MD_FLID;
-                
-                memcpy(&oa.o_inline, &fd->fd_ost_och, FD_OSTDATA_SIZE);
-                oa.o_valid |= OBD_MD_FLHANDLE;
-
-                rc = obd_close(&sbi->ll_osc_conn, &oa, lsm, NULL);
-                if (rc)
-                        CERROR("inode %lu object close failed: rc = "
-                               "%d\n", lli->lli_st_ino, rc);
-       }
-
-        rc2 = llu_mdc_close(&sbi->ll_mdc_conn, inode);
-        if (rc2 && !rc)
-                rc = rc2;
-
-        RETURN(rc);
-}
-
-int llu_iop_close(struct inode *inode)
-{
-        return llu_file_release(inode);
-}
-
-int llu_iop_ipreadv(struct inode *ino,
-                    struct io_arguments *ioargs,
-                    struct ioctx **ioctxp)
-{
-        struct ioctx *ioctx;
-
-        if (!ioargs->ioarg_iovlen)
-                return 0;
-        if (ioargs->ioarg_iovlen < 0)
-                return -EINVAL;
-
-        ioctx = _sysio_ioctx_new(ino, ioargs);
-        if (!ioctx)
-                return -ENOMEM;
-
-        ioctx->ioctx_cc = llu_file_read(ino,
-                                        ioctx->ioctx_iovec,
-                                        ioctx->ioctx_iovlen,
-                                        ioctx->ioctx_offset);
-        if (ioctx->ioctx_cc < 0)
-                ioctx->ioctx_errno = ioctx->ioctx_cc;
-
-        *ioctxp = ioctx;
-        return 0;
-}
-
-int llu_iop_ipwritev(struct inode *ino,
-                     struct io_arguments *ioargs,
-                     struct ioctx **ioctxp)
-{
-        struct ioctx *ioctx;
-
-        if (!ioargs->ioarg_iovlen)
-                return 0;
-        if (ioargs->ioarg_iovlen < 0)
-                return -EINVAL;
-
-        ioctx = _sysio_ioctx_new(ino, ioargs);
-        if (!ioctx)
-                return -ENOMEM;
-
-        ioctx->ioctx_cc = llu_file_write(ino,
-                                         ioctx->ioctx_iovec,
-                                         ioctx->ioctx_iovlen,
-                                         ioctx->ioctx_offset);
-        if (ioctx->ioctx_cc < 0)
-                ioctx->ioctx_errno = ioctx->ioctx_cc;
-
-        *ioctxp = ioctx;
-        return 0;
-}
-
diff --git a/lustre/liblustre/libtest.c b/lustre/liblustre/libtest.c
deleted file mode 100644 (file)
index fce75c0..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-#include <stdio.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-
-#include <portals/api-support.h> /* needed for ptpctl.h */
-#include <portals/ptlctl.h>    /* needed for parse_dump */
-
-
-#include <liblustre.h>
-#include <linux/obd.h>
-#include <linux/obd_class.h>
-#include <../user/procbridge/procbridge.h>
-
-ptl_handle_ni_t         tcpnal_ni;
-
-struct pingcli_args {
-        ptl_nid_t mynid;
-        ptl_nid_t nid;
-       ptl_pid_t port;
-        int count;
-        int size;
-};
-
-struct task_struct *current;
-
-struct obd_class_user_state ocus;
-
-/* portals interfaces */
-inline const ptl_handle_ni_t *
-kportal_get_ni (int nal)
-{
-        return &tcpnal_ni;
-}
-
-inline void
-kportal_put_ni (int nal)
-{
-        return;
-}
-
-void init_current(int argc, char **argv)
-{ 
-        current = malloc(sizeof(*current));
-        strncpy(current->comm, argv[0], sizeof(current->comm));
-        current->pid = getpid();
-
-}
-
-extern ptl_nid_t tcpnal_mynid;
-
-int init_lib_portals(struct pingcli_args *args)
-{
-        int rc;
-
-        PtlInit();
-        tcpnal_mynid = args->mynid;
-        rc = PtlNIInit(procbridge_interface, 0, 0, 0, &tcpnal_ni);
-        if (rc != 0) {
-                CERROR("ksocknal: PtlNIInit failed: error %d\n", rc);
-                PtlFini();
-                RETURN (rc);
-        }
-        PtlNIDebug(tcpnal_ni, ~0);
-        return rc;
-}
-
-extern int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd, unsigned long arg);
-
-
-int lib_ioctl(int dev_id, int opc, void * ptr)
-{
-
-       if (dev_id == OBD_DEV_ID) {
-                struct obd_ioctl_data *ioc = ptr;
-               class_handle_ioctl(&ocus, opc, (unsigned long)ptr);
-
-               /* you _may_ need to call obd_ioctl_unpack or some
-                  other verification function if you want to use ioc
-                  directly here */
-               printf ("processing ioctl cmd: %x buf len: %d\n", 
-                       opc,  ioc->ioc_len);
-       }
-       return (0);
-}
-
-int main(int argc, char **argv) 
-{
-        struct pingcli_args *args;
-       args= malloc(sizeof(*args));
-        if (!args) { 
-                printf("Malloc error\n");
-                exit(1);
-        }
-
-       args->mynid   = ntohl (inet_addr (argv[1]));
-        INIT_LIST_HEAD(&ocus.ocus_conns);
-
-        init_current(argc, argv);
-        init_obdclass();
-        init_lib_portals(args);
-        ptlrpc_init();
-        ldlm_init();
-        osc_init();
-        echo_client_init();
-        /* XXX  need mdc_getlovinfo before lov_init can work.. */
-        //        lov_init();
-
-       parse_dump("/tmp/DUMP_FILE", lib_ioctl);
-
-        printf("Hello\n");
-        return 0;
-}
-
diff --git a/lustre/liblustre/llite_lib.c b/lustre/liblustre/llite_lib.c
deleted file mode 100644 (file)
index b11de88..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Lustre Light Super operations
- *
- *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define DEBUG_SUBSYSTEM S_LLITE
-
-#include <stdlib.h>
-#include <string.h>
-#include <error.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-
-#include <sysio.h>
-#include <fs.h>
-#include <mount.h>
-#include <inode.h>
-#include <file.h>
-
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-
-#include <portals/api-support.h> /* needed for ptpctl.h */
-#include <portals/ptlctl.h>    /* needed for parse_dump */
-
-#include "llite_lib.h"
-
-
-ptl_handle_ni_t         tcpnal_ni;
-struct task_struct *current;
-struct obd_class_user_state ocus;
-
-/* portals interfaces */
-ptl_handle_ni_t *
-kportal_get_ni (int nal)
-{
-        return &tcpnal_ni;
-}
-
-inline void
-kportal_put_ni (int nal)
-{
-        return;
-}
-
-struct ldlm_namespace;
-struct ldlm_res_id;
-struct obd_import;
-
-extern int ldlm_cli_cancel_unused(struct ldlm_namespace *ns, struct ldlm_res_id *res_id, int flags);
-extern int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only);
-extern int ldlm_replay_locks(struct obd_import *imp);
-
-void *inter_module_get(char *arg)
-{
-        if (!strcmp(arg, "tcpnal_ni"))
-                return &tcpnal_ni;
-        else if (!strcmp(arg, "ldlm_cli_cancel_unused"))
-                return ldlm_cli_cancel_unused;
-        else if (!strcmp(arg, "ldlm_namespace_cleanup"))
-                return ldlm_namespace_cleanup;
-        else if (!strcmp(arg, "ldlm_replay_locks"))
-                return ldlm_replay_locks;
-        else
-                return NULL;
-}
-
-void init_current(char *comm)
-{ 
-        current = malloc(sizeof(*current));
-        current->fs = malloc(sizeof(*current->fs));
-        current->fs->umask = umask(0777);
-        umask(current->fs->umask);
-        strncpy(current->comm, comm, sizeof(current->comm));
-        current->pid = getpid();
-        current->fsuid = 0;
-        current->fsgid = 0;
-        current->cap_effective = 0;
-        memset(&current->pending, 0, sizeof(current->pending));
-}
-
-ptl_nid_t tcpnal_mynid;
-
-int init_lib_portals()
-{
-        int rc;
-
-        PtlInit();
-        rc = PtlNIInit(procbridge_interface, 0, 0, 0, &tcpnal_ni);
-        if (rc != 0) {
-                CERROR("ksocknal: PtlNIInit failed: error %d\n", rc);
-                PtlFini();
-                RETURN (rc);
-        }
-        PtlNIDebug(tcpnal_ni, ~0);
-        return rc;
-}
-
-extern int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd, unsigned long arg);
-
-struct mount_option_s mount_option = {NULL, NULL};
-
-/* FIXME simple arg parser FIXME */
-void parse_mount_options(void *arg)
-{
-        char *buf = NULL;
-        struct obd_ioctl_data *data;
-        char *ptr, *comma, *eq, **tgt, *v;
-        int len;
-
-        if (obd_ioctl_getdata(&buf, &len, arg)) {
-                CERROR("OBD ioctl: data error\n");
-                return;
-        }
-        data = (struct obd_ioctl_data *)buf;
-        ptr = data->ioc_inlbuf1;
-        printf("mount option: %s\n", ptr);
-
-        while (ptr) {
-                eq = strchr(ptr, '=');
-                if (!eq)
-                        return;
-
-                *eq = 0;
-                if (!strcmp("osc", ptr))
-                        tgt = &mount_option.osc_uuid;
-                else if (!strcmp("mdc", ptr))
-                        tgt = &mount_option.mdc_uuid;
-                else {
-                        printf("Unknown mount option %s\n", ptr);
-                        return;
-                }
-
-                v = eq + 1;
-                comma = strchr(v, ',');
-                if (comma) {
-                        *comma = 0;
-                        ptr = comma + 1;
-                } else
-                        ptr = NULL;
-
-                *tgt = malloc(strlen(v)+1);
-                strcpy(*tgt, v);
-        }
-
-        if (buf)
-                obd_ioctl_freedata(buf, len);
-}
-
-int lib_ioctl(int dev_id, int opc, void * ptr)
-{
-        int rc;
-
-       if (dev_id == OBD_DEV_ID) {
-                struct obd_ioctl_data *ioc = ptr;
-
-                if (opc == OBD_IOC_MOUNTOPT) {
-                        parse_mount_options(ptr);
-                        return 0;
-                }
-
-               rc = class_handle_ioctl(&ocus, opc, (unsigned long)ptr);
-
-               /* you _may_ need to call obd_ioctl_unpack or some
-                  other verification function if you want to use ioc
-                  directly here */
-               printf ("processing ioctl cmd: %x buf len: %d, rc %d\n", 
-                       opc,  ioc->ioc_len, rc);
-
-                if (rc)
-                        return rc;
-       }
-       return (0);
-}
-
-int lllib_init(char *arg)
-{
-       tcpnal_mynid = ntohl(inet_addr(arg));
-        INIT_LIST_HEAD(&ocus.ocus_conns);
-
-        init_current("dummy");
-        if (init_obdclass() ||
-            init_lib_portals() ||
-            ptlrpc_init() ||
-            ldlm_init() ||
-            mdc_init() ||
-            lov_init() ||
-            osc_init())
-                return -1;
-
-       if (parse_dump("/tmp/DUMP_FILE", lib_ioctl))
-                return -1;
-
-        return _sysio_fssw_register("llite", &llu_fssw_ops);
-}
-
-/* FIXME */
-void generate_random_uuid(unsigned char uuid_out[16])
-{
-        int *arr = (int*)uuid_out;
-        int i;
-
-        for (i = 0; i < sizeof(uuid_out)/sizeof(int); i++)
-                arr[i] = rand();
-}
-
diff --git a/lustre/liblustre/llite_lib.h b/lustre/liblustre/llite_lib.h
deleted file mode 100644 (file)
index ce2e23b..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-#ifndef __LLU_H_
-#define __LLU_H_
-
-#include <liblustre.h>
-#include <linux/obd.h>
-#include <linux/obd_class.h>
-#include <portals/procbridge.h>
-#include <linux/lustre_lite.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-struct ll_file_data {
-        struct obd_client_handle fd_mds_och;
-        struct obd_client_handle fd_ost_och;
-        __u32 fd_flags;
-};
-
-struct llu_sb_info
-{
-        struct obd_uuid         ll_sb_uuid;
-        struct lustre_handle    ll_mdc_conn;
-        struct lustre_handle    ll_osc_conn;
-        obd_id                  ll_rootino;
-        int                     ll_flags;
-        struct list_head        ll_conn_chain;
-};
-
-struct llu_inode_info {
-       struct llu_sb_info      *lli_sbi;
-       struct ll_fid           lli_fid;
-        struct lov_stripe_md   *lli_smd;
-        char                   *lli_symlink_name;
-        /*struct semaphore      lli_open_sem;*/
-        unsigned long          lli_flags;
-        struct list_head       lli_read_extents;
-
-       /* in libsysio we have no chance to store data in file,
-        * so place it here */
-       struct ll_file_data     *lli_file_data;
-
-       /* stat FIXME not 64 bit clean */
-       dev_t                   lli_st_dev;
-       ino_t                   lli_st_ino;
-       mode_t                  lli_st_mode;
-       nlink_t                 lli_st_nlink;
-       uid_t                   lli_st_uid;
-       gid_t                   lli_st_gid;
-       dev_t                   lli_st_rdev;
-       loff_t                  lli_st_size;
-       unsigned int            lli_st_blksize;
-       unsigned int            lli_st_blocks;
-       time_t                  lli_st_atime;
-       time_t                  lli_st_mtime;
-       time_t                  lli_st_ctime;
-
-       /* not for stat, change it later */
-       int                     lli_st_flags;
-       unsigned long           lli_st_generation;
-};
-
-static inline struct llu_sb_info *llu_fs2sbi(struct filesys *fs)
-{
-       return (struct llu_sb_info*)(fs->fs_private);
-}
-
-static inline struct llu_inode_info *llu_i2info(struct inode *inode)
-{
-       return (struct llu_inode_info*)(inode->i_private);
-}
-
-static inline struct llu_sb_info *llu_i2sbi(struct inode *inode)
-{
-        return llu_i2info(inode)->lli_sbi;
-}
-
-static inline struct client_obd *sbi2mdc(struct llu_sb_info *sbi)
-{
-       struct obd_device *obd = class_conn2obd(&sbi->ll_mdc_conn);
-       if (obd == NULL)
-               LBUG();
-       return &obd->u.cli;
-}
-
-static inline struct lustre_handle *llu_i2obdconn(struct inode *inode)
-{
-        return &(llu_i2info(inode)->lli_sbi->ll_osc_conn);
-}
-
-
-struct mount_option_s
-{
-       char *mdc_uuid;
-       char *osc_uuid;
-};
-
-/* llite_lib.c */
-void generate_random_uuid(unsigned char uuid_out[16]);
-
-extern struct mount_option_s mount_option;
-
-/* super.c */
-void llu_update_inode(struct inode *inode, struct mds_body *body,
-                      struct lov_stripe_md *lmm);
-void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid);
-void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid);
-struct inode* llu_new_inode(struct filesys *fs, ino_t ino, mode_t mode);
-
-extern struct fssw_ops llu_fssw_ops;
-
-/* file.c */
-void llu_prepare_mdc_op_data(struct mdc_op_data *data,
-                             struct inode *i1,
-                             struct inode *i2,
-                             const char *name,
-                             int namelen,
-                             int mode);
-int llu_create(struct inode *dir, struct pnode_base *pnode, int mode);
-int llu_iop_open(struct pnode *pnode, int flags, mode_t mode);
-int llu_iop_close(struct inode *inode);
-int llu_iop_ipreadv(struct inode *ino,
-                    struct io_arguments *ioargs,
-                    struct ioctx **ioctxp);
-int llu_iop_ipwritev(struct inode *ino,
-                     struct io_arguments *ioargs,
-                     struct ioctx **ioctxp);
-
-/* rw.c */
-int llu_iop_iodone(struct ioctx *ioctxp __IS_UNUSED);
-ssize_t llu_file_write(struct inode *inode, const struct iovec *iovec,
-                      size_t iovlen, loff_t pos);
-ssize_t llu_file_read(struct inode *inode, const struct iovec *iovec,
-                       size_t iovlen, loff_t pos);
-
-#endif
diff --git a/lustre/liblustre/lltest.c b/lustre/liblustre/lltest.c
deleted file mode 100644 (file)
index acdc47e..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Lustre Light user test program
- *
- *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define _BSD_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/queue.h>
-#include <sys/statvfs.h>
-
-#include <sysio.h>
-#include <mount.h>
-
-
-int do_stat(const char *name)
-{
-       struct stat stat;
-
-       if (lstat(name, &stat)) {
-               perror("failed to stat: ");
-               return -1;
-       }
-       printf("******* stat '%s' ********\n", name);
-       printf("ino:\t\t%lu\n",stat.st_ino);
-       printf("mode:\t\t%o\n",stat.st_mode);
-       printf("nlink:\t\t%d\n",stat.st_nlink);
-        printf("uid/gid:\t%d/%d\n", stat.st_uid, stat.st_gid);
-        printf("size:\t\t%ld\n", stat.st_size);
-        printf("blksize:\t%ld\n", stat.st_blksize);
-        printf("block count:\t%ld\n", stat.st_blocks);
-       printf("atime:\t\t%lu\n",stat.st_atime);
-       printf("mtime:\t\t%lu\n",stat.st_mtime);
-       printf("ctime:\t\t%lu\n",stat.st_ctime);
-       printf("******* end stat ********\n");
-
-       return 0;
-}
-/*
- * Get stats of file and file system.
- *
- * Usage: test_stats [-a] [-r <root-path>] [-m <root-driver>] [<path> ...]
- */
-
-extern int lllib_init(char *arg);
-
-char   *root_driver = "llite";
-char   *root_path = "/";
-unsigned mntflgs = 0;
-struct mount root_mount;
-
-extern int portal_debug;
-extern int portal_subsystem_debug;
-
-char* files[] = {"/dir1", "/dir1/file1", "/dir1/file2", "/dir1/dir2", "/dir1/dir2/file3"};
-
-int
-main(int argc, char * const argv[])
-{
-       struct stat statbuf;
-       int rc, err, i, fd, written, readed;
-       char pgbuf[4096], readbuf[4096];
-       int npages;
-
-       if (_sysio_init() != 0) {
-               perror("init sysio");
-               exit(1);
-       }
-       err = lllib_init(argv[1]);
-       if (err) {
-               perror("init llite driver");
-               exit(1);
-       }       
-
-       err = _sysio_mount_root(root_path, root_driver, mntflgs, NULL);
-       if (err) {
-               errno = -err;
-               perror(root_driver);
-               exit(1);
-       }
-#if 0
-       for (i=0; i< sizeof(files)/sizeof(char*); i++) {
-               printf("******** stat %s *********\n", files[i]);
-               /* XXX ugly, only for testing */
-               err = fixme_lstat(files[i], &statbuf);
-               if (err)
-                       perror(root_driver);
-               printf("******** end stat %s: %d*********\n", files[i], err);
-       }
-#endif
-#if 0
-       portal_debug = 0;
-       portal_subsystem_debug = 0;
-       npages = 10;
-
-       fd = open("/newfile01", O_RDWR|O_CREAT|O_TRUNC, 00664);
-       printf("***************** open return %d ****************\n", fd);
-
-       printf("***************** begin write pages ****************\n");
-       for (i = 0; i < npages; i++ ) {
-               memset(pgbuf, ('A'+ i%10), 4096);
-               written = write(fd, pgbuf, 4096);
-               printf(">>> page %d: %d bytes written\n", i, written);
-       }
-
-       printf("***************** begin read pages ****************\n");
-       lseek(fd, 0, SEEK_SET);
-
-       for (i = 0; i < npages; i++ ) {
-               memset(readbuf, '8', 4096);
-               readed = read(fd, readbuf, 4096);
-               readbuf[10] = 0;
-               printf("<<< page %d: %d bytes (%s)\n", i, readed, readbuf);
-       }
-        close(fd);
-#endif
-
-#if 1
-        //rc = chown("/newfile01", 10, 20);
-        rc = chmod("/newfile01", 0777);
-        printf("-------------- chmod return %d -----------\n", rc);
-        do_stat("/newfile01");
-#endif
-
-       printf("sysio is about shutdown\n");
-       /*
-        * Clean up.
-        */
-       _sysio_shutdown();
-
-       printf("complete successfully\n");
-       return 0;
-}
diff --git a/lustre/liblustre/rw.c b/lustre/liblustre/rw.c
deleted file mode 100644 (file)
index 8562b69..0000000
+++ /dev/null
@@ -1,531 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Lustre Light Super operations
- *
- *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define DEBUG_SUBSYSTEM S_LLITE
-
-#include <stdlib.h>
-#include <string.h>
-#include <error.h>
-#include <assert.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-
-#include <sysio.h>
-#include <fs.h>
-#include <mount.h>
-#include <inode.h>
-#include <file.h>
-
-#include "llite_lib.h"
-
-int llu_iop_iodone(struct ioctx *ioctxp __IS_UNUSED)
-{
-        return 1;
-}
-
-/*
- * this grabs a lock and manually implements behaviour that makes it look
- * like the OST is returning the file size with each lock acquisition
- */
-int llu_extent_lock(struct ll_file_data *fd, struct inode *inode,
-                   struct lov_stripe_md *lsm,
-                   int mode, struct ldlm_extent *extent,
-                   struct lustre_handle *lockh)
-{
-#if 0
-        struct ll_inode_info *lli = ll_i2info(inode);
-        int rc;
-        ENTRY;
-
-        rc = ll_extent_lock_no_validate(fd, inode, lsm, mode, extent, lockh);
-        if (rc != ELDLM_OK)
-                RETURN(rc);
-
-        /* always do a getattr for the first person to pop out of lock
-         * acquisition.. the DID_GETATTR flag and semaphore serialize
-         * this initial race.  we used to make a decision based on whether
-         * the lock was matched or acquired, but the matcher could win the
-         * waking race with the first issuer so that was no good..
-         */
-        if (test_bit(LLI_F_DID_GETATTR, &lli->lli_flags))
-                RETURN(ELDLM_OK);
-
-        down(&lli->lli_getattr_sem);
-
-        if (!test_bit(LLI_F_DID_GETATTR, &lli->lli_flags)) {
-                rc = ll_inode_getattr(inode, lsm, fd ? &fd->fd_ost_och : NULL);
-                if (rc == 0) {
-                        set_bit(LLI_F_DID_GETATTR, &lli->lli_flags);
-                } else {
-                        /* XXX can this fail? */
-                        ll_extent_unlock(fd, inode, lsm, mode, lockh);
-                }
-        }
-
-        up(&lli->lli_getattr_sem);
-        RETURN(rc);
-#else
-        return ELDLM_OK;
-#endif
-}
-
-int ll_extent_unlock(struct ll_file_data *fd, struct inode *inode,
-                struct lov_stripe_md *lsm, int mode,
-                struct lustre_handle *lockh)
-{
-#if 0
-        struct ll_sb_info *sbi = ll_i2sbi(inode);
-        int rc;
-        ENTRY;
-
-        /* XXX phil: can we do this?  won't it screw the file size up? */
-        if ((fd && (fd->fd_flags & LL_FILE_IGNORE_LOCK)) ||
-            (sbi->ll_flags & LL_SBI_NOLCK))
-                RETURN(0);
-
-        rc = obd_cancel(&sbi->ll_osc_conn, lsm, mode, lockh);
-
-        RETURN(rc);
-#else
-        return 0;
-#endif
-}
-
-static int llu_brw(int cmd, struct inode *inode, struct page *page, int flags)
-{
-        struct llu_inode_info *lli = llu_i2info(inode);
-        struct lov_stripe_md *lsm = lli->lli_smd;
-        struct obd_brw_set *set;
-        struct brw_page pg;
-        int rc;
-        ENTRY;
-
-        set = obd_brw_set_new();
-        if (set == NULL)
-                RETURN(-ENOMEM);
-
-        pg.pg = page;
-        pg.off = ((obd_off)page->index) << PAGE_SHIFT;
-
-        /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */
-#if 0
-        if (cmd == OBD_BRW_WRITE && (pg.off + PAGE_SIZE > lli->lli_st_size))
-                pg.count = lli->lli_st_size % PAGE_SIZE;
-        else
-#endif
-                pg.count = PAGE_SIZE;
-
-        CDEBUG(D_PAGE, "%s %d bytes ino %lu at "LPU64"/"LPX64"\n",
-               cmd & OBD_BRW_WRITE ? "write" : "read", pg.count, lli->lli_st_ino,
-               pg.off, pg.off);
-        if (pg.count == 0) {
-                LBUG();
-        }
-
-        pg.flag = flags;
-
-        set->brw_callback = ll_brw_sync_wait;
-        rc = obd_brw(cmd, llu_i2obdconn(inode), lsm, 1, &pg, set, NULL);
-        if (rc) {
-                if (rc != -EIO)
-                        CERROR("error from obd_brw: rc = %d\n", rc);
-        } else {
-                rc = ll_brw_sync_wait(set, CB_PHASE_START);
-                if (rc)
-                        CERROR("error from callback: rc = %d\n", rc);
-        }
-        obd_brw_set_decref(set);
-
-        RETURN(rc);
-}
-
-static int llu_prepare_write(struct inode *inode, struct page *page,
-                             unsigned from, unsigned to)
-{
-        struct llu_inode_info *lli = llu_i2info(inode);
-        obd_off offset = ((obd_off)page->index) << PAGE_SHIFT;
-        int rc = 0;
-        ENTRY;
-
-#if 0
-        if (!PageLocked(page))
-                LBUG();
-
-        if (PageUptodate(page))
-                RETURN(0);
-
-        //POISON(addr + from, 0xca, to - from);
-#endif
-        /* We're completely overwriting an existing page, so _don't_ set it up
-         * to date until commit_write */
-        if (from == 0 && to == PAGE_SIZE)
-                RETURN(0);
-
-        /* If are writing to a new page, no need to read old data.
-         * the extent locking and getattr procedures in ll_file_write have
-         * guaranteed that i_size is stable enough for our zeroing needs */
-        if (lli->lli_st_size <= offset) {
-                memset(kmap(page), 0, PAGE_SIZE);
-                kunmap(page);
-                GOTO(prepare_done, rc = 0);
-        }
-
-        rc = llu_brw(OBD_BRW_READ, inode, page, 0);
-
-        EXIT;
-
- prepare_done:
-        return rc;
-}
-
-static int llu_commit_write(struct inode *inode, struct page *page,
-                            unsigned from, unsigned to)
-{
-        struct llu_inode_info *lli = llu_i2info(inode);
-        loff_t size;
-        int rc;
-        ENTRY;
-#if 0
-        LASSERT(inode == file->f_dentry->d_inode);
-        LASSERT(PageLocked(page));
-
-        CDEBUG(D_INODE, "inode %p is writing page %p from %d to %d at %lu\n",
-               inode, page, from, to, page->index);
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu,from=%d,to=%d\n",
-               inode->i_ino, from, to);
-        /* to match full page case in prepare_write */
-        SetPageUptodate(page);
-        /* mark the page dirty, put it on mapping->dirty,
-         * mark the inode PAGES_DIRTY, put it on sb->dirty */
-        set_page_dirty(page);
-#endif
-        rc = llu_brw(OBD_BRW_WRITE, inode, page, 0);
-        if (rc)
-                return rc;
-
-        /* this is matched by a hack in obdo_to_inode at the moment */
-        size = (((obd_off)page->index) << PAGE_SHIFT) + to;
-        if (size > lli->lli_st_size)
-                lli->lli_st_size = size;
-
-        RETURN(0);
-} /* ll_commit_write */
-
-ssize_t
-llu_generic_file_write(struct inode *inode, const char *buf,
-                       size_t count, loff_t pos)
-{
-       struct page     *page;
-       ssize_t         written;
-       long            status = 0;
-       int             err;
-       unsigned        bytes;
-
-       if ((ssize_t) count < 0)
-               return -EINVAL;
-#if 0
-       down(&inode->i_sem);
-#endif
-       if (pos < 0)
-                return -EINVAL;
-
-       written = 0;
-
-#if 0
-       remove_suid(inode);
-       update_inode_times(inode);
-#endif
-       do {
-               unsigned long index, offset;
-               char *kaddr;
-
-               /*
-                * Try to find the page in the cache. If it isn't there,
-                * allocate a free page.
-                */
-               offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
-               index = pos >> PAGE_CACHE_SHIFT;
-               bytes = PAGE_CACHE_SIZE - offset;
-               if (bytes > count) {
-                       bytes = count;
-               }
-
-               status = -ENOMEM;       /* we'll assign it later anyway */
-               page = __grab_cache_page(index);
-               if (!page)
-                       break;
-
-               kaddr = kmap(page);
-               status = llu_prepare_write(inode, page, offset, offset+bytes);
-               if (status)
-                       goto sync_failure;
-
-               memcpy(kaddr+offset, buf, bytes);
-
-               status = llu_commit_write(inode, page, offset, offset+bytes);
-               if (!status)
-                       status = bytes;
-
-               if (status >= 0) {
-                       written += status;
-                       count -= status;
-                       pos += status;
-                       buf += status;
-               }
-unlock:
-               kunmap(page);
-               page_cache_release(page);
-
-               if (status < 0)
-                       break;
-       } while (count);
-done:
-       err = written ? written : status;
-
-#if 0
-       up(&inode->i_sem);
-#endif
-       return err;
-
-       status = -EFAULT;
-       goto unlock;
-
-sync_failure:
-       /*
-        * If blocksize < pagesize, prepare_write() may have instantiated a
-        * few blocks outside i_size.  Trim these off again.
-        */
-       kunmap(page);
-       page_cache_release(page);
-       goto done;
-}
-
-ssize_t llu_file_write(struct inode *inode, const struct iovec *iovec,
-                       size_t iovlen, loff_t pos)
-{
-        struct llu_inode_info *lli = llu_i2info(inode);
-        struct ll_file_data *fd = lli->lli_file_data; /* XXX not ready don't use it now */
-        struct lustre_handle lockh = { 0 };
-        struct lov_stripe_md *lsm = lli->lli_smd;
-        struct ldlm_extent extent;
-        ldlm_error_t err;
-        ssize_t retval = 0;
-        ENTRY;
-
-        /* XXX consider other types later */
-        if (!S_ISREG(lli->lli_st_mode))
-                LBUG();
-#if 0
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu,size="LPSZ",offset=%Ld\n",
-               inode->i_ino, count, *ppos);
-
-        /*
-         * sleep doing some writeback work of this mount's dirty data
-         * if the VM thinks we're low on memory.. other dirtying code
-         * paths should think about doing this, too, but they should be
-         * careful not to hold locked pages while they do so.  like
-         * ll_prepare_write.  *cough*
-         */
-        ll_check_dirty(inode->i_sb);
-#endif
-        while (iovlen--) {
-                const char *buf = iovec[iovlen].iov_base;
-                size_t count = iovec[iovlen].iov_len;
-
-                /* POSIX, but surprised the VFS doesn't check this already */
-                if (count == 0)
-                        continue;
-
-#if 0
-                if (!S_ISBLK(lli->lli_st_mode) && file->f_flags & O_APPEND) {
-                        extent.start = 0;
-                        extent.end = OBD_OBJECT_EOF;
-                } else  {
-                        extent.start = *ppos;
-                        extent.end = *ppos + count - 1;
-                }
-#else
-                extent.start = pos;
-                extent.end = pos + count - 1;
-#endif
-
-                err = llu_extent_lock(fd, inode, lsm, LCK_PW, &extent, &lockh);
-                if (err != ELDLM_OK)
-                        RETURN(-ENOLCK);
-
-#if 0
-                if (!S_ISBLK(inode->i_mode) && file->f_flags & O_APPEND)
-                        *ppos = inode->i_size;
-
-                CDEBUG(D_INFO, "Writing inode %lu, "LPSZ" bytes, offset %Lu\n",
-                       inode->i_ino, count, *ppos);
-#endif
-                retval += llu_generic_file_write(inode, buf, count, pos);
-        }
-
-        /* XXX errors? */
-        ll_extent_unlock(fd, inode, lsm, LCK_PW, &lockh);
-        return(retval);
-}
-
-static void llu_update_atime(struct inode *inode)
-{
-#if 0
-        struct llu_inode_info *lli = llu_i2info(inode);
-
-#ifdef USE_ATIME
-        struct iattr attr;
-
-        attr.ia_atime = LTIME_S(CURRENT_TIME);
-        attr.ia_valid = ATTR_ATIME;
-
-        if (lli->lli_st_atime == attr.ia_atime) return;
-        if (IS_RDONLY(inode)) return;
-        if (IS_NOATIME(inode)) return;
-
-        /* ll_inode_setattr() sets inode->i_atime from attr.ia_atime */
-        llu_inode_setattr(inode, &attr, 0);
-#else
-        /* update atime, but don't explicitly write it out just this change */
-        inode->i_atime = CURRENT_TIME;
-#endif
-#endif
-}
-
-static size_t llu_generic_file_read(struct inode *inode, char *buf,
-                                    size_t count, loff_t pos)
-{
-        struct llu_inode_info *lli = llu_i2info(inode);
-       unsigned long index, offset;
-       int error = 0;
-        size_t readed = 0;
-
-       index = pos >> PAGE_CACHE_SHIFT;
-       offset = pos & ~PAGE_CACHE_MASK;
-
-       do {
-               struct page *page;
-               unsigned long end_index, nr;
-
-               end_index = lli->lli_st_size >> PAGE_CACHE_SHIFT;
-
-               if (index > end_index)
-                       break;
-               nr = PAGE_CACHE_SIZE;
-               if (index == end_index) {
-                       nr = lli->lli_st_size & ~PAGE_CACHE_MASK;
-                       if (nr <= offset)
-                               break;
-               }
-
-               nr = nr - offset;
-                if (nr > count)
-                        nr = count;
-
-                page = grab_cache_page(index);
-                if (!page) {
-                        error = -ENOMEM;
-                        break;
-                }
-
-                error = llu_brw(OBD_BRW_READ, inode, page, 0);
-               if (error) {
-                       page_cache_release(page);
-                        break;
-               }
-
-                memcpy(buf, kmap(page)+offset, nr);
-               offset += nr;
-               index += offset >> PAGE_CACHE_SHIFT;
-               offset &= ~PAGE_CACHE_MASK;
-                readed += nr;
-                count -= nr;
-
-               page_cache_release(page);
-       } while (count);
-
-        if (error)
-                return error;
-        return readed;
-}
-
-ssize_t llu_file_read(struct inode *inode, const struct iovec *iovec,
-                       size_t iovlen, loff_t pos)
-{
-        struct llu_inode_info *lli = llu_i2info(inode);
-        struct ll_file_data *fd = lli->lli_file_data;
-        struct lov_stripe_md *lsm = lli->lli_smd;
-        struct lustre_handle lockh = { 0 };
-#if 0
-        struct ll_read_extent rextent;
-#else
-        struct ldlm_extent extent;
-#endif
-        ldlm_error_t err;
-        ssize_t retval = 0;
-        ENTRY;
-
-        while (iovlen--) {
-                char *buf = iovec[iovlen].iov_base;
-                size_t count = iovec[iovlen].iov_len;
-
-                /* "If nbyte is 0, read() will return 0 and have no other results."
-                 *                      -- Single Unix Spec */
-                if (count == 0)
-                        RETURN(0);
-
-#if 0
-                rextent.re_extent.start = pos;
-                rextent.re_extent.end = pos + count - 1;
-#else
-                extent.start = pos;
-                extent.end = pos + count - 1;
-#endif
-                err = llu_extent_lock(fd, inode, lsm, LCK_PR, &extent, &lockh);
-                if (err != ELDLM_OK)
-                        RETURN(-ENOLCK);
-#if 0
-                rextent.re_task = current;
-                spin_lock(&lli->lli_read_extent_lock);
-                list_add(&rextent.re_lli_item, &lli->lli_read_extents);
-                spin_unlock(&lli->lli_read_extent_lock);
-#endif
-                CDEBUG(D_INFO, "Reading inode %lu, "LPSZ" bytes, offset %Ld\n",
-                       lli->lli_st_ino, count, pos);
-                retval = llu_generic_file_read(inode, buf, count, pos);
-#if 0
-                spin_lock(&lli->lli_read_extent_lock);
-                list_del(&rextent.re_lli_item);
-                spin_unlock(&lli->lli_read_extent_lock);
-#endif
-        }
-
-        if (retval > 0)
-                llu_update_atime(inode);
-
-        /* XXX errors? */
-        ll_extent_unlock(fd, inode, lsm, LCK_PR, &lockh);
-        RETURN(retval);
-}
-
diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c
deleted file mode 100644 (file)
index 27ac231..0000000
+++ /dev/null
@@ -1,781 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Lustre Light Super operations
- *
- *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define DEBUG_SUBSYSTEM S_LLITE
-
-#include <stdlib.h>
-#include <string.h>
-#include <error.h>
-#include <assert.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-
-#include <sysio.h>
-#include <fs.h>
-#include <mount.h>
-#include <inode.h>
-#include <file.h>
-
-#include "llite_lib.h"
-
-static void llu_fsop_gone(struct filesys *fs)
-{
-        /* FIXME */
-}
-
-static struct inode_ops llu_inode_ops;
-
-void llu_update_inode(struct inode *inode, struct mds_body *body,
-                      struct lov_stripe_md *lsm)
-{
-        struct llu_inode_info *lli = llu_i2info(inode);
-
-        LASSERT ((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0));
-        if (lsm != NULL) {
-                if (lli->lli_smd == NULL)                        
-                        lli->lli_smd = lsm;
-                else
-                        LASSERT (!memcmp (lli->lli_smd, lsm,
-                                          sizeof (*lsm)));
-        }
-
-        if (body->valid & OBD_MD_FLID)
-                lli->lli_st_ino = body->ino;
-        if (body->valid & OBD_MD_FLATIME)
-                LTIME_S(lli->lli_st_atime) = body->atime;
-        if (body->valid & OBD_MD_FLMTIME)
-                LTIME_S(lli->lli_st_mtime) = body->mtime;
-        if (body->valid & OBD_MD_FLCTIME)
-                LTIME_S(lli->lli_st_ctime) = body->ctime;
-        if (body->valid & OBD_MD_FLMODE)
-                lli->lli_st_mode = (lli->lli_st_mode & S_IFMT)|(body->mode & ~S_IFMT);
-        if (body->valid & OBD_MD_FLTYPE)
-                lli->lli_st_mode = (lli->lli_st_mode & ~S_IFMT)|(body->mode & S_IFMT);
-        if (body->valid & OBD_MD_FLUID)
-                lli->lli_st_uid = body->uid;
-        if (body->valid & OBD_MD_FLGID)
-                lli->lli_st_gid = body->gid;
-        if (body->valid & OBD_MD_FLFLAGS)
-                lli->lli_st_flags = body->flags;
-        if (body->valid & OBD_MD_FLNLINK)
-                lli->lli_st_nlink = body->nlink;
-        if (body->valid & OBD_MD_FLGENER)
-                lli->lli_st_generation = body->generation;
-        if (body->valid & OBD_MD_FLRDEV)
-                lli->lli_st_rdev = body->rdev;
-        if (body->valid & OBD_MD_FLSIZE)
-                lli->lli_st_size = body->size;
-        if (body->valid & OBD_MD_FLBLOCKS)
-                lli->lli_st_blocks = body->blocks;
-
-        /* fillin fid */
-        if (body->valid & OBD_MD_FLID)
-                lli->lli_fid.id = body->ino;
-        if (body->valid & OBD_MD_FLGENER)
-                lli->lli_fid.generation = body->generation;
-        if (body->valid & OBD_MD_FLTYPE)
-                lli->lli_fid.f_type = body->mode & S_IFMT;
-}
-
-void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid)
-{
-        struct llu_inode_info *lli = llu_i2info(dst);
-
-        valid &= src->o_valid;
-
-        if (valid & OBD_MD_FLATIME)
-                LTIME_S(lli->lli_st_atime) = src->o_atime;
-        if (valid & OBD_MD_FLMTIME)
-                LTIME_S(lli->lli_st_mtime) = src->o_mtime;
-        if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(lli->lli_st_ctime))
-                LTIME_S(lli->lli_st_ctime) = src->o_ctime;
-        if (valid & OBD_MD_FLSIZE)
-                lli->lli_st_size = src->o_size;
-        if (valid & OBD_MD_FLBLOCKS) /* allocation of space */
-                lli->lli_st_blocks = src->o_blocks;
-        if (valid & OBD_MD_FLBLKSZ)
-                lli->lli_st_blksize = src->o_blksize;
-        if (valid & OBD_MD_FLTYPE)
-                lli->lli_st_mode = (lli->lli_st_mode & ~S_IFMT) | (src->o_mode & S_IFMT);
-        if (valid & OBD_MD_FLMODE)
-                lli->lli_st_mode = (lli->lli_st_mode & S_IFMT) | (src->o_mode & ~S_IFMT);
-        if (valid & OBD_MD_FLUID)
-                lli->lli_st_uid = src->o_uid;
-        if (valid & OBD_MD_FLGID)
-                lli->lli_st_gid = src->o_gid;
-        if (valid & OBD_MD_FLFLAGS)
-                lli->lli_st_flags = src->o_flags;
-        if (valid & OBD_MD_FLNLINK)
-                lli->lli_st_nlink = src->o_nlink;
-        if (valid & OBD_MD_FLGENER)
-                lli->lli_st_generation = src->o_generation;
-        if (valid & OBD_MD_FLRDEV)
-                lli->lli_st_rdev = src->o_rdev;
-}
-
-void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid)
-{
-        struct llu_inode_info *lli = llu_i2info(src);
-
-        if (valid & OBD_MD_FLATIME)
-                dst->o_atime = LTIME_S(lli->lli_st_atime);
-        if (valid & OBD_MD_FLMTIME)
-                dst->o_mtime = LTIME_S(lli->lli_st_mtime);
-        if (valid & OBD_MD_FLCTIME)
-                dst->o_ctime = LTIME_S(lli->lli_st_ctime);
-        if (valid & OBD_MD_FLSIZE)
-                dst->o_size = lli->lli_st_size;
-        if (valid & OBD_MD_FLBLOCKS)   /* allocation of space */
-                dst->o_blocks = lli->lli_st_blocks;
-        if (valid & OBD_MD_FLBLKSZ)
-                dst->o_blksize = lli->lli_st_blksize;
-        if (valid & OBD_MD_FLTYPE)
-                dst->o_mode = (dst->o_mode & ~S_IFMT) | (lli->lli_st_mode & S_IFMT);
-        if (valid & OBD_MD_FLMODE)
-                dst->o_mode = (dst->o_mode & S_IFMT) | (lli->lli_st_mode & ~S_IFMT);
-        if (valid & OBD_MD_FLUID)
-                dst->o_uid = lli->lli_st_uid;
-        if (valid & OBD_MD_FLGID)
-                dst->o_gid = lli->lli_st_gid;
-        if (valid & OBD_MD_FLFLAGS)
-                dst->o_flags = lli->lli_st_flags;
-        if (valid & OBD_MD_FLNLINK)
-                dst->o_nlink = lli->lli_st_nlink;
-        if (valid & OBD_MD_FLGENER)
-                dst->o_generation = lli->lli_st_generation;
-        if (valid & OBD_MD_FLRDEV)
-                dst->o_rdev = (__u32)(lli->lli_st_rdev);
-
-        dst->o_valid |= (valid & ~OBD_MD_FLID);
-}
-
-int llu_inode_getattr(struct inode *inode, struct lov_stripe_md *lsm,
-                      char *ostdata)
-{
-        struct llu_sb_info *sbi = llu_i2sbi(inode);
-        struct obdo oa;
-        int rc;
-        ENTRY;
-
-        LASSERT(lsm);
-        LASSERT(sbi);
-
-        memset(&oa, 0, sizeof oa);
-        oa.o_id = lsm->lsm_object_id;
-        oa.o_mode = S_IFREG;
-        oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE |
-                OBD_MD_FLBLOCKS | OBD_MD_FLMTIME | OBD_MD_FLCTIME;
-
-        if (ostdata != NULL) {
-                memcpy(&oa.o_inline, ostdata, FD_OSTDATA_SIZE);
-                oa.o_valid |= OBD_MD_FLHANDLE;
-        }
-
-        rc = obd_getattr(&sbi->ll_osc_conn, &oa, lsm);
-        if (rc)
-                RETURN(rc);
-
-        obdo_to_inode(inode, &oa, OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
-                           OBD_MD_FLMTIME | OBD_MD_FLCTIME);
-
-        RETURN(0);
-}
-
-struct inode* llu_new_inode(struct filesys *fs, ino_t ino, mode_t mode)
-{
-       struct inode *inode;
-        struct llu_inode_info *lli;
-
-        OBD_ALLOC(lli, sizeof(*lli));
-        if (!lli)
-                return NULL;
-
-        /* initialize lli here */
-        lli->lli_sbi = llu_fs2sbi(fs);
-        lli->lli_smd = NULL;
-        lli->lli_symlink_name = NULL;
-        lli->lli_flags = 0;
-        INIT_LIST_HEAD(&lli->lli_read_extents);
-        lli->lli_file_data = NULL;
-
-        /* could file_identifier be 0 ? FIXME */
-       inode = _sysio_i_new(fs, ino, NULL,
-#ifndef AUTOMOUNT_FILE_NAME
-                            mode & S_IFMT,
-#else
-                            mode,      /* all of the bits! */
-#endif
-                             0,
-                            &llu_inode_ops, lli);
-
-       if (!inode)
-               OBD_FREE(lli, sizeof(*lli));
-
-        return inode;
-}
-
-static int llu_iop_lookup(struct pnode *pnode,
-                          struct inode **inop,
-                          struct intent *intnt __IS_UNUSED,
-                          const char *path __IS_UNUSED)
-{
-        struct pnode_base *pb_dir = pnode->p_parent->p_base;
-        struct ptlrpc_request *request = NULL;
-        struct llu_sb_info *sbi = llu_i2sbi(pb_dir->pb_ino);
-        struct ll_fid *fid = &llu_i2info(pb_dir->pb_ino)->lli_fid;
-        struct qstr *name = &pnode->p_base->pb_name;
-        struct mds_body *body;
-        unsigned long valid;
-        char *pname;
-        int rc, easize;
-        struct ll_read_inode2_cookie lic = {.lic_body = NULL, .lic_lsm = NULL};
-
-        /* the mount root inode have no name, so don't call
-         * remote in this case. but probably we need revalidate
-         * it here? FIXME */
-        if (pnode->p_mount->mnt_root == pnode) {
-                struct inode *i = pnode->p_base->pb_ino;
-                I_REF(i);
-                *inop = i;
-                return 0;
-        }
-
-        if (!name->len)
-                return -EINVAL;
-
-        /* mdc_getattr_name require NULL-terminated name */
-        OBD_ALLOC(pname, name->len + 1);
-        if (!pname)
-                return -ENOMEM;
-        memcpy(pname, name->name, name->len);
-        pname[name->len] = 0;
-
-        valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE;
-
-        /* FIXME before getattr_name, we don't know whether
-         * the inode we are finding is regular or not, so here
-         * we blindly require server feed in EA data */
-        easize = obd_size_diskmd(&sbi->ll_osc_conn, NULL);
-        valid |= OBD_MD_FLEASIZE;
-
-        rc = mdc_getattr_name(&sbi->ll_mdc_conn, fid,
-                              pname, name->len + 1,
-                              valid, easize, &request);
-        if (rc < 0) {
-                CERROR("mdc_getattr_name: %d\n", rc);
-                rc = -ENOENT;
-                goto out;
-        }
-        body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*body));
-
-        *inop = llu_new_inode(pnode->p_mount->mnt_fs, body->ino, body->mode);
-        if (!inop)
-                goto out;
-
-        lic.lic_body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*lic.lic_body));
-        LASSERT (lic.lic_body != NULL);
-        LASSERT_REPSWABBED (request, 0);
-
-        if (S_ISREG(lic.lic_body->mode) &&
-            lic.lic_body->valid & OBD_MD_FLEASIZE) {
-                struct lov_mds_md    *lmm;
-                int                   lmm_size;
-                int                   rc;
-                
-                lmm_size = lic.lic_body->eadatasize;
-                if (lmm_size == 0) {
-                        CERROR ("OBD_MD_FLEASIZE set but eadatasize 0\n");
-                        RETURN (-EPROTO);
-                }
-                lmm = lustre_msg_buf(request->rq_repmsg, 0 + 1, lmm_size);
-                LASSERT(lmm != NULL);
-                LASSERT_REPSWABBED (request, 0 + 1);
-
-                rc = obd_unpackmd (&sbi->ll_osc_conn, 
-                                   &lic.lic_lsm, lmm, lmm_size);
-                if (rc < 0) {
-                        CERROR ("Error %d unpacking eadata\n", rc);
-                        RETURN (rc);
-                }
-                LASSERT (rc >= sizeof (*lic.lic_lsm));
-
-        } else {
-                lic.lic_lsm = NULL;
-        }
-
-        llu_update_inode(*inop, body, lic.lic_lsm);
-
-        if (llu_i2info(*inop)->lli_smd) {
-                rc = llu_inode_getattr(*inop, llu_i2info(*inop)->lli_smd, NULL);
-                if (rc)
-                        _sysio_i_gone(*inop);
-        }
-
-out:
-        ptlrpc_req_finished(request);
-        OBD_FREE(pname, name->len + 1);
-
-        return rc;
-}
-
-static int llu_iop_getattr(struct pnode *pno,
-                           struct inode *ino,
-                           struct intnl_stat *b)
-{
-        struct llu_inode_info *lli = llu_i2info(ino);
-
-        b->st_dev = lli->lli_st_dev;
-        b->st_ino = lli->lli_st_ino;
-        b->st_mode = lli->lli_st_mode;
-        b->st_nlink = lli->lli_st_nlink;
-        b->st_uid = lli->lli_st_uid;
-        b->st_gid = lli->lli_st_gid;
-        b->st_rdev = lli->lli_st_rdev;
-        b->st_size = lli->lli_st_size;
-        b->st_blksize = lli->lli_st_blksize;
-        b->st_blocks = lli->lli_st_blocks;
-        b->st_atime = lli->lli_st_atime;
-        b->st_mtime = lli->lli_st_mtime;
-        b->st_ctime = lli->lli_st_ctime;
-
-        return 0;
-}
-
-int llu_mdc_cancel_unused(struct lustre_handle *conn,
-                          struct llu_inode_info *lli,
-                          int flags)
-{
-        struct ldlm_res_id res_id =
-                { .name = {lli->lli_st_ino, lli->lli_st_generation} };
-        struct obd_device *obddev = class_conn2obd(conn);
-        ENTRY;
-        RETURN(ldlm_cli_cancel_unused(obddev->obd_namespace, &res_id, flags));
-}
-
-static void llu_clear_inode(struct inode *inode)
-{
-        struct llu_sb_info *sbi = llu_i2sbi(inode);
-        struct llu_inode_info *lli = llu_i2info(inode);
-        int rc;
-        ENTRY;
-
-        CDEBUG(D_INODE, "clear inode: %lu\n", lli->lli_st_ino);
-        rc = llu_mdc_cancel_unused(&sbi->ll_mdc_conn, lli,
-                                   LDLM_FL_NO_CALLBACK);
-        if (rc < 0) {
-                CERROR("ll_mdc_cancel_unused: %d\n", rc);
-                /* XXX FIXME do something dramatic */
-        }
-
-        if (lli->lli_smd) {
-                rc = obd_cancel_unused(&sbi->ll_osc_conn, lli->lli_smd, 0);
-                if (rc < 0) {
-                        CERROR("obd_cancel_unused: %d\n", rc);
-                        /* XXX FIXME do something dramatic */
-                }
-        }
-
-        if (lli->lli_smd)
-                obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd);
-
-        if (lli->lli_symlink_name) {
-                OBD_FREE(lli->lli_symlink_name,
-                         strlen(lli->lli_symlink_name) + 1);
-                lli->lli_symlink_name = NULL;
-        }
-
-        EXIT;
-}
-
-void llu_iop_gone(struct inode *inode)
-{
-        struct llu_inode_info *lli = llu_i2info(inode);
-
-        llu_clear_inode(inode);
-
-        OBD_FREE(lli, sizeof(*lli));
-}
-
-static int llu_setattr_raw(struct inode *inode, struct iattr *attr)
-{
-        struct ptlrpc_request *request = NULL;
-        struct llu_sb_info *sbi = llu_i2sbi(inode);
-        struct llu_inode_info *lli = llu_i2info(inode);
-        struct mdc_op_data op_data;
-        int err = 0;
-        ENTRY;
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", lli->lli_st_ino);
-
-        /* if need truncate, do it at first */
-        if (attr->ia_valid & ATTR_SIZE) {
-                printf("************* don't support truncate now !!!!!!!!\n");
-                LBUG();
-        }
-
-        /* Don't send size changes to MDS to avoid "fast EA" problems, and
-         * also avoid a pointless RPC (we get file size from OST anyways).
-         */
-        attr->ia_valid &= ~ATTR_SIZE;
-        if (!attr->ia_valid)
-                RETURN(0);
-
-        llu_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
-
-        err = mdc_setattr(&sbi->ll_mdc_conn, &op_data,
-                          attr, NULL, 0, &request);
-        if (err)
-                CERROR("mdc_setattr fails: err = %d\n", err);
-
-        ptlrpc_req_finished(request);
-
-        if (S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_MTIME_SET) {
-                struct lov_stripe_md *lsm = lli->lli_smd;
-                struct obdo oa;
-                int err2;
-
-                CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n",
-                       lli->lli_st_ino, attr->ia_mtime);
-                oa.o_id = lsm->lsm_object_id;
-                oa.o_mode = S_IFREG;
-                oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMTIME;
-                oa.o_mtime = attr->ia_mtime;
-                err2 = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL);
-                if (err2) {
-                        CERROR("obd_setattr fails: rc=%d\n", err);
-                        if (!err)
-                                err = err2;
-                }
-        }
-        RETURN(err);
-}
-
-/* FIXME here we simply act as a thin layer to glue it with
- * llu_setattr_raw(), which is copy from kernel
- */
-static int llu_iop_setattr(struct pnode *pno,
-                           struct inode *ino,
-                           unsigned mask,
-                           struct intnl_stat *stbuf)
-{
-        struct iattr iattr;
-
-        memset(&iattr, 0, sizeof(iattr));
-
-        if (mask & SETATTR_MODE) {
-                iattr.ia_mode = stbuf->st_mode;
-                iattr.ia_valid |= ATTR_MODE;
-        }
-        if (mask & SETATTR_MTIME) {
-                iattr.ia_mtime = stbuf->st_mtime;
-                iattr.ia_valid |= ATTR_MTIME;
-        }
-        if (mask & SETATTR_ATIME) {
-                iattr.ia_atime = stbuf->st_atime;
-                iattr.ia_valid |= ATTR_ATIME;
-        }
-        if (mask & SETATTR_UID) {
-                iattr.ia_uid = stbuf->st_uid;
-                iattr.ia_valid |= ATTR_UID;
-        }
-        if (mask & SETATTR_GID) {
-                iattr.ia_gid = stbuf->st_gid;
-                iattr.ia_valid |= ATTR_GID;
-        }
-        if (mask & SETATTR_LEN) {
-                iattr.ia_size = stbuf->st_size; /* FIXME signed expansion problem */
-                iattr.ia_valid |= ATTR_SIZE;
-        }
-
-        iattr.ia_valid |= ATTR_RAW;
-        /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME
-         * without ATTR_FROM_OPEN, mds_reint_setattr will call
-         * mds_fid2locked_dentry() and deadlocked at completion_ast call.
-         * Here we workaround it and avoid any locking.
-         * FIXME FIXME FIXME FIXME FIXME FIXME FIXME
-         */
-        iattr.ia_valid |= ATTR_FROM_OPEN;
-
-        return llu_setattr_raw(ino, &iattr);
-}
-
-
-static int llu_mkdir2(struct inode *dir, const char *name, int len, int mode)
-{
-        struct ptlrpc_request *request = NULL;
-        time_t curtime = CURRENT_TIME;
-        struct llu_sb_info *sbi = llu_i2sbi(dir);
-        struct llu_inode_info *lli = llu_i2info(dir);
-        struct mdc_op_data op_data;
-        int err = -EMLINK;
-        ENTRY;
-        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu\n",
-               name, lli->lli_st_ino);
-
-        /* FIXME check this later */
-#if 0 
-        if (dir->i_nlink >= EXT2_LINK_MAX)
-                RETURN(err);
-        mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR;
-#endif
-        mode |= S_IFDIR;
-        llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
-        err = mdc_create(&sbi->ll_mdc_conn, &op_data, NULL, 0, mode,
-                         current->fsuid, current->fsgid,
-                         curtime, 0, &request);
-        ptlrpc_req_finished(request);
-        RETURN(err);
-}
-
-static int llu_iop_mkdir(struct pnode *pno, mode_t mode)
-{
-        struct inode *dir = pno->p_base->pb_parent->pb_ino;
-        struct qstr *qstr = &pno->p_base->pb_name;
-        int rc;
-
-        LASSERT(dir);
-
-        rc = llu_mkdir2(dir, qstr->name, qstr->len, mode);
-
-        return rc;
-}
-
-#ifndef S_IRWXUGO
-#define S_IRWXUGO       (S_IRWXU|S_IRWXG|S_IRWXO)
-#endif
-
-static int llu_symlink2(struct inode *dir, const char *name, int len,
-                        const char *tgt)
-{
-        struct ptlrpc_request *request = NULL;
-        time_t curtime = CURRENT_TIME;
-        struct llu_sb_info *sbi = llu_i2sbi(dir);
-        struct llu_inode_info *lli = llu_i2info(dir);
-        struct mdc_op_data op_data;
-        int err = -EMLINK;
-        ENTRY;
-
-        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu,target=%s\n",
-               name, lli->lli_st_ino, tgt);
-
-#if 0
-        if (dir->i_nlink >= EXT2_LINK_MAX)
-                RETURN(err);
-#endif
-        llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
-        err = mdc_create(&sbi->ll_mdc_conn, &op_data,
-                         tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO,
-                         current->fsuid, current->fsgid, curtime, 0, &request);
-        ptlrpc_req_finished(request);
-        RETURN(err);
-}
-
-static int llu_iop_symlink(struct pnode *pno, const char *data)
-{
-        struct inode *dir = pno->p_base->pb_parent->pb_ino;
-        struct qstr *qstr = &pno->p_base->pb_name;
-        int rc;
-        
-        LASSERT(dir);
-
-        rc = llu_symlink2(dir, qstr->name, qstr->len, data);
-
-        return rc;
-}
-
-struct filesys_ops llu_filesys_ops =
-{
-        fsop_gone: llu_fsop_gone,
-};
-
-
-static struct inode_ops llu_inode_ops = {
-        inop_lookup:    llu_iop_lookup,
-        inop_getattr:   llu_iop_getattr,
-        inop_setattr:   llu_iop_setattr,
-        inop_getdirentries:     NULL,
-        inop_mkdir:     llu_iop_mkdir,
-        inop_rmdir:     NULL,
-        inop_symlink:   llu_iop_symlink,
-        inop_readlink:  NULL,
-        inop_open:      llu_iop_open,
-        inop_close:     llu_iop_close,
-        inop_unlink:    NULL,
-        inop_ipreadv:   llu_iop_ipreadv,
-        inop_ipwritev:  llu_iop_ipwritev,
-        inop_iodone:    llu_iop_iodone,
-        inop_fcntl:     NULL,
-        inop_sync:      NULL,
-        inop_datasync:  NULL,
-        inop_ioctl:     NULL,
-        inop_mknod:     NULL,
-        inop_statvfs:   NULL,
-        inop_gone:      llu_iop_gone,
-};
-
-
-static int
-llu_fsswop_mount(const char *source,
-                 unsigned flags,
-                 const void *data __IS_UNUSED,
-                 struct pnode *tocover,
-                 struct mount **mntp)
-{
-        struct filesys *fs;
-        struct inode *root;
-        struct pnode_base *rootpb;
-        static struct qstr noname = { NULL, 0, 0 };
-        struct ll_fid rootfid;
-
-        struct llu_sb_info *sbi;
-        struct ptlrpc_connection *mdc_conn;
-        struct ptlrpc_request *request = NULL;
-        struct mds_body *root_body;
-        struct obd_uuid param_uuid;
-        class_uuid_t uuid;
-        struct obd_device *obd;
-        char *osc=mount_option.osc_uuid;
-        char *mdc=mount_option.mdc_uuid;
-        int err = -EINVAL;
-
-        ENTRY;
-
-        OBD_ALLOC(sbi, sizeof(*sbi));
-        if (!sbi)
-                RETURN(-ENOMEM);
-
-        INIT_LIST_HEAD(&sbi->ll_conn_chain);
-        generate_random_uuid(uuid);
-        class_uuid_unparse(uuid, &sbi->ll_sb_uuid);
-
-        fs = _sysio_fs_new(&llu_filesys_ops, flags, sbi);
-        if (!fs) {
-                err = -ENOMEM;
-                goto out_free;
-        }
-
-        strncpy(param_uuid.uuid, mdc, sizeof(param_uuid.uuid));
-        obd = class_uuid2obd(&param_uuid);
-        if (!obd) {
-                CERROR("MDC %s: not setup or attached\n", mdc);
-                err = -EINVAL;
-                goto out_free;
-        }
-
-        /* setup mdc */
-        /* FIXME need recover stuff */
-        err = obd_connect(&sbi->ll_mdc_conn, obd, &sbi->ll_sb_uuid);
-        if (err) {
-                CERROR("cannot connect to %s: rc = %d\n", mdc, err);
-                goto out_free;
-        }
-
-        mdc_conn = sbi2mdc(sbi)->cl_import->imp_connection;
-
-        /* setup osc */
-        strncpy(param_uuid.uuid, osc, sizeof(param_uuid.uuid));
-        obd = class_uuid2obd(&param_uuid);
-        if (!obd) {
-                CERROR("OSC %s: not setup or attached\n", osc);
-                err = -EINVAL;
-                goto out_mdc;
-        }
-
-        err = obd_connect(&sbi->ll_osc_conn, obd, &sbi->ll_sb_uuid);
-        if (err) {
-                CERROR("cannot connect to %s: rc = %d\n", osc, err);
-                goto out_mdc;
-        }
-
-        err = mdc_getstatus(&sbi->ll_mdc_conn, &rootfid);
-        if (err) {
-                CERROR("cannot mds_connect: rc = %d\n", err);
-                goto out_osc;
-        }
-        CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id);
-        sbi->ll_rootino = rootfid.id;
-
-/* XXX do we need this??
-        memset(&osfs, 0, sizeof(osfs));
-        rc = obd_statfs(&sbi->ll_mdc_conn, &osfs);
-*/
-        /* fetch attr of root inode */
-        err = mdc_getattr(&sbi->ll_mdc_conn, &rootfid,
-                          OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request);
-        if (err) {
-                CERROR("mdc_getattr failed for root: rc = %d\n", err);
-                goto out_request;
-        }
-
-        root_body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*root_body));
-        LASSERT(sbi->ll_rootino != 0);
-
-        root = llu_new_inode(fs, root_body->ino, root_body->mode);
-        if (!root) {
-               err = -ENOMEM;
-                goto out_request;
-        }
-
-        llu_update_inode(root, root_body, NULL);
-
-       /*
-        * Generate base path-node for root.
-        */
-       rootpb = _sysio_pb_new(&noname, NULL, root);
-       if (!rootpb) {
-               err = -ENOMEM;
-               goto out_inode;
-       }
-
-       err = _sysio_do_mount(fs, rootpb, flags, NULL, mntp);
-       if (err) {
-                _sysio_pb_gone(rootpb);
-               goto out_inode;
-        }
-
-        ptlrpc_req_finished(request);
-        request = NULL;
-
-        printf("************************************************\n");
-        printf("*          Mount successfully!!!!!!!           *\n");
-        printf("************************************************\n");
-
-        return 0;
-
-out_inode:
-        _sysio_i_gone(root);
-out_request:
-        ptlrpc_req_finished(request);
-out_osc:
-        obd_disconnect(&sbi->ll_osc_conn);
-out_mdc:
-        obd_disconnect(&sbi->ll_mdc_conn);
-out_free:
-        OBD_FREE(sbi, sizeof(*sbi));
-        return err;
-}
-
-struct fssw_ops llu_fssw_ops = {
-        llu_fsswop_mount
-};
-
diff --git a/lustre/llite/iod.c b/lustre/llite/iod.c
deleted file mode 100644 (file)
index 3a045f4..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  Copyright (C) 2002, 2003  Cluster File Systems, Inc
- *
- *  this started as an implementation of an io daemon that woke regularly
- *  to force writeback.. the throttling in prepare_write and kupdate's usual
- *  writeback pressure got rid of our thread, but the file name remains.
- */
-#include <linux/version.h>
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/kmod.h>
-#include <linux/pagemap.h>
-#include <linux/mm.h>
-
-/* PG_inactive_clean is shorthand for rmap, we want free_high/low here.. */
-#ifdef PG_inactive_clean
-#include <linux/mm_inline.h>
-#endif
-
-#define DEBUG_SUBSYSTEM S_LLITE
-#include <linux/lustre_lite.h>
-
-#ifndef list_for_each_prev_safe
-#define list_for_each_prev_safe(pos, n, head) \
-        for (pos = (head)->prev, n = pos->prev; pos != (head); \
-                pos = n, n = pos->prev )
-#endif
-
-extern spinlock_t inode_lock;
-
-#define LLWP_MAX_PAGES (PTL_MD_MAX_IOV)
-struct ll_writeback_pages {
-        unsigned        has_whole_pages:1,
-                        num_frags:2,
-                        num_pages:29;
-        struct brw_page pgs[LLWP_MAX_PAGES];
-};
-
-
-/*
- * ugh, we want disk allocation on the target to happen in offset order.  we'll
- * follow sedgewicks advice and stick to the dead simple shellsort -- it'll do
- * fine for our small page arrays and doesn't require allocation.  its an
- * insertion sort that swaps elements that are strides apart, shrinking the
- * stride down until its '1' and the array is sorted.
- */
-void sort_brw_pages(struct brw_page *array, int num)
-{
-        int stride, i, j;
-        struct brw_page tmp;
-
-        if ( num == 1 )
-                return;
-
-        for( stride = 1; stride < num ; stride = (stride*3) +1  )
-                ;
-
-        do {
-                stride /= 3;
-                for ( i = stride ; i < num ; i++ ) {
-                        tmp = array[i];
-                        j = i;
-                        while ( j >= stride &&
-                                        array[j - stride].off > tmp.off ) {
-                                array[j] = array[j - stride];
-                                j -= stride;
-                        }
-                        array[j] = tmp;
-                }
-        } while ( stride > 1 );
-}
-
-/*
- * returns 0 if the page was inserted in the array because it was
- * within i_size.  if we raced with truncate and i_size was less
- * than the page we can unlock the page because truncate_inode_pages will
- * be waiting to cleanup the page
- */
-static int llwp_consume_page(struct ll_writeback_pages *llwp,
-                             struct inode *inode, struct page *page)
-{
-        obd_off off = ((obd_off)page->index) << PAGE_SHIFT;
-        struct brw_page *pg;
-
-        /* we raced with truncate? */
-        if ( off >= inode->i_size ) {
-                unlock_page(page);
-                goto out;
-        }
-
-        page_cache_get(page);
-        pg = &llwp->pgs[llwp->num_pages];
-        llwp->num_pages++;
-
-        pg->pg = page;
-        pg->off = off;
-        pg->flag = OBD_BRW_CREATE;
-        pg->count = PAGE_SIZE;
-
-        /* catch partial writes for files that end mid-page */
-        if ( pg->off + pg->count > inode->i_size )
-                pg->count = inode->i_size & ~PAGE_MASK;
-
-        if ( pg->count == PAGE_SIZE ) {
-                if ( ! llwp->has_whole_pages ) {
-                        llwp->has_whole_pages = 1;
-                        llwp->num_frags++;
-                }
-        } else {
-                llwp->num_frags++;
-        }
-
-        /*
-         * matches ptlrpc_bulk_get assert that trickles down
-         * from a 0 page length going through niobuf and into
-         * the buffer regions being posted
-         */
-        LASSERT(pg->count >= 0);
-
-        CDEBUG(D_CACHE, "brw_page %p: off "LPU64" cnt %d, page %p: ind %ld"
-                        " i_size: "LPU64"\n", pg, pg->off, pg->count, page, 
-                        page->index, inode->i_size);
-
-        if ( llwp->num_frags == 3 || llwp->num_pages == LLWP_MAX_PAGES )
-                return -1;
-
-out:
-        return 0;
-}
-
-/*
- * returns the number of pages that it added to the pgs array
- *
- * this duplicates filemap_fdatasync and gives us an opportunity to grab lots
- * of dirty pages..
- */
-static void ll_get_dirty_pages(struct inode *inode,
-                               struct ll_writeback_pages *llwp)
-{
-        struct address_space *mapping = inode->i_mapping;
-        struct page *page;
-        struct list_head *pos, *n;
-        ENTRY;
-
-        spin_lock(&pagecache_lock);
-
-        list_for_each_prev_safe(pos, n, &mapping->dirty_pages) {
-                page = list_entry(pos, struct page, list);
-
-                if (TryLockPage(page))
-                        continue;
-
-                list_del(&page->list);
-                list_add(&page->list, &mapping->locked_pages);
-
-                if ( ! PageDirty(page) ) {
-                        unlock_page(page);
-                        continue;
-                }
-                ClearPageDirty(page);
-
-                if ( llwp_consume_page(llwp, inode, page) != 0)
-                        break;
-        }
-
-        spin_unlock(&pagecache_lock);
-        EXIT;
-}
-
-static void ll_brw_pages_unlock( struct inode *inode,
-                                 struct ll_writeback_pages *llwp)
-{
-        int rc, i;
-        struct obd_brw_set *set;
-        ENTRY;
-
-        sort_brw_pages(llwp->pgs, llwp->num_pages);
-
-        set = obd_brw_set_new();
-        if (set == NULL) {
-                EXIT;
-                return;
-        }
-        set->brw_callback = ll_brw_sync_wait;
-
-        rc = obd_brw(OBD_BRW_WRITE, ll_i2obdconn(inode),
-                     ll_i2info(inode)->lli_smd, llwp->num_pages, llwp->pgs,
-                     set, NULL);
-        if (rc) {
-                CERROR("error from obd_brw: rc = %d\n", rc);
-        } else {
-                rc = ll_brw_sync_wait(set, CB_PHASE_START);
-                if (rc)
-                        CERROR("error from callback: rc = %d\n", rc);
-        }
-        obd_brw_set_decref(set);
-
-        /* XXX this doesn't make sense to me */
-        rc = 0;
-
-        for ( i = 0 ; i < llwp->num_pages ; i++) {
-                struct page *page = llwp->pgs[i].pg;
-
-                CDEBUG(D_CACHE, "cleaning page %p\n", page);
-                LASSERT(PageLocked(page));
-                unlock_page(page);
-                page_cache_release(page);
-        }
-
-        EXIT;
-}
-
-#ifndef PG_inactive_clean
-#ifdef CONFIG_DISCONTIGMEM
-#error "sorry, we don't support DISCONTIGMEM yet"
-#endif
-/*
- * __alloc_pages marks a zone as needing balancing if an allocation is
- * performed when the zone has fewer free pages than its 'low' water
- * mark.  its cleared when try_to_free_pages makes progress.
- */
-static int zones_need_balancing(void)
-{
-        pg_data_t * pgdat;
-        zone_t *zone;
-        int i;
-
-        for ( pgdat = pgdat_list ; pgdat != NULL ; pgdat = pgdat->node_next ) {
-                for ( i = pgdat->nr_zones-1 ; i >= 0 ; i-- ) {
-                        zone = &pgdat->node_zones[i];
-
-                        if ( zone->need_balance )
-                                return 1;
-                }
-        }
-        return 0;
-}
-#endif
-/* 2.4 doesn't give us a way to find out how many pages we have
- * cached 'cause we're not using buffer_heads.  we are very
- * conservative here and flush the superblock of all dirty data
- * when the vm (rmap or stock) thinks that it is running low
- * and kswapd would have done work.  kupdated isn't good enough
- * because writers (dbench) can dirty _very quickly_, and we
- * allocate under writepage..
- *
- * 2.5 gets this right, see the {inc,dec}_page_state(nr_dirty, )
- */
-static int should_writeback(void)
-{
-#ifdef PG_inactive_clean
-        if (free_high(ALL_ZONES) > 0 || free_low(ANY_ZONE) > 0)
-#else
-        if (zones_need_balancing())
-#endif
-                return 1;
-        return 0;
-}
-
-int ll_check_dirty( struct super_block *sb)
-{
-        unsigned long old_flags; /* hack? */
-        int making_progress;
-        struct ll_writeback_pages *llwp;
-        struct inode *inode;
-        int rc = 0;
-        ENTRY;
-
-        if ( ! should_writeback() )
-                return 0;
-
-        old_flags = current->flags;
-        current->flags |= PF_MEMALLOC;
-        llwp = kmalloc(sizeof(struct ll_writeback_pages), GFP_ATOMIC);
-        if ( llwp == NULL )
-                GOTO(cleanup, rc = -ENOMEM);
-        memset(llwp, 0, offsetof(struct ll_writeback_pages, pgs));
-
-        spin_lock(&inode_lock);
-
-        /*
-         * first we try and write back dirty pages from dirty inodes
-         * until the VM thinkgs we're ok again..
-         */
-        do {
-                struct list_head *pos;
-                inode = NULL;
-                making_progress = 0;
-
-                list_for_each_prev(pos, &sb->s_dirty) {
-                        inode = list_entry(pos, struct inode, i_list);
-
-                        if ( ! (inode->i_state & I_DIRTY_PAGES) ) {
-                                inode = NULL;
-                                continue;
-                        }
-                        break;
-                }
-
-                if ( inode == NULL )
-                        break;
-
-                /* duplicate __sync_one, *sigh* */
-                list_del(&inode->i_list);
-                list_add(&inode->i_list, &inode->i_sb->s_locked_inodes);
-                inode->i_state |= I_LOCK;
-                inode->i_state &= ~I_DIRTY_PAGES;
-
-                spin_unlock(&inode_lock);
-
-                do { 
-                        memset(llwp, 0, sizeof(*llwp));
-                        ll_get_dirty_pages(inode, llwp);
-                        if ( llwp->num_pages ) {
-                                ll_brw_pages_unlock(inode, llwp);
-                                rc += llwp->num_pages;
-                                making_progress = 1;
-                        }
-                } while (llwp->num_pages && should_writeback() );
-
-                spin_lock(&inode_lock);
-
-                if ( ! list_empty(&inode->i_mapping->dirty_pages) )
-                        inode->i_state |= I_DIRTY_PAGES;
-
-                inode->i_state &= ~I_LOCK;
-                /*
-                 * we are sneaky and leave the inode on the dirty list,
-                 * even though it might not still be..
-                 */
-                if (!(inode->i_state & I_FREEING)) {
-                        list_del(&inode->i_list);
-                        list_add(&inode->i_list, &inode->i_sb->s_dirty);
-                }
-                wake_up(&inode->i_wait);
-
-        } while ( making_progress && should_writeback() );
-
-        /*
-         * and if that didn't work, we sleep on any data that might
-         * be under writeback..
-         */
-        while ( should_writeback() ) {
-                if ( list_empty(&sb->s_locked_inodes) )  
-                        break;
-
-                inode = list_entry(sb->s_locked_inodes.next, struct inode, 
-                                i_list);
-
-                atomic_inc(&inode->i_count); /* XXX hack? */
-                spin_unlock(&inode_lock);
-                wait_event(inode->i_wait, !(inode->i_state & I_LOCK));
-                iput(inode);
-                spin_lock(&inode_lock);
-        }
-
-        spin_unlock(&inode_lock);
-
-cleanup:
-        if ( llwp != NULL )
-                kfree(llwp);
-        current->flags = old_flags;
-
-        RETURN(rc);
-}
-
-int ll_batch_writepage( struct inode *inode, struct page *page )
-{
-        unsigned long old_flags; /* hack? */
-        struct ll_writeback_pages *llwp;
-        int rc = 0;
-        ENTRY;
-
-        old_flags = current->flags;
-        current->flags |= PF_MEMALLOC;
-        llwp = kmalloc(sizeof(struct ll_writeback_pages), GFP_ATOMIC);
-        if ( llwp == NULL )
-                GOTO(cleanup, rc = -ENOMEM);
-        memset(llwp, 0, offsetof(struct ll_writeback_pages, pgs));
-
-        llwp_consume_page(llwp, inode, page);
-
-        ll_get_dirty_pages(inode, llwp);
-        if ( llwp->num_pages )
-                ll_brw_pages_unlock(inode, llwp);
-
-cleanup:
-        if ( llwp != NULL )
-                kfree(llwp);
-        current->flags = old_flags;
-        RETURN(rc);
-}
diff --git a/lustre/lov/lov_pack.c b/lustre/lov/lov_pack.c
deleted file mode 100644 (file)
index d28a6c9..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (C) 2002 Cluster File Systems, Inc. <adilger@clusterfs.com>
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * (Un)packing of OST/MDS requests
- *
- */
-
-#define DEBUG_SUBSYSTEM S_LLITE
-
-#include <linux/lustre_net.h>
-#include <linux/obd.h>
-#include <linux/obd_lov.h>
-#include <linux/obd_support.h>
-
-/* lov_packdesc() is in mds/mds_lov.c */
-
-void lov_unpackdesc(struct lov_desc *ld)
-{
-        ld->ld_tgt_count = NTOH__u32(ld->ld_tgt_count);
-        ld->ld_default_stripe_count = HTON__u32(ld->ld_default_stripe_count);
-        ld->ld_default_stripe_size = HTON__u32(ld->ld_default_stripe_size);
-        ld->ld_pattern = HTON__u32(ld->ld_pattern);
-}
-
-/* Pack LOV object metadata for shipment to the MDS.
- *
- * XXX In the future, this will be enhanced to get the EA size from the
- *     underlying OSC device(s) to get their EA sizes so we can stack
- *     LOVs properly.  For now lov_mds_md_size() just assumes one obd_id
- *     per stripe.
- */
-int lov_packmd(struct lustre_handle *conn, struct lov_mds_md **lmmp,
-               struct lov_stripe_md *lsm)
-{
-        struct obd_device *obd = class_conn2obd(conn);
-        struct lov_obd *lov = &obd->u.lov;
-        struct lov_oinfo *loi;
-        struct lov_mds_md *lmm;
-        int ost_count = lov->desc.ld_tgt_count;
-        int stripe_count = ost_count;
-        int lmm_size;
-        int i;
-        ENTRY;
-
-        if (lsm)
-                stripe_count = lsm->lsm_stripe_count;
-
-        /* XXX LOV STACKING call into osc for sizes */
-        lmm_size = lov_mds_md_size(ost_count);
-
-        if (!lmmp)
-                RETURN(lmm_size);
-
-        if (*lmmp && !lsm) {
-                /* endianness */
-                ost_count = ((*lmmp)->lmm_ost_count);
-                OBD_FREE(*lmmp, lov_mds_md_size(ost_count));
-                *lmmp = NULL;
-                RETURN(0);
-        }
-
-        if (!*lmmp) {
-                OBD_ALLOC(*lmmp, lmm_size);
-                if (!*lmmp)
-                        RETURN(-ENOMEM);
-        }
-
-        lmm = *lmmp;
-
-        lmm->lmm_stripe_count = (stripe_count);
-        if (!lsm)
-                RETURN(lmm_size);
-        /* XXX endianness */
-        lmm->lmm_magic = (lsm->lsm_magic);
-        lmm->lmm_object_id = (lsm->lsm_object_id);
-        lmm->lmm_stripe_size = (lsm->lsm_stripe_size);
-        lmm->lmm_stripe_pattern = (lsm->lsm_stripe_pattern);
-        lmm->lmm_stripe_offset = (lsm->lsm_stripe_offset);
-        lmm->lmm_ost_count = (lov->desc.ld_tgt_count);
-
-        /* Only fill in the object ids which we are actually using.
-         * Assumes lmm_objects is otherwise zero-filled. */
-        for (i = 0, loi = lsm->lsm_oinfo; i < stripe_count; i++, loi++)
-                /* XXX call down to osc_packmd() to do the packing */
-                lmm->lmm_objects[loi->loi_ost_idx].l_object_id = (loi->loi_id);
-
-        RETURN(lmm_size);
-}
-
-int lov_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp,
-                 struct lov_mds_md *lmm)
-{
-        struct obd_device *obd = class_conn2obd(conn);
-        struct lov_obd *lov = &obd->u.lov;
-        struct lov_stripe_md *lsm;
-        struct lov_oinfo *loi;
-        int ost_count = lov->desc.ld_active_tgt_count;
-        int ost_offset = 0;
-        int stripe_count = 0;
-        int lsm_size;
-        int i;
-        ENTRY;
-
-        if (lmm)
-                /* endianness */
-                stripe_count = (lmm->lmm_stripe_count);
-
-        if (!stripe_count)
-                stripe_count = lov->desc.ld_default_stripe_count;
-        if (!stripe_count || stripe_count > ost_count)
-                stripe_count = ost_count;
-
-        /* XXX LOV STACKING call into osc for sizes */
-        lsm_size = lov_stripe_md_size(stripe_count);
-
-        if (!lsmp)
-                RETURN(lsm_size);
-
-        if (*lsmp && !lmm) {
-                stripe_count = (*lsmp)->lsm_stripe_count;
-                OBD_FREE(*lsmp, lov_stripe_md_size(stripe_count));
-                *lsmp = NULL;
-                RETURN(0);
-        }
-
-        if (!*lsmp) {
-                OBD_ALLOC(*lsmp, lsm_size);
-                if (!*lsmp)
-                        RETURN(-ENOMEM);
-        }
-
-        lsm = *lsmp;
-
-        lsm->lsm_stripe_count = stripe_count;
-        if (!lmm)
-                RETURN(lsm_size);
-
-        /* XXX endianness */
-        ost_offset = lsm->lsm_stripe_offset = (lmm->lmm_stripe_offset);
-        lsm->lsm_magic = (lmm->lmm_magic);
-        lsm->lsm_object_id = (lmm->lmm_object_id);
-        lsm->lsm_stripe_size = (lmm->lmm_stripe_size);
-        lsm->lsm_stripe_pattern = (lmm->lmm_stripe_pattern);
-
-        for (i = 0, loi = lsm->lsm_oinfo; i < ost_count; i++, ost_offset++) {
-                ost_offset %= ost_count;
-
-                if (!lmm->lmm_objects[ost_offset].l_object_id)
-                        continue;
-
-                LASSERT(loi - lsm->lsm_oinfo < stripe_count);
-                /* XXX LOV STACKING call down to osc_unpackmd() */
-                loi->loi_id = (lmm->lmm_objects[ost_offset].l_object_id);
-                loi->loi_ost_idx = ost_offset;
-                loi++;
-        }
-
-        RETURN(lsm_size);
-}
diff --git a/lustre/mds/mds_internal.h b/lustre/mds/mds_internal.h
deleted file mode 100644 (file)
index 7d047a6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-struct mds_file_data *mds_mfd_new(void);
-void mds_mfd_put(struct mds_file_data *mfd);
-void mds_mfd_destroy(struct mds_file_data *mfd);
diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c
deleted file mode 100644 (file)
index 2f65384..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  lustre/mds/handler.c
- *  Lustre Metadata Server (mds) request handler
- *
- *  Copyright (c) 2001, 2002 Cluster File Systems, Inc.
- *   Author: Peter Braam <braam@clusterfs.com>
- *   Author: Andreas Dilger <adilger@clusterfs.com>
- *   Author: Phil Schwan <phil@clusterfs.com>
- *   Author: Mike Shaver <shaver@clusterfs.com>
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define EXPORT_SYMTAB
-#define DEBUG_SUBSYSTEM S_MDS
-
-#include <linux/module.h>
-#include <linux/lustre_mds.h>
-#include <linux/lustre_dlm.h>
-#include <linux/init.h>
-#include <linux/obd_class.h>
-#include <linux/random.h>
-#include <linux/locks.h>
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
-#include <linux/buffer_head.h>
-#include <linux/workqueue.h>
-#endif
-#include <linux/obd_lov.h>
-#include <linux/lustre_mds.h>
-#include <linux/lustre_fsfilt.h>
-#include <linux/lprocfs_status.h>
-
-extern kmem_cache_t *mds_file_cache;
-extern inline struct mds_obd *mds_req2mds(struct ptlrpc_request *req);
-extern void mds_start_transno(struct mds_obd *mds);
-extern int mds_finish_transno(struct mds_obd *mds, void *handle,
-                              struct ptlrpc_request *req, int rc);
-extern int enqueue_ordered_locks(int lock_mode, struct obd_device *obd,
-                                 struct ldlm_res_id *p1_res_id,
-                                 struct ldlm_res_id *p2_res_id,
-                                 struct ldlm_res_id *c1_res_id,
-                                 struct ldlm_res_id *c2_res_id,
-                                 struct lustre_handle *p1_lockh,
-                                 struct lustre_handle *p2_lockh,
-                                 struct lustre_handle *c1_lockh,
-                                 struct lustre_handle *c2_lockh);
-
-int mds_open(struct mds_update_record *rec, int offset,
-             struct ptlrpc_request *req, struct lustre_handle *child_lockh)
-{
-        struct mds_obd *mds = mds_req2mds(req);
-        struct obd_device *obd = req->rq_export->exp_obd;
-        struct ldlm_reply *rep = lustre_msg_buf(req->rq_repmsg, 0);
-        struct file *file;
-        struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 1);
-        struct dentry *dchild, *parent;
-        struct mds_export_data *med;
-        struct mds_file_data *mfd = NULL;
-        struct ldlm_res_id child_res_id = { .name = {0} };
-        struct lustre_handle parent_lockh;
-        int rc = 0, parent_mode, child_mode = LCK_PR, lock_flags, created = 0;
-        ENTRY;
-
-#warning replay of open needs to be redone
-        /* was this animal open already and the client lost the reply? */
-        /* XXX need some way to detect a reopen, to avoid locked list walks */
-        med = &req->rq_export->exp_mds_data;
-#if 0
-        spin_lock(&med->med_open_lock);
-        list_for_each(tmp, &med->med_open_head) {
-                mfd = list_entry(tmp, typeof(*mfd), mfd_list);
-                if (!memcmp(&mfd->mfd_clienthandle, &body->handle,
-                            sizeof(mfd->mfd_clienthandle)) &&
-                    body->fid1.id == mfd->mfd_file->f_dentry->d_inode->i_ino) {
-                        dchild = mfd->mfd_file->f_dentry;
-                        spin_unlock(&med->med_open_lock);
-                        CERROR("Re opening "LPD64"\n", body->fid1.id);
-                        GOTO(out_pack, rc = 0);
-                }
-        }
-        spin_unlock(&med->med_open_lock);
-#endif
-        rep->lock_policy_res1 |= IT_OPEN_LOOKUP;
-        if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OPEN_PACK)) {
-                CERROR("test case OBD_FAIL_MDS_OPEN_PACK\n");
-                req->rq_status = -ENOMEM;
-                RETURN(-ENOMEM);
-        }
-
-        /* Step 1: Find and lock the parent */
-        parent_mode = (rec->ur_flags & O_CREAT) ? LCK_PW : LCK_PR;
-        parent = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, parent_mode,
-                                       &parent_lockh);
-        if (IS_ERR(parent)) {
-                rc = PTR_ERR(parent);
-                CERROR("parent lookup error %d\n", rc);
-                LBUG();
-                RETURN(rc);
-        }
-        LASSERT(parent->d_inode);
-
-        /* Step 2: Lookup the child */
-        dchild = lookup_one_len(lustre_msg_buf(req->rq_reqmsg, 3),
-                                parent, req->rq_reqmsg->buflens[3] - 1);
-        if (IS_ERR(dchild))
-                GOTO(out_step_2, rc = PTR_ERR(dchild));
-
-        if (dchild->d_inode)
-                rep->lock_policy_res1 |= IT_OPEN_POS;
-        else
-                rep->lock_policy_res1 |= IT_OPEN_NEG;
-
-        /* Step 3: If the child was negative, and we're supposed to,
-         * create it. */
-        if ((rec->ur_flags & O_CREAT) && !dchild->d_inode) {
-                int err;
-                void *handle;
-                mds_start_transno(mds);
-                rep->lock_policy_res1 |= IT_OPEN_CREATE;
-                handle = fsfilt_start(obd, parent->d_inode, FSFILT_OP_CREATE);
-                if (IS_ERR(handle)) {
-                        rc = PTR_ERR(handle);
-                        mds_finish_transno(mds, handle, req, rc);
-                        GOTO(out_step_3, rc);
-                }
-                rc = vfs_create(parent->d_inode, dchild, rec->ur_mode);
-                rc = mds_finish_transno(mds, handle, req, rc);
-                err = fsfilt_commit(obd, parent->d_inode, handle);
-                if (rc || err) {
-                        CERROR("error on commit: err = %d\n", err);
-                        if (!rc)
-                                rc = err;
-                        GOTO(out_step_3, rc);
-                }
-                created = 1;
-                child_mode = LCK_PW;
-        } else if (!dchild->d_inode) {
-                /* It's negative and we weren't supposed to create it */
-                GOTO(out_step_3, rc = -ENOENT);
-        }
-
-        /* Step 4: It's positive, so lock the child */
-        child_res_id.name[0] = dchild->d_inode->i_ino;
-        child_res_id.name[1] = dchild->d_inode->i_generation;
- reacquire:
-        lock_flags = 0;
-        rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL,
-                              child_res_id, LDLM_PLAIN, NULL, 0, child_mode,
-                              &lock_flags, ldlm_completion_ast,
-                              mds_blocking_ast, NULL, NULL, child_lockh);
-        if (rc != ELDLM_OK) {
-                CERROR("ldlm_cli_enqueue: %d\n", rc);
-                GOTO(out_step_3, rc = -EIO);
-        }
-
-        mds_pack_inode2fid(&body->fid1, dchild->d_inode);
-        mds_pack_inode2body(body, dchild->d_inode);
-        if (S_ISREG(dchild->d_inode->i_mode)) {
-                rc = mds_pack_md(obd, req->rq_repmsg, 2, body, dchild->d_inode);
-                if (rc)
-                        GOTO(out_step_4, rc);
-        } else {
-                /* If this isn't a regular file, we can't open it. */
-                GOTO(out_step_3, rc = 0); /* returns the lock to the client */
-        }
-
-        if (!created && (rec->ur_flags & O_CREAT) && (rec->ur_flags & O_EXCL)) {
-                /* File already exists, we didn't just create it, and we
-                 * were passed O_EXCL; err-or. */
-                GOTO(out_step_3, rc = -EEXIST); // returns a lock to the client
-        }
-
-        /* If we're opening a file without an EA, the client needs a write
-         * lock. */
-        if (child_mode != LCK_PW && S_ISREG(dchild->d_inode->i_mode) &&
-            !(body->valid & OBD_MD_FLEASIZE)) {
-                ldlm_lock_decref(child_lockh, child_mode);
-                child_mode = LCK_PW;
-                goto reacquire;
-        }
-
-        /* Step 5: Open it */
-        rep->lock_policy_res1 |= IT_OPEN_OPEN;
-        mfd = kmem_cache_alloc(mds_file_cache, GFP_KERNEL);
-        if (!mfd) {
-                CERROR("mds: out of memory\n");
-                GOTO(out_step_4, req->rq_status = -ENOMEM);
-        }
-
-        /* dentry_open does a dput(de) and mntput(mds->mds_vfsmnt) on error */
-        mntget(mds->mds_vfsmnt);
-        file = dentry_open(dchild,mds->mds_vfsmnt,
-                           rec->ur_flags & ~(O_DIRECT | O_TRUNC));
-        if (IS_ERR(file))
-                GOTO(out_step_5, rc = PTR_ERR(file));
-
-        file->private_data = mfd;
-        mfd->mfd_file = file;
-        get_random_bytes(&mfd->mfd_servercookie, sizeof(mfd->mfd_servercookie));
-        spin_lock(&med->med_open_lock);
-        list_add(&mfd->mfd_list, &med->med_open_head);
-        spin_unlock(&med->med_open_lock);
-
-        body->handle.addr = (__u64)(unsigned long)mfd;
-        body->handle.cookie = mfd->mfd_servercookie;
-        CDEBUG(D_INODE, "file %p: mfd %p, cookie "LPX64"\n",
-               mfd->mfd_file, mfd, mfd->mfd_servercookie);
-        GOTO(out_step_2, rc = 0); /* returns a lock to the client */
-
- out_step_5:
-        if (mfd != NULL) {
-                kmem_cache_free(mds_file_cache, mfd);
-                mfd = NULL;
-        }
- out_step_4:
-        ldlm_lock_decref(child_lockh, child_mode);
- out_step_3:
-        l_dput(dchild);
- out_step_2:
-        l_dput(parent);
-        ldlm_lock_decref(&parent_lockh, parent_mode);
-        RETURN(rc);
-}
diff --git a/lustre/obdclass/lustre_handles.c b/lustre/obdclass/lustre_handles.c
deleted file mode 100644 (file)
index f0987c4..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (C) 2002 Cluster File Systems, Inc.
- *   Author: Phil Schwan <phil@clusterfs.com>
- *
- *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- *
- *   Portals is free software; you can redistribute it and/or
- *   modify it under the terms of version 2.1 of the GNU Lesser General
- *   Public License as published by the Free Software Foundation.
- *
- *   Portals is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU Lesser General Public License for more details.
- *
- *   You should have received a copy of the GNU Lesser General Public
- *   License along with Portals; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/types.h>
-#include <linux/random.h>
-
-#define DEBUG_SUBSYSTEM S_PORTALS
-
-#include <linux/kp30.h>
-#include <linux/lustre_handles.h>
-
-static spinlock_t handle_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t random_lock = SPIN_LOCK_UNLOCKED;
-static struct list_head *handle_hash = NULL;
-static int handle_count = 0;
-
-#define HANDLE_HASH_SIZE (1 << 14)
-#define HANDLE_HASH_MASK (HANDLE_HASH_SIZE - 1)
-
-void class_handle_hash(struct portals_handle *h, portals_handle_addref_cb cb)
-{
-        struct list_head *bucket;
-        ENTRY;
-
-        LASSERT(h != NULL);
-        LASSERT(list_empty(&h->h_link));
-
-        /* My hypothesis is that get_random_bytes, if called from two threads at
-         * the same time, will return the same bytes. -phil */
-        spin_lock(&random_lock);
-        get_random_bytes(&h->h_cookie, sizeof(h->h_cookie));
-        spin_unlock(&random_lock);
-
-        h->h_addref = cb;
-
-        bucket = handle_hash + (h->h_cookie & HANDLE_HASH_MASK);
-
-        CDEBUG(D_INFO, "adding object %p with handle "LPX64" to hash\n",
-               h, h->h_cookie);
-
-        spin_lock(&handle_lock);
-        list_add(&h->h_link, bucket);
-        handle_count++;
-        spin_unlock(&handle_lock);
-        EXIT;
-}
-
-static void class_handle_unhash_nolock(struct portals_handle *h)
-{
-        LASSERT(!list_empty(&h->h_link));
-
-        CDEBUG(D_INFO, "removing object %p with handle "LPX64" from hash\n",
-               h, h->h_cookie);
-
-        handle_count--;
-        list_del_init(&h->h_link);
-}
-
-void class_handle_unhash(struct portals_handle *h)
-{
-        spin_lock(&handle_lock);
-        class_handle_unhash_nolock(h);
-        spin_unlock(&handle_lock);
-}
-
-void *class_handle2object(__u64 cookie)
-{
-        struct list_head *bucket, *tmp;
-        void *retval = NULL;
-        ENTRY;
-
-        LASSERT(handle_hash != NULL);
-
-        spin_lock(&handle_lock);
-        bucket = handle_hash + (cookie & HANDLE_HASH_MASK);
-
-        list_for_each(tmp, bucket) {
-                struct portals_handle *h;
-                h = list_entry(tmp, struct portals_handle, h_link);
-
-                if (h->h_cookie == cookie) {
-                        h->h_addref(h);
-                        retval = h;
-                        break;
-                }
-        }
-        spin_unlock(&handle_lock);
-
-        RETURN(retval);
-}
-
-int class_handle_init(void)
-{
-        struct list_head *bucket;
-
-        LASSERT(handle_hash == NULL);
-
-        PORTAL_ALLOC(handle_hash, sizeof(*handle_hash) * HANDLE_HASH_SIZE);
-        if (handle_hash == NULL)
-                return -ENOMEM;
-
-        for (bucket = handle_hash + HANDLE_HASH_SIZE - 1; bucket >= handle_hash;
-             bucket--)
-                INIT_LIST_HEAD(bucket);
-
-        return 0;
-}
-
-static void cleanup_all_handles(void)
-{
-        int i;
-
-        spin_lock(&handle_lock);
-        for (i = 0; i < HANDLE_HASH_SIZE; i++) {
-                struct list_head *tmp, *pos;
-                list_for_each_safe(tmp, pos, &(handle_hash[i])) {
-                        struct portals_handle *h;
-                        h = list_entry(tmp, struct portals_handle, h_link);
-
-                        CERROR("forcing cleanup for handle "LPX64"\n",
-                               h->h_cookie);
-
-                        class_handle_unhash_nolock(h);
-                }
-        }
-        spin_lock(&handle_lock);
-}
-
-void class_handle_cleanup(void)
-{
-        LASSERT(handle_hash != NULL);
-
-        if (handle_count != 0) {
-                CERROR("handle_count at cleanup: %d\n", handle_count);
-                cleanup_all_handles();
-        }
-
-        PORTAL_FREE(handle_hash, sizeof(*handle_hash) * HANDLE_HASH_SIZE);
-        handle_hash = NULL;
-
-        if (handle_count)
-                CERROR("leaked %d handles\n", handle_count);
-}
diff --git a/lustre/obdclass/lustre_peer.c b/lustre/obdclass/lustre_peer.c
deleted file mode 100644 (file)
index 016354c..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#define DEBUG_SUBSYSTEM S_RPC
-
-#ifdef __KERNEL__
-# include <linux/module.h>
-# include <linux/init.h>
-# include <linux/list.h>
-#else
-# include <liblustre.h>
-#endif
-#include <linux/obd.h>
-#include <linux/obd_support.h>
-#include <linux/obd_class.h>
-#include <linux/lustre_lib.h>
-#include <linux/lustre_ha.h>
-#include <linux/lustre_net.h>
-#include <linux/lprocfs_status.h>
-
-struct uuid_nid_data {
-        struct list_head head;
-        ptl_nid_t nid;
-        char *uuid;
-        __u32 nal;
-        ptl_handle_ni_t ni;
-};
-
-/* FIXME: This should probably become more elegant than a global linked list */
-static struct list_head g_uuid_list;
-static spinlock_t       g_uuid_lock;
-
-void class_init_uuidlist(void)
-{
-        INIT_LIST_HEAD(&g_uuid_list);
-        spin_lock_init(&g_uuid_lock);
-}
-
-void class_exit_uuidlist(void)
-{
-        struct list_head *tmp, *n;
-
-        /* Module going => sole user => don't need to lock g_uuid_list */
-        list_for_each_safe(tmp, n, &g_uuid_list) {
-                struct uuid_nid_data *data =
-                        list_entry(tmp, struct uuid_nid_data, head);
-
-                PORTAL_FREE(data->uuid, strlen(data->uuid) + 1);
-                PORTAL_FREE(data, sizeof(*data));
-        }
-}
-
-int lustre_uuid_to_peer(char *uuid, struct lustre_peer *peer)
-{
-        struct list_head *tmp;
-
-        spin_lock (&g_uuid_lock);
-
-        list_for_each(tmp, &g_uuid_list) {
-                struct uuid_nid_data *data =
-                        list_entry(tmp, struct uuid_nid_data, head);
-
-                if (strcmp(data->uuid, uuid) == 0) {
-                        peer->peer_nid = data->nid;
-                        peer->peer_ni = data->ni;
-
-                        spin_unlock (&g_uuid_lock);
-                        return 0;
-                }
-        }
-
-        spin_unlock (&g_uuid_lock);
-        return -1;
-}
-
-int class_add_uuid(char *uuid, __u64 nid, __u32 nal)
-{
-        const ptl_handle_ni_t *nip;
-        struct uuid_nid_data *data;
-        int rc;
-        int nob = strnlen (uuid, PAGE_SIZE) + 1;
-
-        if (nob > PAGE_SIZE)
-                return -EINVAL;
-
-        nip = kportal_get_ni (nal);
-        if (nip == NULL) {
-                CERROR("get_ni failed: is the NAL module loaded?\n");
-                return -EIO;
-        }
-
-        rc = -ENOMEM;
-        PORTAL_ALLOC(data, sizeof(*data));
-        if (data == NULL)
-                goto fail_0;
-
-        PORTAL_ALLOC(data->uuid, nob);
-        if (data == NULL)
-                goto fail_1;
-
-        memcpy(data->uuid, uuid, nob);
-        data->nid = nid;
-        data->nal = nal;
-        data->ni  = *nip;
-
-        spin_lock (&g_uuid_lock);
-
-        list_add(&data->head, &g_uuid_list);
-
-        spin_unlock (&g_uuid_lock);
-
-        return 0;
-
- fail_1:
-        PORTAL_FREE (data, sizeof (*data));
- fail_0:
-        kportal_put_ni (nal);
-        return (rc);
-}
-
-/* delete only one entry if uuid is specified, otherwise delete all */
-int class_del_uuid (char *uuid)
-{
-        struct list_head  deathrow;
-        struct list_head *tmp;
-        struct list_head *n;
-        struct uuid_nid_data *data;
-
-        INIT_LIST_HEAD (&deathrow);
-
-        spin_lock (&g_uuid_lock);
-
-        list_for_each_safe(tmp, n, &g_uuid_list) {
-                data = list_entry(tmp, struct uuid_nid_data, head);
-
-                if (uuid == NULL || strcmp(data->uuid, uuid) == 0) {
-                        list_del (&data->head);
-                        list_add (&data->head, &deathrow);
-                        if (uuid)
-                                break;
-                }
-        }
-
-        spin_unlock (&g_uuid_lock);
-
-        if (list_empty (&deathrow))
-                return -EINVAL;
-
-        do {
-                data = list_entry(deathrow.next, struct uuid_nid_data, head);
-
-                list_del (&data->head);
-
-                kportal_put_ni (data->nal);
-                PORTAL_FREE(data->uuid, strlen(data->uuid) + 1);
-                PORTAL_FREE(data, sizeof(*data));
-        } while (!list_empty (&deathrow));
-
-        return 0;
-}
diff --git a/lustre/ptlrpc/Makefile.am b/lustre/ptlrpc/Makefile.am
deleted file mode 100644 (file)
index d9ec67e..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright (C) 2001  Cluster File Systems, Inc.
-#
-# This code is issued under the GNU General Public License.
-# See the file COPYING in this distribution
-
-DEFS:=
-
-MODULE = ptlrpc
-modulefs_DATA = ptlrpc.o
-EXTRA_PROGRAMS = ptlrpc
-
-ptlrpc_SOURCES =  rpc.c events.c service.c client.c niobuf.c
-
-include $(top_srcdir)/Rules
diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c
deleted file mode 100644 (file)
index 8fc5669..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (C) 2002 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#define EXPORT_SYMTAB
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#define DEBUG_SUBSYSTEM S_RPC
-
-#include <linux/obd_support.h>
-#include <linux/obd_class.h>
-#include <linux/lustre_net.h>
-
-int ptlrpc_enqueue(struct ptlrpc_client *peer, struct ptlrpc_request *req)
-{
-       struct ptlrpc_request *srv_req;
-       
-       if (!peer->cli_obd) { 
-               EXIT;
-               return -1;
-       }
-
-       OBD_ALLOC(srv_req, sizeof(*srv_req));
-       if (!srv_req) { 
-               EXIT;
-               return -ENOMEM;
-       }
-
-        CDEBUG(0, "peer obd minor %d, incoming req %p, srv_req %p\n",
-              peer->cli_obd->obd_minor, req, srv_req);
-
-       memset(srv_req, 0, sizeof(*req)); 
-
-       /* move the request buffer */
-       srv_req->rq_reqbuf = req->rq_reqbuf;
-       srv_req->rq_reqlen = req->rq_reqlen;
-       srv_req->rq_obd = peer->cli_obd;
-
-       /* remember where it came from */
-       srv_req->rq_reply_handle = req;
-
-       list_add(&srv_req->rq_list, &peer->cli_obd->obd_req_list); 
-       wake_up(&peer->cli_obd->obd_req_waitq);
-       return 0;
-}
-
-int ptlrpc_connect_client(int dev, char *uuid, int req_portal, int rep_portal, 
-                          req_pack_t req_pack, rep_unpack_t rep_unpack,
-                          struct ptlrpc_client *cl)
-{
-        int err; 
-
-        memset(cl, 0, sizeof(*cl));
-        spin_lock_init(&cl->cli_lock);
-       cl->cli_xid = 1;
-       cl->cli_obd = NULL; 
-       cl->cli_request_portal = req_portal;
-       cl->cli_reply_portal = rep_portal;
-       cl->cli_rep_unpack = rep_unpack;
-       cl->cli_req_pack = req_pack;
-
-       /* non networked client */
-       if (dev >= 0 && dev < MAX_OBD_DEVICES) {
-               struct obd_device *obd = &obd_dev[dev];
-               
-               if ((!obd->obd_flags & OBD_ATTACHED) ||
-                   (!obd->obd_flags & OBD_SET_UP)) { 
-                       CERROR("target device %d not att or setup\n", dev);
-                       return -EINVAL;
-               }
-                if (strcmp(obd->obd_type->typ_name, "ost") && 
-                    strcmp(obd->obd_type->typ_name, "mds")) { 
-                        return -EINVAL;
-                }
-
-               cl->cli_obd = &obd_dev[dev];
-               return 0;
-       }
-
-       /* networked */
-       err = kportal_uuid_to_peer(uuid, &cl->cli_server);
-       if (err != 0) { 
-               CERROR("cannot find peer %s!", uuid); 
-       }
-
-        return err;
-}
-
-struct ptlrpc_bulk_desc *ptlrpc_prep_bulk(struct lustre_peer *peer)
-{
-        struct ptlrpc_bulk_desc *bulk;
-
-        OBD_ALLOC(bulk, sizeof(*bulk));
-        if (bulk != NULL) {
-                memset(bulk, 0, sizeof(*bulk));
-                memcpy(&bulk->b_peer, peer, sizeof(*peer));
-                init_waitqueue_head(&bulk->b_waitq);
-        }
-
-        return bulk;
-}
-
-struct ptlrpc_request *ptlrpc_prep_req(struct ptlrpc_client *cl, 
-                                       int opcode, int namelen, char *name,
-                                       int tgtlen, char *tgt)
-{
-       struct ptlrpc_request *request;
-       int rc;
-       ENTRY; 
-
-       OBD_ALLOC(request, sizeof(*request));
-       if (!request) { 
-               CERROR("request allocation out of memory\n");
-               return NULL;
-       }
-
-       memset(request, 0, sizeof(*request));
-
-        spin_lock(&cl->cli_lock);
-       request->rq_xid = cl->cli_xid++;
-        spin_unlock(&cl->cli_lock);
-
-       rc = cl->cli_req_pack(name, namelen, tgt, tgtlen,
-                         &request->rq_reqhdr, &request->rq_req,
-                         &request->rq_reqlen, &request->rq_reqbuf);
-       if (rc) { 
-               CERROR("cannot pack request %d\n", rc); 
-               return NULL;
-       }
-       request->rq_reqhdr->opc = opcode;
-       request->rq_reqhdr->xid = request->rq_xid;
-
-       EXIT;
-       return request;
-}
-
-void ptlrpc_free_req(struct ptlrpc_request *request)
-{
-       OBD_FREE(request, sizeof(*request));
-}
-
-static int ptlrpc_check_reply(struct ptlrpc_request *req)
-{
-        if (req->rq_repbuf != NULL) {
-                req->rq_flags = PTL_RPC_REPLY;
-                EXIT;
-                return 1;
-        }
-
-        if (sigismember(&(current->pending.signal), SIGKILL) ||
-            sigismember(&(current->pending.signal), SIGINT)) { 
-                req->rq_flags = PTL_RPC_INTR;
-                EXIT;
-                return 1;
-        }
-
-        return 0;
-}
-
-/* Abort this request and cleanup any resources associated with it. */
-int ptlrpc_abort(struct ptlrpc_request *request)
-{
-        /* First remove the MD for the reply; in theory, this means
-         * that we can tear down the buffer safely. */
-        PtlMEUnlink(request->rq_reply_me_h);
-        PtlMDUnlink(request->rq_reply_md_h);
-        OBD_FREE(request->rq_repbuf, request->rq_replen);
-        request->rq_repbuf = NULL;
-        request->rq_replen = 0;
-
-        return 0;
-}
-
-int ptlrpc_queue_wait(struct ptlrpc_client *cl, struct ptlrpc_request *req)
-                             
-{
-       int rc;
-        ENTRY;
-
-       init_waitqueue_head(&req->rq_wait_for_rep);
-
-       if (cl->cli_obd) {
-               /* Local delivery */
-                ENTRY;
-               rc = ptlrpc_enqueue(cl, req); 
-       } else {
-               /* Remote delivery via portals. */
-               req->rq_req_portal = cl->cli_request_portal;
-               req->rq_reply_portal = cl->cli_reply_portal;
-               rc = ptl_send_rpc(req, &cl->cli_server);
-       }
-       if (rc) { 
-                CERROR("error %d, opcode %d\n", rc, req->rq_reqhdr->opc);
-               return -rc;
-       }
-
-        CDEBUG(0, "-- sleeping\n");
-        wait_event_interruptible(req->rq_wait_for_rep, ptlrpc_check_reply(req));
-        CDEBUG(0, "-- done\n");
-        
-        if (req->rq_flags == PTL_RPC_INTR) { 
-                /* Clean up the dangling reply buffers */
-                ptlrpc_abort(req);
-                EXIT;
-                return -EINTR;
-        }
-
-        if (req->rq_flags != PTL_RPC_REPLY) { 
-                CERROR("Unknown reason for wakeup\n");
-                EXIT;
-                return -EINTR;
-        }
-
-       rc = cl->cli_rep_unpack(req->rq_repbuf, req->rq_replen,
-                                &req->rq_rephdr, &req->rq_rep);
-       if (rc) {
-               CERROR("unpack_rep failed: %d\n", rc);
-               return rc;
-       }
-        CERROR("got rep %d\n", req->rq_rephdr->xid);
-
-       if ( req->rq_rephdr->status == 0 )
-                CDEBUG(0, "--> buf %p len %d status %d\n", req->rq_repbuf,
-                       req->rq_replen, req->rq_rephdr->status);
-
-       EXIT;
-       return 0;
-}
diff --git a/lustre/ptlrpc/events.c b/lustre/ptlrpc/events.c
deleted file mode 100644 (file)
index f3cfd1c..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (C) 2002 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#define EXPORT_SYMTAB
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#define DEBUG_SUBSYSTEM S_RPC
-
-#include <linux/obd_support.h>
-#include <linux/obd_class.h>
-#include <linux/lustre_net.h>
-
-ptl_handle_eq_t sent_pkt_eq, rcvd_rep_eq, bulk_source_eq, bulk_sink_eq;
-static const ptl_handle_ni_t *socknal_nip = NULL, *qswnal_nip = NULL;
-
-/*
- *  Free the packet when it has gone out
- */
-static int sent_packet_callback(ptl_event_t *ev, void *data)
-{
-        ENTRY;
-
-        if (ev->type == PTL_EVENT_SENT) {
-                OBD_FREE(ev->mem_desc.start, ev->mem_desc.length);
-        } else { 
-                // XXX make sure we understand all events, including ACK's
-                CERROR("Unknown event %d\n", ev->type); 
-                BUG();
-        }
-
-        EXIT;
-        return 1;
-}
-
-/*
- * Wake up the thread waiting for the reply once it comes in.
- */
-static int rcvd_reply_callback(ptl_event_t *ev, void *data)
-{
-        struct ptlrpc_request *rpc = ev->mem_desc.user_ptr;
-        ENTRY;
-
-        if (ev->type == PTL_EVENT_PUT) {
-                rpc->rq_repbuf = ev->mem_desc.start + ev->offset;
-                barrier();
-                wake_up_interruptible(&rpc->rq_wait_for_rep);
-        } else { 
-                // XXX make sure we understand all events, including ACK's
-                CERROR("Unknown event %d\n", ev->type); 
-                BUG();
-        }
-
-        EXIT;
-        return 1;
-}
-
-int server_request_callback(ptl_event_t *ev, void *data)
-{
-        struct ptlrpc_service *service = data;
-        int rc;
-
-        if (ev->rlength != ev->mlength)
-                CERROR("Warning: Possibly truncated rpc (%d/%d)\n",
-                       ev->mlength, ev->rlength);
-
-        /* The ME is unlinked when there is less than 1024 bytes free
-         * on its MD.  This ensures we are always able to handle the rpc, 
-         * although the 1024 value is a guess as to the size of a
-         * large rpc (the known safe margin should be determined).
-         *
-         * NOTE: The portals API by default unlinks all MD's associated
-         *       with an ME when it's unlinked.  For now, this behavior
-         *       has been commented out of the portals library so the
-         *       MD can be unlinked when its ref count drops to zero.
-         *       A new MD and ME will then be created that use the same
-         *       kmalloc()'ed memory and inserted at the ring tail.
-         */
-
-        service->srv_ref_count[service->srv_md_active]++;
-
-        if (ev->offset >= (service->srv_buf_size - 1024)) {
-                CDEBUG(D_INODE, "Unlinking ME %d\n", service->srv_me_active);
-
-                rc = PtlMEUnlink(service->srv_me_h[service->srv_me_active]);
-                service->srv_me_h[service->srv_me_active] = 0;
-
-                if (rc != PTL_OK) {
-                        CERROR("PtlMEUnlink failed - DROPPING soon: %d\n", rc);
-                        BUG();
-                        return rc;
-                }
-
-                service->srv_me_active = NEXT_INDEX(service->srv_me_active,
-                        service->srv_ring_length);
-
-                if (service->srv_me_h[service->srv_me_active] == 0)
-                        CERROR("All %d ring ME's are unlinked!\n",
-                               service->srv_ring_length);
-        }
-
-        if (ev->type == PTL_EVENT_PUT) {
-                wake_up(&service->srv_waitq);
-        } else {
-                CERROR("Unexpected event type: %d\n", ev->type);
-        }
-
-        return 0;
-}
-
-
-static int bulk_source_callback(ptl_event_t *ev, void *data)
-{
-        struct ptlrpc_bulk_desc *bulk = ev->mem_desc.user_ptr;
-
-        ENTRY;
-
-        if (ev->type == PTL_EVENT_SENT) {
-                CDEBUG(D_NET, "got SENT event\n");
-        } else if (ev->type == PTL_EVENT_ACK) {
-                CDEBUG(D_NET, "got ACK event\n");
-                bulk->b_flags = PTL_BULK_SENT;
-                wake_up_interruptible(&bulk->b_waitq);
-        } else {
-                CERROR("Unexpected event type!\n");
-                BUG();
-        }
-
-        EXIT;
-        return 1;
-}
-
-static int bulk_sink_callback(ptl_event_t *ev, void *data)
-{
-        struct ptlrpc_bulk_desc *bulk = ev->mem_desc.user_ptr;
-
-        ENTRY;
-
-        if (ev->type == PTL_EVENT_PUT) {
-                if (bulk->b_buf != ev->mem_desc.start + ev->offset)
-                        CERROR("bulkbuf != mem_desc -- why?\n");
-                bulk->b_flags = PTL_BULK_RCVD;
-                wake_up_interruptible(&bulk->b_waitq);
-        } else {
-                CERROR("Unexpected event type!\n");
-                BUG();
-        }
-
-        EXIT;
-        return 1;
-}
-
-int ptlrpc_init_portals(void)
-{
-        int rc;
-        ptl_handle_ni_t ni;
-
-        socknal_nip = inter_module_get_request("ksocknal_ni", "ksocknal");
-        qswnal_nip = inter_module_get_request("kqswnal_ni", "kqswnal");
-        if (socknal_nip == NULL && qswnal_nip == NULL) {
-                CERROR("get_ni failed: is a NAL module loaded?\n");
-                return -EIO;
-        }
-
-        /* Use the qswnal if it's there */
-        if (qswnal_nip != NULL)
-                ni = *qswnal_nip;
-        else
-                ni = *socknal_nip;
-
-        rc = PtlEQAlloc(ni, 128, sent_packet_callback, NULL, &sent_pkt_eq);
-        if (rc != PTL_OK)
-                CERROR("PtlEQAlloc failed: %d\n", rc);
-
-        rc = PtlEQAlloc(ni, 128, rcvd_reply_callback, NULL, &rcvd_rep_eq);
-        if (rc != PTL_OK)
-                CERROR("PtlEQAlloc failed: %d\n", rc);
-
-        rc = PtlEQAlloc(ni, 128, bulk_source_callback, NULL, &bulk_source_eq);
-        if (rc != PTL_OK)
-                CERROR("PtlEQAlloc failed: %d\n", rc);
-
-        rc = PtlEQAlloc(ni, 128, bulk_sink_callback, NULL, &bulk_sink_eq);
-        if (rc != PTL_OK)
-                CERROR("PtlEQAlloc failed: %d\n", rc);
-
-        return rc;
-}
-
-void ptlrpc_exit_portals(void)
-{
-        PtlEQFree(sent_pkt_eq);
-        PtlEQFree(rcvd_rep_eq);
-        PtlEQFree(bulk_source_eq);
-        PtlEQFree(bulk_sink_eq);
-
-        if (qswnal_nip != NULL)
-                inter_module_put("kqswnal_ni");
-        if (socknal_nip != NULL)
-                inter_module_put("ksocknal_ni");
-}
diff --git a/lustre/ptlrpc/lustre_peer.c b/lustre/ptlrpc/lustre_peer.c
deleted file mode 100644 (file)
index d9042f8..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-
-
-
-struct uuid_nid_data {
-        struct list_head head;
-        char *uuid;
-        __u32 nid;
-        __u32 nal;
-        ptl_handle_ni_t ni;
-};
-
-
-/* FIXME: This should probably become more elegant than a global linked list */
-static struct list_head g_uuid_list;
-static spinlock_t       g_uuid_lock;
-
-
-int lustre_uuid_to_peer(char *uuid, struct lustre_peer *peer)
-{
-        struct list_head *tmp;
-
-        spin_lock (&g_uuid_lock);
-
-        list_for_each(tmp, &g_uuid_list) {
-                struct uuid_nid_data *data =
-                        list_entry(tmp, struct uuid_nid_data, head);
-
-                if (strcmp(data->uuid, uuid) == 0) {
-                        peer->peer_nid = data->nid;
-                        peer->peer_ni = data->ni;
-
-                        spin_unlock (&g_uuid_lock);
-                        return 0;
-                }
-        }
-
-        spin_unlock (&g_uuid_lock);
-        return -1;
-}
-
-/* delete only one entry if uuid is specified, otherwise delete all */
-static int lustre_add_uuid(char *uuid, __u64 nid, __u32 nal)
-{
-        const ptl_handle_ni_t *nip;
-        struct uuid_nid_data *data;
-        int rc;
-        int nob = strnlen (uuid, PAGE_SIZE) + 1;
-
-        if (nob > PAGE_SIZE)
-                return -EINVAL;
-        
-        nip = lustre_get_ni (nal);
-        if (nip == NULL) {
-                CERROR("get_ni failed: is the NAL module loaded?\n");
-                return -EIO;
-        }
-
-        rc = -ENOMEM;
-        PORTAL_ALLOC(data, sizeof(*data));
-        if (data == NULL)
-                goto fail_0;
-
-        PORTAL_ALLOC(data->uuid, nob);
-        if (data == NULL)
-                goto fail_1;
-
-        memcpy(data->uuid, uuid, nob);
-        data->nid = nid;
-        data->nal = nal;
-        data->ni  = *nip;
-
-        spin_lock (&g_uuid_lock);
-
-        list_add(&data->head, &g_uuid_list);
-
-        spin_unlock (&g_uuid_lock);
-
-        return 0;
-
- fail_1:
-        PORTAL_FREE (data, sizeof (*data));
- fail_0:
-        lustre_put_ni (nal);
-        return (rc);
-}
-
-static int lustre_del_uuid (char *uuid)
-{
-        struct list_head  deathrow;
-        struct list_head *tmp;
-        struct list_head *n;
-        struct uuid_nid_data *data;
-        
-        INIT_LIST_HEAD (&deathrow);
-        
-        spin_lock (&g_uuid_lock);
-
-        list_for_each_safe(tmp, n, &g_uuid_list) {
-                data = list_entry(tmp, struct uuid_nid_data, head);
-
-                if (uuid == NULL || strcmp(data->uuid, uuid) == 0) {
-                        list_del (&data->head);
-                        list_add (&data->head, &deathrow);
-                        if (uuid)
-                                break;
-                }
-        }
-
-        spin_unlock (&g_uuid_lock);
-
-        if (list_empty (&deathrow))
-                return -EINVAL;
-        
-        do {
-                data = list_entry(deathrow.next, struct uuid_nid_data, head);
-
-                list_del (&data->head);
-
-                lustre_put_ni (data->nal);
-                PORTAL_FREE(data->uuid, strlen(data->uuid) + 1);
-                PORTAL_FREE(data, sizeof(*data));
-        } while (!list_empty (&deathrow));
-        
-        return 0;
-}
diff --git a/lustre/ptlrpc/niobuf.c b/lustre/ptlrpc/niobuf.c
deleted file mode 100644 (file)
index 33a4900..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (C) 2002 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#define EXPORT_SYMTAB
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#define DEBUG_SUBSYSTEM S_RPC
-
-#include <linux/obd_support.h>
-#include <linux/obd_class.h>
-#include <linux/lustre_net.h>
-
-extern ptl_handle_eq_t bulk_source_eq, sent_pkt_eq, rcvd_rep_eq, bulk_sink_eq;
-static ptl_process_id_t local_id = {PTL_ADDR_GID, PTL_ID_ANY, PTL_ID_ANY};
-
-
-int ptlrpc_check_bulk_sent(struct ptlrpc_bulk_desc *bulk)
-{
-        if (bulk->b_flags == PTL_BULK_SENT) {
-                EXIT;
-                return 1;
-        }
-
-        if (sigismember(&(current->pending.signal), SIGKILL) ||
-            sigismember(&(current->pending.signal), SIGINT)) {
-                bulk->b_flags = PTL_RPC_INTR;
-                EXIT;
-                return 1;
-        }
-
-        CERROR("no event yet\n");
-        return 0;
-}
-
-int ptl_send_buf(struct ptlrpc_request *request, struct lustre_peer *peer,
-                 int portal)
-{
-        int rc;
-        ptl_process_id_t remote_id;
-        ptl_handle_md_t md_h;
-        ptl_ack_req_t ack;
-
-        switch (request->rq_type) {
-        case PTL_RPC_BULK:
-                request->rq_req_md.start = request->rq_bulkbuf;
-                request->rq_req_md.length = request->rq_bulklen;
-                request->rq_req_md.eventq = bulk_source_eq;
-                request->rq_req_md.threshold = 2; /* SENT and ACK events */
-                ack = PTL_ACK_REQ;
-                break;
-        case PTL_RPC_REQUEST:
-                request->rq_req_md.start = request->rq_reqbuf;
-                request->rq_req_md.length = request->rq_reqlen;
-                request->rq_req_md.eventq = sent_pkt_eq;
-                request->rq_req_md.threshold = 1;
-                ack = PTL_NOACK_REQ;
-                break;
-        case PTL_RPC_REPLY:
-                request->rq_req_md.start = request->rq_repbuf;
-                request->rq_req_md.length = request->rq_replen;
-                request->rq_req_md.eventq = sent_pkt_eq;
-                request->rq_req_md.threshold = 1;
-                ack = PTL_NOACK_REQ;
-                break;
-        default:
-                BUG();
-                return -1; /* notreached */
-        }
-        request->rq_req_md.options = PTL_MD_OP_PUT;
-        request->rq_req_md.user_ptr = request;
-
-        rc = PtlMDBind(peer->peer_ni, request->rq_req_md, &md_h);
-        if (rc != 0) {
-                BUG();
-                CERROR("PtlMDBind failed: %d\n", rc);
-                return rc;
-        }
-
-        remote_id.addr_kind = PTL_ADDR_NID;
-        remote_id.nid = peer->peer_nid;
-        remote_id.pid = 0;
-
-        CERROR("Sending %d bytes to portal %d, xid %d\n",
-               request->rq_req_md.length, portal, request->rq_xid);
-
-        rc = PtlPut(md_h, ack, remote_id, portal, 0, request->rq_xid, 0, 0);
-        if (rc != PTL_OK) {
-                BUG();
-                CERROR("PtlPut(%d, %d, %d) failed: %d\n", remote_id.nid,
-                       portal, request->rq_xid, rc);
-                /* FIXME: tear down md */
-        }
-
-        return rc;
-}
-
-int ptlrpc_send_bulk(struct ptlrpc_bulk_desc *bulk, int portal)
-{
-        int rc;
-        ptl_process_id_t remote_id;
-        ptl_handle_md_t md_h;
-
-        bulk->b_md.start = bulk->b_buf;
-        bulk->b_md.length = bulk->b_buflen;
-        bulk->b_md.eventq = bulk_source_eq;
-        bulk->b_md.threshold = 2; /* SENT and ACK events */
-        bulk->b_md.options = PTL_MD_OP_PUT;
-        bulk->b_md.user_ptr = bulk;
-
-        rc = PtlMDBind(bulk->b_peer.peer_ni, bulk->b_md, &md_h);
-        if (rc != 0) {
-                BUG();
-                CERROR("PtlMDBind failed: %d\n", rc);
-                return rc;
-        }
-
-        remote_id.addr_kind = PTL_ADDR_NID;
-        remote_id.nid = bulk->b_peer.peer_nid;
-        remote_id.pid = 0;
-
-        CERROR("Sending %d bytes to portal %d, xid %d\n",
-               bulk->b_md.length, portal, bulk->b_xid);
-
-        rc = PtlPut(md_h, PTL_ACK_REQ, remote_id, portal, 0, bulk->b_xid, 0, 0);
-        if (rc != PTL_OK) {
-                BUG();
-                CERROR("PtlPut(%d, %d, %d) failed: %d\n", remote_id.nid,
-                       portal, bulk->b_xid, rc);
-                /* FIXME: tear down md */
-        }
-
-        return rc;
-}
-
-int ptlrpc_wait_bulk(struct ptlrpc_bulk_desc *bulk)
-{
-        int rc;
-
-        ENTRY;
-
-        rc = PtlMEPrepend(bulk->b_peer.peer_ni, bulk->b_portal, local_id,
-                          bulk->b_xid, 0, PTL_UNLINK, &bulk->b_me_h);
-        if (rc != PTL_OK) {
-                CERROR("PtlMEAttach failed: %d\n", rc);
-                BUG();
-                EXIT;
-                goto cleanup1;
-        }
-
-        bulk->b_md.start = bulk->b_buf;
-        bulk->b_md.length = bulk->b_buflen;
-        bulk->b_md.threshold = 1;
-        bulk->b_md.options = PTL_MD_OP_PUT;
-        bulk->b_md.user_ptr = bulk;
-        bulk->b_md.eventq = bulk_sink_eq;
-
-        rc = PtlMDAttach(bulk->b_me_h, bulk->b_md, PTL_UNLINK, &bulk->b_md_h);
-        if (rc != PTL_OK) {
-                CERROR("PtlMDAttach failed: %d\n", rc);
-                BUG();
-                EXIT;
-                goto cleanup2;
-        }
-
-        CDEBUG(D_NET, "Setup bulk sink buffer: %u bytes, xid %u, portal %u\n",
-               bulk->b_buflen, bulk->b_xid, bulk->b_portal);
-
- cleanup2:
-        PtlMEUnlink(bulk->b_me_h);
- cleanup1:
-        PtlMDUnlink(bulk->b_md_h);
-
-        return rc;
-}
-
-int ptlrpc_reply(struct obd_device *obddev, struct ptlrpc_service *svc,
-                 struct ptlrpc_request *req)
-{
-       struct ptlrpc_request *clnt_req = req->rq_reply_handle;
-       ENTRY;
-
-       if (req->rq_reply_handle == NULL) {
-               /* This is a request that came from the network via portals. */
-
-               /* FIXME: we need to increment the count of handled events */
-                req->rq_type = PTL_RPC_REPLY;
-                req->rq_reqhdr->xid = req->rq_reqhdr->xid;
-               ptl_send_buf(req, &req->rq_peer, svc->srv_rep_portal);
-       } else {
-               /* This is a local request that came from another thread. */
-
-               /* move the reply to the client */ 
-               clnt_req->rq_replen = req->rq_replen;
-               clnt_req->rq_repbuf = req->rq_repbuf;
-               req->rq_repbuf = NULL;
-               req->rq_replen = 0;
-
-               /* free the request buffer */
-               OBD_FREE(req->rq_reqbuf, req->rq_reqlen);
-               req->rq_reqbuf = NULL;
-
-               /* wake up the client */ 
-               wake_up_interruptible(&clnt_req->rq_wait_for_rep); 
-       }
-
-       EXIT;
-       return 0;
-}
-
-int ptlrpc_error(struct obd_device *obddev, struct ptlrpc_service *svc,
-                 struct ptlrpc_request *req)
-{
-       struct ptlrep_hdr *hdr;
-
-       ENTRY;
-
-       OBD_ALLOC(hdr, sizeof(*hdr));
-       if (!hdr) { 
-               EXIT;
-               return -ENOMEM;
-       }
-
-       memset(hdr, 0, sizeof(*hdr));
-       
-       hdr->xid = req->rq_reqhdr->xid;
-       hdr->status = req->rq_status; 
-       hdr->type = OST_TYPE_ERR;
-
-        if (req->rq_repbuf) { 
-                CERROR("req has repbuf\n");
-                BUG();
-        }
-
-       req->rq_repbuf = (char *)hdr;
-       req->rq_replen = sizeof(*hdr); 
-
-       EXIT;
-       return ptlrpc_reply(obddev, svc, req);
-}
-
-int ptl_send_rpc(struct ptlrpc_request *request, struct lustre_peer *peer)
-{
-        ptl_process_id_t local_id;
-        int rc;
-        char *repbuf;
-
-        ENTRY;
-
-        if (request->rq_replen == 0) {
-                CERROR("request->rq_replen is 0!\n");
-                EXIT;
-                return -EINVAL;
-        }
-
-        /* request->rq_repbuf is set only when the reply comes in, in
-         * client_packet_callback() */
-        OBD_ALLOC(repbuf, request->rq_replen);
-        if (!repbuf) { 
-                EXIT;
-                return -ENOMEM;
-        }
-
-        local_id.addr_kind = PTL_ADDR_GID;
-        local_id.gid = PTL_ID_ANY;
-        local_id.rid = PTL_ID_ANY;
-
-        //CERROR("sending req %d\n", request->rq_xid);
-        rc = PtlMEPrepend(peer->peer_ni, request->rq_reply_portal, local_id,
-                          request->rq_xid, 0, PTL_UNLINK,
-                          &request->rq_reply_me_h);
-        if (rc != PTL_OK) {
-                CERROR("PtlMEAttach failed: %d\n", rc);
-                BUG();
-                EXIT;
-                goto cleanup;
-        }
-
-        request->rq_type = PTL_RPC_REQUEST;
-        request->rq_reply_md.start = repbuf;
-        request->rq_reply_md.length = request->rq_replen;
-        request->rq_reply_md.threshold = 1;
-        request->rq_reply_md.options = PTL_MD_OP_PUT;
-        request->rq_reply_md.user_ptr = request;
-        request->rq_reply_md.eventq = rcvd_rep_eq;
-
-        rc = PtlMDAttach(request->rq_reply_me_h, request->rq_reply_md,
-                         PTL_UNLINK, &request->rq_reply_md_h);
-        if (rc != PTL_OK) {
-                CERROR("PtlMDAttach failed: %d\n", rc);
-                BUG();
-                EXIT;
-                goto cleanup2;
-        }
-
-        CDEBUG(D_NET, "Setup reply buffer: %u bytes, xid %u, portal %u\n",
-               request->rq_replen, request->rq_xid, request->rq_reply_portal);
-
-        return ptl_send_buf(request, peer, request->rq_req_portal);
-
- cleanup2:
-        PtlMEUnlink(request->rq_reply_me_h);
- cleanup:
-        OBD_FREE(repbuf, request->rq_replen);
-
-        return rc;
-}
-
-/* ptl_received_rpc() should be called by the sleeping process once
- * it finishes processing an event.  This ensures the ref count is
- * decremented and that the rpc ring buffer cycles properly.
- */ 
-int ptl_received_rpc(struct ptlrpc_service *service) {
-        int rc, index;
-
-        index = service->srv_md_active;
-        CDEBUG(D_INFO, "MD index=%d Ref Count=%d\n", index,
-               service->srv_ref_count[index]);
-        service->srv_ref_count[index]--;
-
-        if ((service->srv_ref_count[index] <= 0) &&
-            (service->srv_me_h[index] == 0)) {
-
-                /* Replace the unlinked ME and MD */
-                rc = PtlMEInsert(service->srv_me_h[service->srv_me_tail],
-                                 service->srv_id, 0, ~0, PTL_RETAIN,
-                                 PTL_INS_AFTER, &(service->srv_me_h[index]));
-                CERROR("Inserting new ME and MD in ring, rc %d\n", rc);
-                service->srv_me_tail = index;
-                service->srv_ref_count[index] = 0;
-                
-                if (rc != PTL_OK) {
-                        CERROR("PtlMEInsert failed: %d\n", rc);
-                        BUG();
-                        return rc;
-                }
-
-                service->srv_md[index].start        = service->srv_buf[index];
-                service->srv_md[index].length       = service->srv_buf_size;
-                service->srv_md[index].threshold    = PTL_MD_THRESH_INF;
-                service->srv_md[index].options      = PTL_MD_OP_PUT;
-                service->srv_md[index].user_ptr     = service;
-                service->srv_md[index].eventq       = service->srv_eq_h;
-
-                rc = PtlMDAttach(service->srv_me_h[index],
-                                 service->srv_md[index],
-                                 PTL_RETAIN, &(service->srv_md_h[index]));
-
-                CDEBUG(D_INFO, "Attach MD in ring, rc %d\n", rc);
-                if (rc != PTL_OK) {
-                        /* XXX cleanup */
-                        BUG();
-                        CERROR("PtlMDAttach failed: %d\n", rc);
-                        return rc;
-                }
-
-                service->srv_md_active =
-                        NEXT_INDEX(index, service->srv_ring_length);
-        } 
-        
-        return 0;
-}
diff --git a/lustre/ptlrpc/pinger.c b/lustre/ptlrpc/pinger.c
deleted file mode 100644 (file)
index a657712..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Portal-RPC reconnection and replay operations, for use in recovery.
- *
- *  Copyright (c) 2003 Cluster File Systems, Inc.
- *   Author: Phil Schwan <phil@clusterfs.com>
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/version.h>
-
-#define DEBUG_SUBSYSTEM S_RPC
-#include <linux/obd_support.h>
-#include <linux/obd_class.h>
-#include "ptlrpc_internal.h"
-
-static struct ptlrpc_thread *pinger_thread = NULL;
-static spinlock_t pinger_lock = SPIN_LOCK_UNLOCKED;
-static struct list_head pinger_imports = LIST_HEAD_INIT(pinger_imports);
-
-int ptlrpc_pinger_add_import(struct obd_import *imp)
-{
-        ENTRY;
-        if (!list_empty(&imp->imp_pinger_chain))
-                RETURN(-EALREADY);
-
-        spin_lock(&pinger_lock);
-        list_add(&imp->imp_pinger_chain, &pinger_imports);
-        spin_unlock(&pinger_lock);
-        RETURN(0);
-}
-
-int ptlrpc_pinger_del_import(struct obd_import *imp)
-{
-        ENTRY;
-        if (list_empty(&imp->imp_pinger_chain))
-                RETURN(-EALREADY);
-
-        spin_lock(&pinger_lock);
-        list_del_init(&imp->imp_pinger_chain);
-        spin_unlock(&pinger_lock);
-        RETURN(0);
-}
-
-static void ptlrpc_pinger_do_stuff(void)
-{
-
-
-
-}
-
-static int ptlrpc_pinger_main(void *arg)
-{
-        struct ptlrpc_svc_data *data = (struct ptlrpc_svc_data *)arg;
-        struct ptlrpc_thread *thread = data->thread;
-        unsigned long flags;
-        int rc = 0;
-        ENTRY;
-
-        lock_kernel();
-        ptlrpc_daemonize();
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-        sigfillset(&current->blocked);
-        recalc_sigpending();
-#else
-        spin_lock_irqsave(&current->sigmask_lock, flags);
-        sigfillset(&current->blocked);
-        recalc_sigpending(current);
-        spin_unlock_irqrestore(&current->sigmask_lock, flags);
-#endif
-
-#ifdef __arch_um__
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        sprintf(current->comm, "%s|%d", data->name, current->thread.extern_pid);
-#endif
-#else
-        strcpy(current->comm, data->name);
-#endif
-        unlock_kernel();
-
-        /* Record that the thread is running */
-        thread->t_flags = SVC_RUNNING;
-        wake_up(&thread->t_ctl_waitq);
-
-        /* And now, loop forever on requests */
-        while (1) {
-                struct l_wait_info lwi = LWI_TIMEOUT(5 * HZ, NULL, NULL);
-                l_wait_event(thread->t_ctl_waitq,
-                             thread->t_flags & SVC_STOPPING, &lwi);
-
-                if (thread->t_flags & SVC_STOPPING) {
-                        thread->t_flags &= ~SVC_STOPPING;
-                        EXIT;
-                        break;
-                }
-                ptlrpc_pinger_do_stuff();
-        }
-
-        thread->t_flags = SVC_STOPPED;
-        wake_up(&thread->t_ctl_waitq);
-
-        CDEBUG(D_NET, "pinger thread exiting, process %d: rc = %d\n",
-               current->pid, rc);
-        return rc;
-}
-
-int ptlrpc_pinger_start(void)
-{
-        struct l_wait_info lwi = { 0 };
-        struct ptlrpc_svc_data d;
-        int rc;
-        ENTRY;
-
-        spin_lock(&pinger_lock);
-        if (pinger_thread != NULL)
-                GOTO(out, rc = -EALREADY);
-
-        OBD_ALLOC(pinger_thread, sizeof(*pinger_thread));
-        if (pinger_thread == NULL)
-                GOTO(out, rc = -ENOMEM);
-        init_waitqueue_head(&pinger_thread->t_ctl_waitq);
-
-        d.name = "Lustre pinger";
-        d.thread = pinger_thread;
-
-        /* CLONE_VM and CLONE_FILES just avoid a needless copy, because we
-         * just drop the VM and FILES in ptlrpc_daemonize() right away. */
-        rc = kernel_thread(ptlrpc_pinger_main, &d, CLONE_VM | CLONE_FILES);
-        if (rc < 0) {
-                CERROR("cannot start thread: %d\n", rc);
-                OBD_FREE(pinger_thread, sizeof(*pinger_thread));
-                GOTO(out, rc);
-        }
-        l_wait_event(pinger_thread->t_ctl_waitq,
-                     pinger_thread->t_flags & SVC_RUNNING, &lwi);
-
- out:
-        spin_unlock(&pinger_lock);
-        RETURN(rc);
-}
-
-int ptlrpc_stop_pinger(void)
-{
-        struct l_wait_info lwi = { 0 };
-        int rc = 0;
-        ENTRY;
-
-        spin_lock(&pinger_lock);
-        if (pinger_thread == NULL)
-                GOTO(out, rc = -EALREADY);
-
-        pinger_thread->t_flags = SVC_STOPPING;
-        wake_up(&pinger_thread->t_ctl_waitq);
-        l_wait_event(pinger_thread->t_ctl_waitq,
-                     (pinger_thread->t_flags & SVC_STOPPED), &lwi);
-
-        OBD_FREE(pinger_thread, sizeof(*pinger_thread));
-
- out:
-        spin_unlock(&pinger_lock);
-        RETURN(rc);
-}
diff --git a/lustre/ptlrpc/ptlrpc_internal.h b/lustre/ptlrpc/ptlrpc_internal.h
deleted file mode 100644 (file)
index 6f1738a..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (C) 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/* Intramodule declarations for ptlrpc. */
-
-#ifndef PTLRPC_INTERNAL_H
-#define PTLRPC_INTERNAL_H
-
-struct ldlm_namespace;
-struct obd_import;
-struct ldlm_res_id;
-
-/* ldlm hooks that we need, managed via inter_module_{get,put} */
-extern int (*ptlrpc_ldlm_namespace_cleanup)(struct ldlm_namespace *, int);
-extern int (*ptlrpc_ldlm_cli_cancel_unused)(struct ldlm_namespace *,
-                                     struct ldlm_res_id *, int);
-extern int (*ptlrpc_ldlm_replay_locks)(struct obd_import *);
-
-int ptlrpc_get_ldlm_hooks(void);
-void ptlrpc_daemonize(void);
-
-int ptlrpc_request_handle_eviction(struct ptlrpc_request *);
-
-#endif /* PTLRPC_INTERNAL_H */
diff --git a/lustre/ptlrpc/ptlrpc_module.c b/lustre/ptlrpc/ptlrpc_module.c
deleted file mode 100644 (file)
index 7478526..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#define EXPORT_SYMTAB
-#define DEBUG_SUBSYSTEM S_RPC
-
-#ifdef __KERNEL__
-# include <linux/module.h>
-# include <linux/init.h>
-#else
-# include <liblustre.h>
-#endif
-
-#include <linux/obd_support.h>
-#include <linux/obd_class.h>
-#include <linux/lustre_net.h>
-
-#include "ptlrpc_internal.h"
-
-extern int ptlrpc_init_portals(void);
-extern void ptlrpc_exit_portals(void);
-
-int (*ptlrpc_ldlm_namespace_cleanup)(struct ldlm_namespace *, int);
-int (*ptlrpc_ldlm_replay_locks)(struct obd_import *);
-
-#define GET_HOOK(name)                                                         \
-if (!ptlrpc_##name) {                                                          \
-        if (!(ptlrpc_##name = inter_module_get(#name))) {                      \
-                CERROR("can't i_m_g(\"" #name "\")\n");                        \
-                return 0;                                                      \
-        }                                                                      \
-}
-
-static int ldlm_hooks_referenced;
-
-/* This is called from ptlrpc_get_connection, which runs after all the modules
- * are loaded, but before anything else interesting happens.
- */
-int ptlrpc_get_ldlm_hooks(void)
-{
-        if (ldlm_hooks_referenced)
-                return 1;
-
-        GET_HOOK(ldlm_namespace_cleanup);
-        GET_HOOK(ldlm_replay_locks);
-
-        ldlm_hooks_referenced = 1;
-        RETURN(1);
-}
-
-#undef GET_HOOK
-
-#define PUT_HOOK(hook)                                                         \
-if (ptlrpc_##hook) {                                                           \
-        inter_module_put(#hook);                                               \
-        ptlrpc_##hook = NULL;                                                  \
-}
-
-void ptlrpc_put_ldlm_hooks(void)
-{
-        ENTRY;
-        PUT_HOOK(ldlm_namespace_cleanup);
-        PUT_HOOK(ldlm_replay_locks);
-        ldlm_hooks_referenced = 0;
-        EXIT;
-}
-
-#undef PUT_HOOK
-
-int ptlrpc_ldlm_hooks_referenced(void)
-{
-        return ldlm_hooks_referenced;
-}
-
-__init int ptlrpc_init(void)
-{
-        int rc;
-        ENTRY;
-
-        rc = ptlrpc_init_portals();
-        if (rc)
-                RETURN(rc);
-
-        ptlrpc_init_connection();
-
-        ptlrpc_put_connection_superhack = ptlrpc_put_connection;
-        ptlrpc_abort_inflight_superhack = ptlrpc_abort_inflight;
-        RETURN(0);
-}
-
-static void __exit ptlrpc_exit(void)
-{
-        ptlrpc_exit_portals();
-        ptlrpc_cleanup_connection();
-}
-
-/* connection.c */
-EXPORT_SYMBOL(ptlrpc_readdress_connection);
-EXPORT_SYMBOL(ptlrpc_get_connection);
-EXPORT_SYMBOL(ptlrpc_put_connection);
-EXPORT_SYMBOL(ptlrpc_connection_addref);
-EXPORT_SYMBOL(ptlrpc_init_connection);
-EXPORT_SYMBOL(ptlrpc_cleanup_connection);
-
-/* niobuf.c */
-EXPORT_SYMBOL(ptlrpc_bulk_put);
-EXPORT_SYMBOL(ptlrpc_bulk_get);
-EXPORT_SYMBOL(ptlrpc_register_bulk_put);
-EXPORT_SYMBOL(ptlrpc_register_bulk_get);
-EXPORT_SYMBOL(ptlrpc_abort_bulk);
-EXPORT_SYMBOL(ptlrpc_reply);
-EXPORT_SYMBOL(ptlrpc_error);
-EXPORT_SYMBOL(ptlrpc_resend_req);
-EXPORT_SYMBOL(ptl_send_rpc);
-EXPORT_SYMBOL(ptlrpc_link_svc_me);
-EXPORT_SYMBOL(obd_brw_set_new);
-EXPORT_SYMBOL(obd_brw_set_add);
-EXPORT_SYMBOL(obd_brw_set_del);
-EXPORT_SYMBOL(obd_brw_set_decref);
-EXPORT_SYMBOL(obd_brw_set_addref);
-
-/* client.c */
-EXPORT_SYMBOL(ptlrpc_init_client);
-EXPORT_SYMBOL(ptlrpc_cleanup_client);
-EXPORT_SYMBOL(ptlrpc_req_to_uuid);
-EXPORT_SYMBOL(ptlrpc_uuid_to_connection);
-EXPORT_SYMBOL(ptlrpc_queue_wait);
-EXPORT_SYMBOL(ptlrpc_continue_req);
-EXPORT_SYMBOL(ptlrpc_replay_req);
-EXPORT_SYMBOL(ptlrpc_restart_req);
-EXPORT_SYMBOL(ptlrpc_prep_req);
-EXPORT_SYMBOL(ptlrpc_free_req);
-EXPORT_SYMBOL(ptlrpc_abort);
-EXPORT_SYMBOL(ptlrpc_req_finished);
-EXPORT_SYMBOL(ptlrpc_request_addref);
-EXPORT_SYMBOL(ptlrpc_prep_bulk_imp);
-EXPORT_SYMBOL(ptlrpc_prep_bulk_exp);
-EXPORT_SYMBOL(ptlrpc_free_bulk);
-EXPORT_SYMBOL(ptlrpc_prep_bulk_page);
-EXPORT_SYMBOL(ptlrpc_free_bulk_page);
-EXPORT_SYMBOL(ll_brw_sync_wait);
-EXPORT_SYMBOL(ptlrpc_abort_inflight);
-EXPORT_SYMBOL(ptlrpc_retain_replayable_request);
-EXPORT_SYMBOL(ptlrpc_next_xid);
-
-EXPORT_SYMBOL(ptlrpc_prep_set);
-EXPORT_SYMBOL(ptlrpc_drop_set);
-EXPORT_SYMBOL(ptlrpc_set_add_req);
-EXPORT_SYMBOL(ptlrpc_req_completed);
-EXPORT_SYMBOL(ptlrpc_req_result);
-
-/* service.c */
-EXPORT_SYMBOL(ptlrpc_init_svc);
-EXPORT_SYMBOL(ptlrpc_stop_all_threads);
-EXPORT_SYMBOL(ptlrpc_start_thread);
-EXPORT_SYMBOL(ptlrpc_unregister_service);
-
-/* pack_generic.c */
-EXPORT_SYMBOL(lustre_pack_msg);
-EXPORT_SYMBOL(lustre_msg_size);
-EXPORT_SYMBOL(lustre_unpack_msg);
-EXPORT_SYMBOL(lustre_msg_buf);
-EXPORT_SYMBOL(lustre_msg_string);
-EXPORT_SYMBOL(lustre_swab_reqbuf);
-EXPORT_SYMBOL(lustre_swab_repbuf);
-EXPORT_SYMBOL(lustre_swab_obdo);
-EXPORT_SYMBOL(lustre_swab_obd_statfs);
-EXPORT_SYMBOL(lustre_swab_obd_ioobj);
-EXPORT_SYMBOL(lustre_swab_niobuf_remote);
-EXPORT_SYMBOL(lustre_swab_ost_body);
-EXPORT_SYMBOL(lustre_swab_ll_fid);
-EXPORT_SYMBOL(lustre_swab_mds_status_req);
-EXPORT_SYMBOL(lustre_swab_mds_fileh_body);
-EXPORT_SYMBOL(lustre_swab_mds_body);
-EXPORT_SYMBOL(lustre_swab_mds_rec_setattr);
-EXPORT_SYMBOL(lustre_swab_mds_rec_create);
-EXPORT_SYMBOL(lustre_swab_mds_rec_link);
-EXPORT_SYMBOL(lustre_swab_mds_rec_unlink);
-EXPORT_SYMBOL(lustre_swab_mdx_rec_rename);
-EXPORT_SYMBOL(lustre_swab_lov_desc);
-EXPORT_SYMBOL(lustre_swab_ldlm_res_id);
-EXPORT_SYMBOL(lustre_swab_ldlm_extent);
-EXPORT_SYMBOL(lustre_swab_ldlm_intent);
-EXPORT_SYMBOL(lustre_swab_ldlm_resource_desc);
-EXPORT_SYMBOL(lustre_swab_ldlm_lock_desc);
-EXPORT_SYMBOL(lustre_swab_ldlm_request);
-EXPORT_SYMBOL(lustre_swab_ldlm_reply);
-EXPORT_SYMBOL(lustre_swab_ptlbd_op);
-EXPORT_SYMBOL(lustre_swab_ptlbd_niob);
-EXPORT_SYMBOL(lustre_swab_ptlbd_rsp);
-
-/* ptlrpc_module.c */
-EXPORT_SYMBOL(ptlrpc_put_ldlm_hooks);
-EXPORT_SYMBOL(ptlrpc_ldlm_hooks_referenced);
-
-/* recover.c */
-EXPORT_SYMBOL(ptlrpc_run_recovery_upcall);
-EXPORT_SYMBOL(ptlrpc_reconnect_import);
-EXPORT_SYMBOL(ptlrpc_replay);
-EXPORT_SYMBOL(ptlrpc_resend);
-EXPORT_SYMBOL(ptlrpc_wake_delayed);
-EXPORT_SYMBOL(ptlrpc_set_import_active);
-EXPORT_SYMBOL(ptlrpc_fail_import);
-EXPORT_SYMBOL(ptlrpc_fail_export);
-EXPORT_SYMBOL(ptlrpc_recover_import);
-
-#ifdef __KERNEL__
-MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
-MODULE_DESCRIPTION("Lustre Request Processor");
-MODULE_LICENSE("GPL");
-
-module_init(ptlrpc_init);
-module_exit(ptlrpc_exit);
-#endif
diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c
deleted file mode 100644 (file)
index f560a41..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (C) 2002 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#define EXPORT_SYMTAB
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#define DEBUG_SUBSYSTEM S_RPC
-
-#include <linux/obd_support.h>
-#include <linux/obd_class.h>
-#include <linux/lustre_net.h>
-
-extern int server_request_callback(ptl_event_t *ev, void *data);
-
-static int ptlrpc_check_event(struct ptlrpc_service *svc)
-{
-        
-        if (sigismember(&(current->pending.signal), SIGKILL) ||
-            sigismember(&(current->pending.signal), SIGINT)) { 
-                svc->srv_flags |= SVC_KILLED;
-                EXIT;
-                return 1;
-        }
-
-        if ( svc->srv_flags & SVC_STOPPING ) {
-                EXIT;
-                return 1;
-        }
-
-        if ( svc->srv_eq_h ) { 
-                int rc;
-                rc = PtlEQGet(svc->srv_eq_h, &svc->srv_ev);
-
-                if (rc == PTL_OK) { 
-                        svc->srv_flags |= SVC_EVENT;
-                        EXIT;
-                        return 1;
-                }
-
-                if (rc == PTL_EQ_DROPPED) { 
-                        CERROR("dropped event!\n");
-                        BUG();
-                }
-                CERROR("PtlEQGet returns %d\n", rc); 
-                EXIT;
-                return 0;
-        }
-
-        if (!list_empty(&svc->srv_reqs)) {
-                svc->srv_flags |= SVC_LIST;
-                EXIT;
-                return 1;
-        }
-                
-        EXIT;
-        return 0;
-}
-
-struct ptlrpc_service *
-ptlrpc_init_svc(__u32 bufsize, int req_portal, int rep_portal, char *uuid,
-                req_unpack_t unpack, rep_pack_t pack, svc_handler_t handler)
-{
-        int err;
-        struct ptlrpc_service *svc;
-
-        OBD_ALLOC(svc, sizeof(*svc)); 
-        if ( !svc ) { 
-                CERROR("no memory\n");
-                return NULL;
-        }
-
-        memset(svc, 0, sizeof(*svc)); 
-
-        spin_lock_init(&svc->srv_lock);
-        INIT_LIST_HEAD(&svc->srv_reqs);
-        init_waitqueue_head(&svc->srv_ctl_waitq); 
-        init_waitqueue_head(&svc->srv_waitq); 
-
-        svc->srv_thread = NULL;
-       svc->srv_flags = 0;
-
-        svc->srv_buf_size = bufsize;
-        svc->srv_rep_portal = rep_portal;
-        svc->srv_req_portal = req_portal;
-        svc->srv_req_unpack = unpack;
-        svc->srv_rep_pack = pack;
-        svc->srv_handler = handler;
-       err = kportal_uuid_to_peer(uuid, &svc->srv_self);
-        if (err) { 
-                CERROR("cannot get peer for uuid %s", uuid); 
-                OBD_FREE(svc, sizeof(*svc));
-                return NULL; 
-        }
-        return svc;
-}
-
-static int ptlrpc_main(void *arg)
-{
-        int rc;
-        struct ptlrpc_svc_data *data = (struct ptlrpc_svc_data *)arg;
-       struct obd_device *obddev = data->dev;
-        struct ptlrpc_service *svc = data->svc;
-
-       ENTRY;
-
-       lock_kernel();
-       daemonize();
-       spin_lock_irq(&current->sigmask_lock);
-       sigfillset(&current->blocked);
-       recalc_sigpending(current);
-       spin_unlock_irq(&current->sigmask_lock);
-
-       sprintf(current->comm, data->name);
-
-       /* Record that the  thread is running */
-       svc->srv_thread = current;
-        svc->srv_flags = SVC_RUNNING;
-       wake_up(&svc->srv_ctl_waitq); 
-
-       /* XXX maintain a list of all managed devices: insert here */
-
-       /* And now, loop forever on requests */
-       while (1) {
-
-                wait_event(svc->srv_waitq, ptlrpc_check_event(svc));
-                
-                if (svc->srv_flags & SVC_SIGNAL) {
-                        EXIT;
-                        break;
-                }
-
-                if (svc->srv_flags & SVC_STOPPING) {
-                        EXIT;
-                        break;
-                }
-
-                if (svc->srv_flags & SVC_EVENT) { 
-                       struct ptlrpc_request request;
-                        svc->srv_flags = SVC_RUNNING; 
-
-                        /* FIXME: If we move to an event-driven model,
-                         * we should put the request on the stack of
-                         * mds_handle instead. */
-                        memset(&request, 0, sizeof(request));
-                        request.rq_obd = obddev;
-                        request.rq_reqbuf = svc->srv_ev.mem_desc.start + svc->srv_ev.offset;
-                        request.rq_reqlen = svc->srv_ev.mem_desc.length;
-                        request.rq_xid = svc->srv_ev.match_bits;
-                        CERROR("got req %d\n", request.rq_xid);
-
-                        request.rq_peer.peer_nid = svc->srv_ev.initiator.nid;
-                        /* FIXME: this NI should be the incoming NI.
-                         * We don't know how to find that from here. */
-                        request.rq_peer.peer_ni = svc->srv_self.peer_ni;
-                        rc = svc->srv_handler(obddev, svc, &request);
-                        ptl_received_rpc(svc);
-                        continue;
-                }
-
-                if (svc->srv_flags & SVC_LIST) { 
-                       struct ptlrpc_request *request;
-                        svc->srv_flags = SVC_RUNNING; 
-
-                        spin_lock(&svc->srv_lock);
-                        request = list_entry(svc->srv_reqs.next,
-                                             struct ptlrpc_request,
-                                             rq_list);
-                        list_del(&request->rq_list);
-                        spin_unlock(&svc->srv_lock);
-                        rc = svc->srv_handler(obddev, svc, request);
-                        continue;
-                }
-                CERROR("unknown break in service"); 
-                break; 
-        }
-
-       svc->srv_thread = NULL;
-        svc->srv_flags = SVC_STOPPED;
-       wake_up(&svc->srv_ctl_waitq);
-       CERROR("svc exiting process %d\n", current->pid);
-       return 0;
-}
-
-void ptlrpc_stop_thread(struct ptlrpc_service *svc)
-{
-       svc->srv_flags = SVC_STOPPING;
-
-        wake_up(&svc->srv_waitq);
-        wait_event_interruptible(svc->srv_ctl_waitq, 
-                                 (svc->srv_flags & SVC_STOPPED));
-}
-
-int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc,
-                                char *name)
-{
-        struct ptlrpc_svc_data d;
-        int rc;
-       ENTRY;
-
-        d.dev = dev;
-        d.svc = svc;
-        d.name = name;
-
-       init_waitqueue_head(&svc->srv_waitq);
-
-       init_waitqueue_head(&svc->srv_ctl_waitq);
-       rc = kernel_thread(ptlrpc_main, (void *) &d, 
-                           CLONE_VM | CLONE_FS | CLONE_FILES);
-        if (rc < 0) { 
-                CERROR("cannot start thread\n"); 
-                return -EINVAL;
-        }
-        wait_event(svc->srv_ctl_waitq, svc->srv_flags & SVC_RUNNING);
-
-       EXIT;
-        return 0;
-}
-
-
-int rpc_register_service(struct ptlrpc_service *service, char *uuid)
-{
-        struct lustre_peer peer;
-        int rc, i;
-
-        rc = kportal_uuid_to_peer(uuid, &peer);
-        if (rc != 0) {
-                CERROR("Invalid uuid \"%s\"\n", uuid);
-                return -EINVAL;
-        }
-
-        service->srv_ring_length = RPC_RING_LENGTH;
-        service->srv_me_active = 0;
-        service->srv_md_active = 0;
-
-        service->srv_id.addr_kind = PTL_ADDR_GID;
-        service->srv_id.gid = PTL_ID_ANY;
-        service->srv_id.rid = PTL_ID_ANY;
-
-        rc = PtlEQAlloc(peer.peer_ni, 128, server_request_callback,
-                        service, &(service->srv_eq_h));
-
-        if (rc != PTL_OK) {
-                CERROR("PtlEQAlloc failed: %d\n", rc);
-                return rc;
-        }
-
-        /* Attach the leading ME on which we build the ring */
-        rc = PtlMEAttach(peer.peer_ni, service->srv_req_portal,
-                         service->srv_id, 0, ~0, PTL_RETAIN,
-                         &(service->srv_me_h[0]));
-
-        if (rc != PTL_OK) {
-                CERROR("PtlMEAttach failed: %d\n", rc);
-                return rc;
-        }
-
-        for (i = 0; i < service->srv_ring_length; i++) {
-                OBD_ALLOC(service->srv_buf[i], service->srv_buf_size);
-
-                if (service->srv_buf[i] == NULL) {
-                        CERROR("no memory\n");
-                        return -ENOMEM;
-                }
-
-                /* Insert additional ME's to the ring */
-                if (i > 0) {
-                        rc = PtlMEInsert(service->srv_me_h[i-1],
-                                         service->srv_id, 0, ~0, PTL_RETAIN,
-                                         PTL_INS_AFTER,&(service->srv_me_h[i]));
-                        service->srv_me_tail = i;
-
-                        if (rc != PTL_OK) {
-                                CERROR("PtlMEInsert failed: %d\n", rc);
-                                return rc;
-                        }
-                }
-
-                service->srv_ref_count[i] = 0;
-                service->srv_md[i].start        = service->srv_buf[i];
-                service->srv_md[i].length        = service->srv_buf_size;
-                service->srv_md[i].threshold        = PTL_MD_THRESH_INF;
-                service->srv_md[i].options        = PTL_MD_OP_PUT;
-                service->srv_md[i].user_ptr        = service;
-                service->srv_md[i].eventq        = service->srv_eq_h;
-
-                rc = PtlMDAttach(service->srv_me_h[i], service->srv_md[i],
-                                 PTL_RETAIN, &(service->srv_md_h[i]));
-
-                if (rc != PTL_OK) {
-                        /* cleanup */
-                        CERROR("PtlMDAttach failed: %d\n", rc);
-                        return rc;
-                }
-        }
-
-        return 0;
-}
-
-int rpc_unregister_service(struct ptlrpc_service *service)
-{
-        int rc, i;
-
-        for (i = 0; i < service->srv_ring_length; i++) {
-                rc = PtlMDUnlink(service->srv_md_h[i]);
-                if (rc)
-                        CERROR("PtlMDUnlink failed: %d\n", rc);
-        
-                rc = PtlMEUnlink(service->srv_me_h[i]);
-                if (rc)
-                        CERROR("PtlMEUnlink failed: %d\n", rc);
-
-                if (service->srv_buf[i] != NULL)
-                        OBD_FREE(service->srv_buf[i], service->srv_buf_size);
-                service->srv_buf[i] = NULL;
-        }
-
-        rc = PtlEQFree(service->srv_eq_h);
-        if (rc)
-                CERROR("PtlEQFree failed: %d\n", rc);
-
-        return 0;
-}
-
diff --git a/lustre/scripts/llite-group.sh b/lustre/scripts/llite-group.sh
deleted file mode 100644 (file)
index 879a858..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/bin/sh
-#
-# llite-group.sh : Cluster Manager service script for Lustre
-#
-# This must be named llite-<group>.sh, where group is the device 
-# group that is being managed by the cluster manager service.
-#
-
-set -e
-set -vx
-
-[ -f ${LUSTRE_CFG:=/etc/lustre/lustre.cfg} ] && . ${LUSTRE_CFG}
-
-LDAPURL=${LDAPURL:-ldap://localhost}
-CONFIG=${CONFIG:-test23}
-
-LACTIVE=${LACTIVE:-/usr/sbin/lactive}
-LCONF=${LCONF:-/usr/sbin/lconf}
-
-group=`basename $0 .sh| cut -d- -f2`
-confopt="--ldapurl $LDAPURL --config $CONFIG"
-
-[ -z "$group" ] && exit 0
-
-node=`hostname -s`
-
-[ -d ${STATUS_DIR:=/var/lustre} ] || mkdir -p $STATUS_DIR
-
-start() {
-        echo -n "Starting $SERVICE: "
-       python2 $LACTIVE $confopt --group $group --active $node
-        python2 $LCONF -v $confopt
-        RETVAL=$?
-       echo done
-}
-
-stop() {
-        echo -n "Shutting down $SERVICE: "
-        python2 $LCONF -v --cleanup --failover $confopt
-        RETVAL=$?
-        echo done
-}
-
-status() {
-        RETVAL=0
-}
-
-
-case "$1" in
-  start)
-       start
-       ;;
-  stop)
-       stop
-       ;;
-  restart)
-       restart
-       ;;
-  status)
-       status $SERVICE
-       ;;
-  *)
-       echo "Usage: $0 {start|stop|status}"
-       exit 1
-esac
-
-exit $RETVAL
diff --git a/lustre/scripts/nodelustre b/lustre/scripts/nodelustre
deleted file mode 100755 (executable)
index b5e6540..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#! /bin/sh
-# nodelustre - Start and stop Lustre on MCR nodes
-# Copyright (C) 2002  Cluster File Systems, Inc.
-# Gord Eagle <gord@clusterfs.com>, 2002-09-10
-
-# Set this to the shared config file.
-MASTER_CONFIG=http://emcri/lustre.xml
-CONFIG=/etc/lustre/lustre.xml
-COMPUTE_NODE=client
-
-LCONF=/usr/local/cfs/lustre/utils/lconf
-WGET=wget
-
-case "$1" in
-start | stop)
-  # Fetch the config file.  We can't use --output-document because it
-  # makes Wget ignore timestamping.
-  if test -n "$MASTER_CONFIG"; then
-    (cd `echo "$CONFIG" | sed 's%/[^/]*$%%'` && \
-      $WGET --timestamping "$MASTER_CONFIG") || exit $?
-  fi
-
-  # Map all client nodes to the COMPUTE_NODE virtual node.
-  if test -n "$COMPUTE_NODE" && nodeattr compute; then
-    node=" --node $COMPUTE_NODE"
-  else
-    node=
-  fi
-
-  # If we're stopping, do the lconf cleanup.
-  if test "$1" = stop; then
-    cleanup=' --cleanup'
-  else
-    cleanup=
-  fi
-
-  $LCONF$cleanup$node "$CONFIG"
-  ;;
-
-*)
-  echo "$0 {start|stop}" 1>&2
-  exit 1
-  ;;
-esac
-
-exit 0
diff --git a/lustre/scripts/version_tag.pl b/lustre/scripts/version_tag.pl
deleted file mode 100644 (file)
index a92fef4..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/usr/bin/perl
-# -*- Mode: perl; indent-tabs-mode: nil; cperl-indent-level: 4 -*-
-
-use strict;
-use diagnostics;
-use IO::File;
-use Time::Local;
-
-my $pristine = 1;
-my $kernver;
-
-sub get_tag()
-{
-    my $tag;
-
-    my $tagfile = new IO::File;
-    if (!$tagfile->open("CVS/Tag")) {
-        return "HEAD";
-    } else {
-        my $tmp = <$tagfile>;
-        $tagfile->close();
-
-        $tmp =~ m/T(.*)/;
-        return $1;
-    }
-}
-
-sub get_latest_mtime()
-{
-    my %months=("Jan" => 0, "Feb" => 1, "Mar" => 2, "Apr" => 3, "May" => 4,
-                "Jun" => 5, "Jul" => 6, "Aug" => 7, "Sep" => 8, "Oct" => 9,
-                "Nov" => 10, "Dec" => 11);
-
-    my $last_mtime = 0;
-    my @entries = `find . -name Entries`;
-    my $entry_file;
-    foreach $entry_file (@entries) {
-        chomp($entry_file);
-        my $entry = new IO::File;
-        if (!$entry->open($entry_file)) {
-            die "unable to open $entry_file: $!\n";
-        }
-        my $line;
-        while (defined($line = <$entry>)) {
-            chomp($line);
-            #print "line: $line\n";
-            my ($junk, $file, $version, $date) = split(/\//, $line);
-
-            #print "junk: $junk\nfile: $file\nver: $version\ndate: $date\n";
-            #print "last_mtime: " . localtime($last_mtime) . "\n";
-
-            if ($junk eq "D" ||
-                $file eq "lustre.spec.in" ||
-                $file !~ m/\.(c|h|am|in)$/) {
-                next;
-            }
-
-            my $cur_dir = $entry_file;
-            $cur_dir =~ s/\/CVS\/Entries$//;
-            my @statbuf = stat("$cur_dir/$file");
-            my $mtime = $statbuf[9];
-            my $local_date = gmtime($mtime);
-            if ($local_date ne $date &&
-                $file ne "lustre.spec.in") {
-                #print "$file : " . localtime($mtime) . "\n";
-                $pristine = 0;
-            }
-
-            if ($mtime > $last_mtime) {
-                $last_mtime = $mtime;
-            }
-
-            if ($date) {
-                my @t = split(/ +/, $date);
-                if (int(@t) != 5) {
-                    #print "skipping: $date\n";
-                    next;
-                }
-                my ($hours, $min, $sec) = split(/:/, $t[3]);
-                my ($mon, $mday, $year) = ($t[1], $t[2], $t[4]);
-                my $secs = 0;
-                $mon = $months{$mon};
-                $secs = timelocal($sec, $min, $hours, $mday, $mon, $year);
-                if ($secs > $last_mtime) {
-                    $last_mtime = $secs;
-                }
-            }
-        }
-        $entry->close();
-    }
-    return $last_mtime;
-}
-
-sub get_linuxdir()
-{
-    my $config = new IO::File;
-    my ($line, $dir);
-    if (!$config->open("Makefile")) {
-        die "Run ./configure first\n";
-    }
-    while (defined($line = <$config>)) {
-        chomp($line);
-        if ($line =~ /LINUX = (.*)/) {
-            $dir = $1;
-            last;
-        }
-    }
-    $config->close();
-    my $ver = new IO::File;
-    if (!$ver->open("$dir/include/linux/version.h")) {
-        die "Run make dep on $dir\n";
-    }
-    while(defined($line = <$ver>)) {
-        $line =~ /\#define UTS_RELEASE "(.*)"/;
-        if ($1) {
-            $kernver = $1;
-            last;
-        }
-    }
-    $ver->close();
-    chomp($kernver);
-    $dir =~ s/\//\./g;
-    return $dir;
-}
-
-sub generate_ver($$$)
-{
-    my $tag = shift;
-    my $mtime = shift;
-    my $linuxdir = shift;
-
-    #print "localtime: " . localtime($mtime) . "\n";
-
-    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
-      localtime($mtime);
-    $year += 1900;
-    $mon++;
-    my $show_last = sprintf("%04d%02d%02d%02d%02d%02d", $year, $mon, $mday,
-                            $hour, $min, $sec);
-
-    print "#define BUILD_VERSION \"";
-    if ($pristine) {
-        print "$tag-$show_last-PRISTINE-$linuxdir-$kernver\"\n";
-    } else {
-        print "$tag-$show_last-CHANGED-$linuxdir-$kernver\"\n";
-    }
-}
-
-if ($ARGV[0]) {
-    chdir($ARGV[0]);
-}
-my $linuxdir = get_linuxdir();
-my $tag = get_tag();
-my $mtime = get_latest_mtime();
-generate_ver($tag, $mtime, $linuxdir);
-
-exit(0);
diff --git a/lustre/tests/acceptance-metadata-double.sh b/lustre/tests/acceptance-metadata-double.sh
deleted file mode 100644 (file)
index f647a55..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/bin/sh
-set -e
-
-#
-# Runs create.pl and rename.pl on two mountpoints with increasing load, varying
-# debug levels.  Assumes that the node is already setup with llmount2.sh
-#
-
-SRCDIR="`dirname $0`"
-CREATE=$SRCDIR/create.pl
-
-debug_client_on()
-{
-       echo -1 > /proc/sys/portals/debug
-}
-
-debug_client_off()
-{
-       echo 0 > /proc/sys/portals/debug
-}
-
-MNT=${MNT:-/mnt/lustre}
-
-debug_client_on
-echo "create.pl, 2 mounts, 1 thread, 10 ops, debug on"
-perl $CREATE -- $MNT 2 10
-echo "create.pl, 2 mounts, 1 thread, 100 ops, debug on"
-perl $CREATE --silent -- $MNT 2 100
-echo "create.pl --mcreate=0, 2 mounts, 1 thread, 10 ops, debug on"
-perl $CREATE --mcreate=0 -- $MNT 2 10
-echo "create.pl --mcreate=0, 2 mounts, 1 thread, 100 ops, debug on"
-perl $CREATE --mcreate=0 --silent -- $MNT 2 100
-echo "rename.pl, 2 mounts, 1 thread, 10 ops, debug on"
-perl rename.pl --count=2 $MNT 10
-echo "rename.pl, 2 mounts, 1 thread, 100 ops, debug on"
-perl rename.pl --count=2 --silent $MNT 100
-
-debug_client_off
-echo "create.pl, 2 mounts, 1 thread, 1000 ops, debug off"
-perl $CREATE --silent -- $MNT 2 1000
-echo "create.pl --mcreate=0, 2 mounts, 1 thread, 1000 ops, debug off"
-perl $CREATE --silent --mcreate=0 -- $MNT 2 1000
-echo "rename.pl, 2 mounts, 1 thread, 1000 ops, debug off"
-perl rename.pl --count=2 --silent $MNT 1000
-
-debug_client_on
-echo "create.pl, 2 mounts, 2 threads, 100 ops, debug on"
-perl $CREATE --silent -- $MNT 2 100 &
-perl $CREATE --silent -- $MNT 2 100 &
-wait
-echo "create.pl --mcreate=0, 2 mounts, 2 threads, 100 ops, debug on"
-perl $CREATE --silent --mcreate=0 -- $MNT 2 100 &
-perl $CREATE --silent --mcreate=0 -- $MNT 2 100 &
-wait
-echo "rename.pl, 2 mounts, 2 thread, 1000 ops, debug on"
-perl rename.pl --count=2 --silent $MNT 1000 &
-perl rename.pl --count=2 --silent $MNT 1000 &
-wait
-
-debug_client_off
-echo "create.pl, 2 mounts, 2 threads, 2000 ops, debug off"
-perl $CREATE --silent -- $MNT 2 2000 &
-perl $CREATE --silent -- $MNT 2 2000 &
-wait
-echo "create.pl --mcreate=0, 2 mounts, 2 threads, 2000 ops, debug off"
-perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 &
-perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 &
-wait
-echo "rename.pl, 2 mounts, 2 threads, 2000 ops, debug off"
-perl rename.pl --count=2 --silent $MNT 2000 &
-perl rename.pl --count=2 --silent $MNT 2000 &
-wait
-
-debug_client_on
-echo "create.pl, 2 mounts, 4 threads, 100 ops, debug on"
-for i in `seq 1 4`; do
-  perl $CREATE --silent -- $MNT 2 100 &
-done
-wait
-echo "create.pl --mcreate=0, 2 mounts, 4 threads, 100 ops, debug on"
-for i in `seq 1 4`; do
-  perl $CREATE --silent --mcreate=0 -- $MNT 2 100 &
-done
-wait
-echo "rename.pl, 2 mounts, 4 threads, 2000 ops, debug on"
-for i in `seq 1 4`; do
-  perl rename.pl --count=2 --silent $MNT 2000 &
-done
-wait
-
-debug_client_off
-echo "create.pl, 2 mounts, 4 threads, 2000 ops, debug off"
-for i in `seq 1 4`; do
-  perl $CREATE --silent -- $MNT 2 2000 &
-done
-wait
-echo "create.pl --mcreate=0, 2 mounts, 4 threads, 2000 ops, debug off"
-for i in `seq 1 4`; do
-  perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 &
-done
-wait
-echo "rename.pl, 2 mounts, 4 threads, 2000 ops, debug off"
-for i in `seq 1 4`; do
-  perl rename.pl --count=2 --silent $MNT 2000 &
-done
-wait
-
-debug_client_on
-echo "create.pl, 2 mounts, 8 threads, 500 ops, debug on"
-for i in `seq 1 8`; do
-  perl $CREATE --silent -- $MNT 2 500 &
-done
-wait
-echo "create.pl --mcreate=0, 2 mounts, 8 threads, 500 ops, debug on"
-for i in `seq 1 8`; do
-  perl $CREATE --silent --mcreate=0 -- $MNT 2 500 &
-done
-wait
-echo "rename.pl, 2 mounts, 8 threads, 2000 ops, debug on"
-for i in `seq 1 8`; do
-  perl rename.pl --count=2 --silent $MNT 2000 &
-done
-wait
-
-debug_client_off
-echo "create.pl, 2 mounts, 8 threads, 2000 ops, debug off"
-for i in `seq 1 8`; do
-  perl $CREATE --silent -- $MNT 2 2000 &
-done
-wait
-echo "create.pl --mcreate=0, 2 mounts, 8 threads, 2000 ops, debug off"
-for i in `seq 1 8`; do
-  perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 &
-done
-wait
-echo "rename.pl, 2 mounts, 8 threads, 2000 ops, debug off"
-for i in `seq 1 8`; do
-  perl rename.pl --count=2 --silent $MNT 2000 &
-done
-wait
diff --git a/lustre/tests/acceptance-metadata-single.sh b/lustre/tests/acceptance-metadata-single.sh
deleted file mode 100644 (file)
index 501d2be..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/bin/sh
-set -e
-
-#
-# Runs create.pl and rename.pl on a single mountpoint with increasing
-# load, varying debug levels
-#
-
-SRCDIR="`dirname $0`/"
-. $SRCDIR/common.sh
-
-MNT=${MNT:-/mnt/lustre}
-
-debug_client_on
-echo "create.pl, 1 mount, 1 thread, 10 ops, debug on"
-perl create.pl -- $MNT -1 10
-echo "create.pl, 1 mount, 1 thread, 100 ops, debug on"
-perl create.pl --silent -- $MNT -1 100
-echo "create.pl --mcreate=0, 1 mount, 1 thread, 10 ops, debug on"
-perl create.pl --mcreate=0 -- $MNT -1 10
-echo "create.pl --mcreate=0, 1 mount, 1 thread, 100 ops, debug on"
-perl create.pl --mcreate=0 --silent -- $MNT -1 100
-echo "rename.pl, 1 mount, 1 thread, 10 ops, debug on"
-perl rename.pl $MNT 10
-echo "rename.pl, 1 mount, 1 thread, 100 ops, debug on"
-perl rename.pl --silent $MNT 100
-
-debug_client_off
-echo "create.pl, 1 mount, 1 thread, 1000 ops, debug off"
-perl create.pl --silent -- $MNT -1 1000
-echo "create.pl --mcreate=0, 1 mount, 1 thread, 1000 ops, debug off"
-perl create.pl --silent --mcreate=0 -- $MNT -1 1000
-echo "rename.pl, 1 mount, 1 thread, 1000 ops, debug off"
-perl rename.pl --silent $MNT 1000
-
-debug_client_on
-echo "create.pl, 1 mount, 2 threads, 100 ops, debug on"
-perl create.pl --silent -- $MNT -1 100 &
-perl create.pl --silent -- $MNT -1 100 &
-wait
-echo "create.pl --mcreate=0, 1 mount, 2 threads, 100 ops, debug on"
-perl create.pl --silent --mcreate=0 -- $MNT -1 100 &
-perl create.pl --silent --mcreate=0 -- $MNT -1 100 &
-wait
-echo "rename.pl, 1 mount, 2 thread, 1000 ops, debug on"
-perl rename.pl --silent $MNT 1000 &
-perl rename.pl --silent $MNT 1000 &
-wait
-
-debug_client_off
-echo "create.pl, 1 mount, 2 threads, 2000 ops, debug off"
-perl create.pl --silent -- $MNT -1 2000 &
-perl create.pl --silent -- $MNT -1 2000 &
-wait
-echo "create.pl --mcreate=0, 1 mount, 2 threads, 2000 ops, debug off"
-perl create.pl --silent --mcreate=0 -- $MNT -1 2000 &
-perl create.pl --silent --mcreate=0 -- $MNT -1 2000 &
-wait
-echo "rename.pl, 1 mount, 2 threads, 2000 ops, debug off"
-perl rename.pl --silent $MNT 2000 &
-perl rename.pl --silent $MNT 2000 &
-wait
-
-debug_client_on
-echo "create.pl, 1 mount, 4 threads, 100 ops, debug on"
-for i in `seq 1 4`; do
-  perl create.pl --silent -- $MNT -1 100 &
-done
-wait
-echo "create.pl --mcreate=0, 1 mount, 4 threads, 100 ops, debug on"
-for i in `seq 1 4`; do
-  perl create.pl --silent --mcreate=0 -- $MNT -1 100 &
-done
-wait
-echo "rename.pl, 1 mount, 4 threads, 2000 ops, debug on"
-for i in `seq 1 4`; do
-  perl rename.pl --silent $MNT 2000 &
-done
-wait
-
-debug_client_off
-echo "create.pl, 1 mount, 4 threads, 2000 ops, debug off"
-for i in `seq 1 4`; do
-  perl create.pl --silent -- $MNT -1 2000 &
-done
-wait
-echo "create.pl --mcreate=0, 1 mount, 4 threads, 2000 ops, debug off"
-for i in `seq 1 4`; do
-  perl create.pl --silent --mcreate=0 -- $MNT -1 2000 &
-done
-wait
-echo "rename.pl, 1 mount, 4 threads, 2000 ops, debug off"
-for i in `seq 1 4`; do
-  perl rename.pl --silent $MNT 2000 &
-done
-wait
-
-debug_client_on
-echo "create.pl, 1 mount, 8 threads, 500 ops, debug on"
-for i in `seq 1 8`; do
-  perl create.pl --silent -- $MNT -1 500 &
-done
-wait
-echo "create.pl --mcreate=0, 1 mount, 8 threads, 500 ops, debug on"
-for i in `seq 1 8`; do
-  perl create.pl --silent --mcreate=0 -- $MNT -1 500 &
-done
-wait
-echo "rename.pl, 1 mount, 8 threads, 2000 ops, debug on"
-for i in `seq 1 8`; do
-  perl rename.pl --silent $MNT 2000 &
-done
-wait
-
-debug_client_off
-echo "create.pl, 1 mount, 8 threads, 2000 ops, debug off"
-for i in `seq 1 8`; do
-  perl create.pl --silent -- $MNT -1 2000 &
-done
-wait
-echo "create.pl --mcreate=0, 1 mount, 8 threads, 2000 ops, debug off"
-for i in `seq 1 8`; do
-  perl create.pl --silent --mcreate=0 -- $MNT -1 2000 &
-done
-wait
-echo "rename.pl, 1 mount, 8 threads, 2000 ops, debug off"
-for i in `seq 1 8`; do
-  perl rename.pl --silent $MNT 2000 &
-done
-wait
diff --git a/lustre/tests/ba-echo.sh b/lustre/tests/ba-echo.sh
deleted file mode 100644 (file)
index d971016..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-
-config=${1:-ba-echo.xml}
-
-LMC="save_cmd"
-LMC_REAL="../../lustre/utils/lmc -m $config"
-
-PORT=988
-TCPBUF=1048576
-OST=ba-ost-1
-CLIENT=client
-UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt}
-
-h2ip () {
-    echo "${1}"
-}
-BATCH=/tmp/lmc-batch.$$
-save_cmd() {
-    echo "$@" >> $BATCH
-}
-
-[ -f $config ] && rm $config
-
-# Client node
-${LMC} --node $CLIENT --tcpbuf $TCPBUF --net '*' tcp $PORT
-
-OBD_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST`
-[ "$OBD_UUID" ] && OBD_UUID="--obduuid=$OBD_UUID" || echo "$OST: no UUID"
-
-# server node
-${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp $PORT
-${LMC} --node $OST --obdtype=obdecho $OBD_UUID --ost
-
-# osc on client
-${LMC} --node $CLIENT --osc OSC_$OST
-
-$LMC_REAL --batch $BATCH
-rm -f $BATCH
diff --git a/lustre/tests/ba-mount.sh b/lustre/tests/ba-mount.sh
deleted file mode 100644 (file)
index 2a2ff3d..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/bash
-
-# There are configurations for three machines in this config file: the OST,
-# the MDS/client, other clients
-#
-# To start your cluster using the ba-mount.xml file that this produces, first
-# run:
-# > lconf ba-mount.xml
-# on the MDS/client, and then run:
-# > lconf --node client ba-mount.xml
-# on any other clients.
-
-config=${1:-ba-mount.xml}
-
-LMC_REAL="${LMC:-../utils/lmc} -m config"
-LMC="save_cmd"
-
-PORT=988
-TCPBUF=1048576
-OST=ba-ost-1
-MDS=mds-hostname
-UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt}
-
-h2ip () {
-    echo "${1}"
-}
-BATCH=/tmp/lmc-batch.$$
-save_cmd() {
-    echo "$@" >> $BATCH
-}
-
-[ -f $config ] && rm $config
-
-# MDS/client node
-${LMC} --node $MDS --tcpbuf $TCPBUF --net '*' tcp $PORT
-${LMC} --node $MDS --mds mds1 /tmp/mds1 50000
-
-OBD_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST`
-[ "$OBD_UUID" ] && OBD_UUID="--obduuid=$OBD_UUID" || echo "$OST: no UUID"
-
-# server node
-${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp $PORT
-${LMC} --node $OST $OBD_UUID --ost bluearc
-
-# mount point on the MDS/client
-${LMC} --node $MDS --mtpt /mnt/lustre mds1 OSC_$OST
-
-# other clients
-${LMC} --node client --tcpbuf $TCPBUF --net '*' tcp $PORT
-${LMC} --node client --mtpt /mnt/lustre mds1 OSC_$OST
-
-$LMC_REAL --batch $BATCH
-rm -f $BATCH
diff --git a/lustre/tests/checkstack.pl b/lustre/tests/checkstack.pl
deleted file mode 100644 (file)
index 9c0d097..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/usr/bin/perl
-
-#      Check the stack usage of functions
-#
-#      Copyright Joern Engel <joern@wh.fh-wedel.de>
-#      Inspired by Linus Torvalds
-#      Original idea maybe from Keith Owens
-#
-#      Usage:
-#      objdump -d vmlinux | checkstack.pl <arch>
-#
-#      find <moduledir> -name "*.o" | while read M; do
-#              objdump -d $M | perl ~/checkstack.pl <arch> | \
-#                      sed "s/^/`basename $M`: /" ; done | \
-#      awk '/esp/ { print $5, $2, $4 }' | sort -nr
-#
-#      TODO :  Port to all architectures (one regex per arch)
-#              Speed this puppy up
-
-# check for arch
-# 
-# $re is used for three matches:
-# $& (whole re) matches the complete objdump line with the stack growth
-# $1 (first bracket) matches the code that will be displayed in the output
-# $2 (second bracket) matches the size of the stack growth
-#
-# use anything else and feel the pain ;)
-{
-       my $arch = shift;
-       $x      = "[0-9a-f]";   # hex character
-       $xs     = "[0-9a-f ]";  # hex character or space
-       if ($arch =~ /^i[3456]86$/) {
-               #c0105234:       81 ec ac 05 00 00       sub    $0x5ac,%esp
-               $re = qr/^.*(sub/s\$(0x$x{3,5}),\%esp)$/o;
-       } elsif ($arch =~ /^ia64$/) {
-               #                                        adds r12=-384,r12
-               $re = qr/.*(adds/sr12=-($x{3,5}),r12)/o;
-       } elsif ($arch =~ /^ppc$/) {
-               #c00029f4:       94 21 ff 30     stwu    r1,-208(r1)
-               $re = qr/.*(stwu/sr1,-($x{3,5})\(r1\))/o;
-       } elsif ($arch =~ /^s390x?$/) {
-               #   11160:       a7 fb ff 60             aghi   %r15,-160
-               $re = qr/.*(ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2}))/o;
-       } else {
-               print("wrong or unknown architecture\n");
-               exit
-       }
-}
-
-sub bysize($) {
-       ($asize = $a) =~ s/$re/\2/;
-       ($bsize = $b) =~ s/$re/\2/;
-       $bsize <=> $asize
-}
-
-#
-# main()
-#
-$funcre = qr/^$x* \<(.*)\>:$/;
-while ($line = <STDIN>) {
-       if ($line =~ m/$funcre/) {
-               ($func = $line) =~ s/$funcre/\1/;
-               chomp($func);
-       }
-
-       if ($line =~ m/$re/) {
-               (my $addr = $line) =~ s/^($xs{8}).*/0x\1/o;
-               chomp($addr);
-
-               my $intro = "$addr $func:";
-               my $padlen = 56 - length($intro);
-               while ($padlen > 0) {
-                       $intro .= '     ';
-                       $padlen -= 8;
-               }
-               (my $code = $line) =~ s/$re/\1/;
-
-               $stack[@stack] = "$intro $code";
-       }
-}
-
-@sortedstack = sort bysize @stack;
-
-foreach $i (@sortedstack) {
-       print("$i");
-}
---
-Andreas Dilger
-http://sourceforge.net/projects/ext2resize/
-http://www-mddsp.enel.ucalgary.ca/People/adilger/
-
-
diff --git a/lustre/tests/compile.sh b/lustre/tests/compile.sh
deleted file mode 100644 (file)
index 13c142e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-set -evx
-
-MNT=${MNT:-/mnt/lustre}
-DIR=${DIR:-$MNT}
-SRC=${SRC:-`dirname $0`/../..}
-while date; do
-       for i in portals lustre; do
-               TGT=$DIR/$i
-               [ -d $TGT ] || cp -av $SRC/$i/ $TGT
-               make -C $TGT clean
-               make -C $TGT -j2
-               make -C $TGT clean
-       done
-done
diff --git a/lustre/tests/mkdirdeep.c b/lustre/tests/mkdirdeep.c
deleted file mode 100644 (file)
index cfd1535..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Compile with:
- * cc -I../../portals/include -o mkdirdeep mkdirdeep.c 
- *    -L../../portals/linux/utils -lptlctl 
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <linux/limits.h>
-#include <portals/lltrace.h>
-
-static int opt_depth = 1;
-static int opt_mknod = 0; 
-static int opt_verbose = 0;
-static int opt_trace = 1;
-static char* basepathname = 0;
-static char mycwd[PATH_MAX];
-static char* pname = 0;
-static char* outputfilename = 0;
-
-void usage()
-{
-        fprintf(stderr, "Usage: %s --depth <d> --output <outputtracefilename>"
-                "[--mknod] [--verbose] [--notrace] <basepath>\n", pname);
-        exit(1);
-}
-
-int do_mkdir(char* path)
-{
-        int rc = mkdir(path, 0755);
-        if (rc!=0) 
-                fprintf(stderr, "mkdir(%s) failed: %s\n",
-                        path, strerror(errno));
-        if (opt_verbose)
-                printf("mkdir %s\n", path);
-        return rc;
-}
-
-
-int do_mknod(char* path)
-{
-        int rc = mknod(path, 0755, S_IFIFO);
-        if (rc!=0) 
-                fprintf(stderr, "mkdir(%s) failed: %s\n",
-                        path, strerror(errno));
-        if (opt_verbose)
-                printf("mknod %s\n", path);
-        return rc;
-}
-
-int do_chdir(char* path)
-{
-        int rc = chdir(path);
-        if (rc!=0) 
-                fprintf(stderr, "chdir(%s) failed: %s\n",
-                        path, strerror(errno));
-        if (opt_verbose)
-                printf("chdir %s\n", path);
-
-        return rc;
-}
-
-
-int do_stat(char* path)
-{
-        char mark_buf[PATH_MAX];
-        struct stat mystat;
-        int rc = stat(path, &mystat);
-        if (rc!=0) 
-                fprintf(stderr, "stat(%s) failed: %s\n",
-                        path, strerror(errno));
-        if (opt_verbose)
-                printf("stat %s = inode %lu\n", path, mystat.st_ino);
-
-        if (opt_trace) {
-                snprintf(mark_buf, PATH_MAX, "stat %s = inode %lu", 
-                         path, mystat.st_ino);
-                ltrace_mark(0, mark_buf);
-        }
-
-        return rc;
-}
-
-int main(int argc, char** argv)
-{
-        int c, opt_index, i, mypid;
-
-        static struct option long_options[] = {
-                {"depth", 1, 0, 0 },
-                {"help", 0, 0, 0 },
-                {"mknod", 0, 0, 0 },  
-                {"verbose", 0, 0, 0 },  
-                {"notrace", 0, 0, 0 },  
-                {"output", 1, 0, 0 },  
-                {0,0,0,0}
-        };
-
-        char full_pathname[PATH_MAX];
-        char rel_pathname[PATH_MAX];
-        char mark_buf[PATH_MAX];
-
-        pname = strdup(argv[0]);
-        
-        while (1) {
-                c = getopt_long(argc, argv, "d:mhv", long_options, &opt_index);
-                if (c == -1)
-                        break;
-                if (c==0) {
-                        if (!strcmp(long_options[opt_index].name, "notrace")) {
-                                opt_trace = 0;
-                                continue;
-                        }
-                        c = long_options[opt_index].name[0];
-                }
-                switch (c) {
-                case 'd': 
-                        opt_depth = atoi(optarg);
-                        if ((opt_depth == 0) || (opt_depth > 100))
-                                usage();
-                        break;
-                case 'm':
-                        opt_mknod = 1;
-                        break;
-                case 'v':
-                        opt_verbose = 1;
-                        break;
-                case 'o':
-                        outputfilename = optarg;
-                        break;
-                case 'h':
-                case '?': 
-                case ':': 
-                default:
-                        usage();
-                        break;
-                }
-        }
-                
-        if (optind != (argc-1)) 
-                usage();
-
-        if (outputfilename == NULL)
-                usage();
-
-        basepathname = argv[optind];
-        mypid = getpid();
-        
-        printf("%s(pid=%d) depth=%d mknod=%d, basepathname=%s, "
-               "trace=%d, outputfilename=%s\n",
-               pname, mypid, opt_depth, opt_mknod, basepathname, opt_trace, 
-               outputfilename);
-
-        if (!getcwd(&mycwd[0], sizeof(mycwd))) {
-                fprintf(stderr, "%s: unable to getcwd()\n", pname);
-                exit(1);
-        }
-
-        if (opt_trace) {
-                ltrace_start();
-                ltrace_clear();
-                snprintf(mark_buf, PATH_MAX, 
-                         "Initialize - mkdir %s; chdir %s",
-                         basepathname, basepathname);
-                ltrace_mark(2, mark_buf);
-        }
-
-        if (do_mkdir(basepathname)!=0)
-                exit(1);
-        if (do_chdir(basepathname)!=0)
-                exit(1);
-
-        /* Create directory tree with depth level of subdirectories */
-
-        if (opt_trace) {
-                snprintf(mark_buf, PATH_MAX, 
-                         "Create Directory Tree (depth %d)", opt_depth);
-                ltrace_mark(2, mark_buf);
-        }
-
-        for (i=0; i<opt_depth; i++) {
-                
-                snprintf(rel_pathname, sizeof(rel_pathname),"%d", i+1);
-                
-                 if (i == (opt_depth-1)) {
-                         /* Last Iteration */
-                         
-                         if (opt_trace) {
-                                 snprintf(mark_buf, PATH_MAX, 
-                                          "Tree Leaf (%d) %s/stat", i,
-                                          (opt_mknod ? "mknod" : "mkdir"));
-                                 ltrace_mark(3, mark_buf);
-                         }
-                         
-                         if (opt_mknod)
-                                 do_mknod(rel_pathname);
-                         else
-                                 do_mkdir(rel_pathname);
-                         /* Now stat it */
-                         do_stat(rel_pathname);
-                 }
-                else {
-                        /* Not Leaf */
-
-                        if (opt_trace) {
-                                snprintf(mark_buf, PATH_MAX, 
-                                         "Tree Level (%d) mkdir/stat/chdir",
-                                         i);
-                                ltrace_mark(3, mark_buf);
-                        }
-                        
-                        do_mkdir(rel_pathname);
-                        do_stat(rel_pathname);
-                        do_chdir(rel_pathname);
-                }
-        }
-        
-        /* Stat through directory tree with fullpaths */
-
-        if (opt_trace) {
-                snprintf(mark_buf, PATH_MAX, "Walk Directory Tree");
-                ltrace_mark(2, mark_buf);
-        }
-
-        do_chdir(basepathname);
-
-        strncpy(full_pathname, basepathname, sizeof(full_pathname));
-
-        for (i=0; i<opt_depth; i++) {
-                snprintf(rel_pathname, sizeof(rel_pathname),"%d", i+1);
-                strcat(full_pathname, "/");
-                strcat(full_pathname, rel_pathname);
-
-                if (opt_trace) {
-                        snprintf(mark_buf, PATH_MAX, "stat %s", 
-                                 full_pathname);
-                        ltrace_mark(2, mark_buf);
-                }
-
-                do_stat(full_pathname);
-        }
-
-        /* Cleanup */
-
-        if (opt_trace) {
-                snprintf(mark_buf, PATH_MAX, "Cleanup");
-                ltrace_mark(2, mark_buf);
-        }
-
-        if (opt_trace) {
-                    ltrace_write_file(outputfilename);
-                    ltrace_add_processnames(outputfilename);
-                    ltrace_stop();
-        }
-
-        do_chdir(basepathname);        
-        
-        snprintf(full_pathname, sizeof(full_pathname), 
-                 "rm -rf %s\n", basepathname);
-        if (opt_verbose) 
-                printf("Cleanup: %s", full_pathname);
-
-        system(full_pathname);
-
-        printf("%s (pid=%d) done.\n", pname, mypid);
-        return 0;
-}
diff --git a/lustre/tests/mkdirmany.c b/lustre/tests/mkdirmany.c
deleted file mode 100755 (executable)
index f90327a..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-int main(int argc, char ** argv)
-{
-        int i, rc, count;
-        char dirname[4096];
-
-        if (argc < 3) {
-                printf("Usage %s dirnamebase count\n", argv[0]);
-                return 1;
-        }
-
-        if (strlen(argv[1]) > 4080) {
-                printf("name too long\n");
-                return 1;
-        }
-
-        count = strtoul(argv[2], NULL, 0);
-
-        for (i=0 ; i < count ; i++) {
-                sprintf(dirname, "%s-%d", argv[1], i);
-                rc = mkdir(dirname, S_IFREG| 0444);
-                if (rc) {
-                        printf("mkdir(%s) error: %s\n",
-                               dirname, strerror(errno));
-                        break;
-                }
-               if ((i % 10000) == 0)
-                   printf(" - created %d (time %ld)\n", i, time(0));
-        }
-        return rc;
-}
diff --git a/lustre/tests/mlink.c b/lustre/tests/mlink.c
deleted file mode 100755 (executable)
index 5688b9f..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-int main(int argc, char ** argv)
-{
-        int rc;
-
-        if (argc < 3) { 
-                printf("Usage: %s file link\n", argv[0]);
-                return 1;
-        }
-
-        rc = link(argv[1], argv[2]);
-        if (rc) { 
-                printf("link(%s, %s) error: %s\n", argv[1], argv[2],
-                      strerror(errno));
-               return errno;
-        }
-       return 0;
-} 
diff --git a/lustre/tests/munlink.c b/lustre/tests/munlink.c
deleted file mode 100755 (executable)
index a3c18c5..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-int main(int argc, char ** argv)
-{
-        int rc;
-
-        if (argc < 2) { 
-                printf("Usage %s filename\n", argv[0]);
-                return 1;
-        }
-
-        rc = unlink(argv[1]);
-        if (rc) { 
-                printf("unlink(%s) error: %s\n", argv[1], strerror(errno));
-        }
-        return rc;
-} 
diff --git a/lustre/tests/open_delay.c b/lustre/tests/open_delay.c
deleted file mode 100644 (file)
index 2f41884..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <linux/lustre_lib.h>
-#include <linux/lustre_lite.h>
-#include <linux/obd_lov.h>
-
-int main(int argc, char **argv)
-{
-        int fd; 
-
-        if (argc != 2) { 
-                printf("Usage %s <filename>\n", argv[0]); 
-                exit(1);
-        }
-
-        fd = open(argv[1], O_RDONLY | O_LOV_DELAY_CREATE);
-        if (fd == -1) { 
-                printf("Error opening %s\n", argv[1]);
-                exit(1);
-        }
-
-        return 0;
-}
diff --git a/lustre/tests/opendevunlink.c b/lustre/tests/opendevunlink.c
deleted file mode 100644 (file)
index fde7d36..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- */
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <string.h>
-
-int main(int argc, char **argv)
-{
-        char *dname1, *dname2;
-        int fddev1, fddev2, rc;
-        //DIR *dp;
-        struct stat st1, st2;
-
-        if (argc < 2 || argc > 3) {
-                fprintf(stderr, "usage: %s filename1 [filename2]\n", argv[0]);
-                exit(1);
-        }
-
-        dname1 = argv[1];
-        if (argc == 3)
-                dname2 = argv[2];
-        else
-                dname2 = argv[1];
-
-        //create the special file (right now only test on pipe)
-        fprintf(stderr, "creating special file %s\n", dname1);
-        rc = mknod(dname1, 0777|S_IFIFO, 0);
-        if (rc == -1) {
-                fprintf(stderr, "creating %s fails: %s\n", 
-                        dname1, strerror(errno));
-                exit(1);
-        }
-
-        // open the special file again
-        fprintf(stderr, "opening file\n");
-        fddev1 = open(dname1, O_RDONLY | O_NONBLOCK);
-        if (fddev1 == -1) {
-                fprintf(stderr, "open %s fails: %s\n",
-                        dname1, strerror(errno));
-                exit(1);
-        }
-        
-        // doesn't matter if the two dirs are the same??
-        fddev2 = open(dname2, O_RDONLY | O_NONBLOCK);
-        if (fddev2 == -1) {
-                fprintf(stderr, "open %s fails: %s\n",
-                        dname2, strerror(errno));
-                exit(1);
-        }
-        
-        // delete the special file
-        fprintf (stderr, "unlinking %s\n", dname1);
-        rc = unlink(dname1);
-        if (rc) {
-                fprintf(stderr, "unlink %s error: %s\n", 
-                        dname1, strerror(errno));
-                exit(1);
-        }
-
-        if (access(dname2, F_OK) == 0){
-                fprintf(stderr, "%s still exists\n", dname2);
-                exit(1);
-        }
-
-        if (access(dname1, F_OK) == 0){
-                fprintf(stderr, "%s still exists\n", dname1);
-                exit(1);
-        }
-
-        // fchmod one special file
-        rc = fchmod (fddev1, 0777);
-        if(rc == -1)
-        {
-                fprintf(stderr, "fchmod unlinked special file %s fails: %s\n", 
-                        dname1, strerror(errno));
-                exit(1);
-        }
-                
-        // fstat two files to check if they are the same
-        rc = fstat(fddev1, &st1);
-        if(rc == -1)
-        {
-                fprintf(stderr, "fstat unlinked special file %s fails: %s\n", 
-                        dname1, strerror(errno));
-                exit(1);
-        }
-
-        rc = fstat(fddev2, &st2);
-        if (rc == -1) {
-                fprintf(stderr, "fstat file %s fails: %s\n",
-                        dname2, strerror(errno));
-                exit(1);
-        }
-
-        if (st1.st_mode != st2.st_mode) {  // can we do this?
-                fprintf(stderr, "fstat different value on %s and %s\n",                                 dname1, dname2);
-                exit(1);
-        }        
-
-        fprintf(stderr, "Ok, everything goes well.\n");
-        return 0;
-}
-
diff --git a/lustre/tests/opendirunlink.c b/lustre/tests/opendirunlink.c
deleted file mode 100644 (file)
index 2664618..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- */
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <string.h>
-
-int main(int argc, char **argv)
-{
-        char *dname1, *dname2;
-        int fddir1, fddir2, rc;
-        //DIR *dp;
-        struct stat st1, st2;
-
-        if (argc < 2 || argc > 3) {
-                fprintf(stderr, "usage: %s dirname1 [dirname2]\n", argv[0]);
-                exit(1);
-        }
-
-        dname1 = argv[1];
-        if (argc == 3)
-                dname2 = argv[2];
-        else
-                dname2 = argv[1];
-
-        //create the directory
-        fprintf(stderr, "creating directory %s\n", dname1);
-        rc = mkdir(dname1, 0744);
-        if (rc == -1) {
-                fprintf(stderr, "creating %s fails: %s\n", 
-                        dname1, strerror(errno));
-                exit(1);
-        }
-
-        // open the dir again
-        fprintf(stderr, "opening directory\n");
-        fddir1 = open(dname1, O_RDONLY | O_DIRECTORY);
-        if (fddir1 == -1) {
-                fprintf(stderr, "open %s fails: %s\n",
-                        dname1, strerror(errno));
-                exit(1);
-        }
-        
-        // doesn't matter if the two dirs are the same??
-        fddir2 = open(dname2, O_RDONLY | O_DIRECTORY);
-        if (fddir2 == -1) {
-                fprintf(stderr, "open %s fails: %s\n",
-                        dname2, strerror(errno));
-                exit(1);
-        }
-        
-        // another method
-/*        
-        if ( (dp = opendir(dname2)) == NULL) {
-                fprintf(stderr, "opendir() %s\n", strerror(errno));
-                exit(1);
-        }
-        fddir = dirfd(dp);
-*/
-
-        // delete the dir
-        fprintf (stderr, "unlinking %s\n", dname1);
-        rc = rmdir(dname1);
-        if (rc) {
-                fprintf(stderr, "unlink %s error: %s\n", 
-                        dname1, strerror(errno));
-                exit(1);
-        }
-
-        if (access(dname2, F_OK) == 0){
-                fprintf(stderr, "%s still exists\n", dname2);
-                exit(1);
-        }
-
-        if (access(dname1, F_OK) == 0){
-                fprintf(stderr, "%s still exists\n", dname1);
-                exit(1);
-        }
-
-        // fchmod the dir
-        rc = fchmod (fddir1, 0777);
-        if(rc == -1)
-        {
-                fprintf(stderr, "fchmod unlinked dir fails %s\n", 
-                        strerror(errno));
-                exit(1);
-        }
-                
-        // fstat two dirs to check if they are the same
-        rc = fstat(fddir1, &st1);
-        if(rc == -1)
-        {
-                fprintf(stderr, "fstat unlinked dir %s fails %s\n", 
-                        dname1, strerror(errno));
-                exit(1);
-        }
-
-        rc = fstat(fddir2, &st2);
-        if (rc == -1) {
-                fprintf(stderr, "fstat dir %s fails %s\n",
-                        dname2, strerror(errno));
-                exit(1);
-        }
-
-        if (st1.st_mode != st2.st_mode) {  // can we do this?
-                fprintf(stderr, "fstat different value on %s and %s\n",                                 dname1, dname2);
-                exit(1);
-        }        
-
-        fprintf(stderr, "Ok, everything goes well.\n");
-        return 0;
-}
-
diff --git a/lustre/tests/openfile.c b/lustre/tests/openfile.c
deleted file mode 100644 (file)
index ab5cbdb..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- */
-
-#if 0
-#define DEBUG
-#endif
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-typedef struct flag_mapping {
-       char string[20];
-       int  flag;
-} FLAG_MAPPING;
-
-FLAG_MAPPING flag_table[] = {
-       {"O_RDONLY", O_RDONLY},
-       {"O_WRONLY", O_WRONLY},
-       {"O_RDWR", O_RDWR},
-       {"O_CREAT", O_CREAT},
-       {"O_EXCL", O_EXCL},
-       {"O_NOCTTY", O_NOCTTY},
-       {"O_TRUNC", O_TRUNC},
-       {"O_APPEND", O_APPEND},
-       {"O_NONBLOCK", O_NONBLOCK},
-       {"O_NDELAY", O_NDELAY},
-       {"O_SYNC", O_SYNC},
-       {"O_NOFOLLOW", O_NOFOLLOW},
-       {"O_DIRECTORY", O_DIRECTORY},
-       {"O_LARGEFILE", O_LARGEFILE},
-       {"", -1}
-};
-
-void Usage_and_abort(void)
-{
-       fprintf(stderr, "Usage: openfile -f flags [ -m mode ] filename \n");
-       fprintf(stderr, "e.g. openfile -f O_RDWR:O_CREAT -m 0755 /etc/passwd\n");
-       exit(-1);
-}
-
-int main(int argc, char** argv)
-{
-        int i;
-        int    flags=0;
-        mode_t mode=0;
-        char*  fname=NULL;
-        int    mode_set=0;
-        int    flag_set=0;
-        int    file_set=0;
-        char   c;
-        char*  cloned_flags;
-
-        if(argc == 1) {
-                Usage_and_abort();
-        }
-
-        while ((c = getopt (argc, argv, "f:m:")) != -1) {
-                switch (c) {
-                case 'f': {
-                        char *tmp;
-
-                        cloned_flags = (char*)malloc(strlen(optarg));
-                        if (cloned_flags==NULL) {
-                                fprintf(stderr, "Insufficient memory.\n");
-                                exit(-1);
-                        }
-
-                        strncpy(cloned_flags, optarg, strlen(optarg));
-                        tmp = strtok(optarg, ":");
-                        while (tmp) {
-                                int i = 0;
-#ifdef DEBUG
-                                printf("flags = %s\n",tmp);
-#endif
-                                flag_set = 1;
-                                while (flag_table[i].flag != -1) {
-                                        int r;
-                                        r = strncasecmp(tmp, (flag_table[i].string),
-                                                        strlen((flag_table[i].string)) );
-
-                                        if (r == 0)
-                                                break;
-                                        i++;
-                                }
-
-                                if (flag_table[i].flag != -1) {
-                                        flags |= flag_table[i].flag;
-                                } else {
-                                        fprintf(stderr, "No such flag: %s\n",
-                                                tmp);
-                                        exit(-1);
-                                }
-
-                                tmp = strtok(NULL, ":");
-
-                        }
-#ifdef DEBUG
-                        printf("flags = %x\n", flags);
-#endif
-                        break;
-                }
-                case 'm':
-#ifdef DEBUG
-                        printf("mode = %s\n", optarg);
-#endif
-                        mode = strtol (optarg, NULL, 8);
-                        mode_set = 1;
-#ifdef DEBUG
-                        printf("mode = %o\n", mode);
-#endif
-                        break;
-                default:
-                        fprintf(stderr, "Bad parameters.\n");
-                        Usage_and_abort();
-                }
-        }
-
-        if (optind == argc) {
-                fprintf(stderr, "Bad parameters.\n");
-                Usage_and_abort();
-        }
-
-        fname = argv[optind];
-        file_set = 1;
-
-        if (!flag_set || !file_set) {
-                fprintf(stderr, "Missing flag or file-name\n");
-                exit(-1);
-        }
-
-
-        if (mode_set)
-                i = open(fname, flags, mode);
-        else
-                i = open(fname, flags);
-
-        if (i != -1) {
-                fprintf(stderr, "Succeed in opening file \"%s\"(flags=%s",
-                        fname, cloned_flags);
-
-                if (mode_set)
-                        fprintf(stderr, ", mode=%o", mode);
-                fprintf(stderr, ")\n");
-                close (i);
-        } else {
-                fprintf(stderr, "Error in opening file \"%s\"(flags=%s",
-                        fname, cloned_flags);
-                if (mode_set)
-                        fprintf(stderr, ", mode=%o", mode);
-                fprintf(stderr, ") %s\n", strerror(errno));
-        }
-        return(i);
-}
diff --git a/lustre/tests/recovery-cleanup.sh b/lustre/tests/recovery-cleanup.sh
deleted file mode 100755 (executable)
index 481ebaa..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/bin/sh
-
-set -ex
-
-LUSTRE=${LUSTRE:-`dirname $0`/..}
-PATH=$PATH:$LUSTRE/utils:$LUSTRE/tests
-
-. $LUSTRE/../ltest/functional/llite/common/common.sh
-
-PDSH='pdsh -S -w'
-
-# XXX I wish all this stuff was in some default-config.sh somewhere
-MDSNODE=${MDSNODE:-mdev6}
-OSTNODE=${OSTNODE:-mdev7}
-CLIENT=${CLIENTNODE:-mdev8}
-NETWORKTYPE=${NETWORKTYPE:-tcp}
-MOUNTPT=${MOUNTPT:-/mnt/lustre}
-CONFIG=recovery-small.xml
-MDSDEV=/tmp/mds
-OSTDEV=/tmp/ost
-MDSSIZE=100000
-OSTSIZE=100000
-
-do_mds() {
-    $PDSH $MDSNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@"
-}
-
-do_client() {
-    $PDSH $CLIENT "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@"
-}
-
-do_ost() {
-    $PDSH $OSTNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@"
-}
-
-drop_request() {
-    do_mds "echo 0x121 > /proc/sys/lustre/fail_loc"
-    do_client "$1 & sleep ${TIMEOUT:-5}; sleep 2; kill \$!"
-    do_mds "echo 0 > /proc/sys/lustre/fail_loc"
-}
-
-make_config() {
-    rm -f $CONFIG
-    for NODE in $CLIENT $MDSNODE $OSTNODE; do
-       lmc -m $CONFIG --add net --node $NODE --nid `h2$NETWORKTYPE $NODE` \
-           --nettype $NETWORKTYPE || exit 4
-    done
-    lmc -m $CONFIG --add mds --node $MDSNODE --mds mds1 --dev $MDSDEV \
-        --size $MDSSIZE || exit 5
-    lmc -m $CONFIG --add ost --node $OSTNODE --ost ost1 --dev $OSTDEV \
-        --size $OSTSIZE || exit 6
-    lmc -m $CONFIG --add mtpt --node $CLIENT --path $MOUNTPT --mds mds1 \
-        --ost ost1 || exit 7
-}
-
-start_mds() {
-    do_mds "lconf $@ $CONFIG"
-}
-
-shutdown_mds() {
-    do_mds "lconf $@ --cleanup $CONFIG"
-}
-
-start_ost() {
-    do_ost "lconf $@ $CONFIG"
-}
-
-shutdown_ost() {
-    do_ost "lconf $@ --cleanup $CONFIG"
-}
-
-mount_client() {
-    do_client "lconf $@ $CONFIG"
-}
-
-unmount_client() {
-    do_client "lconf $@ --cleanup $CONFIG"
-}
-
-setup() {
-    make_config
-    start_mds ${REFORMAT:---reformat}
-    start_ost ${REFORMAT:---reformat}
-    mount_client --timeout=${TIMEOUT:-5} --recovery_upcall=/bin/true
-}
-
-cleanup() {
-    do_mds "echo 0 > /proc/sys/lustre/fail_loc"
-    unmount_client $@ || true
-    shutdown_mds $@ || true
-    shutdown_ost $@ || true
-}
-
-wait_for_timeout() {
-    # wait to make sure we enter recovery
-    # it'd be better if the upcall notified us somehow, I think
-    sleep $(( ${TIMEOUT:-5} + 2 ))
-}
-
-try_to_cleanup() {
-    kill -INT $!
-    unmount_client --force
-    mount_client --timeout=${TIMEOUT:-5} --recovery_upcall=/bin/true
-}
-
-if [ ! -z "$ONLY" ]; then
-    eval "$ONLY"
-    exit $?
-fi
-
-setup
-drop_request "mcreate /mnt/lustre/1" & wait_for_timeout
-try_to_cleanup
-
-drop_request "tchmod 111 /mnt/lustre/2" & wait_for_timeout
-try_to_cleanup
-
-drop_request "statone /mnt/lustre/2" & wait_for_timeout
-try_to_cleanup
-
-do_client "cp /etc/resolv.conf /mnt/lustre/resolv.conf"
-drop_request "cat /mnt/lustre/resolv.conf > /dev/null" & wait_for_timeout
-try_to_cleanup
-
-drop_request "mv /mnt/lustre/resolv.conf /mnt/lustre/renamed" & wait_for_timeout
-try_to_cleanup
-
-drop_request "mlink /mnt/lustre/renamed-again /mnt/lustre/link1" & wait_for_timeout
-try_to_cleanup
-
-drop_request "munlink /mnt/lustre/link1" & wait_for_timeout
-try_to_cleanup
-
-cleanup
diff --git a/lustre/tests/recovery-small.sh b/lustre/tests/recovery-small.sh
deleted file mode 100755 (executable)
index b57b169..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/bin/sh
-
-set -ex
-
-LUSTRE=${LUSTRE:-`dirname $0`/..}
-PATH=$PATH:$LUSTRE/utils:$LUSTRE/tests
-
-. $LUSTRE/../ltest/functional/llite/common/common.sh
-
-PDSH='pdsh -S -w'
-
-# XXX I wish all this stuff was in some default-config.sh somewhere
-MDSNODE=${MDSNODE:-dev2}
-OSTNODE=${OSTNODE:-dev3}
-CLIENT=${CLIENTNODE:-dev4}
-NETWORKTYPE=${NETWORKTYPE:-tcp}
-MOUNTPT=${MOUNTPT:-/mnt/lustre}
-CONFIG=recovery-small.xml
-MDSDEV=/tmp/mds
-OSTDEV=/tmp/ost
-MDSSIZE=100000
-OSTSIZE=100000
-
-do_mds() {
-    $PDSH $MDSNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@"
-}
-
-do_client() {
-    $PDSH $CLIENT "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@"
-}
-
-do_ost() {
-    $PDSH $OSTNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@"
-}
-
-drop_request() {
-    do_mds "echo 0x121 > /proc/sys/lustre/fail_loc"
-    do_client "$1"
-    do_mds "echo 0 > /proc/sys/lustre/fail_loc"
-}
-
-drop_reply() {
-    do_mds "echo 0x120 > /proc/sys/lustre/fail_loc"
-    do_client "$@"
-    do_mds "echo 0 > /proc/sys/lustre/fail_loc"
-}
-
-make_config() {
-    rm -f $CONFIG
-    for NODE in $CLIENT $MDSNODE $OSTNODE; do
-       lmc -m $CONFIG --add net --node $NODE --nid `h2$NETWORKTYPE $NODE` \
-           --nettype $NETWORKTYPE || exit 4
-    done
-    lmc -m $CONFIG --add mds --node $MDSNODE --mds mds1 --dev $MDSDEV \
-        --size $MDSSIZE || exit 5
-    lmc -m $CONFIG --add ost --node $OSTNODE --obd obd1 --dev $OSTDEV \
-        --size $OSTSIZE || exit 6
-    lmc -m $CONFIG --add mtpt --node $CLIENT --path $MOUNTPT --mds mds1 \
-        --obd obd1 || exit 7
-}
-
-start_mds() {
-    do_mds "lconf $@ $CONFIG"
-}
-
-shutdown_mds() {
-    do_mds "lconf $@ --cleanup $CONFIG"
-}
-
-start_ost() {
-    do_ost "lconf $@ $CONFIG"
-}
-
-shutdown_ost() {
-    do_ost "lconf $@ --cleanup $CONFIG"
-}
-
-mount_client() {
-    do_client "lconf $@ $CONFIG"
-}
-
-unmount_client() {
-    do_client "lconf $@ --cleanup $CONFIG"
-}
-
-setup() {
-    make_config
-    start_mds --reformat
-    start_ost --reformat
-    # XXX we should write our own upcall, when we move this somewhere better.
-    mount_client --timeout=10 \
-        --recovery_upcall=$PWD/../../ltest/functional/llite/09/client-upcall.sh
-}
-
-cleanup() {
-    unmount_client || true
-    shutdown_mds || true
-    shutdown_ost || true
-}
-
-replay() {
-    if [ $# -gt 1 ]; then
-        do_client "$1"
-        shift
-    fi
-    do_mds "sync"
-    do_mds 'echo -e "device \$mds1\\nprobe\\nnotransno\\nreadonly" | lctl'
-    do_client "$1" &
-    shutdown_mds -f
-    start_mds
-    wait
-}
-
-if [ ! -z "$ONLY" ]; then
-    eval "$ONLY"
-    exit $?
-fi
-
-setup
-drop_request "mcreate /mnt/lustre/1"
-drop_reply "mcreate /mnt/lustre/2"
-replay "mcreate /mnt/lustre/3"
-cleanup
diff --git a/lustre/tests/rename.pl b/lustre/tests/rename.pl
deleted file mode 100644 (file)
index 3ba9368..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use diagnostics;
-use Getopt::Long;
-
-sub usage () {
-    print "Usage: $0 <mount point prefix> <iterations>\n";
-    print "example: $0 --count=2 /mnt/lustre 50\n";
-    print "         will test in /mnt/lustre1 and /mnt/lustre2\n";
-    print "         $0 --count=0 /mnt/lustre 50\n";
-    print "         will test in /mnt/lustre only\n";
-    exit;
-}
-my ($j, $k, $d, $f1, $f2, $path, $silent);
-my $count = 0;
-my $create = 10;
-
-GetOptions("silent!"=> \$silent,
-           "count=i" => \$count,
-           "create=i" => \$create);
-
-my $mtpt = shift || usage();
-my $i = shift || usage();
-my $total = $i;
-my $files = 6;
-my $dirs = 3;
-my $mcreate = 0; # should we use mcreate or open?
-
-my $which = "";
-if ($count > 0) {
-    $which = int(rand() * $count) + 1;
-}
-
-$k = $dirs;
-if ($create == 0) {
-    $k = 0;
-}
-while ($k--) {
-    $path = "$mtpt$which/$k";
-    my $rc = mkdir $path, 0755;
-    print "mkdir $path failed: $!\n" if !$rc;
-    $j = $files;
-    while ($j--) {
-        `./mcreate $path/$j`;
-    }
-}
-
-while ($i--) {
-    my $which = "";
-    if ($count > 0) {
-        $which = int(rand() * $count) + 1;
-    }
-    $d = int(rand() * $dirs);
-    $f1 = int(rand() * $files);
-    $f2 = int(rand() * $files);
-    print "[$$] $mtpt$which/$d/$f1 $mtpt$which/$d/$f2 ...\n" if !$silent;
-    my $rc = rename "$mtpt$which/$d/$f1", "$mtpt$which/$d/$f2";
-    print "[$$] done: $rc\n" if !$silent;
-    if (($total - $i) % 100 == 0) {
-        print STDERR "[" . $$ . "]" . ($total - $i) . " operations\n";
-    }
-}
-
-$k = $dirs;
-if ($create == 0) {
-    $k = 0;
-}
-while ($k--) {
-    $path = "$mtpt$which/$k";
-    $j = $files;
-    while ($j--) {
-        unlink "$path/$j";
-    }
-    my $rc = rmdir $path;
-    print "rmdir $path failed: $!\n" if !$rc;
-}
-
-print "Done.\n";
diff --git a/lustre/tests/runas.c b/lustre/tests/runas.c
deleted file mode 100644 (file)
index 3d29f1b..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#define DEBUG 0
-
-void
-Usage_and_abort()
-{
-       fprintf(stderr, "Usage: runas -u user_id [ -g grp_id ]" \
-           " command_to_be_run \n");
-       exit(-1);
-}
-
-// Usage: runas -u user_id [ -g grp_id ] "command_to_be_run"
-// return: the return value of "command_to_be_run"
-// NOTE: returning -1 might be the return code of this program itself or
-// the "command_to_be_run"
-
-// ROOT runs "runas" for free
-// Other users run "runas" requires  chmod 6755 "command_to_be_run"
-
-int 
-main(int argc, char**argv)
-{
-        char command[1024];
-        char *cmd_ptr;
-        int status;
-        int c,i;
-        int gid_is_set = 0;
-        int uid_is_set = 0;
-        uid_t user_id;
-        gid_t grp_id;
-
-        if(argc == 1) {
-                Usage_and_abort();
-        }
-
-        // get UID and GID
-        while ((c = getopt (argc, argv, "u:g:h")) != -1) {
-                switch (c) {
-                case 'u':
-                        user_id = (uid_t)atoi(optarg);
-                        uid_is_set = 1;
-                        if(!gid_is_set) {
-                                  grp_id = user_id;
-                        }
-                 break;
-
-                 case 'g':
-                         grp_id = (gid_t)atoi(optarg);
-                         gid_is_set = 1;
-                 break;
-
-                 case 'h':
-                         Usage_and_abort ();
-                 break;
-
-                 default:
-                 //      fprintf(stderr, "Bad parameters.\n");
-                 //      Usage_and_abort ();
-                 }
-        }
-
-        if (!uid_is_set){
-                Usage_and_abort ();
-        }
-  
-
-        if(optind == argc) {
-                fprintf(stderr, "Bad parameters.\n");
-                Usage_and_abort();
-        }
-
-
-        // assemble the command
-        cmd_ptr = command ;
-        for (i = optind; i < argc; i++)
-                 cmd_ptr += sprintf(cmd_ptr,  "%s ", argv[i]);
-
-
-#if DEBUG
-  system("whoami");
-#endif
-
-        // set GID
-        status = setregid(grp_id, grp_id );
-        if( status == -1) {
-                 fprintf(stderr, "Cannot change grp_ID to %d, errno=%d (%s)\n",
-                  grp_id, errno, strerror(errno) );
-                 exit(-1);
-        }
-
-        // set UID
-        status = setreuid(user_id, user_id );
-        if(status == -1) {
-                  fprintf(stderr,"Cannot change user_ID to %d, errno=%d (%s)\n",
-                   user_id, errno, strerror(errno) );
-                  exit(-1);
-        }
-
-#if DEBUG
-  system("whoami");
-#endif
-
-        fprintf(stdout, "running as USER(%d), Grp (%d):  \"%s\" \n", 
-           user_id, grp_id, command );
-
-        // run the command
-        status = system(command);
-
-        // pass the return code of command_to_be_run out of this wrapper
-        if (status == -1) {
-                 fprintf(stderr, "%s: system() command failed to run\n",
-                           argv[0]);
-        }
-        else{
-                 status = WEXITSTATUS(status);
-                 fprintf(stderr, "[%s #%d] \"%s\" returns %d (%s).\n", argv[0],
-                        user_id, argv[optind], status, strerror(status));
-
-        }
-
-        return(status);
-}
-
diff --git a/lustre/tests/runslabinfo b/lustre/tests/runslabinfo
deleted file mode 100755 (executable)
index 48d6602..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-while sleep 1 ; do
-       egrep "ll_|ldlm|filp|dentry|inode|portals|size-[0-9]* " /proc/slabinfo
-        echo '-----------------------'
-done
diff --git a/lustre/tests/runvmstat b/lustre/tests/runvmstat
deleted file mode 100755 (executable)
index 6bff5ce..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-vmstat 1 | while read LINE ; do echo "`date +%H:%M:%S`: $LINE" ; done
diff --git a/lustre/tests/sanity-ldlm.sh b/lustre/tests/sanity-ldlm.sh
deleted file mode 100644 (file)
index e5bd422..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/bash
-
-set -e
-
-SRCDIR=`dirname $0`
-PATH=$PWD/$SRCDIR:$SRCDIR:$SRCDIR/../utils:$PATH
-
-MOUNT=${MOUNT:-/mnt/lustre}
-DIR=${DIR:-$MOUNT}
-export NAME=$NAME
-clean() {
-        echo -n "cln.."
-        sh llmountcleanup.sh > /dev/null || exit 20
-}
-CLEAN=${CLEAN:-clean}
-start() {
-        echo -n "mnt.."
-        sh llrmount.sh > /dev/null || exit 10
-        echo "done"
-}
-START=${START:-start}
-
-log() {
-       echo "$*"
-       lctl mark "$*" || /bin/true
-}
-
-pass() {
-    echo PASS
-}
-
-mount | grep $MOUNT || sh llmount.sh
-
-log '== drop ldlm request  ======================== test 1'
-echo 0x302 > /proc/sys/lustre/fail_loc
-echo 3 > /proc/sys/lustre/timeout
-touch $DIR/f &
-sleep 5
-echo 0 > /proc/sys/lustre/fail_loc
-lctl --device 6 recover
-pass
-$CLEAN
-$START
-
-log '== drop ldlm reply (bug 1139) ================ test 2'
-echo 0x213 > /proc/sys/lustre/fail_loc
-echo 3 > /proc/sys/lustre/timeout
-touch $DIR/f
-pass
-$CLEAN
-$START
-
-log '== drop reply after completion (bug 1068) ==== test 3'
-touch $DIR/f
-stat $DIR/f
-echo 0x213 > /proc/sys/lustre/fail_loc
-echo 3 > /proc/sys/lustre/timeout
-echo foo >> $DIR/f
-pass
-$CLEAN
-$START
diff --git a/lustre/tests/statone.c b/lustre/tests/statone.c
deleted file mode 100644 (file)
index 5250984..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <liblustre.h>
-#include <linux/lustre_lib.h>
-#include <linux/obd.h>
-
-int main(int argc, char **argv)
-{
-    struct obd_ioctl_data data;
-    char rawbuf[8192], parent[4096], *buf = rawbuf, *base, *t;
-    int max = sizeof(rawbuf), fd, offset, rc;
-
-    if (argc != 2) {
-        printf("usage: %s filename\n", argv[0]);
-        return 1;
-    }
-
-    base = argv[1];
-    t = strrchr(base, '/');
-    if (!t) {
-        strcpy(parent, ".");
-        offset = -1;
-    } else {
-        strncpy(parent, base, t - base);
-        offset = t - base - 1;
-    }
-
-    fd = open(parent, O_RDONLY);
-    if (fd < 0) {
-        printf("open(%s) error: %s\n", parent, strerror(errno));
-        exit(errno);
-    }
-
-    memset(&data, 0, sizeof(data));
-    data.ioc_version = OBD_IOCTL_VERSION;
-    data.ioc_len = sizeof(data);
-    if (offset >= 0)
-        data.ioc_inlbuf1 = base + offset + 2;
-    else
-        data.ioc_inlbuf1 = base;
-    data.ioc_inllen1 = strlen(data.ioc_inlbuf1) + 1;
-    
-    if (obd_ioctl_pack(&data, &buf, max)) {
-        printf("ioctl_pack failed.\n");
-        exit(1);
-    }
-    
-    rc = ioctl(fd, IOC_MDC_LOOKUP, buf);
-    if (rc < 0) {
-        printf("ioctl(%s/%s) error: %s\n", parent,
-               data.ioc_inlbuf1, strerror(errno));
-        exit(errno);
-    }
-
-    return 0;
-}
diff --git a/lustre/tests/unlinkmany.c b/lustre/tests/unlinkmany.c
deleted file mode 100644 (file)
index ba1bee7..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-void usage(char *prog)
-{
-       printf("usage: %s filenamefmt count\n", prog);
-       printf("       %s filenamefmt start count\n", prog);
-}
-
-int main(int argc, char ** argv)
-{
-        int i, rc = 0;
-        char format[4096], *fmt;
-        char filename[4096];
-        long start, last;
-       long begin = 0, count;
-
-        if (argc < 3 || argc > 4) {
-               usage(argv[0]);
-                return 1;
-        }
-
-        if (strlen(argv[1]) > 4080) {
-                printf("name too long\n");
-                return 1;
-        }
-
-        start = last = time(0);
-
-       if (argc == 3) {
-               count = strtol(argv[2], NULL, 0);
-               if (count < 1) {
-                        printf("count must be at least one\n");
-                        return 1;
-                }
-       } else {
-               begin = strtol(argv[2], NULL, 0);
-               count = strtol(argv[3], NULL, 0);
-       }
-
-       if (strchr(argv[1], '%')) {
-               fmt = argv[1];
-        } else {
-               sprintf(format, "%s%%d", argv[1]);
-               fmt = format;
-       }
-        for (i = 0; i < count; i++, begin++) {
-                sprintf(filename, fmt, begin);
-                rc = unlink(filename);
-                if (rc) {
-                        printf("unlink(%s) error: %s\n",
-                               filename, strerror(errno));
-                        rc = errno;
-                        break;
-                }
-                if ((i % 10000) == 0) {
-                        printf(" - unlinked %d (time %ld ; total %ld ; last "
-                               "%ld)\n", i, time(0), time(0) - start,
-                               time(0) - last);
-                        last = time(0);
-                }
-        }
-        printf("total: %d unlinks in %ld seconds: %f unlinks/second\n", i,
-               time(0) - start, ((float)i / (time(0) - start)));
-
-        return rc;
-}
diff --git a/lustre/tests/writeme.c b/lustre/tests/writeme.c
deleted file mode 100644 (file)
index ab8692f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-int main(int argc, char **argv)
-{
-        int fd, rc; 
-        int i = 0;
-        char buf[4096];
-        
-        memset(buf, 0, 4096);
-
-        if (argc != 2) { 
-                printf("Usage openme <filename>\n"); 
-                exit(1);
-        }
-
-        fd = open(argv[1], O_RDWR | O_CREAT, 0600);
-        if (fd == -1) { 
-                printf("Error opening %s\n", argv[1]);
-                exit(1);
-        }
-
-        while (1) { 
-                sprintf(buf, "write %d\n", i); 
-                rc = write(fd, buf, sizeof(buf)); 
-                sleep(1); 
-        }
-        return 0;
-}
diff --git a/lustre/utils/Lustre/.cvsignore b/lustre/utils/Lustre/.cvsignore
deleted file mode 100644 (file)
index 97e22b9..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Makefile
-Makefile.in
-.deps
-*.pyc
diff --git a/lustre/utils/Lustre/Makefile.am b/lustre/utils/Lustre/Makefile.am
deleted file mode 100644 (file)
index e8e522f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-pymod_SCRIPTS = __init__.py lustredb.py error.py cmdline.py
-EXTRA_DIST = $(pymod_SCRIPTS)
diff --git a/lustre/utils/Lustre/cmdline.py b/lustre/utils/Lustre/cmdline.py
deleted file mode 100644 (file)
index 53bb6e8..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-#!/usr/bin/env python
-#
-#  Copyright (C) 2002 Cluster File Systems, Inc.
-#   Author: Robert Read <rread@clusterfs.com>
-#   This file is part of Lustre, http://www.lustre.org.
-#
-#   Lustre is free software; you can redistribute it and/or
-#   modify it under the terms of version 2 of the GNU General Public
-#   License as published by the Free Software Foundation.
-#
-#   Lustre is distributed in the hope that it will be useful,
-#   but WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#   GNU General Public License for more details.
-#
-#   You should have received a copy of the GNU General Public License
-#   along with Lustre; if not, write to the Free Software
-#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-
-# Standard the comand line handling for all the python tools.
-
-import sys, getopt, types
-import string
-import error
-
-class Options:
-    FLAG = 1
-    PARAM = 2
-    INTPARAM = 3
-    def __init__(self, cmd, remain_help, options):
-        self.options = options
-        shorts = ""
-        longs = []
-        options.append(('help,h', "Print this help")) 
-        for opt in options:
-            long = self.long(opt)
-            short = self.short(opt)
-            if self.type(opt) in (Options.PARAM, Options.INTPARAM):
-                if short:  short = short + ':'
-                if long: long = long + '='
-            shorts = shorts + short
-            longs.append(long)
-        self.short_opts = shorts
-        self.long_opts = longs
-        self.cmd = cmd
-        self.remain_help = remain_help
-
-    def init_values(self):
-        values = {}
-        for opt in self.options:
-            values[self.key(opt)] = self.default(opt)
-        return values
-
-    def long(self, option):
-        n = string.find(option[0], ',')
-        if n < 0: return option[0]
-        else:     return option[0][0:n]
-
-    def key(self, option):
-        key = self.long(option)
-        return string.replace(key, '-', '_')
-        
-    def short(self, option):
-        n = string.find(option[0], ',')
-        if n < 0: return ''
-        else:     return option[0][n+1:]
-
-    def help(self, option):
-        return option[1]
-    
-    def type(self, option):
-        if len(option) >= 3:
-            return option[2]
-        return Options.FLAG
-    
-    def default(self, option):
-        if len(option) >= 4:
-            return option[3]
-        return None
-
-    def lookup_option(self, key, key_func):
-        for opt in self.options:
-            if key_func(opt) == key:
-                return opt
-
-    def lookup_short(self, key):
-        return self.lookup_option(key, self.short)
-
-    def lookup_long(self, key):
-        return self.lookup_option(key, self.long)
-
-    def handle_opts(self, opts):
-        values = self.init_values()
-        for o, a in opts:
-            if o[0:2] != '--':
-                option = self.lookup_short(o[1:])
-            else:
-                option = self.lookup_long(o[2:])
-            if self.type(option) == Options.PARAM:
-                val = a
-            elif self.type(option) == Options.INTPARAM:
-                try: 
-                    val = int(a)
-                except ValueError, e:
-                    raise error.OptionError("option: '%s' expects integer value, got '%s' "  % (o,a))
-            else:
-                val = 1
-            values[self.key(option)] = val
-        return values
-                
-        
-    class option_wrapper:
-        def __init__(self, values):
-            self.__dict__['values'] = values
-        def __getattr__(self, name):
-            if self.values.has_key(name):
-                return self.values[name]
-            else:
-                raise error.OptionError("bad option name: " + name)
-        def __setattr__(self, name, value):
-            self.values[name] = value
-
-    def parse(self, argv):
-        try:
-            opts, args = getopt.getopt(argv, self.short_opts, self.long_opts)
-            values = self.handle_opts(opts)
-            if values["help"]:
-                self.usage()
-                sys.exit(0)
-            return self.option_wrapper(values), args
-        except getopt.error, e:
-            raise error.OptionError(str(e))
-
-    def usage(self):
-        ret = 'usage: %s [options] %s\n' % (self.cmd, self.remain_help)
-        for opt in self.options:
-            s = self.short(opt)
-            if s: str = "-%s|--%s" % (s,self.long(opt))
-            else: str = "--%s" % (self.long(opt),)
-            if self.type(opt) in (Options.PARAM, Options.INTPARAM):
-                str = "%s <arg>" % (str,)
-            help = self.help(opt)
-            n = string.find(help, '\n')
-            if self.default(opt) != None:
-                if n < 0:
-                    str = "%-15s  %s (default=%s)" %(str, help,
-                                                     self.default(opt))
-                else:
-                    str = "%-15s  %s (default=%s)%s" %(str, help[0:n],
-                                                       self.default(opt),
-                                                       help[n:])
-            else:
-                str = "%-15s  %s" %(str, help)
-            ret = ret + str + "\n"
-        print ret
-
-# Test driver
-if __name__ == "__main__":
-    cl = Options("test", "xml_file", [
-                  ('verbose,v', "verbose ", Options.FLAG, 0),
-                  ('cleanup,d', "shutdown"),
-                  ('gdb',     "Display gdb module file ", Options.FLAG, 0),
-                  ('device', "device path ", Options.PARAM),
-                  ('ldapurl', "LDAP server URL ", Options.PARAM),
-                  ('lustre', "Lustre source dir ", Options.PARAM),
-                  ('portals', "Portals source dir ", Options.PARAM),
-                  ('maxlevel', """Specify the maximum level
-                    Levels are aproximatly like:
-                            70 - mountpoint, echo_client, osc, mdc, lov""",
-                   Options.INTPARAM, 100),
-
-                  ])
-
-    conf, args = cl.parse(sys.argv[1:])
-
-    for key in conf.values.keys():
-        print "%-10s = %s" % (key, conf.values[key])
diff --git a/lustre/utils/Lustre/error.py b/lustre/utils/Lustre/error.py
deleted file mode 100644 (file)
index 6c30416..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-import exceptions
-
-class LconfError (exceptions.Exception):
-    def __init__(self, args):
-        self.args = args
-
-class OptionError (exceptions.Exception):
-    def __init__(self, args):
-        self.args = args
-
diff --git a/lustre/utils/Lustre/lustredb.py b/lustre/utils/Lustre/lustredb.py
deleted file mode 100644 (file)
index 784a63e..0000000
+++ /dev/null
@@ -1,407 +0,0 @@
-import sys, types, string, os
-import re, exceptions
-import xml.dom.minidom
-import Lustre
-
-# ============================================================
-# XML processing and query
-
-class LustreDB:
-    def lookup(self, uuid):
-        """ lookup returns a new LustreDB instance"""
-        return self._lookup_by_uuid(uuid)
-
-    def lookup_name(self, name, class_name = ""):
-        """ lookup returns a new LustreDB instance"""
-        return self._lookup_by_name(name, class_name)
-
-    def lookup_class(self, class_name):
-        """ lookup returns a new LustreDB instance"""
-        return self._lookup_by_class(class_name)
-
-    def get_val(self, tag, default=None):
-        v =  self._get_val(tag)
-        if v:
-            return v
-        if default != None:
-            return default
-        return None
-
-    def get_class(self):
-        return self._get_class()
-
-    def get_val_int(self, tag, default=0):
-        str = self._get_val(tag)
-        try:
-            if str:
-                return int(str)
-            return default
-        except ValueError:
-            raise LconfError("text value is not integer:", str)
-            
-    def get_first_ref(self, tag):
-        """ Get the first uuidref of the type TAG. Only
-        one is expected.  Returns the uuid."""
-        uuids = self._get_refs(tag)
-        if len(uuids) > 0:
-            return  uuids[0]
-        return None
-    
-    def get_refs(self, tag):
-        """ Get all the refs of type TAG.  Returns list of uuids. """
-        uuids = self._get_refs(tag)
-        return uuids
-
-    def get_all_refs(self):
-        """ Get all the refs.  Returns list of uuids. """
-        uuids = self._get_all_refs()
-        return uuids
-
-    def nid2server(self, nid, net_type):
-        netlist = self.lookup_class('network')
-        for net_db in netlist:
-            if net_db.get_val('nid') == nid and net_db.get_val('nettype') == net_type: 
-                return net_db
-        return None
-    
-    # Find the target_device for target on a node
-    # node->profiles->device_refs->target
-    def get_node_tgt_dev(self, node_name, target_uuid):
-        node_db = self.lookup_name(node_name)
-        if not node_db:
-            return None
-        return self.get_tgt_dev(target_uuid)
-
-    # get all network uuids for this node
-    def get_networks(self):
-        ret = []
-        prof_list = self.get_refs('profile')
-        for prof_uuid in prof_list:
-            prof_db = self.lookup(prof_uuid)
-            net_list = prof_db.get_refs('network')
-            for net_uuid in net_list:
-                ret.append(net_uuid)
-        return ret
-
-    def get_active_dev(self, tgtuuid):
-        tgt = self.lookup(tgtuuid)
-        tgt_dev_uuid =tgt.get_first_ref('active')
-        return tgt_dev_uuid
-
-    def get_tgt_dev(self, tgtuuid):
-        prof_list = self.get_refs('profile')
-        for prof_uuid in prof_list:
-            prof_db = self.lookup(prof_uuid)
-            if not prof_db:
-                panic("profile:", profile, "not found.")
-            for ref_class, ref_uuid in prof_db.get_all_refs(): 
-                if ref_class in ('osd', 'mdsdev'):
-                    devdb = self.lookup(ref_uuid)
-                    uuid = devdb.get_first_ref('target')
-                    if tgtuuid == uuid:
-                        return ref_uuid
-        return None
-
-    def get_group(self, group):
-        ret = []
-        devs = self.lookup_class('mds')
-        for tgt in devs:
-            if tgt.get_val('group', "") == group:
-                ret.append(tgt.getUUID())
-        devs = self.lookup_class('ost')
-        for tgt in devs:
-            if tgt.get_val('group', "") == group:
-                ret.append(tgt.getUUID())
-        return ret
-
-    # Change the current active device for a target
-    def update_active(self, tgtuuid, new_uuid):
-        self._update_active(tgtuuid, new_uuid)
-
-    def get_version(self):
-        return self.get_val('version')
-
-class LustreDB_XML(LustreDB):
-    def __init__(self, dom, root_node):
-        # init xmlfile
-        self.dom_node = dom
-        self.root_node = root_node
-
-    def xmltext(self, dom_node, tag):
-        list = dom_node.getElementsByTagName(tag)
-        if len(list) > 0:
-            dom_node = list[0]
-            dom_node.normalize()
-            if dom_node.firstChild:
-                txt = string.strip(dom_node.firstChild.data)
-                if txt:
-                    return txt
-
-    def xmlattr(self, dom_node, attr):
-        return dom_node.getAttribute(attr)
-
-    def _get_val(self, tag):
-        """a value could be an attribute of the current node
-        or the text value in a child node"""
-        ret  = self.xmlattr(self.dom_node, tag)
-        if not ret:
-            ret = self.xmltext(self.dom_node, tag)
-        return ret
-
-    def _get_class(self):
-        return self.dom_node.nodeName
-
-    def get_ref_type(self, ref_tag):
-        res = string.split(ref_tag, '_')
-        return res[0]
-
-    #
-    # [(ref_class, ref_uuid),]
-    def _get_all_refs(self):
-        list = []
-        for n in self.dom_node.childNodes: 
-            if n.nodeType == n.ELEMENT_NODE:
-                ref_uuid = self.xml_get_ref(n)
-                ref_class = self.get_ref_type(n.nodeName)
-                list.append((ref_class, ref_uuid))
-                    
-        list.sort()
-        return list
-
-    def _get_refs(self, tag):
-        """ Get all the refs of type TAG.  Returns list of uuids. """
-        uuids = []
-        refname = '%s_ref' % tag
-        reflist = self.dom_node.getElementsByTagName(refname)
-        for r in reflist:
-            uuids.append(self.xml_get_ref(r))
-        return uuids
-
-    def xmllookup_by_uuid(self, dom_node, uuid):
-        for n in dom_node.childNodes:
-            if n.nodeType == n.ELEMENT_NODE:
-                if self.xml_get_uuid(n) == uuid:
-                    return n
-                else:
-                    n = self.xmllookup_by_uuid(n, uuid)
-                    if n: return n
-        return None
-
-    def _lookup_by_uuid(self, uuid):
-        dom = self. xmllookup_by_uuid(self.root_node, uuid)
-        if dom:
-            return LustreDB_XML(dom, self.root_node)
-
-    def xmllookup_by_name(self, dom_node, name):
-        for n in dom_node.childNodes:
-            if n.nodeType == n.ELEMENT_NODE:
-                if self.xml_get_name(n) == name:
-                    return n
-                else:
-                    n = self.xmllookup_by_name(n, name)
-                    if n: return n
-        return None
-
-    def _lookup_by_name(self, name, class_name):
-        dom = self.xmllookup_by_name(self.root_node, name)
-        if dom:
-            return LustreDB_XML(dom, self.root_node)
-
-    def xmllookup_by_class(self, dom_node, class_name):
-        return dom_node.getElementsByTagName(class_name)
-
-    def _lookup_by_class(self, class_name):
-        ret = []
-        domlist = self.xmllookup_by_class(self.root_node, class_name)
-        for node in domlist:
-            ret.append(LustreDB_XML(node, self.root_node))
-        return ret
-
-    def xml_get_name(self, n):
-        return n.getAttribute('name')
-        
-    def getName(self):
-        return self.xml_get_name(self.dom_node)
-
-    def xml_get_ref(self, n):
-        return n.getAttribute('uuidref')
-
-    def xml_get_uuid(self, dom_node):
-        return dom_node.getAttribute('uuid')
-
-    def getUUID(self):
-        return self.xml_get_uuid(self.dom_node)
-
-    def get_routes(self, type, gw):
-        """ Return the routes as a list of tuples of the form:
-        [(type, gw, lo, hi),]"""
-        res = []
-        tbl = self.dom_node.getElementsByTagName('routetbl')
-        for t in tbl:
-            routes = t.getElementsByTagName('route')
-            for r in routes:
-                net_type = self.xmlattr(r, 'type')
-                if type != net_type:
-                    lo = self.xmlattr(r, 'lo')
-                    hi = self.xmlattr(r, 'hi')
-                    res.append((type, gw, lo, hi))
-        return res
-
-    def get_route_tbl(self):
-        ret = []
-        for r in self.dom_node.getElementsByTagName('route'):
-            net_type = self.xmlattr(r, 'type')
-            gw = self.xmlattr(r, 'gw')
-            lo = self.xmlattr(r, 'lo')
-            hi = self.xmlattr(r, 'hi')
-            ret.append((net_type, gw, lo, hi))
-        return ret
-
-    def _update_active(self, tgt, new):
-        raise LconfError("updates not implemented for XML")
-
-# ================================================================    
-# LDAP Support
-class LustreDB_LDAP(LustreDB):
-    def __init__(self, name, attrs,
-                 base = "fs=lustre",
-                 parent = None,
-                 url  = "ldap://localhost",
-                 user = "cn=Manager, fs=lustre",
-                 pw   = "secret"
-                 ):
-        self._name = name
-        self._attrs = attrs
-        self._base = base
-        self._parent = parent
-        self._url  = url
-        self._user = user
-        self._pw   = pw
-        if parent:
-            self.l = parent.l
-            self._base = parent._base
-        else:
-            self.open()
-
-    def open(self):
-        import ldap
-        try:
-            self.l = ldap.initialize(self._url)
-            # Set LDAP protocol version used
-            self.l.protocol_version=ldap.VERSION3
-            # user and pw only needed if modifying db
-            self.l.bind_s(self._user, self._pw, ldap.AUTH_SIMPLE);
-        except ldap.LDAPError, e:
-            raise Lustre.LconfError('Unable to connection to ldap server')
-
-        try:
-            self._name, self._attrs = self.l.search_s(self._base,
-                                                      ldap.SCOPE_BASE)[0]
-        except ldap.LDAPError, e:
-            raise Lustre.LconfError("no config found in ldap: %s"
-                                      % (self._base,))
-    def close(self):
-        self.l.unbind_s()
-
-    def ldap_search(self, filter):
-        """Return list of uuids matching the filter."""
-        import ldap
-        dn = self._base
-        ret = []
-        uuids = []
-        try:
-            for name, attrs in self.l.search_s(dn, ldap.SCOPE_ONELEVEL,
-                                        filter, ["uuid"]):
-                for v in attrs['uuid']:
-                    uuids.append(v)
-        except ldap.NO_SUCH_OBJECT, e:
-            pass
-        except ldap.LDAPError, e:
-            print e                     # FIXME: die here?
-        if len(uuids) > 0:
-            for uuid in uuids:
-                ret.append(self._lookup_by_uuid(uuid))
-        return ret
-
-    def _lookup_by_name(self, name, class_name):
-        list =  self.ldap_search("lustreName=%s" %(name))
-        if len(list) == 1:
-            return list[0]
-        return None
-
-    def _lookup_by_class(self, class_name):
-        return self.ldap_search("objectclass=%s" %(string.upper(class_name)))
-
-    def _lookup_by_uuid(self, uuid):
-        import ldap
-        dn = "uuid=%s,%s" % (uuid, self._base)
-        ret = None
-        try:
-            for name, attrs in self.l.search_s(dn, ldap.SCOPE_BASE,
-                                               "objectclass=*"):
-                ret = LustreDB_LDAP(name, attrs,  parent = self)
-                        
-        except ldap.NO_SUCH_OBJECT, e:
-            pass                        # just return empty list
-        except ldap.LDAPError, e:
-            print e                     # FIXME: die here?
-        return ret
-
-
-    def _get_val(self, k):
-        ret = None
-        if self._attrs.has_key(k):
-            v = self._attrs[k]
-            if type(v) == types.ListType:
-                ret = str(v[0])
-            else:
-                ret = str(v)
-        return ret
-
-    def _get_class(self):
-        return string.lower(self._attrs['objectClass'][0])
-
-    def get_ref_type(self, ref_tag):
-        return ref_tag[:-3]
-
-    #
-    # [(ref_class, ref_uuid),]
-    def _get_all_refs(self):
-        list = []
-        for k in self._attrs.keys():
-            if re.search('.*Ref', k):
-                for uuid in self._attrs[k]:
-                    ref_class = self.get_ref_type(k)
-                    list.append((ref_class, uuid))
-        return list
-
-    def _get_refs(self, tag):
-        """ Get all the refs of type TAG.  Returns list of uuids. """
-        uuids = []
-        refname = '%sRef' % tag
-        if self._attrs.has_key(refname):
-            return self._attrs[refname]
-        return []
-
-    def getName(self):
-        return self._get_val('lustreName')
-
-    def getUUID(self):
-        return self._get_val('uuid')
-
-    def get_route_tbl(self):
-        return []
-
-    def _update_active(self, tgtuuid, newuuid):
-        """Return list of uuids matching the filter."""
-        import ldap
-        dn = "uuid=%s,%s" %(tgtuuid, self._base)
-        ret = []
-        uuids = []
-        try:
-            self.l.modify_s(dn, [(ldap.MOD_REPLACE, "activeRef", newuuid)])
-        except ldap.NO_SUCH_OBJECT, e:
-            print e
-        except ldap.LDAPError, e:
-            print e                     # FIXME: die here?
-        return 
diff --git a/lustre/utils/lactive b/lustre/utils/lactive
deleted file mode 100644 (file)
index 6d7771d..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python
-#
-#  Copyright (C) 2002 Cluster File Systems, Inc.
-#   Author: Robert Read <rread@clusterfs.com>
-#   This file is part of Lustre, http://www.lustre.org.
-#
-#   Lustre is free software; you can redistribute it and/or
-#   modify it under the terms of version 2 of the GNU General Public
-#   License as published by the Free Software Foundation.
-#
-#   Lustre is distributed in the hope that it will be useful,
-#   but WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#   GNU General Public License for more details.
-#
-#   You should have received a copy of the GNU General Public License
-#   along with Lustre; if not, write to the Free Software
-#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-
-# For all the OST/MDSs that are primary on the --primary node, set
-# them to be active on --active if that OST is available on --active.
-#
-# Make the active node the active node for all devices it shares with the
-# old. The bulk of this code is for figuring out which devices to
-# change, and what to change them to.
-
-# XXX add error checking
-# XXX make this code less ugly
-
-import sys, getopt, types
-import string, os
-import ldap
-import Lustre
-
-lactive_options = [
-    ('ldapurl',"LDAP server URL", Lustre.Options.PARAM,
-     "ldap://localhost"),
-    ('config', "Cluster config name used for LDAP query", Lustre.Options.PARAM),
-    ('group', "The group of devices to update", Lustre.Options.PARAM),
-    ('active', "The active node name", Lustre.Options.PARAM),
-    ]
-
-def fatal(*args):
-    msg = string.join(map(str,args))
-    print "! " + msg
-    sys.exit(1)
-
-
-cl = Lustre.Options("lactive","", lactive_options)
-config, args = cl.parse(sys.argv[1:])
-
-if not (config.group or config.active):
-    fatal("Must specify both  group and active node.")
-
-if not config.config:
-    fatal("Missing config")
-    
-base = "config=%s,fs=lustre" % (config.config,)
-db = Lustre.LustreDB_LDAP('', {}, base=base, url = config.ldapurl)
-
-active_node = db.lookup_name(config.active)
-if not active_node:
-    fatal(config.active, "node not found in database.")
-
-devices =  db.get_group(config.group)
-if len(devices) < 0:
-    fatal("no devices found for group", config.group)
-
-# for all devices in group
-  # lookup device in active node
-  # update the active device 
-for tgtuuid in devices:
-    active_uuid = db.get_active_dev(tgtuuid)
-    new_active_uuid = active_node.get_tgt_dev(tgtuuid)
-    if active_uuid != new_active_uuid:
-        print ("%s: changing active %s to %s:%s"
-               % (tgtuuid, active_uuid,
-                  config.active, new_active_uuid))
-        db.update_active(tgtuuid, new_active_uuid)
-
-
-
-
-
diff --git a/lustre/utils/lfind.c b/lustre/utils/lfind.c
deleted file mode 100644 (file)
index 6628a9c..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-#define _XOPEN_SOURCE 500
-
-#include <stdio.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <libgen.h>
-#include <ftw.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#define        printk printf
-#include <linux/lustre_lib.h>
-#include <linux/lustre_lite.h>
-
-#warning Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c
-#define MAX_LOV_UUID_COUNT     1000
-#define OBD_NOT_FOUND          ((__u32)-1)
-#define        debugMsg                if (debug) printf
-
-char *         cmd;
-int            debug;
-struct option  longOpts[] = {
-                       {"debug", 0, 0, 'd'},
-                       {"help", 0, 0, 'h'},
-                       {"obd", 1, 0, 'o'},
-                       {"query", 0, 0, 'o'},
-                       {0, 0, 0, 0}
-               };
-int            query;
-char *         shortOpts = "dho:qv";
-char *         usageMsg = "[ --obd <obd uuid> | --query ] <dir|file> ...";
-
-int            max_stripe_count = MAX_LOV_UUID_COUNT;
-obd_uuid_t *   obduuid;
-__u32          obdcount;
-__u32          obdindex;
-char *         buf;
-int            buflen;
-struct obd_ioctl_data data;
-struct lov_desc desc;
-obd_uuid_t *   uuids;
-int            uuidslen;
-int            cfglen;
-struct lov_user_md *lum;
-int            lumlen;
-
-void   init();
-void   usage(FILE *stream);
-void   errMsg(char *fmt, ...);
-void   processPath(char *path);
-int    processFile(
-               const char *path,
-               const struct stat *sp,
-               int flag,
-               struct FTW *ftwp
-       );
-__u32  getobdindex(const char *path);
-
-int
-main (int argc, char **argv) {
-       int c;
-
-       cmd = basename(argv[0]);
-
-       while ((c = getopt_long(argc, argv, shortOpts, longOpts, NULL)) != -1) {
-               switch (c) {
-               case 'd':
-                       debug++;
-                       break;
-               case 'o':
-                       if (obduuid) {
-                               errMsg("obd '%s' already specified: '%s'.",
-                                       obduuid, optarg);
-                               exit(1);
-                       }
-
-                       obduuid = (obd_uuid_t *)optarg;
-                       break;
-               case 'h':
-                       usage(stdout);
-                       exit(0);
-               case 'q':
-                       query++;
-                       break;
-               case '?':
-                       usage(stderr);
-                       exit(1);
-               default:
-                       errMsg("Internal error. Valid '%s' unrecognized.",
-                               argv[optind - 1]);
-                       usage(stderr);
-                       exit(1);
-               }
-       }
-
-       if (optind >= argc) {
-               usage(stderr);
-               exit(1);
-       }
-
-       if (obduuid == NULL)
-               query++;
-
-       init();
-
-       do {
-               processPath(argv[optind]);
-       } while (++optind < argc);
-
-       exit (0);
-}
-
-void
-init()
-{
-       int datalen, desclen;
-
-       datalen = size_round(sizeof(data));
-       desclen = size_round(sizeof(desc));
-       uuidslen = size_round(max_stripe_count * sizeof(*uuids));
-       cfglen = datalen + desclen + uuidslen;
-       lumlen = sizeof(*lum) + max_stripe_count * sizeof(*lum->lum_luoinfo);
-       if (cfglen > lumlen)
-               buflen = cfglen;
-       else
-               buflen = lumlen;
-
-#warning max ioctl buffer size currently hardcoded to 8192
-       if (buflen > 8192) {
-               int nuuids, remaining, nluoinfos;
-
-               buflen = 8192;
-               nuuids = (buflen - datalen - desclen) / sizeof(*uuids);
-               uuidslen = size_round(nuuids * sizeof(*uuids));
-               remaining = nuuids * sizeof(*uuids);
-               if (uuidslen > remaining)
-                       nuuids--;
-               nluoinfos = (buflen - sizeof(*lum)) / sizeof(*lum->lum_luoinfo);
-               if (nuuids > nluoinfos)
-                       max_stripe_count = nluoinfos;
-               else
-                       max_stripe_count = nuuids;
-
-               cfglen = datalen + desclen + uuidslen;
-               lumlen = sizeof(*lum) + max_stripe_count *
-                               sizeof(*lum->lum_luoinfo);
-       }
-
-       if ((buf = malloc(buflen)) == NULL) {
-               errMsg("Unable to allocate %d bytes of memory for ioctl's.",
-                       buflen);
-               exit(1);
-       }
-
-       lum = (struct lov_user_md *)buf;
-       uuids = (obd_uuid_t *)buf;
-}
-
-void
-usage(FILE *stream)
-{
-       fprintf(stream, "usage: %s %s\n", cmd, usageMsg);
-}
-
-void
-errMsg(char *fmt, ...)
-{
-       va_list args;
-
-       fprintf(stderr, "%s: ", cmd);
-       va_start(args, fmt);
-       vfprintf(stderr, fmt, args);
-       va_end(args);
-       fprintf(stderr, "\n");
-}
-
-void
-processPath(char *path)
-{
-       obdindex = OBD_NOT_FOUND;
-       nftw((const char *)path, processFile, 128, FTW_PHYS|FTW_MOUNT);
-}
-
-int
-processFile(const char *path,
-       const struct stat *sp,
-       int flag,
-       struct FTW *ftwp
-) {
-       struct lov_user_oinfo *luoinfo;
-       int fd;
-       int count;
-       int rc;
-       int i;
-
-       if (flag != FTW_F)
-               return 0;
-
-       if ((obdcount == 0) && (getobdindex(path) == OBD_NOT_FOUND)) {
-               /* terminate nftw walking this tree */
-               return(1);
-       }
-
-       if ((fd = open(path, O_RDONLY)) < 0) {
-               errMsg("open \"%.20s\" failed.", path);
-               perror("open");
-               exit(1);
-       }
-
-       memset((void *)buf, 0, buflen);
-        lum->lum_stripe_count = max_stripe_count;
-
-       if ((rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE, (void *)lum)) < 0) {
-               errMsg("LL_IOC_LOV_GETSTRIPE ioctl failed.");
-               perror("ioctl");
-               exit(1);
-       }
-
-       close(fd);
-
-       count = lum->lum_stripe_count;
-       luoinfo = lum->lum_luoinfo;
-
-       if (query) {
-               printf("%s\n", path);
-               for (i = 0; i < count; i++, luoinfo++) {
-                       printf("%4d: obdindex: %-4d objid: %lld\n",
-                               i, luoinfo->luo_idx, luoinfo->luo_id);
-               }
-               return(0);
-       }
-
-       debugMsg("LL_IOC_LOV_GETSTRIPE:%s: obdindex: %d count: %d\n",
-               path, obdindex, count);
-
-       for (i = 0; i < count; i++, luoinfo++) {
-               debugMsg("%-4d: obdidx: %-4d objid: %lld\n",
-                       i, luoinfo->luo_idx, luoinfo->luo_id);
-               if (luoinfo->luo_idx == obdindex) {
-                       printf("%s\n", path);
-                       return 0;
-               }
-       }
-
-       return(0);
-}
-
-__u32
-getobdindex(const char *path)
-{
-       obd_uuid_t *uuidp;
-       int fd;
-       int rc;
-       int i;
-
-       if ((fd = open(path, O_RDONLY)) < 0) {
-               errMsg("open \"%.20s\" failed.", path);
-               perror("open");
-               exit(1);
-       }
-
-        data.ioc_inllen1 = sizeof(desc);
-        data.ioc_inlbuf1 = (char *)&desc;
-        data.ioc_inllen2 = uuidslen;
-        data.ioc_inlbuf2 = (char *)uuids;
-        data.ioc_inllen3 = 0;
-
-        memset(&desc, 0, sizeof(desc));
-        desc.ld_tgt_count = max_stripe_count;
-
-        if (obd_ioctl_pack(&data, &buf, buflen)) {
-                errMsg("internal buffering error.");
-               exit(1);
-        }
-
-        rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
-        if (rc) {
-               errMsg("OBD_IOC_LOV_GET_CONFIG ioctl failed: %d.", errno);
-               perror("ioctl");
-                exit(1);
-        }
-
-       if (obd_ioctl_unpack(&data, buf, buflen)) {
-               errMsg("Invalid reply from ioctl.");
-                exit(1);
-       }
-
-       close(fd);
-
-        obdcount = desc.ld_tgt_count;
-
-       if (query) {
-               printf("OBDS:\n");
-               for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++)
-                       printf("%4d: %s\n", i, (char *)uuidp);
-
-               return(0);
-       }
-
-        for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) {
-               rc = strncmp((const char *)obduuid, (const char *)uuidp,
-                               sizeof(*uuidp));
-               if (rc == 0) {
-                       obdindex = i;
-                       break;
-               }
-       }
-
-       if (obdindex == OBD_NOT_FOUND) {
-               errMsg("obd UUID '%s' not found.", obduuid);
-               return(OBD_NOT_FOUND);
-       }
-
-       return(0);
-}
diff --git a/lustre/utils/llparser.pm b/lustre/utils/llparser.pm
deleted file mode 100644 (file)
index 5cee31f..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-#!/usr/bin/perl
-# Copyright (C) 2002 Cluster File Systems, Inc.
-# Author: Hariharan Thantry <thantry@users.sourceforge.net>
-
-#   This file is part of Lustre, http://www.lustre.org.
-#
-#   Lustre is free software; you can redistribute it and/or
-#   modify it under the terms of version 2 of the GNU General Public
-#   License as published by the Free Software Foundation.
-#
-#   Lustre is distributed in the hope that it will be useful,
-#   but WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#   GNU General Public License for more details.
-#
-#   You should have received a copy of the GNU General Public License
-#   along with Lustre; if not, write to the Free Software
-#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-
-
-package llparser;
-require Exporter;
-@ISA = qw(Exporter);
-@EXPORT = qw(parse_file print_rpcrelations parse_foptions %ll_subsystems 
-       %subsysnum %trace_masks $e_subsys $e_mask $e_processor $e_time 
-       $e_file $e_line $e_function $e_pid $e_stack $e_fmtstr $e_backref 
-       $e_treeparent $e_numchildren $e_youngestchild $e_next $e_pidhead 
-       $e_rpcsndrcv $e_rpcpid $e_rpcxid $e_rpcnid $e_rpcopc $e_rpcnext 
-       $e_curlineref $SEND $RCV);
-
-($e_subsys, 
- $e_mask, 
- $e_processor, 
- $e_time, 
- $e_file, 
- $e_line, 
- $e_function, 
- $e_pid, 
- $e_stack, 
- $e_fmtstr, 
- $e_treeparent, 
- $e_numchildren,
- $e_youngestchild, 
- $e_pidhead,
- $e_next, 
- $e_backref) = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
-
-($e_rpcpid,
- $e_rpcxid,
- $e_rpcnid,
- $e_rpcopc,
- $e_rpcnext, 
- $e_rpcsndrcv,
- $e_curlineref) = (0, 1, 2, 3, 4, 5, 6); 
-
-$SEND = 0;
-$RCV  = 1;
-
-$REGEX=qr/^\s*(\w+)\s*:\s*(\d+)\s*:\s*(\d+)\s*:\s*(\d+\.(?:\d+))\s*\(\s*([^:]+)\s*:\s*(\d+)\s*:\s*([^()]+)\s*\(\)\s*(?:(?:\d+)\s*\|\s*)?(\d+)\s*\+\s*(\d+)\s*(?:.*)\):(.*)$/;
-
-$RPCREGEX = qr/^\s*(?:Sending|Handling)\s*RPC\s*pid:xid:nid:opc\s*(\d+):(?:0x)?(\w+):(?:0x)?(\w+):(\d+)\s*$/;
-$FILEOPTIONREGEX = qr/(--server)|(-s)/;
-$SENDING = qr/Sending/;
-
-
-# Needs to match definition in portals/include/linux/kp30.h
-%ll_subsystems = ("00" => "UNDEFINED", "01" => "MDC", "02" => "MDS", 
-                 "03" => "OSC",  "04" => "OST",  "05" => "CLASS",
-                 "06" => "OBDFS","07" => "LLITE","08" => "RPC",
-                 "09" => "EXT2OBD","0a" => "PORTALS","0b" => "SOCKNAL",
-                 "0c" => "QSWNAL","0d" => "PINGER","0e" => "FILTER",
-                 "0f" => "TRACE","10" => "ECHO","11" => "LDLM",
-                 "12" => "LOV", "13" => "GMNAL","14" => "PTLROUTER" );
-
-%subsysnum;
-$subsysnum->{UNDEFINED} = 0;
-$subsysnum->{MDC} = 1;
-$subsysnum->{MDS} = 2;
-$subsysnum->{OSC} = 3;
-$subsysnum->{OST} = 4;
-$subsysnum->{CLASS} = 5;
-$subsysnum->{OBDFS} = 6;
-$subsysnum->{LLITE} = 7;
-$subsysnum->{RPC} = 8;
-$subsysnum->{EXT2OBD} = 9;
-$subsysnum->{PORTALS} = 10;
-$subsysnum->{SOCKNAL} = 11;
-$subsysnum->{QSWNAL} = 12;
-$subsysnum->{PINGER} = 13;
-$subsysnum->{FILTER} = 14;
-$subsysnum->{TRACE} = 15; # obdtrace, not to be confused with D_TRACE */
-$subsysnum->{ECHO} = 16;
-$subsysnum->{LDLM} = 17;
-$subsysnum->{LOV} = 18;
-$subsysnum->{GMNAL} = 19;
-$subsysnum->{PTLROUTER} = 20;
-
-%tracemasks;
-$tracemasks->{TRACE} = 1 << 0; # /* ENTRY/EXIT markers */
-$tracemasks->{INODE} = 1 << 1; #
-$tracemasks->{SUPER} = 1 << 2; #
-$tracemasks->{EXT2} = 1 << 3; # /* anything from ext2_debug */
-$tracemasks->{MALLOC} = 1 << 4; # /* print malloc, free information */
-$tracemasks->{CACHE} = 1 << 5; # /* cache-related items */
-$tracemasks->{INFO} = 1 << 6; # /* general information */
-$tracemasks->{IOCTL} = 1 << 7; # /* ioctl related information */
-$tracemasks->{BLOCKS} = 1 << 8; # /* ext2 block allocation */
-$tracemasks->{NET} = 1 << 9; # /* network communications */
-$tracemasks->{WARNING} = 1 << 10; #
-$tracemasks->{BUFFS} = 1 << 11; #
-$tracemasks->{OTHER} = 1 << 12; #
-$tracemasks->{DENTRY} = 1 << 13; #
-$tracemasks->{PORTALS} = 1 << 14; # /* ENTRY/EXIT markers */
-$tracemasks->{PAGE} = 1 << 15; # /* bulk page handling */
-$tracemasks->{DLMTRACE} = 1 << 16; #
-$tracemasks->{ERROR} = 1 << 17; # /* CERROR} = ...) == CDEBUG} = D_ERROR, ...) */
-$tracemasks->{EMERG} = 1 << 18; # /* CEMERG} = ...) == CDEBUG} = D_EMERG, ...) */
-$tracemasks->{HA} = 1 << 19; # /* recovery and failover */
-$tracemasks->{RPCTRACE} = 1 << 19; # /* recovery and failover */
-
-# Contains all the file names, the first filename is the 
-# client. After that are all servers.
-my @filearray = ();
-
-
-# Create backlinks between array entries based on the calling sequence
-# For each new PID encountered, the first entry will be present in the 
-# PID hash.
-
-sub create_links {
-    my $arrayref = shift @_;
-    my $pidhashref = shift @_;
-    my $stitchref = shift @_;
-    my %local_hash;
-    my $hash_lineref;
-    my $tmpfmtref;
-    my $tmpref;
-    my $firstlineaftermarker = 0;
-
-    foreach $lineref (@$arrayref) {
-       next if ($lineref->[$e_time] == 0); # Skip the client marker line
-       my $pidprevious = $pidhashref->{$lineref->[$e_pid]};
-       if ($pidprevious->[$e_next] == 0) {
-           $pidprevious->[$e_next] = $lineref;
-           if (exists $local_hash{$lineref->[$e_pid]} 
-               && $firstlineaftermarker) {
-               $hash_lineref=$local_hash{$lineref->[$e_pid]};
-               $hash_lineref->[$e_next] =$lineref;
-               $firstlineaftermarker = 0;
-           } 
-       } elsif ($local_hash{$lineref->[$e_pid]} == 0) {
-               # True only for the first line, the marker line.
-               $local_hash{$lineref->[$e_pid]}=$lineref;
-               #print "LINE ADDED TO HASH: @$lineref\n";
-               $firstlineaftermarker = 1; 
-       }
-       # Stack grows upward (assumes x86 kernel)
-       if ($lineref->[$e_stack] < $pidprevious->[$e_stack]) {
-           # lineref is not a child of pidprevious, find its parent
-         LINE: while(($lineref->[$e_stack] < $pidprevious->[$e_stack]) &&
-                     ($lineref->[$e_function] == $pidprevious->[$e_function])
-                     ) {
-                         #This second part of the comparision is a HACK  
-                         last LINE if ($pidprevious->[$e_backref] == 0); 
-                         $pidprevious = $pidprevious->[$e_backref];
-         }
-       }
-       if ($lineref->[$e_stack] > $pidprevious->[$e_stack]) {
-           # lineref is child of pidprevious, with the caveat that they must
-            # belong to different functions. This is a HACK 
-           # until CDEBUG is modified
-           while($lineref->[$e_function] eq $pidprevious->[$e_function]) {
-             last if ($pidprevious->[$e_backref] == 0);
-              $pidprevious = $pidprevious->[$e_backref];
-           }   
-
-           $lineref->[$e_backref] = $pidprevious;
-           $pidprevious->[$e_numchildren]++;
-       } else {
-           # lineref is sibling of pidprevious
-           $lineref->[$e_numchildren] = 0;
-           $lineref->[$e_backref] = $pidprevious->[$e_backref];
-           ($lineref->[$e_backref])->[$e_numchildren]++;
-       }
-
-       $pidhashref->{$lineref->[$e_pid]} = $lineref;
-       $lineref->[$e_youngestchild] = $lineref;
-       while ($pidprevious->[$e_backref] != 0) {
-           $pidprevious->[$e_youngestchild] = $lineref;
-           $pidprevious = $pidprevious->[$e_backref];
-       }
-       $pidprevious->[$e_youngestchild] = $lineref;
-       $lineref->[$e_pidhead]=$pidprevious;
-       
-        # Stitch together rpc's
-       if($lineref->[$e_fmtstr] =~ $RPCREGEX) {
-           #print "RPC LINE: @$lineref\n";
-           $tmpfmtref = [$1, $2, $3, $4, 0, 0, 0];
-           if ($lineref->[$e_fmtstr] =~ $SENDING) {
-               $tmpfmtref->[$e_rpcsndrcv] = $SEND;
-           } else { $tmpfmtref->[$e_rpcsndrcv] = $RCV; }
-           $tmpfmtref->[$e_curlineref] = $lineref;
-           $stitchref->{$lineref->[$e_time]} = $tmpfmtref;
-           
-       }
-           
-    }
-match_rpcs($stitchref);
-return $arrayref;      
-}
-
-
-
-
-# Main loop, parses the debug log
-
-sub parse_file {
-    my %hasharray;
-    my $input_files = shift;
-    
-    my $stitch_ref = shift;
-    my $pid = shift;
-    my $rpctrace = shift;
-    my $trace = shift;
-    my $nodlm = shift;
-    my $noclass = shift;
-    my $nonet = shift;
-
-    print "$pid, $rpctrace, $nodlm, $noclass, $nonet\n";
-    $backref = 0;
-    $treeparent = 0;
-    $numchildren = 0;
-    $youngestchild = 0;
-    $next = 0;
-    $pidhead = 0;
-    $iter = 0;
-                       
-    foreach $file (@$input_files) {
-       
-       open(FILEHANDLE, $file) or die "Can't open file: $file\n";
-       while(<FILEHANDLE>) {
-           if (/$REGEX/) {
-               @parsed_line=($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, 
-                             $treeparent, $numchildren, $youngestchild, 
-                             $pidhead, $next, $backref);
-               next if (($parsed_line[$e_pid] != $pid) && 
-                        ($pid) && ($iter == 0));
-               next if (($parsed_line[$e_mask] != $tracemasks->{RPCTRACE}) 
-                        && ($rpctrace));
-               next if ($trace && $parsed_line[$e_mask] != 
-                        $tracemasks->{TRACE});
-               next if ($nodlm && hex($parsed_line[$e_subsys]) == 
-                        $subsysnum->{LDLM});
-               next if ($noclass && hex($parsed_line[$e_subsys]) == 
-                        $subsysnum->{CLASS});
-               next if ($nonet && (hex($parsed_line[$e_subsys]) == 
-                                   $subsysnum->{RPC} ||
-                                   hex($parsed_line[$e_subsys]) == 
-                                   $subsysnum->{NET} ||        
-                                   hex($parsed_line[$e_subsys]) == 
-                                   $subsysnum->{PORTALS} ||
-                                   hex($parsed_line[$e_subsys]) == 
-                                   $subsysnum->{SOCKNAL} ||
-                                   hex($parsed_line[$e_subsys]) == 
-                                   $subsysnum->{QSWNAL} ||
-                                   hex($parsed_line[$e_subsys]) == 
-                                   $subsysnum->{GMNAL}));      
-               
-               
-               if (!exists($hasharray{$parsed_line[$e_pid]})) {
-                   # Push a marker for the beginning of this PID
-                   my @marker_line;
-                   $marker_line[$e_subsys] = 0;
-                   $marker_line[$e_mask] = 0;
-                   $marker_line[$e_processor] = 0;
-                   $marker_line[$e_time] = $parsed_line[$e_time];
-                   $marker_line[$e_file] = 0;
-                   $marker_line[$e_line] = 0;
-                   $marker_line[$e_function] = 0;
-                   $marker_line[$e_pid] = $parsed_line[$e_pid];
-                   # marker lines are everyone's parent, so stack value zero
-                   $marker_line[$e_stack] = 0; 
-                   $marker_line[$e_fmtstr] = "";
-                   $marker_line[$e_treeparent] = 0;
-                   $marker_line[$e_numchildren] = 0;
-                   $marker_line[$e_youngestchild] = 0;
-                   $marker_line[$e_pidhead] = 0;
-                   $marker_line[$e_next]= \@parsed_line;
-                   $marker_line[$e_backref] = 0;
-                   $hasharray{$parsed_line[$e_pid]} = \@marker_line;
-                   push @$array_parsed, [ @marker_line ];
-                   
-               }
-               push @$array_parsed, [ @parsed_line ];
-           }
-           
-       }
-       close(FILEHANDLE);
-       if ($iter == 0) {
-           # Insert end of client line marker, an all zero pattern;
-           @marker_line = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-           push @$array_parsed, [ @marker_line ]; 
-           
-       }
-       $iter ++;
-    }
-    
-    $array_parsed=create_links($array_parsed, \%hasharray, $stitch_ref);
-    #print_array($array_parsed);
-    return $array_parsed;
-}
-
-sub print_array {
-
-    my $arrayref = shift;
-    foreach $lineref(@$arrayref){
-       if ($lineref->[$e_backref]==0){
-               print "MARKER LINE(addr): $lineref contents: [@$lineref]\n";
-       } else {
-
-               print "REGULAR LINE (addr) :$lineref contents:[@$lineref]\n";
-       }
-    }
-    
-}
-
-sub print_rpcrelations {
-
-    my $rpchashref = shift;
-    foreach $rpckeys (sort keys %$rpchashref) {
-       $tmpref = $rpchashref->{$rpckeys};
-       #print "Key: $rpckeys, Contents: @$tmpref\n";
-
-    }
-
-}
-sub match_rpcs {
-    my $rpchashref = shift;
-    foreach $rpckeys (sort keys %$rpchashref) {
-       $tmpref = $rpchashref->{$rpckeys};
-       #print "MATCHING: $@tmpref...\n";
-       foreach $cmpkeys (sort keys %$rpchashref) {
-           next if($cmpkeys == $rpckeys);
-           $cmpref = $rpchashref->{$cmpkeys};
-        #   print "Line compared: @$cmpref\n";
-           next if ($tmpref->[$e_rpcsndrcv] == $cmpref->[$e_rpcsndrcv]);
-           next if ($tmpref->[$e_rpcpid] != $cmpref->[$e_rpcpid]);
-           next if ($tmpref->[$e_rpcxid] != $cmpref->[$e_rpcxid]);
-           if ($tmpref->[$e_rpcsndrcv] == $SEND) {
-               $tmpref->[$e_rpcnext] = $cmpkeys;
-               #print "MACTHED: KEY 1: $rpckeys CONTENTS: @$tmpref", 
-               #"KEY2: $cmpkeys CONTENTS: @$cmpref\n"
-               
-           }
-                   
-       }
-
-    }
-
-}
-
-sub getnextchild {
-    my $rootline = shift;
-    my $lineref = shift;
-    my $tempref = $lineref->[$e_next];
-    if ($tempref == 0)  {
-       return 0;
-    }
-
-    if (($tempref->[$e_stack] > $rootline->[$e_stack]) ||
-       (($tempref->[$e_stack] <= $rootline->[$e_stack]) &&
-        ($tempref->[$e_function] == $rootline->[$e_function])
-        )){
-       # Child
-       return $tempref;
-       
-    }
-       return 0;
-       
-       
-}
-
-
-sub parse_foptions {
-    
-    my $inarg = shift;
-    my $idx = 0;
-    foreach $elem(@$inarg) {
-       next if ($elem =~ /$FILEOPTIONREGEX/);
-       $filearray[$idx] = $elem;
-       $idx++;    
-    }
-    return \@filearray;
-}
-
-1;
-#$array_parsed=parse_file();
-#print_array($array_parsed);
diff --git a/lustre/utils/load_ldap.sh b/lustre/utils/load_ldap.sh
deleted file mode 100755 (executable)
index 531d385..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-#
-# Load a lustre config xml into an openldap database.
-# See https://projects.clusterfs.com/lustre/LustreLDAP
-# for more details.
-#
-# Usage: load_ldap.sh <xml_file>
-set -e
-
-LDAP_BASE=${LDAP_BASE:-fs=lustre}
-LDAP_ROOTDN=${LDAP_ROOTDN:-cn=Manager,fs=lustre}
-LDAP_PW=${LDAP_PW:-secret}
-LDAP_AUTH="-x -D $LDAP_ROOTDN -w $LDAP_PW"
-LUSTRE=${LUSTRE:-`dirname $0`/..}
-
-[ ! -z $LDAPURL ] && LDAP_AUTH="$LDAP_AUTH -H $LDAPURL"
-
-XML=${XML:-$1}
-
-if [ -z "$XML" ] || [  ! -r $XML ]; then
-     echo "usage: $0 xmlfile"
-     exit 1
-fi
-
-NAME=`basename $XML .xml`
-LDIF=/tmp/$NAME.ldif
-
-# add the top level record, if needed
-ldapsearch $LDAP_AUTH -b $LDAP_BASE > /dev/null 2>&1 ||
-    ldapadd $LDAP_AUTH -f $LUSTRE/conf/top.ldif
-
-# If this config already exists, then delete it
-ldapsearch $LDAP_AUTH -b config=$NAME,$LDAP_BASE > /dev/null 2>&1 && 
-    ldapdelete $LDAP_AUTH -r config=$NAME,$LDAP_BASE
-
-4xslt -D config=$NAME $XML $LUSTRE/conf/lustre2ldif.xsl  > $LDIF
-
-echo "Loading config to 'config=$NAME,$LDAP_BASE' ..."
-ldapadd $LDAP_AUTH -f $LDIF
-
-rm -f $LDIF
diff --git a/lustre/utils/lstripe.c b/lustre/utils/lstripe.c
deleted file mode 100644 (file)
index 65055a5..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-
-
-/****************** Custom includes ********************/
-#include <linux/lustre_lite.h>
-#include <linux/lustre_idl.h>
-
-
-/******************  Functions ******************/
-
-void usage(char *pgm)
-{
-       fprintf(stderr, "\nIncorrect parameters!  Correct usage:\n\n" );
-       fprintf(stderr, "%s <output filename> <stripe size> <OST #> <stripe #>\n", pgm);
-
-       fprintf(stderr, "\n\nArgument explanations:\n---------------------\n\n");
-       fprintf(stderr, "<output filename> = the full name and path of the output file to create\n");
-       fprintf(stderr, "<stripe size> = the number of bytes to have in each stripe.\n");
-       fprintf(stderr, "<OST #> = the OST number to start the striping on.\n");
-       fprintf(stderr, "<stripe #> = the number of stripes to use.\n");
-
-       fprintf(stderr, "\n\nExamples:\n---------\n\n");
-
-       fprintf(stderr, "%s /mnt/lustre/ost1 131072 0 1\n", pgm);
-       fprintf(stderr, "\t\tcreates a file only on ost1.\n\n");
-
-       fprintf(stderr, "%s /mnt/lustre/ost2 131072 1 1\n", pgm);
-       fprintf(stderr, "\t\tcreates a file only on ost2.\n\n");
-
-       fprintf(stderr, "%s /mnt/lustre/ost1and2 131072 0 2\n", pgm);
-       fprintf(stderr, "\t\tcreates a 128k file with 2 stripes, on ost1 and ost2.\n");
-
-       fprintf(stderr, "%s /mnt/lustre/ost1and2 131072 1 2\n", pgm);
-       fprintf(stderr, "\t\tcreates a 128k file with 2 stripes, on ost2 and ost1.\n");
-}
-
-int create_file(char *name, long stripe_size, int stripe_offset,
-               int stripe_count)
-{
-       struct lov_mds_md a_striping;
-       int fd, result = 0;
-
-       /*  Initialize IOCTL striping pattern structure  */
-       a_striping.lmm_magic = LOV_MAGIC;
-       a_striping.lmm_stripe_pattern = 0;
-       a_striping.lmm_stripe_size = stripe_size;
-       a_striping.lmm_stripe_offset = stripe_offset;
-       a_striping.lmm_stripe_count = stripe_count;
-
-       fd = open(name, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644);
-       if (fd < 0) {
-               fprintf(stderr, "\nUnable to open '%s': %s\n",
-                       name, strerror(errno));
-               result = -errno;
-       } else if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, &a_striping)) {
-               fprintf(stderr, "\nError on ioctl for '%s' (%d): %s\n",
-                       name, fd, strerror(errno));
-               result = -errno;
-       } else if (close(fd) < 0) {
-               fprintf(stderr, "\nError on close for '%s' (%d): %s\n",
-                       name, fd, strerror(errno));
-               result = -errno;
-       }
-
-       return result;
-}
-
-int main(int argc, char *argv[])
-{
-       int result;
-       long st_size;
-       int  st_offset,
-            st_count;
-
-       /*  Check to make sure we have enough parameters  */
-       if (argc != 5) {
-               usage(argv[0]);
-               return(-1);
-       }
-
-       /* Get the stripe size */
-       st_size = atol(argv[2]);
-
-       /* Get the stripe offset*/
-       st_offset = atoi(argv[3]);
-
-       /* Get the stripe count */
-       st_count = atoi(argv[4]);
-
-       /*  Create the file, as specified.  Return and display any errors.  */
-       result = create_file(argv[1], st_size, st_offset, st_count);
-
-       return result;
-}
diff --git a/lustre/utils/obdio.c b/lustre/utils/obdio.c
deleted file mode 100644 (file)
index f79d21d..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (C) 2002 Cluster File Systems, Inc.
- *   Author: Eric Barton <eeb@clusterfs.com>
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <signal.h>
-
-#include <linux/lustre_lib.h>
-#include <linux/lustre_idl.h>
-#include <linux/lustre_dlm.h>
-#include <linux/obd_lov.h>      /* for IOC_LOV_SET_OSC_ACTIVE */
-#include <linux/obd.h>          /* for struct lov_stripe_md */
-#include <linux/obd_class.h>
-#include <linux/lustre_build_version.h>
-
-#include <unistd.h>
-#include <sys/un.h>
-#include <time.h>
-#include <sys/time.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <string.h>
-
-#include <asm/page.h>           /* needed for PAGE_SIZE - rread */
-
-#define __KERNEL__
-#include <linux/list.h>
-#undef __KERNEL__
-
-#include "obdctl.h"
-
-struct obdio_conn {
-        int                   oc_fd;
-        uint64_t               oc_conn_addr;
-        uint64_t               oc_conn_cookie;
-        struct obd_ioctl_data  oc_data;
-        char                   oc_buffer[8192];
-};
-
-char *
-obdio_alloc_aligned_buffer (char **spacep, int size) 
-{
-        int   pagesize = getpagesize();
-        char *space = malloc (size + pagesize - 1);
-        
-        *spacep = space;
-        if (space == NULL)
-                return (NULL);
-        
-        return ((char *)(((unsigned long)space + pagesize - 1) & ~(pagesize - 1)));
-}
-
-void
-obdio_iocinit (struct obdio_conn *conn)
-{
-        memset (&conn->oc_data, 0, sizeof (conn->oc_data));
-        conn->oc_data.ioc_version = OBD_IOCTL_VERSION;
-        conn->oc_data.ioc_addr = conn->oc_conn_addr;
-        conn->oc_data.ioc_cookie = conn->oc_conn_cookie;
-        conn->oc_data.ioc_len = sizeof (conn->oc_data);
-}
-
-int
-obdio_ioctl (struct obdio_conn *conn, int cmd) 
-{
-        char *buf = conn->oc_buffer;
-        int   rc;
-        int   rc2;
-        
-        rc = obd_ioctl_pack (&conn->oc_data, &buf, sizeof (conn->oc_buffer));
-        if (rc != 0) {
-                fprintf (stderr, "obd_ioctl_pack: %d (%s)\n", 
-                         rc, strerror (errno));
-                abort ();
-        }
-        
-        rc = ioctl (conn->oc_fd, cmd, buf);
-        if (rc != 0)
-                return (rc);
-        
-        rc2 = obd_ioctl_unpack (&conn->oc_data, buf, sizeof (conn->oc_buffer));
-        if (rc2 != 0) {
-                fprintf (stderr, "obd_ioctl_unpack: %d (%s)\n",
-                         rc2, strerror (errno));
-                abort ();
-        }
-        
-        return (rc);
-}
-
-struct obdio_conn *
-obdio_connect (int device)
-{
-        struct obdio_conn  *conn;
-        int                 rc;
-
-        conn = malloc (sizeof (*conn));
-        if (conn == NULL) {
-                fprintf (stderr, "obdio_connect: no memory\n");
-                return (NULL);
-        }
-        memset (conn, 0, sizeof (*conn));
-        
-       conn->oc_fd = open ("/dev/obd", O_RDWR);
-       if (conn->oc_fd < 0) {
-                fprintf (stderr, "Can't open /dev/obd: %s\n",
-                         strerror (errno));
-                goto failed;
-        }
-
-        obdio_iocinit (conn);
-        conn->oc_data.ioc_dev = device;
-        rc = obdio_ioctl (conn, OBD_IOC_DEVICE);
-        if (rc != 0) {
-                fprintf (stderr, "Can't set device %d: %s\n",
-                         device, strerror (errno));
-                goto failed;
-        }
-        
-        obdio_iocinit (conn);
-        rc = obdio_ioctl (conn, OBD_IOC_CONNECT);
-        if (rc != 0) {
-                fprintf (stderr, "Can't connect to device %d: %s\n",
-                         device, strerror (errno));
-                goto failed;
-        }
-        
-        conn->oc_conn_addr = conn->oc_data.ioc_addr;
-        conn->oc_conn_cookie = conn->oc_data.ioc_cookie;
-        return (conn);
-        
- failed:
-        free (conn);
-        return (NULL);
-}
-
-void
-obdio_disconnect (struct obdio_conn *conn) 
-{
-        close (conn->oc_fd);
-        /* obdclass will automatically close on last ref */
-        free (conn);
-}
-
-int
-obdio_open (struct obdio_conn *conn, uint64_t oid, struct lustre_handle *fh) 
-{
-        int    rc;
-        
-        obdio_iocinit (conn);
-        
-        conn->oc_data.ioc_obdo1.o_id = oid;
-        conn->oc_data.ioc_obdo1.o_mode = S_IFREG;
-        conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE;
-        
-        rc = obdio_ioctl (conn, OBD_IOC_OPEN);
-        
-        if (rc == 0)
-                obd_oa2handle (fh, &conn->oc_data.ioc_obdo1);
-
-        return (rc);
-}
-
-int
-obdio_close (struct obdio_conn *conn, uint64_t oid, struct lustre_handle *fh) 
-{
-        obdio_iocinit (conn);
-        
-
-        conn->oc_data.ioc_obdo1.o_id = oid;
-        conn->oc_data.ioc_obdo1.o_mode = S_IFREG;
-        obd_handle2oa (&conn->oc_data.ioc_obdo1, fh);
-        conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | 
-                                          OBD_MD_FLMODE | OBD_MD_FLHANDLE;
-        
-        return (obdio_ioctl (conn, OBD_IOC_CLOSE));
-}
-
-int
-obdio_pread (struct obdio_conn *conn, uint64_t oid, 
-             char *buffer, uint32_t count, uint64_t offset) 
-{
-        obdio_iocinit (conn);
-        
-        conn->oc_data.ioc_obdo1.o_id = oid;
-        conn->oc_data.ioc_obdo1.o_mode = S_IFREG;
-        conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE;
-
-        conn->oc_data.ioc_pbuf2 = buffer;
-        conn->oc_data.ioc_plen2 = count;
-        conn->oc_data.ioc_count = count;
-        conn->oc_data.ioc_offset = offset;
-
-        return (obdio_ioctl (conn, OBD_IOC_BRW_READ));
-}
-
-int
-obdio_pwrite (struct obdio_conn *conn, uint64_t oid, 
-              char *buffer, uint32_t count, uint64_t offset) 
-{
-        obdio_iocinit (conn);
-        
-        conn->oc_data.ioc_obdo1.o_id = oid;
-        conn->oc_data.ioc_obdo1.o_mode = S_IFREG;
-        conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE;
-
-        conn->oc_data.ioc_pbuf2 = buffer;
-        conn->oc_data.ioc_plen2 = count;
-        conn->oc_data.ioc_count = count;
-        conn->oc_data.ioc_offset = offset;
-
-        return (obdio_ioctl (conn, OBD_IOC_BRW_WRITE));
-}
-
-void
-obdio_test_extent (struct obdio_conn *conn, uint32_t myid, int reps,
-                   uint64_t oid, uint64_t offset, uint32_t size)
-{
-        char     *space;
-        char     *buffer = obdio_alloc_aligned_buffer (&space, size);
-        uint32_t *ibuf;
-        int       i;
-        int       j;
-        int       rc;
-        
-        if (buffer == NULL) {
-                fprintf (stderr, "Can't allocate buffer size %d\n", size);
-                abort ();
-        }
-
-        for (i = 0; i < reps; i++) {
-                ibuf = (uint32_t *) buffer;
-                for (j = 0; j < size / (4 * sizeof (*ibuf)); j++) {
-                        ibuf[0] = myid;
-                        ibuf[1] = i;
-                        ibuf[2] = j;
-                        ibuf[3] = myid;
-                        ibuf += 4;
-                }
-                
-                rc = obdio_pwrite (conn, oid, buffer, size, offset);
-                if (rc != 0) {
-                        fprintf (stderr, "Error writing "LPX64" @ "LPU64" for %u: %s\n",
-                                 oid, offset, size, strerror (errno));
-                        abort ();
-                }
-                
-                memset (buffer, 0xbb, size);
-                
-                rc = obdio_pread (conn, oid, buffer, size, offset);
-                if (rc != 0) {
-                        fprintf (stderr, "Error reading "LPX64" @ "LPU64" for %u: %s\n",
-                                 oid, offset, size, strerror (errno));
-                        abort ();
-                }
-                
-                ibuf = (uint32_t *) buffer;
-                for (j = 0; j < size / (4 * sizeof (*ibuf)); j++) {
-                        if (ibuf[0] != myid ||
-                            ibuf[1] != i ||
-                            ibuf[2] != j ||
-                            ibuf[3] != myid) {
-                                fprintf (stderr, "Error checking "LPX64" @ "LPU64" for %u, chunk %d: %s\n",
-                                         oid, offset, size, j, strerror (errno));
-                                fprintf (stderr, "Expected [%x,%x,%x,%x], got [%x,%x,%x,%x]\n",
-                                         myid, i, j, myid, ibuf[0], ibuf[1], ibuf[2], ibuf[3]);
-                                abort ();
-                        }
-                        ibuf += 4;
-                }
-        }
-}
-
-int
-parse_kmg (uint64_t *valp, char *str)
-{
-        uint64_t        val;
-        char            mod[32];
-
-        switch (sscanf (str, LPU64"%1[gGmMkK]", &val, mod))
-        {
-        default:
-                return (-1);
-
-        case 1:
-                *valp = val;
-                return (0);
-
-        case 2:
-                switch (*mod)
-                {
-                case 'g':
-                case 'G':
-                        *valp = val << 30;
-                        return (0);
-
-                case 'm':
-                case 'M':
-                        *valp = val << 20;
-                        return (0);
-
-                case 'k':
-                case 'K':
-                        *valp = val << 10;
-                        return (0);
-
-                default:
-                        *valp = val;
-                        return (0);
-                }
-        }
-}
-
-void
-usage (char *cmdname, int help) 
-{
-        char *name = strrchr (cmdname, '/');
-        
-        if (name == NULL)
-                name = cmdname;
-        
-        fprintf (help ? stdout : stderr,
-                 "usage: %s -d device -s size -o offset [-i id][-n reps] oid\n",
-                 name);
-}
-
-int
-main (int argc, char **argv) 
-{
-        struct lustre_handle fh;
-        uint32_t           myid = getpid ();
-        uint64_t           oid;
-        uint64_t           base_offset = 0;
-        int                set_base = 0;
-        uint32_t           size = 0;
-        int                set_size = 0;
-        int                device = 0;
-        int                set_device = 0;
-        int                reps = 1;
-        char              *end;
-        struct obdio_conn *conn;
-        uint64_t           val;
-        int                rc;
-        int                c;
-
-        while ((c = getopt (argc, argv, "hi:s:b:d:n:")) != -1)
-                switch (c) {
-                case 'h':
-                        usage (argv[0], 1);
-                        return (0);
-                        
-                case 'i':
-                        myid = strtol (optarg, &end, 0);
-                        if (end == optarg || *end != 0) {
-                                fprintf (stderr, "Can't parse id %s\n",
-                                         optarg);
-                                return (1);
-                        }
-                        myid = (uint32_t)val;
-                        break;
-                        
-                case 's':
-                        if (parse_kmg (&val, optarg) != 0) {
-                                fprintf (stderr, "Can't parse size %s\n",
-                                         optarg);
-                                return (1);
-                        }
-                        size = (uint32_t)val;
-                        set_size++;
-                        break;
-                        
-                case 'b':
-                        if (parse_kmg (&val, optarg) != 0) {
-                                fprintf (stderr, "Can't parse base offset %s\n",
-                                         optarg);
-                                return (1);
-                        }
-                        base_offset = val;
-                        set_base++;
-                        break;
-
-                case 'd':
-                        device = strtol (optarg, &end, 0);
-                        if (end == optarg || *end != 0) {
-                                fprintf (stderr, "Can't parse device %s\n",
-                                         optarg);
-                                return (1);
-                        }
-                        set_device++;
-                        break;
-                case 'n':
-                        if (parse_kmg (&val, optarg) != 0) {
-                                fprintf (stderr, "Can't parse reps %s\n",
-                                         optarg);
-                                return (1);
-                        }
-                        reps = (int)val;
-                        break;
-                        
-                default:
-                        usage (argv[0], 0);
-                        return (1);
-        }
-
-        if (!set_size ||
-            !set_base ||
-            !set_device ||
-            optind == argc) {
-                fprintf (stderr, "No %s specified\n",
-                         !set_size ? "size" :
-                         !set_base ? "base offset" :
-                         !set_device ? "device" : "object id");
-                return (1);
-        }
-        
-        oid = strtoull (argv[optind], &end, 0);
-        if (end == argv[optind] || *end != 0) {
-                fprintf (stderr, "Can't parse object id %s\n",
-                         argv[optind]);
-                return (1);
-        }
-        
-        conn = obdio_connect (device);
-        if (conn == NULL)
-                return (1);
-        
-        rc = obdio_open (conn, oid, &fh);
-        if (rc != 0) {
-                fprintf (stderr, "Failed to open object "LPX64": %s\n",
-                         oid, strerror (errno));
-                return (1);
-        }
-        
-        obdio_test_extent (conn, myid, reps, oid, base_offset, size);
-        
-        rc = obdio_close (conn, oid, &fh);
-        if (rc != 0) {
-                fprintf (stderr, "Error closing object "LPX64": %s\n",
-                         oid, strerror (errno));
-                return (1);
-        }
-
-        obdio_disconnect (conn);
-        return (0);
-}
-
-
diff --git a/lustre/utils/obdstat.c b/lustre/utils/obdstat.c
deleted file mode 100644 (file)
index b66fcc3..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-struct one_stat {
-       char       *name;
-        int         fd;
-       long long   current;
-       long long   delta;
-};
-
-struct one_stat *read_bytes;
-struct one_stat *read_reqs;
-struct one_stat *write_bytes;
-struct one_stat *write_reqs;
-struct one_stat *getattr_reqs;
-struct one_stat *setattr_reqs;
-struct one_stat *create_reqs;
-struct one_stat *destroy_reqs;
-struct one_stat *statfs_reqs;
-struct one_stat *open_reqs;
-struct one_stat *close_reqs;
-struct one_stat *punch_reqs;
-
-struct one_stat *
-init_one_stat (char *basename, char *name) 
-{
-       char             fname[1024];
-       struct one_stat *stat = (struct one_stat *)malloc (sizeof (*stat));
-       
-       if (stat == NULL) {
-               fprintf (stderr, "Can't allocate stat %s: %s\n", 
-                        name, strerror (errno));
-               abort ();
-       }
-
-       snprintf (fname, sizeof (fname), "%s/%s", basename, name);
-
-       memset (stat, 0, sizeof (*stat));
-       stat->name = name;
-
-       stat->fd = open (fname, O_RDONLY);
-       if (stat->fd < 0 ) {
-               fprintf (stderr, "Can't open stat %s: %s\n", 
-                        fname, strerror (errno));
-               abort ();
-       }
-
-       return (stat);
-}
-
-void
-update_one_stat (struct one_stat *stat) 
-{
-        static char buffer[1024];
-       long long prev = stat->current;
-       int  nob;
-
-       lseek (stat->fd, 0, SEEK_SET);
-       nob = read (stat->fd, buffer, sizeof (buffer) - 1);
-       if (nob < 0) {
-               fprintf (stderr, "Can't read stat %s: %s\n",
-                        stat->name, strerror (errno));
-               abort ();
-       }
-       
-       buffer[nob] = 0;
-       if (sscanf (buffer, "%Ld", &stat->current) != 1) {
-               fprintf (stderr, "Can't parse stat %s: %s\n",
-                        stat->name, strerror (errno));
-               abort ();
-       }
-
-       stat->delta = stat->current - prev;
-}
-
-double
-timenow ()
-{
-       struct timeval tv;
-   
-       gettimeofday (&tv, NULL);
-       return (tv.tv_sec + tv.tv_usec / 1000000.0);
-}
-
-void
-do_stat (void)
-{
-       static double last = 0.0;
-       double now;
-       double t;
-   
-       now = timenow();
-
-       update_one_stat (read_bytes);
-       update_one_stat (read_reqs);
-       update_one_stat (write_bytes);
-       update_one_stat (write_reqs);
-       update_one_stat (getattr_reqs);
-       update_one_stat (setattr_reqs);
-       update_one_stat (open_reqs);
-       update_one_stat (close_reqs);
-       update_one_stat (create_reqs);
-       update_one_stat (destroy_reqs);
-       update_one_stat (statfs_reqs);
-       update_one_stat (punch_reqs);
-       
-       if (last == 0.0) {
-               printf ("R %Ld/%Ld W %Ld/%Ld attr %Ld/%Ld open %Ld/%Ld create %Ld/%Ld stat %Ld punch %Ld\n",
-                       read_bytes->current, read_reqs->current,
-                       write_bytes->current, write_reqs->current,
-                       getattr_reqs->current, setattr_reqs->current,
-                       open_reqs->current, close_reqs->current,
-                       create_reqs->current, destroy_reqs->current,
-                       statfs_reqs->current, punch_reqs->current);
-       } else {
-               t = now - last;
-
-               printf ("R %7Ld (%6d/s %7.2fMb/s) W %7Ld (%6d/s %7.2fMb/s)",
-                       read_reqs->delta, (int)(read_reqs->delta / t),
-                       read_bytes->delta / ((1<<20) * t),
-                       write_reqs->delta, (int)(write_reqs->delta / t),
-                       write_bytes->delta / ((1<<20) * t));
-               
-               if (getattr_reqs->delta != 0)
-                       printf (" ga:%Ld", getattr_reqs->delta);
-               
-               if (setattr_reqs->delta != 0)
-                       printf (" sa:%Ld", setattr_reqs->delta);
-
-               if (open_reqs->delta != 0)
-                       printf (" op:%Ld", open_reqs->delta);
-               
-               if (close_reqs->delta != 0)
-                       printf (" cl:%Ld", close_reqs->delta);
-
-               if (create_reqs->delta != 0)
-                       printf (" cx:%Ld", create_reqs->delta);
-               
-               if (destroy_reqs->delta != 0)
-                       printf (" dx:%Ld", destroy_reqs->delta);
-
-               if (statfs_reqs->delta != 0)
-                       printf (" st:%Ld", statfs_reqs->delta);
-               
-               if (punch_reqs->delta != 0)
-                       printf (" pu:%Ld", punch_reqs->delta);
-               
-               printf ("\n");
-       }
-
-       last = timenow();
-}
-
-int main (int argc, char **argv)
-{
-       char *basedir = "/proc/sys/obdfilter";
-       int  interval = 0;
-   
-       if (argc > 1)
-               interval = atoi (argv[1]);
-
-       read_bytes = init_one_stat (basedir, "read_bytes");
-       read_reqs = init_one_stat (basedir, "read_reqs");
-       write_bytes = init_one_stat (basedir, "write_bytes");
-       write_reqs = init_one_stat (basedir, "write_reqs");
-       getattr_reqs = init_one_stat (basedir, "getattr_reqs");
-       setattr_reqs = init_one_stat (basedir, "setattr_reqs");
-       create_reqs = init_one_stat (basedir, "create_reqs");
-       destroy_reqs = init_one_stat (basedir, "destroy_reqs");
-       statfs_reqs = init_one_stat (basedir, "statfs_reqs");
-       open_reqs = init_one_stat (basedir, "open_reqs");
-       close_reqs = init_one_stat (basedir, "close_reqs");
-       punch_reqs = init_one_stat (basedir, "punch_reqs");
-
-       do_stat ();
-
-       if (interval == 0)
-               return (0);
-   
-       for (;;) {
-               sleep (interval);
-               do_stat ();
-       }
-}