From 46d4b6b414ef0829ada755daf18d8bd45c16dfaf Mon Sep 17 00:00:00 2001 From: nathan Date: Tue, 22 Mar 2005 00:27:22 +0000 Subject: [PATCH] b=4834 Land b_release_1_4_1 onto b1_4 (20050321_1527) --- .../patches/ext3-extents-2.6.5.patch | 418 +- .../patches/ext3-extents-2.6.9-rhel4.patch | 507 +- .../patches/ext3-mballoc2-2.6-suse.patch | 292 +- .../patches/ext3-mballoc2-2.6.9-rhel4.patch | 169 +- lustre/ChangeLog | 7 + lustre/autoconf/lustre-core.m4 | 26 +- lustre/autoconf/lustre-version.ac | 2 +- lustre/conf/modules.conf | 2 + lustre/include/liblustre.h | 3 +- lustre/include/linux/lprocfs_status.h | 2 + lustre/include/linux/lustre_dlm.h | 15 +- lustre/include/linux/lustre_fsfilt.h | 21 +- lustre/include/linux/lustre_idl.h | 11 +- lustre/include/linux/lustre_import.h | 4 +- lustre/include/linux/lustre_lib.h | 2 +- lustre/include/linux/lustre_lite.h | 76 - lustre/include/linux/lustre_mds.h | 2 +- lustre/include/linux/lustre_net.h | 8 +- lustre/include/linux/obd.h | 11 +- lustre/include/linux/obd_class.h | 39 +- lustre/include/linux/obd_support.h | 54 +- .../kernel-2.6.9-2.6-rhel4-i686-smp.config | 2740 ++++++++++ .../kernel-2.6.9-2.6-rhel4-i686.config | 2735 ++++++++++ .../kernel-2.6.9-2.6-rhel4-ia64-smp.config | 1908 +++++++ .../kernel-2.6.9-2.6-rhel4-ia64.config | 1908 +++++++ .../kernel-2.6.9-2.6-rhel4-x86_64-smp.config | 2632 ++++++++++ .../kernel-2.6.9-2.6-rhel4-x86_64.config | 2633 ++++++++++ .../patches/configurable-x86-stack-2.4.20-rh.patch | 311 -- .../patches/configurable-x86-stack-2.4.22-rh.patch | 311 -- .../patches/dev_read_only-2.6-lnxi.patch | 150 + .../patches/dev_read_only-2.6-suse.patch | 140 +- .../patches/dev_read_only_2.4.20-rh.patch | 110 +- .../patches/dev_read_only_2.4.21-chaos.patch | 144 +- .../patches/dev_read_only_hp_2.4.20.patch | 77 - lustre/kernel_patches/patches/dsp.patch | 142 - .../patches/dynamic-locks-2.4.20-rh.patch | 217 - lustre/kernel_patches/patches/exports.patch | 57 - .../patches/ext3-delete_thread-suse.patch | 496 -- .../patches/ext3-ea-in-inode-2.4.21-suse2.patch | 760 +++ .../patches/ext3-extents-2.4.20-rh.patch | 2807 ---------- .../patches/ext3-extents-2.4.21-chaos.patch | 546 +- .../patches/ext3-extents-2.4.21-suse2.patch | 476 +- .../patches/ext3-extents-2.4.24.patch | 471 +- .../patches/ext3-extents-2.6.5.patch | 418 +- .../patches/ext3-extents-2.6.9-rhel4.patch | 507 +- .../patches/ext3-extents-asyncdel-2.4.20-rh.patch | 29 - .../ext3-extents-asyncdel-2.4.21-chaos.patch | 8 +- .../patches/ext3-extents-asyncdel-2.4.24.patch | 2 +- .../kernel_patches/patches/ext3-htree-suse.patch | 2557 --------- .../patches/ext3-init-generation-2.6-suse.patch | 12 - .../patches/ext3-mballoc2-2.6-suse.patch | 292 +- .../patches/ext3-mballoc2-2.6.7.patch | 1750 ------- .../patches/ext3-mballoc2-2.6.9-rhel4.patch | 169 +- .../patches/ext3-o_direct-1.2.4.20-rh.patch | 197 - .../patches/ext3-orphan_lock-suse.patch | 81 - .../patches/ext3-pdirops-2.4.20-rh.patch | 1248 ----- .../patches/ext3_delete_thread_2.4.20_chaos.patch | 500 -- .../patches/ext3_orphan_lock-2.4.20-rh.patch | 82 - .../patches/extN-wantedi-2.4.22-rh.patch | 217 - .../patches/gpl_header-chaos-2.4.20.patch | 11 - .../patches/iod-rmap-exports-2.4.20.patch | 86 - .../patches/iod-stock-24-exports.patch | 48 - .../patches/iod-stock-exports-2.4.22-rh.patch | 48 - .../kernel_text_address-2.4.21-suse-171.patch | 116 - .../patches/linux-2.4.20-xattr-0.8.54-chaos.patch | 5531 -------------------- .../patches/linux-2.4.21-xattr-0.8.54-suse.patch | 5349 ------------------- lustre/kernel_patches/patches/lustre_version.patch | 3 +- .../patches/netconsole-2.4.20-rh.patch | 469 -- .../patches/nfs_export_kernel-2.4.20-rh.patch | 739 --- .../patches/nfs_export_kernel-2.4.20.patch | 735 --- .../patches/nfs_export_kernel-2.4.22-rh.patch | 737 --- lustre/kernel_patches/patches/revert-76chaos.patch | 289 - .../patches/sd_iostats-2.6-rhel4.patch | 457 ++ .../patches/socket-exports-2.4.22-rh.patch | 41 - .../patches/tcp_zero_copy_2.4.20_chaos.patch | 476 -- .../patches/vfs-pdirops-2.4.20-rh.patch | 269 - .../patches/vfs_intent-2.4.20-rh.patch | 1880 ------- .../patches/vfs_intent-2.4.21-chaos.patch | 1870 ------- .../patches/vfs_intent-2.4.22-rh.patch | 1829 ------- .../patches/vfs_intent-2.6-rhel4.patch | 2 +- lustre/kernel_patches/patches/x86-fpu-crash.patch | 36 - .../patches/xattr-0.8.54-2.4.22-rh.patch | 5396 ------------------- lustre/kernel_patches/series/2.6-rhel4.series | 1 + lustre/kernel_patches/series/2.6-suse-lnxi.series | 1 + lustre/kernel_patches/series/2.6-vanilla.series | 15 - lustre/kernel_patches/series/hp-pnnl-2.4.20 | 3 +- .../series/ldiskfs-2.6-vanilla.series | 11 - lustre/kernel_patches/series/rh-2.4.20 | 53 - lustre/kernel_patches/series/rh-2.4.22 | 30 - lustre/kernel_patches/series/suse-2.4.19 | 35 - lustre/kernel_patches/series/suse-2.4.21 | 32 - .../series/{suse-2.4.21-2 => suse-2.4.21-cray} | 2 +- lustre/kernel_patches/series/vanilla-2.4.24 | 1 - lustre/kernel_patches/targets/2.6-rhel4.target.in | 24 + lustre/kernel_patches/which_patch | 13 +- lustre/ldlm/ldlm_lib.c | 30 +- lustre/ldlm/ldlm_lockd.c | 19 +- lustre/ldlm/ldlm_resource.c | 68 +- lustre/liblustre/llite_lib.c | 64 +- lustre/liblustre/super.c | 8 +- lustre/llite/dcache.c | 8 +- lustre/llite/llite_internal.h | 77 + lustre/llite/llite_lib.c | 30 +- lustre/llite/rw.c | 11 +- lustre/lov/lov_log.c | 28 +- lustre/lov/lov_obd.c | 16 +- lustre/lvfs/fsfilt_ext3.c | 28 +- lustre/mdc/mdc_request.c | 10 +- lustre/mds/handler.c | 68 +- lustre/mds/mds_fs.c | 23 +- lustre/mds/mds_internal.h | 4 +- lustre/mds/mds_log.c | 20 +- lustre/mds/mds_lov.c | 79 +- lustre/mds/mds_open.c | 29 +- lustre/obdclass/class_obd.c | 6 +- lustre/obdclass/genops.c | 28 +- lustre/obdclass/llog_obd.c | 30 +- lustre/obdclass/llog_test.c | 6 +- lustre/obdclass/lprocfs_status.c | 10 + lustre/obdclass/obd_config.c | 167 +- lustre/obdclass/sysctl.c | 32 +- lustre/obdecho/echo.c | 12 +- lustre/obdecho/echo_client.c | 8 +- lustre/obdfilter/filter.c | 89 +- lustre/osc/osc_request.c | 37 +- lustre/ost/ost_handler.c | 2 +- lustre/ptlrpc/client.c | 5 +- lustre/ptlrpc/niobuf.c | 20 +- lustre/ptlrpc/pinger.c | 57 +- lustre/ptlrpc/recover.c | 2 +- lustre/ptlrpc/service.c | 10 + lustre/tests/Makefile.am | 2 +- lustre/tests/Makefile.mk | 5 +- lustre/tests/cfg/insanity-local.sh | 2 +- lustre/tests/local.sh | 16 +- lustre/tests/lov.sh | 16 +- lustre/tests/recovery-small.sh | 89 +- lustre/tests/replay-dual.sh | 3 +- lustre/tests/sanity.sh | 8 +- lustre/tests/sanityN.sh | 2 +- lustre/tests/test-framework.sh | 31 +- lustre/tests/uml.sh | 12 +- lustre/tests/writemany.c | 250 + lustre/utils/lconf | 8 +- 144 files changed, 19800 insertions(+), 39934 deletions(-) create mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-i686-smp.config create mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-i686.config create mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-ia64-smp.config create mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-ia64.config create mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-x86_64-smp.config create mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-x86_64.config delete mode 100644 lustre/kernel_patches/patches/configurable-x86-stack-2.4.20-rh.patch delete mode 100644 lustre/kernel_patches/patches/configurable-x86-stack-2.4.22-rh.patch create mode 100644 lustre/kernel_patches/patches/dev_read_only-2.6-lnxi.patch delete mode 100644 lustre/kernel_patches/patches/dev_read_only_hp_2.4.20.patch delete mode 100644 lustre/kernel_patches/patches/dsp.patch delete mode 100644 lustre/kernel_patches/patches/dynamic-locks-2.4.20-rh.patch delete mode 100644 lustre/kernel_patches/patches/exports.patch delete mode 100644 lustre/kernel_patches/patches/ext3-delete_thread-suse.patch create mode 100644 lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.21-suse2.patch delete mode 100644 lustre/kernel_patches/patches/ext3-extents-2.4.20-rh.patch delete mode 100644 lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.20-rh.patch delete mode 100644 lustre/kernel_patches/patches/ext3-htree-suse.patch delete mode 100644 lustre/kernel_patches/patches/ext3-init-generation-2.6-suse.patch delete mode 100644 lustre/kernel_patches/patches/ext3-mballoc2-2.6.7.patch delete mode 100644 lustre/kernel_patches/patches/ext3-o_direct-1.2.4.20-rh.patch delete mode 100644 lustre/kernel_patches/patches/ext3-orphan_lock-suse.patch delete mode 100644 lustre/kernel_patches/patches/ext3-pdirops-2.4.20-rh.patch delete mode 100644 lustre/kernel_patches/patches/ext3_delete_thread_2.4.20_chaos.patch delete mode 100644 lustre/kernel_patches/patches/ext3_orphan_lock-2.4.20-rh.patch delete mode 100644 lustre/kernel_patches/patches/extN-wantedi-2.4.22-rh.patch delete mode 100644 lustre/kernel_patches/patches/gpl_header-chaos-2.4.20.patch delete mode 100644 lustre/kernel_patches/patches/iod-rmap-exports-2.4.20.patch delete mode 100644 lustre/kernel_patches/patches/iod-stock-24-exports.patch delete mode 100644 lustre/kernel_patches/patches/iod-stock-exports-2.4.22-rh.patch delete mode 100644 lustre/kernel_patches/patches/kernel_text_address-2.4.21-suse-171.patch delete mode 100644 lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-chaos.patch delete mode 100644 lustre/kernel_patches/patches/linux-2.4.21-xattr-0.8.54-suse.patch delete mode 100644 lustre/kernel_patches/patches/netconsole-2.4.20-rh.patch delete mode 100644 lustre/kernel_patches/patches/nfs_export_kernel-2.4.20-rh.patch delete mode 100644 lustre/kernel_patches/patches/nfs_export_kernel-2.4.20.patch delete mode 100644 lustre/kernel_patches/patches/nfs_export_kernel-2.4.22-rh.patch delete mode 100644 lustre/kernel_patches/patches/revert-76chaos.patch create mode 100644 lustre/kernel_patches/patches/sd_iostats-2.6-rhel4.patch delete mode 100644 lustre/kernel_patches/patches/socket-exports-2.4.22-rh.patch delete mode 100644 lustre/kernel_patches/patches/tcp_zero_copy_2.4.20_chaos.patch delete mode 100644 lustre/kernel_patches/patches/vfs-pdirops-2.4.20-rh.patch delete mode 100644 lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch delete mode 100644 lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch delete mode 100644 lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch delete mode 100644 lustre/kernel_patches/patches/x86-fpu-crash.patch delete mode 100644 lustre/kernel_patches/patches/xattr-0.8.54-2.4.22-rh.patch delete mode 100644 lustre/kernel_patches/series/2.6-vanilla.series delete mode 100644 lustre/kernel_patches/series/ldiskfs-2.6-vanilla.series delete mode 100644 lustre/kernel_patches/series/rh-2.4.20 delete mode 100644 lustre/kernel_patches/series/rh-2.4.22 delete mode 100644 lustre/kernel_patches/series/suse-2.4.19 delete mode 100644 lustre/kernel_patches/series/suse-2.4.21 rename lustre/kernel_patches/series/{suse-2.4.21-2 => suse-2.4.21-cray} (96%) create mode 100644 lustre/kernel_patches/targets/2.6-rhel4.target.in create mode 100644 lustre/tests/writemany.c diff --git a/ldiskfs/kernel_patches/patches/ext3-extents-2.6.5.patch b/ldiskfs/kernel_patches/patches/ext3-extents-2.6.5.patch index 671fbc0..053c0fb 100644 --- a/ldiskfs/kernel_patches/patches/ext3-extents-2.6.5.patch +++ b/ldiskfs/kernel_patches/patches/ext3-extents-2.6.5.patch @@ -3,9 +3,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c =================================================================== --- linux-2.6.5-sles9.orig/fs/ext3/extents.c 2005-02-17 22:07:57.023609040 +0300 +++ linux-2.6.5-sles9/fs/ext3/extents.c 2005-02-23 01:02:37.396435640 +0300 -@@ -0,0 +1,2356 @@ +@@ -0,0 +1,2349 @@ +/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com ++ * Copyright(c) 2003, 2004, 2005, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify @@ -54,17 +54,17 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +{ + if (eh->eh_magic != EXT3_EXT_MAGIC) { + printk(KERN_ERR "EXT3-fs: invalid magic = 0x%x\n", -+ (unsigned) eh->eh_magic); ++ (unsigned)eh->eh_magic); + return -EIO; + } + if (eh->eh_max == 0) { + printk(KERN_ERR "EXT3-fs: invalid eh_max = %u\n", -+ (unsigned) eh->eh_max); ++ (unsigned)eh->eh_max); + return -EIO; + } + if (eh->eh_entries > eh->eh_max) { + printk(KERN_ERR "EXT3-fs: invalid eh_entries = %u\n", -+ (unsigned) eh->eh_entries); ++ (unsigned)eh->eh_entries); + return -EIO; + } + return 0; @@ -107,8 +107,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * - ENOMEM + */ +static int ext3_ext_get_access(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path) +{ + int err; + @@ -129,7 +129,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * - EIO + */ +static int ext3_ext_dirty(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int err; + if (path->p_bh) { @@ -144,8 +144,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int inline +ext3_ext_new_block(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, struct ext3_extent *ex, -+ int *err) ++ struct ext3_ext_path *path, struct ext3_extent *ex, ++ int *err) +{ + int goal, depth, newblock; + struct inode *inode; @@ -164,7 +164,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + unsigned long colour; + + bg_start = (ei->i_block_group * -+ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + ++ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + + le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); + colour = (current->pid % 16) * + (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); @@ -187,8 +187,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 6; +#endif @@ -200,8 +200,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 5; +#endif @@ -212,8 +212,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 3; +#endif @@ -224,9 +224,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 4; +#endif @@ -234,7 +233,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +static void ext3_ext_show_path(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int k, l = path->p_depth; @@ -243,12 +242,12 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + for (k = 0; k <= l; k++, path++) { + if (path->p_idx) { + ext_debug(tree, " %d->%d", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + } else if (path->p_ext) { + ext_debug(tree, " %d:%d:%d", -+ path->p_ext->ee_block, -+ path->p_ext->ee_len, -+ path->p_ext->ee_start); ++ path->p_ext->ee_block, ++ path->p_ext->ee_len, ++ path->p_ext->ee_start); + } else + ext_debug(tree, " []"); + } @@ -257,7 +256,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +static void ext3_ext_show_leaf(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int depth = EXT_DEPTH(tree); @@ -273,7 +272,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + + for (i = 0; i < eh->eh_entries; i++, ex++) { + ext_debug(tree, "%d:%d:%d ", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + } + ext_debug(tree, "\n"); +#endif @@ -284,11 +283,12 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + int depth = path->p_depth; + int i; + -+ for (i = 0; i <= depth; i++, path++) ++ for (i = 0; i <= depth; i++, path++) { + if (path->p_bh) { + brelse(path->p_bh); + path->p_bh = NULL; + } ++ } +} + +/* @@ -296,7 +296,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch_idx(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent_idx *ix; @@ -322,7 +322,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + + ix += l; + path->p_idx = ix; -+ ext_debug(tree, " -> %d->%d ", path->p_idx->ei_block, path->p_idx->ei_leaf); ++ ext_debug(tree," -> %d->%d ",path->p_idx->ei_block,path->p_idx->ei_leaf); + + while (l++ < r) { + if (block < ix->ei_block) @@ -330,7 +330,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + path->p_idx = ix++; + } + ext_debug(tree, " -> %d->%d\n", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + +#ifdef CHECK_BINSEARCH + { @@ -340,9 +340,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + for (k = 0; k < eh->eh_entries; k++, ix++) { + if (k != 0 && ix->ei_block <= ix[-1].ei_block) { + printk("k=%d, ix=0x%p, first=0x%p\n", k, -+ ix, EXT_FIRST_INDEX(eh)); ++ ix, EXT_FIRST_INDEX(eh)); + printk("%u <= %u\n", -+ ix->ei_block,ix[-1].ei_block); ++ ix->ei_block,ix[-1].ei_block); + } + EXT_ASSERT(k == 0 || ix->ei_block > ix[-1].ei_block); + if (block < ix->ei_block) @@ -352,7 +352,6 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + EXT_ASSERT(chix == path->p_idx); + } +#endif -+ +} + +/* @@ -360,7 +359,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent *ex; @@ -394,7 +393,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + ex += l; + path->p_ext = ex; + ext_debug(tree, " -> %d:%d:%d ", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + + while (l++ < r) { + if (block < ex->ee_block) @@ -402,7 +401,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + path->p_ext = ex++; + } + ext_debug(tree, " -> %d:%d:%d\n", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + +#ifdef CHECK_BINSEARCH + { @@ -418,7 +417,6 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + EXT_ASSERT(chex == path->p_ext); + } +#endif -+ +} + +int ext3_extent_tree_init(handle_t *handle, struct ext3_extents_tree *tree) @@ -439,7 +437,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +struct ext3_ext_path * +ext3_ext_find_extent(struct ext3_extents_tree *tree, int block, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + struct buffer_head *bh; @@ -461,7 +459,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* account possible depth increase */ + if (!path) { + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2), -+ GFP_NOFS); ++ GFP_NOFS); + if (!path) + return ERR_PTR(-ENOMEM); + } @@ -471,7 +469,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* walk through the tree */ + while (i) { + ext_debug(tree, "depth %d: num %d, max %d\n", -+ ppos, eh->eh_entries, eh->eh_max); ++ ppos, eh->eh_entries, eh->eh_max); + ext3_ext_binsearch_idx(tree, path + ppos, block); + path[ppos].p_block = path[ppos].p_idx->ei_leaf; + path[ppos].p_depth = i; @@ -519,9 +517,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * it check where to insert: before curp or after curp + */ +static int ext3_ext_insert_index(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *curp, -+ int logical, int ptr) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *curp, ++ int logical, int ptr) +{ + struct ext3_extent_idx *ix; + int len, err; @@ -537,9 +535,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d after: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ (curp->p_idx + 1), (curp->p_idx + 2)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ (curp->p_idx + 1), (curp->p_idx + 2)); + memmove(curp->p_idx + 2, curp->p_idx + 1, len); + } + ix = curp->p_idx + 1; @@ -548,9 +546,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + len = len * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d before: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ curp->p_idx, (curp->p_idx + 1)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ curp->p_idx, (curp->p_idx + 1)); + memmove(curp->p_idx + 1, curp->p_idx, len); + ix = curp->p_idx; + } @@ -578,8 +576,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * - initialize subtree + */ +static int ext3_ext_split(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext, int at) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext, int at) +{ + struct buffer_head *bh = NULL; + int depth = EXT_DEPTH(tree); @@ -600,13 +598,13 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) { + border = path[depth].p_ext[1].ee_block; + ext_debug(tree, "leaf will be splitted." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } else { + border = newext->ee_block; + ext_debug(tree, "leaf will be added." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } + + /* @@ -664,12 +662,11 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + while (path[depth].p_ext <= + EXT_MAX_EXTENT(path[depth].p_hdr)) { + ext_debug(tree, "move %d:%d:%d in new leaf %lu\n", -+ path[depth].p_ext->ee_block, -+ path[depth].p_ext->ee_start, -+ path[depth].p_ext->ee_len, -+ newblock); -+ memmove(ex++, path[depth].p_ext++, -+ sizeof(struct ext3_extent)); ++ path[depth].p_ext->ee_block, ++ path[depth].p_ext->ee_start, ++ path[depth].p_ext->ee_len, ++ newblock); ++ memmove(ex++, path[depth].p_ext++, sizeof(struct ext3_extent)); + neh->eh_entries++; + m++; + } @@ -722,21 +719,21 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + fidx->ei_leaf = oldblock; + + ext_debug(tree, "int.index at %d (block %lu): %lu -> %lu\n", -+ i, newblock, border, oldblock); ++ i, newblock, border, oldblock); + /* copy indexes */ + m = 0; + path[i].p_idx++; + + ext_debug(tree, "cur 0x%p, last 0x%p\n", path[i].p_idx, -+ EXT_MAX_INDEX(path[i].p_hdr)); ++ EXT_MAX_INDEX(path[i].p_hdr)); + EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) == -+ EXT_LAST_INDEX(path[i].p_hdr)); ++ EXT_LAST_INDEX(path[i].p_hdr)); + while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { + ext_debug(tree, "%d: move %d:%d in new index %lu\n", -+ i, path[i].p_idx->ei_block, -+ path[i].p_idx->ei_leaf, newblock); ++ i, path[i].p_idx->ei_block, ++ path[i].p_idx->ei_leaf, newblock); + memmove(++fidx, path[i].p_idx++, -+ sizeof(struct ext3_extent_idx)); ++ sizeof(struct ext3_extent_idx)); + neh->eh_entries++; + EXT_ASSERT(neh->eh_entries <= neh->eh_max); + m++; @@ -766,7 +763,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* insert new index */ + if (!err) + err = ext3_ext_insert_index(handle, tree, path + at, -+ border, newblock); ++ border, newblock); + +cleanup: + if (bh) { @@ -796,9 +793,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * just created block + */ +static int ext3_ext_grow_indepth(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp = path; + struct ext3_extent_header *neh; @@ -830,7 +827,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* set size of new block */ + neh = EXT_BLOCK_HDR(bh); + /* old root could have indexes or leaves -+ * so calculate e_max right way */ ++ * so calculate eh_max right way */ + if (EXT_DEPTH(tree)) + neh->eh_max = ext3_ext_space_block_idx(tree); + else @@ -857,7 +854,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + neh = EXT_ROOT_HDR(tree); + fidx = EXT_FIRST_INDEX(neh); + ext_debug(tree, "new root: num %d(%d), lblock %d, ptr %d\n", -+ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); ++ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); + + neh->eh_depth = path->p_depth + 1; + err = ext3_ext_dirty(handle, tree, curp); @@ -872,9 +869,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * then it requests in-depth growing + */ +static int ext3_ext_create_new_leaf(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp; + int depth, i, err = 0; @@ -950,12 +947,12 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if (depth == path->p_depth) { + /* leaf */ + if (path[depth].p_ext != -+ EXT_LAST_EXTENT(path[depth].p_hdr)) ++ EXT_LAST_EXTENT(path[depth].p_hdr)) + return path[depth].p_ext[1].ee_block; + } else { + /* index */ + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + } + depth--; @@ -968,7 +965,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * returns first allocated block from next leaf or EXT_MAX_BLOCK + */ +static unsigned ext3_ext_next_leaf_block(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth; + @@ -984,7 +981,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + + while (depth >= 0) { + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + depth--; + } @@ -998,7 +995,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * TODO: do we need to correct tree in all cases? + */ +int ext3_ext_correct_indexes(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + int depth = EXT_DEPTH(tree); @@ -1048,8 +1045,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int inline +ext3_can_extents_be_merged(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex1, ++ struct ext3_extent *ex2) +{ + if (ex1->ee_block + ex1->ee_len != ex2->ee_block) + return 0; @@ -1071,8 +1068,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * creating new leaf in no-space case + */ +int ext3_ext_insert_extent(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_extent_header * eh; + struct ext3_extent *ex, *fex; @@ -1088,8 +1085,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* try to insert block into found extent and return */ + if (ex && ext3_can_extents_be_merged(tree, ex, newext)) { + ext_debug(tree, "append %d block to %d:%d (from %d)\n", -+ newext->ee_len, ex->ee_block, ex->ee_len, -+ ex->ee_start); ++ newext->ee_len, ex->ee_block, ex->ee_len, ++ ex->ee_start); + if ((err = ext3_ext_get_access(handle, tree, path + depth))) + return err; + ex->ee_len += newext->ee_len; @@ -1117,12 +1114,12 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + eh = npath[depth].p_hdr; + if (eh->eh_entries < eh->eh_max) { + ext_debug(tree, "next leaf isnt full(%d)\n", -+ eh->eh_entries); ++ eh->eh_entries); + path = npath; + goto repeat; + } + ext_debug(tree, "next leaf hasno free space(%d,%d)\n", -+ eh->eh_entries, eh->eh_max); ++ eh->eh_entries, eh->eh_max); + } + + /* @@ -1144,8 +1141,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if (!nearex) { + /* there is no extent in this leaf, create first one */ + ext_debug(tree, "first extent in the leaf: %d:%d:%d\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len); ++ newext->ee_block, newext->ee_start, ++ newext->ee_len); + path[depth].p_ext = EXT_FIRST_EXTENT(eh); + } else if (newext->ee_block > nearex->ee_block) { + EXT_ASSERT(newext->ee_block != nearex->ee_block); @@ -1154,10 +1151,10 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d after: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, ++ newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 2, nearex + 1, len); + } + path[depth].p_ext = nearex + 1; @@ -1166,9 +1163,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d before: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 1, nearex, len); + path[depth].p_ext = nearex; + } @@ -1189,8 +1186,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* merge with next extent! */ + nearex->ee_len += nearex[1].ee_len; + if (nearex + 1 < EXT_LAST_EXTENT(eh)) { -+ len = (EXT_LAST_EXTENT(eh) - nearex - 1) -+ * sizeof(struct ext3_extent); ++ len = (EXT_LAST_EXTENT(eh) - nearex - 1) * ++ sizeof(struct ext3_extent); + memmove(nearex + 1, nearex + 2, len); + } + eh->eh_entries--; @@ -1324,7 +1321,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static inline void +ext3_ext_put_in_cache(struct ext3_extents_tree *tree, __u32 block, -+ __u32 len, __u32 start, int type) ++ __u32 len, __u32 start, int type) +{ + EXT_ASSERT(len > 0); + if (tree->cex) { @@ -1341,8 +1338,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + */ +static inline void +ext3_ext_put_gap_in_cache(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ unsigned long block) ++ struct ext3_ext_path *path, ++ unsigned long block) +{ + int depth = EXT_DEPTH(tree); + unsigned long lblock, len; @@ -1361,16 +1358,16 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + lblock = block; + len = ex->ee_block - block; + ext_debug(tree, "cache gap(before): %lu [%lu:%lu]", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len); + } else if (block >= ex->ee_block + ex->ee_len) { + lblock = ex->ee_block + ex->ee_len; + len = ext3_ext_next_allocated_block(path); + ext_debug(tree, "cache gap(after): [%lu:%lu] %lu", -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) block); ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) block); + EXT_ASSERT(len > lblock); + len = len - lblock; + } else { @@ -1384,7 +1381,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static inline int +ext3_ext_in_cache(struct ext3_extents_tree *tree, unsigned long block, -+ struct ext3_extent *ex) ++ struct ext3_extent *ex) +{ + struct ext3_ext_cache *cex = tree->cex; + @@ -1397,16 +1394,16 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + return EXT3_EXT_CACHE_NO; + + EXT_ASSERT(cex->ec_type == EXT3_EXT_CACHE_GAP || -+ cex->ec_type == EXT3_EXT_CACHE_EXTENT); ++ cex->ec_type == EXT3_EXT_CACHE_EXTENT); + if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) { + ex->ee_block = cex->ec_block; + ex->ee_start = cex->ec_start; + ex->ee_len = cex->ec_len; + ext_debug(tree, "%lu cached by %lu:%lu:%lu\n", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) ex->ee_start); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) ex->ee_start); + return cex->ec_type; + } + @@ -1420,7 +1417,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * last index in the block only + */ +int ext3_ext_rm_idx(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct buffer_head *bh; + int err; @@ -1434,7 +1431,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if ((err = ext3_ext_dirty(handle, tree, path))) + return err; + ext_debug(tree, "index is empty, remove it, free block %d\n", -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + bh = sb_find_get_block(tree->inode->i_sb, path->p_idx->ei_leaf); + ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf); + ext3_free_blocks(handle, tree->inode, path->p_idx->ei_leaf, 1); @@ -1442,7 +1439,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth = EXT_DEPTH(tree); + int needed; @@ -1479,8 +1476,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int +ext3_ext_split_for_rm(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, tex; + struct ext3_ext_path *npath; @@ -1514,7 +1511,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* FIXME: some callback to free underlying resource + * and correct ee_start? */ + ext_debug(tree, "split extent: head %u:%u, tail %u:%u\n", -+ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); ++ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); + + npath = ext3_ext_find_extent(tree, ex->ee_block, NULL); + if (IS_ERR(npath)) @@ -1528,13 +1525,12 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + kfree(npath); + + return err; -+ +} + +static int +ext3_ext_rm_leaf(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, *fu = NULL, *lu, *le; + int err = 0, correct_index = 0; @@ -1567,8 +1563,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + } + + lu = ex; -+ while (ex >= EXT_FIRST_EXTENT(eh) && -+ ex->ee_block + ex->ee_len > start) { ++ while (ex >= EXT_FIRST_EXTENT(eh) && ex->ee_block + ex->ee_len > start) { + ext_debug(tree, "remove ext %u:%u\n", ex->ee_block, ex->ee_len); + path[depth].p_ext = ex; + @@ -1595,7 +1590,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + block = ex->ee_block; + num = 0; + EXT_ASSERT(a == ex->ee_block && -+ b == ex->ee_block + ex->ee_len - 1); ++ b == ex->ee_block + ex->ee_len - 1); + } + + if (ex == EXT_FIRST_EXTENT(eh)) @@ -1637,7 +1632,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + goto out; + + ext_debug(tree, "new extent: %u:%u:%u\n", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + ex--; + } + @@ -1701,7 +1696,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +int ext3_ext_remove_space(struct ext3_extents_tree *tree, -+ unsigned long start, unsigned long end) ++ unsigned long start, unsigned long end) +{ + struct inode *inode = tree->inode; + struct super_block *sb = inode->i_sb; @@ -1725,8 +1720,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + */ + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL); + if (IS_ERR(path)) { -+ ext3_error(sb, "ext3_ext_remove_space", -+ "Can't allocate path array"); ++ ext3_error(sb, __FUNCTION__, "Can't allocate path array"); + ext3_journal_stop(handle); + return -ENOMEM; + } @@ -1758,19 +1752,19 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + ext3_ext_last_covered(path[i].p_hdr, end); + path[i].p_block = path[i].p_hdr->eh_entries + 1; + ext_debug(tree, "init index ptr: hdr 0x%p, num %d\n", -+ path[i].p_hdr, path[i].p_hdr->eh_entries); ++ path[i].p_hdr, path[i].p_hdr->eh_entries); + } else { + /* we've already was here, see at next index */ + path[i].p_idx--; + } + + ext_debug(tree, "level %d - index, first 0x%p, cur 0x%p\n", -+ i, EXT_FIRST_INDEX(path[i].p_hdr), -+ path[i].p_idx); ++ i, EXT_FIRST_INDEX(path[i].p_hdr), ++ path[i].p_idx); + if (ext3_ext_more_to_rm(path + i)) { + /* go to the next level */ + ext_debug(tree, "move to level %d (block %d)\n", -+ i + 1, path[i].p_idx->ei_leaf); ++ i + 1, path[i].p_idx->ei_leaf); + memset(path + i + 1, 0, sizeof(*path)); + path[i+1].p_bh = sb_bread(sb, path[i].p_idx->ei_leaf); + if (!path[i+1].p_bh) { @@ -1893,7 +1887,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +static int ext3_ext_mergable(struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex2) +{ + /* FIXME: support for large fs */ + if (ex1->ee_start + ex1->ee_len == ex2->ee_start) @@ -1903,8 +1897,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int +ext3_remove_blocks_credits(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed; + @@ -1919,8 +1913,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int +ext3_remove_blocks(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed = ext3_remove_blocks_credits(tree, ex, from, to); + handle_t *handle = ext3_journal_start(tree->inode, needed); @@ -1935,7 +1929,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + num = ex->ee_block + ex->ee_len - from; + start = ex->ee_start + ex->ee_len - num; + ext_debug(tree, "free last %lu blocks starting %lu\n", -+ num, start); ++ num, start); + for (i = 0; i < num; i++) { + bh = sb_find_get_block(tree->inode->i_sb, start + i); + ext3_forget(handle, 0, tree->inode, bh, start + i); @@ -1943,17 +1937,17 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + ext3_free_blocks(handle, tree->inode, start, num); + } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { + printk("strange request: removal %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } else { + printk("strange request: removal(2) %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } + ext3_journal_stop(handle); + return 0; +} + +static int ext3_ext_find_goal(struct inode *inode, -+ struct ext3_ext_path *path, unsigned long block) ++ struct ext3_ext_path *path, unsigned long block) +{ + struct ext3_inode_info *ei = EXT3_I(inode); + unsigned long bg_start; @@ -1983,8 +1977,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +static int ext3_new_block_cb(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int *err) ++ struct ext3_ext_path *path, ++ struct ext3_extent *ex, int *err) +{ + struct inode *inode = tree->inode; + int newblock, goal; @@ -2021,7 +2015,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +}; + +void ext3_init_tree_desc(struct ext3_extents_tree *tree, -+ struct inode *inode) ++ struct inode *inode) +{ + tree->inode = inode; + tree->root = (void *) EXT3_I(inode)->i_data; @@ -2032,8 +2026,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +int ext3_ext_get_block(handle_t *handle, struct inode *inode, -+ long iblock, struct buffer_head *bh_result, -+ int create, int extend_disksize) ++ long iblock, struct buffer_head *bh_result, ++ int create, int extend_disksize) +{ + struct ext3_ext_path *path = NULL; + struct ext3_extent newex; @@ -2044,7 +2038,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + __clear_bit(BH_New, &bh_result->b_state); + ext3_init_tree_desc(&tree, inode); + ext_debug(&tree, "block %d requested for inode %u\n", -+ (int) iblock, (unsigned) inode->i_ino); ++ (int) iblock, (unsigned) inode->i_ino); + down(&EXT3_I(inode)->truncate_sem); + + /* check in cache */ @@ -2087,11 +2081,11 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if (iblock >= ex->ee_block && iblock < ex->ee_block + ex->ee_len) { + newblock = iblock - ex->ee_block + ex->ee_start; + ext_debug(&tree, "%d fit into %d:%d -> %d\n", -+ (int) iblock, ex->ee_block, ex->ee_len, -+ newblock); ++ (int) iblock, ex->ee_block, ex->ee_len, ++ newblock); + ext3_ext_put_in_cache(&tree, ex->ee_block, -+ ex->ee_len, ex->ee_start, -+ EXT3_EXT_CACHE_EXTENT); ++ ex->ee_len, ex->ee_start, ++ EXT3_EXT_CACHE_EXTENT); + goto out; + } + } @@ -2112,7 +2106,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if (!newblock) + goto out2; + ext_debug(&tree, "allocate new block: goal %d, found %d\n", -+ goal, newblock); ++ goal, newblock); + + /* try to insert new extent into found leaf and return */ + newex.ee_block = iblock; @@ -2130,7 +2124,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + __set_bit(BH_New, &bh_result->b_state); + + ext3_ext_put_in_cache(&tree, newex.ee_block, newex.ee_len, -+ newex.ee_start, EXT3_EXT_CACHE_EXTENT); ++ newex.ee_start, EXT3_EXT_CACHE_EXTENT); +out: + ext3_ext_show_leaf(&tree, path); + __set_bit(BH_Mapped, &bh_result->b_state); @@ -2190,8 +2184,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + EXT3_I(inode)->i_disksize = inode->i_size; + ext3_mark_inode_dirty(handle, inode); + -+ last_block = (inode->i_size + sb->s_blocksize - 1) -+ >> EXT3_BLOCK_SIZE_BITS(sb); ++ last_block = (inode->i_size + sb->s_blocksize - 1) >> ++ EXT3_BLOCK_SIZE_BITS(sb); + err = ext3_ext_remove_space(&tree, last_block, EXT_MAX_BLOCK); + + /* In a multi-transaction truncate, we only make the final @@ -2259,8 +2253,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int +ext3_ext_store_extent_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_ext_cache *newex) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *newex) +{ + struct ext3_extent_buf *buf = (struct ext3_extent_buf *) tree->private; + @@ -2284,8 +2278,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int +ext3_ext_collect_stats_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_ext_cache *ex) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *ex) +{ + struct ext3_extent_tree_stats *buf = + (struct ext3_extent_tree_stats *) tree->private; @@ -2302,7 +2296,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +int ext3_ext_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, -+ unsigned long arg) ++ unsigned long arg) +{ + int err = 0; + @@ -2322,7 +2316,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + tree.private = &buf; + down(&EXT3_I(inode)->truncate_sem); + err = ext3_ext_walk_space(&tree, buf.start, EXT_MAX_BLOCK, -+ ext3_ext_store_extent_cb); ++ ext3_ext_store_extent_cb); + up(&EXT3_I(inode)->truncate_sem); + if (err == 0) + err = buf.err; @@ -2337,7 +2331,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + buf.leaf_num = 0; + tree.private = &buf; + err = ext3_ext_walk_space(&tree, 0, EXT_MAX_BLOCK, -+ ext3_ext_collect_stats_cb); ++ ext3_ext_collect_stats_cb); + up(&EXT3_I(inode)->truncate_sem); + if (!err) + err = copy_to_user((void *) arg, &buf, sizeof(buf)); @@ -2359,19 +2353,26 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +EXPORT_SYMBOL(ext3_ext_walk_space); +EXPORT_SYMBOL(ext3_ext_find_goal); +EXPORT_SYMBOL(ext3_ext_calc_credits_for_insert); -+ Index: linux-2.6.5-sles9/fs/ext3/ialloc.c =================================================================== --- linux-2.6.5-sles9.orig/fs/ext3/ialloc.c 2005-02-23 01:01:52.366281264 +0300 +++ linux-2.6.5-sles9/fs/ext3/ialloc.c 2005-02-23 01:02:37.398435336 +0300 -@@ -647,6 +647,10 @@ +@@ -647,6 +647,18 @@ DQUOT_FREE_INODE(inode); goto fail2; } -+ if (test_opt(sb, EXTENTS)) { -+ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; -+ ext3_extents_initialize_blockmap(handle, inode); -+ } ++ if (test_opt(sb, EXTENTS) && S_ISREG(inode->i_mode)) { ++ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; ++ ext3_extents_initialize_blockmap(handle, inode); ++ if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS)) { ++ err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); ++ if (err) goto fail; ++ EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS); ++ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "call ext3_journal_dirty_metadata"); ++ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); ++ } ++ } ++ err = ext3_mark_inode_dirty(handle, inode); if (err) { ext3_std_error(sb, err); @@ -2385,13 +2386,13 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c +static inline int +ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block, -+ struct buffer_head *bh, int create, int extend_disksize) ++ struct buffer_head *bh, int create, int extend_disksize) +{ + if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) + return ext3_ext_get_block(handle, inode, block, bh, create, -+ extend_disksize); ++ extend_disksize); + return ext3_get_block_handle(handle, inode, block, bh, create, -+ extend_disksize); ++ extend_disksize); +} + static int ext3_get_block(struct inode *inode, sector_t iblock, @@ -2404,7 +2405,7 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c - ret = ext3_get_block_handle(handle, inode, iblock, - bh_result, create, 1); + ret = ext3_get_block_wrap(handle, inode, iblock, -+ bh_result, create, 1); ++ bh_result, create, 1); return ret; } @@ -2415,7 +2416,7 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c - ret = ext3_get_block_handle(handle, inode, iblock, - bh_result, create, 0); + ret = ext3_get_block_wrap(handle, inode, iblock, -+ bh_result, create, 0); ++ bh_result, create, 0); if (ret == 0) bh_result->b_size = (1 << inode->i_blkbits); return ret; @@ -2451,9 +2452,9 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3; int ret; -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) -+ return ext3_ext_writepage_trans_blocks(inode, bpp); -+ ++ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) ++ return ext3_ext_writepage_trans_blocks(inode, bpp); ++ if (ext3_should_journal_data(inode)) ret = 3 * (bpp + indirects) + 2; else @@ -2478,7 +2479,7 @@ Index: linux-2.6.5-sles9/fs/ext3/super.c struct ext3_super_block *es = sbi->s_es; int i; -+ ext3_ext_release(sb); ++ ext3_ext_release(sb); ext3_xattr_put_super(sb); journal_destroy(sbi->s_journal); if (!(sb->s_flags & MS_RDONLY)) { @@ -2526,8 +2527,8 @@ Index: linux-2.6.5-sles9/fs/ext3/super.c percpu_counter_mod(&sbi->s_dirs_counter, ext3_count_dirs(sb)); -+ ext3_ext_init(sb); -+ ++ ext3_ext_init(sb); ++ return 0; failed_mount3: @@ -2550,14 +2551,17 @@ Index: linux-2.6.5-sles9/include/linux/ext3_fs.h =================================================================== --- linux-2.6.5-sles9.orig/include/linux/ext3_fs.h 2005-02-23 01:02:35.823674736 +0300 +++ linux-2.6.5-sles9/include/linux/ext3_fs.h 2005-02-23 01:02:37.414432904 +0300 -@@ -186,6 +186,7 @@ +@@ -186,8 +186,9 @@ + #define EXT3_NOTAIL_FL 0x00008000 /* don't merge file tail */ #define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ #define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ - #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ +#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ + #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ - #define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ +-#define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ ++#define EXT3_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */ #define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ + @@ -211,6 +212,9 @@ #endif #define EXT3_IOC_GETRSVSZ _IOR('f', 5, long) @@ -2577,6 +2581,21 @@ Index: linux-2.6.5-sles9/include/linux/ext3_fs.h /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef clear_opt +@@ -503,11 +509,13 @@ + #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ + #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ + #define EXT3_FEATURE_INCOMPAT_META_BG 0x0010 ++#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ + + #define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR + #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ + EXT3_FEATURE_INCOMPAT_RECOVER| \ +- EXT3_FEATURE_INCOMPAT_META_BG) ++ EXT3_FEATURE_INCOMPAT_META_BG| \ ++ EXT3_FEATURE_INCOMPAT_EXTENTS) + #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ + EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ + EXT3_FEATURE_RO_COMPAT_BTREE_DIR) @@ -729,6 +735,7 @@ @@ -2592,7 +2611,7 @@ Index: linux-2.6.5-sles9/include/linux/ext3_fs.h +/* extents.c */ +extern int ext3_ext_writepage_trans_blocks(struct inode *, int); +extern int ext3_ext_get_block(handle_t *, struct inode *, long, -+ struct buffer_head *, int, int); ++ struct buffer_head *, int, int); +extern void ext3_ext_truncate(struct inode *, struct page *); +extern void ext3_ext_init(struct super_block *); +extern void ext3_ext_release(struct super_block *); @@ -2606,7 +2625,7 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h =================================================================== --- linux-2.6.5-sles9.orig/include/linux/ext3_extents.h 2005-02-17 22:07:57.023609040 +0300 +++ linux-2.6.5-sles9/include/linux/ext3_extents.h 2005-02-23 01:02:37.416432600 +0300 -@@ -0,0 +1,265 @@ +@@ -0,0 +1,264 @@ +/* + * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas @@ -2648,7 +2667,7 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + */ +#define EXT_DEBUG_ +#ifdef EXT_DEBUG -+#define ext_debug(tree,fmt,a...) \ ++#define ext_debug(tree,fmt,a...) \ +do { \ + if (test_opt((tree)->inode->i_sb, EXTDEBUG)) \ + printk(fmt, ##a); \ @@ -2761,14 +2780,14 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + int (*mark_buffer_dirty)(handle_t *h, void *buffer); + int (*mergable)(struct ext3_extent *ex1, struct ext3_extent *ex2); + int (*remove_extent_credits)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*remove_extent)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*new_block)(handle_t *, struct ext3_extents_tree *, -+ struct ext3_ext_path *, struct ext3_extent *, -+ int *); ++ struct ext3_ext_path *, struct ext3_extent *, ++ int *); +}; + +/* @@ -2778,8 +2797,8 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + * callback must return valid extent (passed or newly created) + */ +typedef int (*ext_prepare_callback)(struct ext3_extents_tree *, -+ struct ext3_ext_path *, -+ struct ext3_ext_cache *); ++ struct ext3_ext_path *, ++ struct ext3_ext_cache *); + +#define EXT_CONTINUE 0 +#define EXT_BREAK 1 @@ -2831,7 +2850,7 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + && depth != 0); \ + BUG_ON((path)[0].p_depth != depth); \ +} -+ ++ + +/* + * this structure is used to gather extents from the tree via ioctl @@ -2853,13 +2872,13 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + int leaf_num; +}; + ++extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); +extern int ext3_extent_tree_init(handle_t *, struct ext3_extents_tree *); +extern int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *, struct ext3_ext_path *); +extern int ext3_ext_insert_extent(handle_t *, struct ext3_extents_tree *, struct ext3_ext_path *, struct ext3_extent *); +extern int ext3_ext_walk_space(struct ext3_extents_tree *, unsigned long, unsigned long, ext_prepare_callback); +extern int ext3_ext_remove_space(struct ext3_extents_tree *, unsigned long, unsigned long); +extern struct ext3_ext_path * ext3_ext_find_extent(struct ext3_extents_tree *, int, struct ext3_ext_path *); -+extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); +extern int ext3_ext_calc_blockmap_metadata(struct inode *, int); + +static inline void @@ -2871,7 +2890,6 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + + +#endif /* _LINUX_EXT3_EXTENTS */ -+ Index: linux-2.6.5-sles9/include/linux/ext3_fs_i.h =================================================================== --- linux-2.6.5-sles9.orig/include/linux/ext3_fs_i.h 2005-02-23 01:01:52.425272296 +0300 diff --git a/ldiskfs/kernel_patches/patches/ext3-extents-2.6.9-rhel4.patch b/ldiskfs/kernel_patches/patches/ext3-extents-2.6.9-rhel4.patch index 78c5d81..02745cc 100644 --- a/ldiskfs/kernel_patches/patches/ext3-extents-2.6.9-rhel4.patch +++ b/ldiskfs/kernel_patches/patches/ext3-extents-2.6.9-rhel4.patch @@ -2,9 +2,9 @@ Index: linux-stage/fs/ext3/extents.c =================================================================== --- linux-stage.orig/fs/ext3/extents.c 2005-02-25 15:33:48.890198160 +0200 +++ linux-stage/fs/ext3/extents.c 2005-02-25 15:33:48.917194056 +0200 -@@ -0,0 +1,2313 @@ +@@ -0,0 +1,2347 @@ +/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com ++ * Copyright(c) 2003, 2004, 2005, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify @@ -48,6 +48,27 @@ Index: linux-stage/fs/ext3/extents.c +#include +#include + ++ ++static inline int ext3_ext_check_header(struct ext3_extent_header *eh) ++{ ++ if (eh->eh_magic != EXT3_EXT_MAGIC) { ++ printk(KERN_ERR "EXT3-fs: invalid magic = 0x%x\n", ++ (unsigned)eh->eh_magic); ++ return -EIO; ++ } ++ if (eh->eh_max == 0) { ++ printk(KERN_ERR "EXT3-fs: invalid eh_max = %u\n", ++ (unsigned)eh->eh_max); ++ return -EIO; ++ } ++ if (eh->eh_entries > eh->eh_max) { ++ printk(KERN_ERR "EXT3-fs: invalid eh_entries = %u\n", ++ (unsigned)eh->eh_entries); ++ return -EIO; ++ } ++ return 0; ++} ++ +static handle_t *ext3_ext_journal_restart(handle_t *handle, int needed) +{ + int err; @@ -85,8 +106,8 @@ Index: linux-stage/fs/ext3/extents.c + * - ENOMEM + */ +static int ext3_ext_get_access(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path) +{ + int err; + @@ -107,7 +128,7 @@ Index: linux-stage/fs/ext3/extents.c + * - EIO + */ +static int ext3_ext_dirty(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int err; + if (path->p_bh) { @@ -122,8 +143,8 @@ Index: linux-stage/fs/ext3/extents.c + +static int inline +ext3_ext_new_block(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, struct ext3_extent *ex, -+ int *err) ++ struct ext3_ext_path *path, struct ext3_extent *ex, ++ int *err) +{ + int goal, depth, newblock; + struct inode *inode; @@ -142,7 +163,7 @@ Index: linux-stage/fs/ext3/extents.c + unsigned long colour; + + bg_start = (ei->i_block_group * -+ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + ++ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + + le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); + colour = (current->pid % 16) * + (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); @@ -165,8 +186,8 @@ Index: linux-stage/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 6; +#endif @@ -178,8 +199,8 @@ Index: linux-stage/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 5; +#endif @@ -190,8 +211,8 @@ Index: linux-stage/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 3; +#endif @@ -202,9 +223,8 @@ Index: linux-stage/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 4; +#endif @@ -212,7 +232,7 @@ Index: linux-stage/fs/ext3/extents.c +} + +static void ext3_ext_show_path(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int k, l = path->p_depth; @@ -221,12 +241,12 @@ Index: linux-stage/fs/ext3/extents.c + for (k = 0; k <= l; k++, path++) { + if (path->p_idx) { + ext_debug(tree, " %d->%d", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + } else if (path->p_ext) { + ext_debug(tree, " %d:%d:%d", -+ path->p_ext->ee_block, -+ path->p_ext->ee_len, -+ path->p_ext->ee_start); ++ path->p_ext->ee_block, ++ path->p_ext->ee_len, ++ path->p_ext->ee_start); + } else + ext_debug(tree, " []"); + } @@ -235,7 +255,7 @@ Index: linux-stage/fs/ext3/extents.c +} + +static void ext3_ext_show_leaf(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int depth = EXT_DEPTH(tree); @@ -251,7 +271,7 @@ Index: linux-stage/fs/ext3/extents.c + + for (i = 0; i < eh->eh_entries; i++, ex++) { + ext_debug(tree, "%d:%d:%d ", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + } + ext_debug(tree, "\n"); +#endif @@ -262,11 +282,12 @@ Index: linux-stage/fs/ext3/extents.c + int depth = path->p_depth; + int i; + -+ for (i = 0; i <= depth; i++, path++) ++ for (i = 0; i <= depth; i++, path++) { + if (path->p_bh) { + brelse(path->p_bh); + path->p_bh = NULL; + } ++ } +} + +/* @@ -274,7 +295,7 @@ Index: linux-stage/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch_idx(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent_idx *ix; @@ -300,7 +321,7 @@ Index: linux-stage/fs/ext3/extents.c + + ix += l; + path->p_idx = ix; -+ ext_debug(tree, " -> %d->%d ", path->p_idx->ei_block, path->p_idx->ei_leaf); ++ ext_debug(tree," -> %d->%d ",path->p_idx->ei_block,path->p_idx->ei_leaf); + + while (l++ < r) { + if (block < ix->ei_block) @@ -308,7 +329,7 @@ Index: linux-stage/fs/ext3/extents.c + path->p_idx = ix++; + } + ext_debug(tree, " -> %d->%d\n", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + +#ifdef CHECK_BINSEARCH + { @@ -318,9 +339,9 @@ Index: linux-stage/fs/ext3/extents.c + for (k = 0; k < eh->eh_entries; k++, ix++) { + if (k != 0 && ix->ei_block <= ix[-1].ei_block) { + printk("k=%d, ix=0x%p, first=0x%p\n", k, -+ ix, EXT_FIRST_INDEX(eh)); ++ ix, EXT_FIRST_INDEX(eh)); + printk("%u <= %u\n", -+ ix->ei_block,ix[-1].ei_block); ++ ix->ei_block,ix[-1].ei_block); + } + EXT_ASSERT(k == 0 || ix->ei_block > ix[-1].ei_block); + if (block < ix->ei_block) @@ -330,7 +351,6 @@ Index: linux-stage/fs/ext3/extents.c + EXT_ASSERT(chix == path->p_idx); + } +#endif -+ +} + +/* @@ -338,7 +358,7 @@ Index: linux-stage/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent *ex; @@ -372,7 +392,7 @@ Index: linux-stage/fs/ext3/extents.c + ex += l; + path->p_ext = ex; + ext_debug(tree, " -> %d:%d:%d ", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + + while (l++ < r) { + if (block < ex->ee_block) @@ -380,7 +400,7 @@ Index: linux-stage/fs/ext3/extents.c + path->p_ext = ex++; + } + ext_debug(tree, " -> %d:%d:%d\n", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + +#ifdef CHECK_BINSEARCH + { @@ -396,7 +416,6 @@ Index: linux-stage/fs/ext3/extents.c + EXT_ASSERT(chex == path->p_ext); + } +#endif -+ +} + +int ext3_extent_tree_init(handle_t *handle, struct ext3_extents_tree *tree) @@ -417,7 +436,7 @@ Index: linux-stage/fs/ext3/extents.c + +struct ext3_ext_path * +ext3_ext_find_extent(struct ext3_extents_tree *tree, int block, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + struct buffer_head *bh; @@ -429,15 +448,17 @@ Index: linux-stage/fs/ext3/extents.c + + eh = EXT_ROOT_HDR(tree); + EXT_ASSERT(eh); ++ if (ext3_ext_check_header(eh)) ++ goto err; ++ + i = depth = EXT_DEPTH(tree); + EXT_ASSERT(eh->eh_max); + EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ EXT_ASSERT(i == 0 || eh->eh_entries > 0); + + /* account possible depth increase */ + if (!path) { + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2), -+ GFP_NOFS); ++ GFP_NOFS); + if (!path) + return ERR_PTR(-ENOMEM); + } @@ -447,29 +468,34 @@ Index: linux-stage/fs/ext3/extents.c + /* walk through the tree */ + while (i) { + ext_debug(tree, "depth %d: num %d, max %d\n", -+ ppos, eh->eh_entries, eh->eh_max); ++ ppos, eh->eh_entries, eh->eh_max); + ext3_ext_binsearch_idx(tree, path + ppos, block); + path[ppos].p_block = path[ppos].p_idx->ei_leaf; + path[ppos].p_depth = i; + path[ppos].p_ext = NULL; + + bh = sb_bread(tree->inode->i_sb, path[ppos].p_block); -+ if (!bh) { -+ ext3_ext_drop_refs(path); -+ kfree(path); -+ return ERR_PTR(-EIO); -+ } ++ if (!bh) ++ goto err; ++ + eh = EXT_BLOCK_HDR(bh); + ppos++; + EXT_ASSERT(ppos <= depth); + path[ppos].p_bh = bh; + path[ppos].p_hdr = eh; + i--; ++ ++ if (ext3_ext_check_header(eh)) ++ goto err; + } + + path[ppos].p_depth = i; + path[ppos].p_hdr = eh; + path[ppos].p_ext = NULL; ++ path[ppos].p_idx = NULL; ++ ++ if (ext3_ext_check_header(eh)) ++ goto err; + + /* find extent */ + ext3_ext_binsearch(tree, path + ppos, block); @@ -477,6 +503,12 @@ Index: linux-stage/fs/ext3/extents.c + ext3_ext_show_path(tree, path); + + return path; ++ ++err: ++ printk(KERN_ERR "EXT3-fs: header is corrupted!\n"); ++ ext3_ext_drop_refs(path); ++ kfree(path); ++ return ERR_PTR(-EIO); +} + +/* @@ -484,9 +516,9 @@ Index: linux-stage/fs/ext3/extents.c + * it check where to insert: before curp or after curp + */ +static int ext3_ext_insert_index(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *curp, -+ int logical, int ptr) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *curp, ++ int logical, int ptr) +{ + struct ext3_extent_idx *ix; + int len, err; @@ -502,9 +534,9 @@ Index: linux-stage/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d after: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ (curp->p_idx + 1), (curp->p_idx + 2)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ (curp->p_idx + 1), (curp->p_idx + 2)); + memmove(curp->p_idx + 2, curp->p_idx + 1, len); + } + ix = curp->p_idx + 1; @@ -513,9 +545,9 @@ Index: linux-stage/fs/ext3/extents.c + len = len * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d before: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ curp->p_idx, (curp->p_idx + 1)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ curp->p_idx, (curp->p_idx + 1)); + memmove(curp->p_idx + 1, curp->p_idx, len); + ix = curp->p_idx; + } @@ -543,8 +575,8 @@ Index: linux-stage/fs/ext3/extents.c + * - initialize subtree + */ +static int ext3_ext_split(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext, int at) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext, int at) +{ + struct buffer_head *bh = NULL; + int depth = EXT_DEPTH(tree); @@ -565,13 +597,13 @@ Index: linux-stage/fs/ext3/extents.c + if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) { + border = path[depth].p_ext[1].ee_block; + ext_debug(tree, "leaf will be splitted." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } else { + border = newext->ee_block; + ext_debug(tree, "leaf will be added." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } + + /* @@ -629,12 +661,11 @@ Index: linux-stage/fs/ext3/extents.c + while (path[depth].p_ext <= + EXT_MAX_EXTENT(path[depth].p_hdr)) { + ext_debug(tree, "move %d:%d:%d in new leaf %lu\n", -+ path[depth].p_ext->ee_block, -+ path[depth].p_ext->ee_start, -+ path[depth].p_ext->ee_len, -+ newblock); -+ memmove(ex++, path[depth].p_ext++, -+ sizeof(struct ext3_extent)); ++ path[depth].p_ext->ee_block, ++ path[depth].p_ext->ee_start, ++ path[depth].p_ext->ee_len, ++ newblock); ++ memmove(ex++, path[depth].p_ext++, sizeof(struct ext3_extent)); + neh->eh_entries++; + m++; + } @@ -687,21 +718,21 @@ Index: linux-stage/fs/ext3/extents.c + fidx->ei_leaf = oldblock; + + ext_debug(tree, "int.index at %d (block %lu): %lu -> %lu\n", -+ i, newblock, border, oldblock); ++ i, newblock, border, oldblock); + /* copy indexes */ + m = 0; + path[i].p_idx++; + + ext_debug(tree, "cur 0x%p, last 0x%p\n", path[i].p_idx, -+ EXT_MAX_INDEX(path[i].p_hdr)); ++ EXT_MAX_INDEX(path[i].p_hdr)); + EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) == -+ EXT_LAST_INDEX(path[i].p_hdr)); ++ EXT_LAST_INDEX(path[i].p_hdr)); + while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { + ext_debug(tree, "%d: move %d:%d in new index %lu\n", -+ i, path[i].p_idx->ei_block, -+ path[i].p_idx->ei_leaf, newblock); ++ i, path[i].p_idx->ei_block, ++ path[i].p_idx->ei_leaf, newblock); + memmove(++fidx, path[i].p_idx++, -+ sizeof(struct ext3_extent_idx)); ++ sizeof(struct ext3_extent_idx)); + neh->eh_entries++; + EXT_ASSERT(neh->eh_entries <= neh->eh_max); + m++; @@ -731,7 +762,7 @@ Index: linux-stage/fs/ext3/extents.c + /* insert new index */ + if (!err) + err = ext3_ext_insert_index(handle, tree, path + at, -+ border, newblock); ++ border, newblock); + +cleanup: + if (bh) { @@ -761,9 +792,9 @@ Index: linux-stage/fs/ext3/extents.c + * just created block + */ +static int ext3_ext_grow_indepth(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp = path; + struct ext3_extent_header *neh; @@ -795,7 +826,7 @@ Index: linux-stage/fs/ext3/extents.c + /* set size of new block */ + neh = EXT_BLOCK_HDR(bh); + /* old root could have indexes or leaves -+ * so calculate e_max right way */ ++ * so calculate eh_max right way */ + if (EXT_DEPTH(tree)) + neh->eh_max = ext3_ext_space_block_idx(tree); + else @@ -822,7 +853,7 @@ Index: linux-stage/fs/ext3/extents.c + neh = EXT_ROOT_HDR(tree); + fidx = EXT_FIRST_INDEX(neh); + ext_debug(tree, "new root: num %d(%d), lblock %d, ptr %d\n", -+ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); ++ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); + + neh->eh_depth = path->p_depth + 1; + err = ext3_ext_dirty(handle, tree, curp); @@ -837,9 +868,9 @@ Index: linux-stage/fs/ext3/extents.c + * then it requests in-depth growing + */ +static int ext3_ext_create_new_leaf(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp; + int depth, i, err = 0; @@ -915,12 +946,12 @@ Index: linux-stage/fs/ext3/extents.c + if (depth == path->p_depth) { + /* leaf */ + if (path[depth].p_ext != -+ EXT_LAST_EXTENT(path[depth].p_hdr)) ++ EXT_LAST_EXTENT(path[depth].p_hdr)) + return path[depth].p_ext[1].ee_block; + } else { + /* index */ + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + } + depth--; @@ -933,7 +964,7 @@ Index: linux-stage/fs/ext3/extents.c + * returns first allocated block from next leaf or EXT_MAX_BLOCK + */ +static unsigned ext3_ext_next_leaf_block(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth; + @@ -949,7 +980,7 @@ Index: linux-stage/fs/ext3/extents.c + + while (depth >= 0) { + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + depth--; + } @@ -963,7 +994,7 @@ Index: linux-stage/fs/ext3/extents.c + * TODO: do we need to correct tree in all cases? + */ +int ext3_ext_correct_indexes(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + int depth = EXT_DEPTH(tree); @@ -1013,8 +1044,8 @@ Index: linux-stage/fs/ext3/extents.c + +static int inline +ext3_can_extents_be_merged(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex1, ++ struct ext3_extent *ex2) +{ + if (ex1->ee_block + ex1->ee_len != ex2->ee_block) + return 0; @@ -1036,8 +1067,8 @@ Index: linux-stage/fs/ext3/extents.c + * creating new leaf in no-space case + */ +int ext3_ext_insert_extent(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_extent_header * eh; + struct ext3_extent *ex, *fex; @@ -1046,7 +1077,6 @@ Index: linux-stage/fs/ext3/extents.c + int depth, len, err, next; + + EXT_ASSERT(newext->ee_len > 0); -+ EXT_ASSERT(newext->ee_len < EXT_CACHE_MARK); + depth = EXT_DEPTH(tree); + ex = path[depth].p_ext; + EXT_ASSERT(path[depth].p_hdr); @@ -1054,8 +1084,8 @@ Index: linux-stage/fs/ext3/extents.c + /* try to insert block into found extent and return */ + if (ex && ext3_can_extents_be_merged(tree, ex, newext)) { + ext_debug(tree, "append %d block to %d:%d (from %d)\n", -+ newext->ee_len, ex->ee_block, ex->ee_len, -+ ex->ee_start); ++ newext->ee_len, ex->ee_block, ex->ee_len, ++ ex->ee_start); + if ((err = ext3_ext_get_access(handle, tree, path + depth))) + return err; + ex->ee_len += newext->ee_len; @@ -1083,12 +1113,12 @@ Index: linux-stage/fs/ext3/extents.c + eh = npath[depth].p_hdr; + if (eh->eh_entries < eh->eh_max) { + ext_debug(tree, "next leaf isnt full(%d)\n", -+ eh->eh_entries); ++ eh->eh_entries); + path = npath; + goto repeat; + } + ext_debug(tree, "next leaf hasno free space(%d,%d)\n", -+ eh->eh_entries, eh->eh_max); ++ eh->eh_entries, eh->eh_max); + } + + /* @@ -1110,8 +1140,8 @@ Index: linux-stage/fs/ext3/extents.c + if (!nearex) { + /* there is no extent in this leaf, create first one */ + ext_debug(tree, "first extent in the leaf: %d:%d:%d\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len); ++ newext->ee_block, newext->ee_start, ++ newext->ee_len); + path[depth].p_ext = EXT_FIRST_EXTENT(eh); + } else if (newext->ee_block > nearex->ee_block) { + EXT_ASSERT(newext->ee_block != nearex->ee_block); @@ -1120,10 +1150,10 @@ Index: linux-stage/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d after: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, ++ newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 2, nearex + 1, len); + } + path[depth].p_ext = nearex + 1; @@ -1132,9 +1162,9 @@ Index: linux-stage/fs/ext3/extents.c + len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d before: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 1, nearex, len); + path[depth].p_ext = nearex; + } @@ -1155,8 +1185,8 @@ Index: linux-stage/fs/ext3/extents.c + /* merge with next extent! */ + nearex->ee_len += nearex[1].ee_len; + if (nearex + 1 < EXT_LAST_EXTENT(eh)) { -+ len = (EXT_LAST_EXTENT(eh) - nearex - 1) -+ * sizeof(struct ext3_extent); ++ len = (EXT_LAST_EXTENT(eh) - nearex - 1) * ++ sizeof(struct ext3_extent); + memmove(nearex + 1, nearex + 2, len); + } + eh->eh_entries--; @@ -1186,7 +1216,8 @@ Index: linux-stage/fs/ext3/extents.c + unsigned long num, ext_prepare_callback func) +{ + struct ext3_ext_path *path = NULL; -+ struct ext3_extent *ex, cbex; ++ struct ext3_ext_cache cbex; ++ struct ext3_extent *ex; + unsigned long next, start = 0, end = 0; + unsigned long last = block + num; + int depth, exists, err = 0; @@ -1245,14 +1276,20 @@ Index: linux-stage/fs/ext3/extents.c + EXT_ASSERT(end > start); + + if (!exists) { -+ cbex.ee_block = start; -+ cbex.ee_len = end - start; -+ cbex.ee_start = 0; -+ } else -+ cbex = *ex; ++ cbex.ec_block = start; ++ cbex.ec_len = end - start; ++ cbex.ec_start = 0; ++ cbex.ec_type = EXT3_EXT_CACHE_GAP; ++ } else { ++ cbex.ec_block = ex->ee_block; ++ cbex.ec_len = ex->ee_len; ++ cbex.ec_start = ex->ee_start; ++ cbex.ec_type = EXT3_EXT_CACHE_EXTENT; ++ } + ++ EXT_ASSERT(cbex.ec_len > 0); + EXT_ASSERT(path[depth].p_hdr); -+ err = func(tree, path, &cbex, exists); ++ err = func(tree, path, &cbex); + ext3_ext_drop_refs(path); + + if (err < 0) @@ -1270,7 +1307,7 @@ Index: linux-stage/fs/ext3/extents.c + path = NULL; + } + -+ block = cbex.ee_block + cbex.ee_len; ++ block = cbex.ec_block + cbex.ec_len; + } + + if (path) { @@ -1283,7 +1320,7 @@ Index: linux-stage/fs/ext3/extents.c + +static inline void +ext3_ext_put_in_cache(struct ext3_extents_tree *tree, __u32 block, -+ __u32 len, __u32 start, int type) ++ __u32 len, __u32 start, int type) +{ + EXT_ASSERT(len > 0); + if (tree->cex) { @@ -1300,8 +1337,8 @@ Index: linux-stage/fs/ext3/extents.c + */ +static inline void +ext3_ext_put_gap_in_cache(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ unsigned long block) ++ struct ext3_ext_path *path, ++ unsigned long block) +{ + int depth = EXT_DEPTH(tree); + unsigned long lblock, len; @@ -1320,16 +1357,16 @@ Index: linux-stage/fs/ext3/extents.c + lblock = block; + len = ex->ee_block - block; + ext_debug(tree, "cache gap(before): %lu [%lu:%lu]", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len); + } else if (block >= ex->ee_block + ex->ee_len) { + lblock = ex->ee_block + ex->ee_len; + len = ext3_ext_next_allocated_block(path); + ext_debug(tree, "cache gap(after): [%lu:%lu] %lu", -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) block); ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) block); + EXT_ASSERT(len > lblock); + len = len - lblock; + } else { @@ -1343,7 +1380,7 @@ Index: linux-stage/fs/ext3/extents.c + +static inline int +ext3_ext_in_cache(struct ext3_extents_tree *tree, unsigned long block, -+ struct ext3_extent *ex) ++ struct ext3_extent *ex) +{ + struct ext3_ext_cache *cex = tree->cex; + @@ -1356,16 +1393,16 @@ Index: linux-stage/fs/ext3/extents.c + return EXT3_EXT_CACHE_NO; + + EXT_ASSERT(cex->ec_type == EXT3_EXT_CACHE_GAP || -+ cex->ec_type == EXT3_EXT_CACHE_EXTENT); ++ cex->ec_type == EXT3_EXT_CACHE_EXTENT); + if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) { + ex->ee_block = cex->ec_block; + ex->ee_start = cex->ec_start; + ex->ee_len = cex->ec_len; + ext_debug(tree, "%lu cached by %lu:%lu:%lu\n", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) ex->ee_start); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) ex->ee_start); + return cex->ec_type; + } + @@ -1379,7 +1416,7 @@ Index: linux-stage/fs/ext3/extents.c + * last index in the block only + */ +int ext3_ext_rm_idx(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct buffer_head *bh; + int err; @@ -1393,7 +1430,7 @@ Index: linux-stage/fs/ext3/extents.c + if ((err = ext3_ext_dirty(handle, tree, path))) + return err; + ext_debug(tree, "index is empty, remove it, free block %d\n", -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + bh = sb_find_get_block(tree->inode->i_sb, path->p_idx->ei_leaf); + ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf); + ext3_free_blocks(handle, tree->inode, path->p_idx->ei_leaf, 1); @@ -1401,7 +1438,7 @@ Index: linux-stage/fs/ext3/extents.c +} + +int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth = EXT_DEPTH(tree); + int needed; @@ -1438,8 +1475,8 @@ Index: linux-stage/fs/ext3/extents.c + +static int +ext3_ext_split_for_rm(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, tex; + struct ext3_ext_path *npath; @@ -1473,7 +1510,7 @@ Index: linux-stage/fs/ext3/extents.c + /* FIXME: some callback to free underlying resource + * and correct ee_start? */ + ext_debug(tree, "split extent: head %u:%u, tail %u:%u\n", -+ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); ++ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); + + npath = ext3_ext_find_extent(tree, ex->ee_block, NULL); + if (IS_ERR(npath)) @@ -1487,13 +1524,12 @@ Index: linux-stage/fs/ext3/extents.c + kfree(npath); + + return err; -+ +} + +static int +ext3_ext_rm_leaf(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, *fu = NULL, *lu, *le; + int err = 0, correct_index = 0; @@ -1526,8 +1562,7 @@ Index: linux-stage/fs/ext3/extents.c + } + + lu = ex; -+ while (ex >= EXT_FIRST_EXTENT(eh) && -+ ex->ee_block + ex->ee_len > start) { ++ while (ex >= EXT_FIRST_EXTENT(eh) && ex->ee_block + ex->ee_len > start) { + ext_debug(tree, "remove ext %u:%u\n", ex->ee_block, ex->ee_len); + path[depth].p_ext = ex; + @@ -1554,7 +1589,7 @@ Index: linux-stage/fs/ext3/extents.c + block = ex->ee_block; + num = 0; + EXT_ASSERT(a == ex->ee_block && -+ b == ex->ee_block + ex->ee_len - 1); ++ b == ex->ee_block + ex->ee_len - 1); + } + + if (ex == EXT_FIRST_EXTENT(eh)) @@ -1596,7 +1631,7 @@ Index: linux-stage/fs/ext3/extents.c + goto out; + + ext_debug(tree, "new extent: %u:%u:%u\n", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + ex--; + } + @@ -1660,7 +1695,7 @@ Index: linux-stage/fs/ext3/extents.c +} + +int ext3_ext_remove_space(struct ext3_extents_tree *tree, -+ unsigned long start, unsigned long end) ++ unsigned long start, unsigned long end) +{ + struct inode *inode = tree->inode; + struct super_block *sb = inode->i_sb; @@ -1684,8 +1719,7 @@ Index: linux-stage/fs/ext3/extents.c + */ + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL); + if (IS_ERR(path)) { -+ ext3_error(sb, "ext3_ext_remove_space", -+ "Can't allocate path array"); ++ ext3_error(sb, __FUNCTION__, "Can't allocate path array"); + ext3_journal_stop(handle); + return -ENOMEM; + } @@ -1717,19 +1751,19 @@ Index: linux-stage/fs/ext3/extents.c + ext3_ext_last_covered(path[i].p_hdr, end); + path[i].p_block = path[i].p_hdr->eh_entries + 1; + ext_debug(tree, "init index ptr: hdr 0x%p, num %d\n", -+ path[i].p_hdr, path[i].p_hdr->eh_entries); ++ path[i].p_hdr, path[i].p_hdr->eh_entries); + } else { + /* we've already was here, see at next index */ + path[i].p_idx--; + } + + ext_debug(tree, "level %d - index, first 0x%p, cur 0x%p\n", -+ i, EXT_FIRST_INDEX(path[i].p_hdr), -+ path[i].p_idx); ++ i, EXT_FIRST_INDEX(path[i].p_hdr), ++ path[i].p_idx); + if (ext3_ext_more_to_rm(path + i)) { + /* go to the next level */ + ext_debug(tree, "move to level %d (block %d)\n", -+ i + 1, path[i].p_idx->ei_leaf); ++ i + 1, path[i].p_idx->ei_leaf); + memset(path + i + 1, 0, sizeof(*path)); + path[i+1].p_bh = sb_bread(sb, path[i].p_idx->ei_leaf); + if (!path[i+1].p_bh) { @@ -1852,7 +1886,7 @@ Index: linux-stage/fs/ext3/extents.c +} + +static int ext3_ext_mergable(struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex2) +{ + /* FIXME: support for large fs */ + if (ex1->ee_start + ex1->ee_len == ex2->ee_start) @@ -1862,8 +1896,8 @@ Index: linux-stage/fs/ext3/extents.c + +static int +ext3_remove_blocks_credits(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed; + @@ -1878,8 +1912,8 @@ Index: linux-stage/fs/ext3/extents.c + +static int +ext3_remove_blocks(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed = ext3_remove_blocks_credits(tree, ex, from, to); + handle_t *handle = ext3_journal_start(tree->inode, needed); @@ -1894,7 +1928,7 @@ Index: linux-stage/fs/ext3/extents.c + num = ex->ee_block + ex->ee_len - from; + start = ex->ee_start + ex->ee_len - num; + ext_debug(tree, "free last %lu blocks starting %lu\n", -+ num, start); ++ num, start); + for (i = 0; i < num; i++) { + bh = sb_find_get_block(tree->inode->i_sb, start + i); + ext3_forget(handle, 0, tree->inode, bh, start + i); @@ -1902,17 +1936,17 @@ Index: linux-stage/fs/ext3/extents.c + ext3_free_blocks(handle, tree->inode, start, num); + } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { + printk("strange request: removal %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } else { + printk("strange request: removal(2) %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } + ext3_journal_stop(handle); + return 0; +} + +static int ext3_ext_find_goal(struct inode *inode, -+ struct ext3_ext_path *path, unsigned long block) ++ struct ext3_ext_path *path, unsigned long block) +{ + struct ext3_inode_info *ei = EXT3_I(inode); + unsigned long bg_start; @@ -1942,8 +1976,8 @@ Index: linux-stage/fs/ext3/extents.c +} + +static int ext3_new_block_cb(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int *err) ++ struct ext3_ext_path *path, ++ struct ext3_extent *ex, int *err) +{ + struct inode *inode = tree->inode; + int newblock, goal; @@ -1980,7 +2014,7 @@ Index: linux-stage/fs/ext3/extents.c +}; + +void ext3_init_tree_desc(struct ext3_extents_tree *tree, -+ struct inode *inode) ++ struct inode *inode) +{ + tree->inode = inode; + tree->root = (void *) EXT3_I(inode)->i_data; @@ -1991,8 +2025,8 @@ Index: linux-stage/fs/ext3/extents.c +} + +int ext3_ext_get_block(handle_t *handle, struct inode *inode, -+ long iblock, struct buffer_head *bh_result, -+ int create, int extend_disksize) ++ long iblock, struct buffer_head *bh_result, ++ int create, int extend_disksize) +{ + struct ext3_ext_path *path = NULL; + struct ext3_extent newex; @@ -2003,7 +2037,7 @@ Index: linux-stage/fs/ext3/extents.c + clear_buffer_new(bh_result); + ext3_init_tree_desc(&tree, inode); + ext_debug(&tree, "block %d requested for inode %u\n", -+ (int) iblock, (unsigned) inode->i_ino); ++ (int) iblock, (unsigned) inode->i_ino); + down(&EXT3_I(inode)->truncate_sem); + + /* check in cache */ @@ -2046,11 +2080,11 @@ Index: linux-stage/fs/ext3/extents.c + if (iblock >= ex->ee_block && iblock < ex->ee_block + ex->ee_len) { + newblock = iblock - ex->ee_block + ex->ee_start; + ext_debug(&tree, "%d fit into %d:%d -> %d\n", -+ (int) iblock, ex->ee_block, ex->ee_len, -+ newblock); ++ (int) iblock, ex->ee_block, ex->ee_len, ++ newblock); + ext3_ext_put_in_cache(&tree, ex->ee_block, -+ ex->ee_len, ex->ee_start, -+ EXT3_EXT_CACHE_EXTENT); ++ ex->ee_len, ex->ee_start, ++ EXT3_EXT_CACHE_EXTENT); + goto out; + } + } @@ -2071,7 +2105,7 @@ Index: linux-stage/fs/ext3/extents.c + if (!newblock) + goto out2; + ext_debug(&tree, "allocate new block: goal %d, found %d\n", -+ goal, newblock); ++ goal, newblock); + + /* try to insert new extent into found leaf and return */ + newex.ee_block = iblock; @@ -2089,7 +2123,7 @@ Index: linux-stage/fs/ext3/extents.c + set_buffer_new(bh_result); + + ext3_ext_put_in_cache(&tree, newex.ee_block, newex.ee_len, -+ newex.ee_start, EXT3_EXT_CACHE_EXTENT); ++ newex.ee_start, EXT3_EXT_CACHE_EXTENT); +out: + ext3_ext_show_leaf(&tree, path); + map_bh(bh_result, inode->i_sb, newblock); @@ -2147,8 +2181,8 @@ Index: linux-stage/fs/ext3/extents.c + EXT3_I(inode)->i_disksize = inode->i_size; + ext3_mark_inode_dirty(handle, inode); + -+ last_block = (inode->i_size + sb->s_blocksize - 1) -+ >> EXT3_BLOCK_SIZE_BITS(sb); ++ last_block = (inode->i_size + sb->s_blocksize - 1) >> ++ EXT3_BLOCK_SIZE_BITS(sb); + err = ext3_ext_remove_space(&tree, last_block, EXT_MAX_BLOCK); + + /* In a multi-transaction truncate, we only make the final @@ -2216,13 +2250,14 @@ Index: linux-stage/fs/ext3/extents.c + +static int +ext3_ext_store_extent_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newex, int exist) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *newex) +{ + struct ext3_extent_buf *buf = (struct ext3_extent_buf *) tree->private; + -+ if (!exist) ++ if (newex->ec_type != EXT3_EXT_CACHE_EXTENT) + return EXT_CONTINUE; ++ + if (buf->err < 0) + return EXT_BREAK; + if (buf->cur - buf->buffer + sizeof(*newex) > buf->buflen) @@ -2240,14 +2275,14 @@ Index: linux-stage/fs/ext3/extents.c + +static int +ext3_ext_collect_stats_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int exist) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *ex) +{ + struct ext3_extent_tree_stats *buf = + (struct ext3_extent_tree_stats *) tree->private; + int depth; + -+ if (!exist) ++ if (ex->ec_type != EXT3_EXT_CACHE_EXTENT) + return EXT_CONTINUE; + + depth = EXT_DEPTH(tree); @@ -2278,7 +2313,7 @@ Index: linux-stage/fs/ext3/extents.c + tree.private = &buf; + down(&EXT3_I(inode)->truncate_sem); + err = ext3_ext_walk_space(&tree, buf.start, EXT_MAX_BLOCK, -+ ext3_ext_store_extent_cb); ++ ext3_ext_store_extent_cb); + up(&EXT3_I(inode)->truncate_sem); + if (err == 0) + err = buf.err; @@ -2293,7 +2328,7 @@ Index: linux-stage/fs/ext3/extents.c + buf.leaf_num = 0; + tree.private = &buf; + err = ext3_ext_walk_space(&tree, 0, EXT_MAX_BLOCK, -+ ext3_ext_collect_stats_cb); ++ ext3_ext_collect_stats_cb); + up(&EXT3_I(inode)->truncate_sem); + if (!err) + err = copy_to_user((void *) arg, &buf, sizeof(buf)); @@ -2315,19 +2350,26 @@ Index: linux-stage/fs/ext3/extents.c +EXPORT_SYMBOL(ext3_ext_walk_space); +EXPORT_SYMBOL(ext3_ext_find_goal); +EXPORT_SYMBOL(ext3_ext_calc_credits_for_insert); -+ Index: linux-stage/fs/ext3/ialloc.c =================================================================== --- linux-stage.orig/fs/ext3/ialloc.c 2005-02-25 14:50:50.304202816 +0200 +++ linux-stage/fs/ext3/ialloc.c 2005-02-25 15:33:48.920193600 +0200 -@@ -646,6 +646,10 @@ +@@ -646,6 +646,18 @@ DQUOT_FREE_INODE(inode); goto fail2; } -+ if (test_opt(sb, EXTENTS)) { -+ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; -+ ext3_extents_initialize_blockmap(handle, inode); -+ } ++ if (test_opt(sb, EXTENTS) && S_ISREG(inode->i_mode)) { ++ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; ++ ext3_extents_initialize_blockmap(handle, inode); ++ if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS)) { ++ err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); ++ if (err) goto fail; ++ EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS); ++ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "call ext3_journal_dirty_metadata"); ++ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); ++ } ++ } ++ err = ext3_mark_inode_dirty(handle, inode); if (err) { ext3_std_error(sb, err); @@ -2341,13 +2383,13 @@ Index: linux-stage/fs/ext3/inode.c +static inline int +ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block, -+ struct buffer_head *bh, int create, int extend_disksize) ++ struct buffer_head *bh, int create, int extend_disksize) +{ + if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) + return ext3_ext_get_block(handle, inode, block, bh, create, -+ extend_disksize); ++ extend_disksize); + return ext3_get_block_handle(handle, inode, block, bh, create, -+ extend_disksize); ++ extend_disksize); +} + static int ext3_get_block(struct inode *inode, sector_t iblock, @@ -2360,7 +2402,7 @@ Index: linux-stage/fs/ext3/inode.c - ret = ext3_get_block_handle(handle, inode, iblock, - bh_result, create, 1); + ret = ext3_get_block_wrap(handle, inode, iblock, -+ bh_result, create, 1); ++ bh_result, create, 1); return ret; } @@ -2405,9 +2447,9 @@ Index: linux-stage/fs/ext3/inode.c int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3; int ret; -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) -+ return ext3_ext_writepage_trans_blocks(inode, bpp); -+ ++ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) ++ return ext3_ext_writepage_trans_blocks(inode, bpp); ++ if (ext3_should_journal_data(inode)) ret = 3 * (bpp + indirects) + 2; else @@ -2432,18 +2474,16 @@ Index: linux-stage/fs/ext3/super.c struct ext3_super_block *es = sbi->s_es; int i; -+ ext3_ext_release(sb); ++ ext3_ext_release(sb); ext3_xattr_put_super(sb); journal_destroy(sbi->s_journal); if (!(sb->s_flags & MS_RDONLY)) { -@@ -457,6 +458,10 @@ +@@ -457,6 +458,8 @@ #endif ei->i_rsv_window.rsv_end = EXT3_RESERVE_WINDOW_NOT_ALLOCATED; ei->vfs_inode.i_version = 1; -+ ei->i_cached_extent[0] = 0; -+ ei->i_cached_extent[1] = 0; -+ ei->i_cached_extent[2] = 0; -+ ei->i_cached_extent[3] = 0; ++ ++ memset(&ei->i_cached_extent, 0, sizeof(ei->i_cached_extent)); return &ei->vfs_inode; } @@ -2482,8 +2522,8 @@ Index: linux-stage/fs/ext3/super.c percpu_counter_mod(&sbi->s_dirs_counter, ext3_count_dirs(sb)); -+ ext3_ext_init(sb); -+ ++ ext3_ext_init(sb); ++ return 0; failed_mount3: @@ -2506,14 +2546,17 @@ Index: linux-stage/include/linux/ext3_fs.h =================================================================== --- linux-stage.orig/include/linux/ext3_fs.h 2005-02-25 14:53:56.424908168 +0200 +++ linux-stage/include/linux/ext3_fs.h 2005-02-25 15:39:12.841950008 +0200 -@@ -186,6 +186,7 @@ +@@ -186,8 +186,9 @@ #define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ #define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ +#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ - #define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ +-#define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ ++#define EXT3_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */ #define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ + + /* @@ -237,6 +238,9 @@ #endif #define EXT3_IOC_GETRSVSZ _IOR('f', 5, long) @@ -2524,16 +2567,30 @@ Index: linux-stage/include/linux/ext3_fs.h /* * Structure of an inode on the disk -@@ -359,6 +363,9 @@ +@@ -359,6 +363,8 @@ #define EXT3_MOUNT_RESERVATION 0x20000 /* Preallocation */ #define EXT3_MOUNT_IOPEN 0x40000 /* Allow access via iopen */ #define EXT3_MOUNT_IOPEN_NOPRIV 0x80000 /* Make iopen world-readable */ +#define EXT3_MOUNT_EXTENTS 0x100000/* Extents support */ +#define EXT3_MOUNT_EXTDEBUG 0x200000/* Extents debug */ -+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H +@@ -503,11 +509,13 @@ + #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ + #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ + #define EXT3_FEATURE_INCOMPAT_META_BG 0x0010 ++#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ + + #define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR + #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ + EXT3_FEATURE_INCOMPAT_RECOVER| \ +- EXT3_FEATURE_INCOMPAT_META_BG) ++ EXT3_FEATURE_INCOMPAT_META_BG| \ ++ EXT3_FEATURE_INCOMPAT_EXTENTS) + #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ + EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ + EXT3_FEATURE_RO_COMPAT_BTREE_DIR) @@ -756,6 +763,7 @@ @@ -2549,7 +2606,7 @@ Index: linux-stage/include/linux/ext3_fs.h +/* extents.c */ +extern int ext3_ext_writepage_trans_blocks(struct inode *, int); +extern int ext3_ext_get_block(handle_t *, struct inode *, long, -+ struct buffer_head *, int, int); ++ struct buffer_head *, int, int); +extern void ext3_ext_truncate(struct inode *, struct page *); +extern void ext3_ext_init(struct super_block *); +extern void ext3_ext_release(struct super_block *); @@ -2563,7 +2620,7 @@ Index: linux-stage/include/linux/ext3_extents.h =================================================================== --- linux-stage.orig/include/linux/ext3_extents.h 2005-02-25 15:33:48.891198008 +0200 +++ linux-stage/include/linux/ext3_extents.h 2005-02-25 15:33:48.944189952 +0200 -@@ -0,0 +1,252 @@ +@@ -0,0 +1,264 @@ +/* + * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas @@ -2605,7 +2662,7 @@ Index: linux-stage/include/linux/ext3_extents.h + */ +#define EXT_DEBUG_ +#ifdef EXT_DEBUG -+#define ext_debug(tree,fmt,a...) \ ++#define ext_debug(tree,fmt,a...) \ +do { \ + if (test_opt((tree)->inode->i_sb, EXTDEBUG)) \ + printk(fmt, ##a); \ @@ -2718,14 +2775,14 @@ Index: linux-stage/include/linux/ext3_extents.h + int (*mark_buffer_dirty)(handle_t *h, void *buffer); + int (*mergable)(struct ext3_extent *ex1, struct ext3_extent *ex2); + int (*remove_extent_credits)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*remove_extent)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*new_block)(handle_t *, struct ext3_extents_tree *, -+ struct ext3_ext_path *, struct ext3_extent *, -+ int *); ++ struct ext3_ext_path *, struct ext3_extent *, ++ int *); +}; + +/* @@ -2735,8 +2792,8 @@ Index: linux-stage/include/linux/ext3_extents.h + * callback must return valid extent (passed or newly created) + */ +typedef int (*ext_prepare_callback)(struct ext3_extents_tree *, -+ struct ext3_ext_path *, -+ struct ext3_extent *, int); ++ struct ext3_ext_path *, ++ struct ext3_ext_cache *); + +#define EXT_CONTINUE 0 +#define EXT_BREAK 1 @@ -2744,7 +2801,6 @@ Index: linux-stage/include/linux/ext3_extents.h + + +#define EXT_MAX_BLOCK 0xffffffff -+#define EXT_CACHE_MARK 0xffff + + +#define EXT_FIRST_EXTENT(__hdr__) \ @@ -2776,6 +2832,20 @@ Index: linux-stage/include/linux/ext3_extents.h + +#define EXT_ASSERT(__x__) if (!(__x__)) BUG(); + ++#define EXT_CHECK_PATH(tree,path) \ ++{ \ ++ int depth = EXT_DEPTH(tree); \ ++ BUG_ON((unsigned long) (path) < __PAGE_OFFSET); \ ++ BUG_ON((unsigned long) (path)[depth].p_idx < \ ++ __PAGE_OFFSET && (path)[depth].p_idx != NULL); \ ++ BUG_ON((unsigned long) (path)[depth].p_ext < \ ++ __PAGE_OFFSET && (path)[depth].p_ext != NULL); \ ++ BUG_ON((unsigned long) (path)[depth].p_hdr < __PAGE_OFFSET); \ ++ BUG_ON((unsigned long) (path)[depth].p_bh < __PAGE_OFFSET \ ++ && depth != 0); \ ++ BUG_ON((path)[0].p_depth != depth); \ ++} ++ + +/* + * this structure is used to gather extents from the tree via ioctl @@ -2797,13 +2867,13 @@ Index: linux-stage/include/linux/ext3_extents.h + int leaf_num; +}; + ++extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); +extern int ext3_extent_tree_init(handle_t *, struct ext3_extents_tree *); +extern int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *, struct ext3_ext_path *); +extern int ext3_ext_insert_extent(handle_t *, struct ext3_extents_tree *, struct ext3_ext_path *, struct ext3_extent *); +extern int ext3_ext_walk_space(struct ext3_extents_tree *, unsigned long, unsigned long, ext_prepare_callback); +extern int ext3_ext_remove_space(struct ext3_extents_tree *, unsigned long, unsigned long); +extern struct ext3_ext_path * ext3_ext_find_extent(struct ext3_extents_tree *, int, struct ext3_ext_path *); -+extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); +extern int ext3_ext_calc_blockmap_metadata(struct inode *, int); + +static inline void @@ -2815,7 +2885,6 @@ Index: linux-stage/include/linux/ext3_extents.h + + +#endif /* _LINUX_EXT3_EXTENTS */ -+ Index: linux-stage/include/linux/ext3_fs_i.h =================================================================== --- linux-stage.orig/include/linux/ext3_fs_i.h 2005-02-25 14:50:50.320200384 +0200 @@ -2825,7 +2894,7 @@ Index: linux-stage/include/linux/ext3_fs_i.h struct semaphore truncate_sem; struct inode vfs_inode; + -+ __u32 i_cached_extent[4]; ++ __u32 i_cached_extent[4]; }; #endif /* _LINUX_EXT3_FS_I */ diff --git a/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch b/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch index 82957f1..b9bcfac 100644 --- a/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch +++ b/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch @@ -1,10 +1,10 @@ -Index: linux-2.6.5-sles9/fs/ext3/mballoc.c +Index: linux-2.6.5-suse/fs/ext3/mballoc.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/mballoc.c 2005-02-17 22:07:57.023609040 +0300 -+++ linux-2.6.5-sles9/fs/ext3/mballoc.c 2005-02-23 01:56:19.101662000 +0300 -@@ -0,0 +1,1835 @@ +--- linux-2.6.5-suse.orig/fs/ext3/mballoc.c 2005-03-02 22:42:20.659360368 +0300 ++++ linux-2.6.5-suse/fs/ext3/mballoc.c 2005-03-11 16:13:13.000000000 +0300 +@@ -0,0 +1,1863 @@ +/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com ++ * Copyright(c) 2003, 2004, 2005, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify @@ -39,6 +39,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + +/* + * TODO: ++ * - bitmap/buddy read-ahead (proposed by Oleg Drokin aka green) + * - track min/max extents in each group for better group selection + * - is it worthwhile to use buddies directly if req is 2^N blocks? + * - mb_mark_used() may allocate chunk right after splitting buddy @@ -96,7 +97,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + __u32 mh_magic; +}; + -+#define EXT3_MB_MAGIC_V1 0xbaad16fc ++#define EXT3_MB_MAGIC_V1 0xbabd16fd + + +struct ext3_free_extent { @@ -109,7 +110,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + struct super_block *ac_sb; + + /* search goals */ -+struct ext3_free_extent ac_g_ex; ++ struct ext3_free_extent ac_g_ex; + + /* the best found extent */ + struct ext3_free_extent ac_b_ex; @@ -148,47 +149,50 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c +void ext3_mb_poll_new_transaction(struct super_block *, handle_t *); +void ext3_mb_free_committed_blocks(struct super_block *); + -+#define mb_correct_addr_and_bit(bit,addr) \ -+{ \ -+ if ((unsigned long)addr & 1) { \ -+ bit += 8; \ -+ addr--; \ -+ } \ -+ if ((unsigned long)addr & 2) { \ -+ bit += 16; \ -+ addr--; \ -+ addr--; \ -+ } \ ++#if BITS_PER_LONG == 64 ++#define mb_correct_addr_and_bit(bit,addr) \ ++{ \ ++ bit += ((unsigned long) addr & 7UL) << 3; \ ++ addr = (void *) ((unsigned long) addr & ~7UL); \ +} ++#elif BITS_PER_LONG == 32 ++#define mb_correct_addr_and_bit(bit,addr) \ ++{ \ ++ bit += ((unsigned long) addr & 3UL) << 3; \ ++ addr = (void *) ((unsigned long) addr & ~3UL); \ ++} ++#else ++#error "how many bits you are?!" ++#endif + +static inline int mb_test_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ return test_bit(bit, addr); ++ return ext2_test_bit(bit, addr); +} + +static inline void mb_set_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ __set_bit(bit, addr); ++ ext2_set_bit(bit, addr); +} + +static inline void mb_set_bit_atomic(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ set_bit(bit, addr); ++ ext2_set_bit_atomic(NULL, bit, addr); +} + +static inline void mb_clear_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ __clear_bit(bit, addr); ++ ext2_clear_bit(bit, addr); +} + +static inline void mb_clear_bit_atomic(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ clear_bit(bit, addr); ++ ext2_clear_bit_atomic(NULL, bit, addr); +} + +static inline void *mb_find_buddy(struct ext3_buddy *e3b, int order, int *max) @@ -199,8 +203,10 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + J_ASSERT(EXT3_MB_BITMAP(e3b) != EXT3_MB_BUDDY(e3b)); + J_ASSERT(max != NULL); + -+ if (order > e3b->bd_blkbits + 1) ++ if (order > e3b->bd_blkbits + 1) { ++ *max = 0; + return NULL; ++ } + + /* at order 0 we see each particular block */ + *max = 1 << (e3b->bd_blkbits + 3); @@ -234,12 +240,6 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + "can't get block for buddy bitmap\n"); + goto out; + } -+ if (!buffer_uptodate(e3b->bd_bh)) { -+ ll_rw_block(READ, 1, &e3b->bd_bh); -+ wait_on_buffer(e3b->bd_bh); -+ } -+ J_ASSERT(buffer_uptodate(e3b->bd_bh)); -+ + /* load buddy */ + e3b->bd_bh2 = sb_getblk(sb, sbi->s_buddy_blocks[group]->bb_buddy); + if (e3b->bd_bh2 == NULL) { @@ -247,10 +247,15 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + "can't get block for buddy bitmap\n"); + goto out; + } -+ if (!buffer_uptodate(e3b->bd_bh2)) { ++ ++ if (!buffer_uptodate(e3b->bd_bh)) ++ ll_rw_block(READ, 1, &e3b->bd_bh); ++ if (!buffer_uptodate(e3b->bd_bh2)) + ll_rw_block(READ, 1, &e3b->bd_bh2); -+ wait_on_buffer(e3b->bd_bh2); -+ } ++ ++ wait_on_buffer(e3b->bd_bh); ++ J_ASSERT(buffer_uptodate(e3b->bd_bh)); ++ wait_on_buffer(e3b->bd_bh2); + J_ASSERT(buffer_uptodate(e3b->bd_bh2)); + + e3b->bd_blkbits = sb->s_blocksize_bits; @@ -300,22 +305,22 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + count = 0; + for (i = 0; i < max; i++) { + -+ if (!mb_test_bit(i, buddy)) { ++ if (mb_test_bit(i, buddy)) { + /* only single bit in buddy2 may be 1 */ -+ if (mb_test_bit(i << 1, buddy2)) -+ J_ASSERT(!mb_test_bit((i<<1)+1, buddy2)); -+ else if (mb_test_bit((i << 1) + 1, buddy2)) -+ J_ASSERT(!mb_test_bit(i << 1, buddy2)); ++ if (!mb_test_bit(i << 1, buddy2)) ++ J_ASSERT(mb_test_bit((i<<1)+1, buddy2)); ++ else if (!mb_test_bit((i << 1) + 1, buddy2)) ++ J_ASSERT(mb_test_bit(i << 1, buddy2)); + continue; + } + + /* both bits in buddy2 must be 0 */ -+ J_ASSERT(!mb_test_bit(i << 1, buddy2)); -+ J_ASSERT(!mb_test_bit((i << 1) + 1, buddy2)); ++ J_ASSERT(mb_test_bit(i << 1, buddy2)); ++ J_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); + + for (j = 0; j < (1 << order); j++) { + k = (i * (1 << order)) + j; -+ J_ASSERT(mb_test_bit(k, EXT3_MB_BITMAP(e3b))); ++ J_ASSERT(!mb_test_bit(k, EXT3_MB_BITMAP(e3b))); + } + count++; + } @@ -325,14 +330,14 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + + buddy = mb_find_buddy(e3b, 0, &max); + for (i = 0; i < max; i++) { -+ if (mb_test_bit(i, buddy)) ++ if (!mb_test_bit(i, buddy)) + continue; + /* check used bits only */ + for (j = 0; j < e3b->bd_blkbits + 1; j++) { + buddy2 = mb_find_buddy(e3b, j, &max2); + k = i >> j; + J_ASSERT(k < max2); -+ J_ASSERT(!mb_test_bit(k, buddy2)); ++ J_ASSERT(mb_test_bit(k, buddy2)); + } + } +} @@ -363,7 +368,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + bb = EXT3_MB_BUDDY(e3b); + while (order <= e3b->bd_blkbits + 1) { + block = block >> 1; -+ if (mb_test_bit(block, bb)) { ++ if (!mb_test_bit(block, bb)) { + /* this block is part of buddy of order 'order' */ + return order; + } @@ -424,8 +429,8 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + block = first++; + order = 0; + -+ J_ASSERT(!mb_test_bit(block, EXT3_MB_BITMAP(e3b))); -+ mb_set_bit(block, EXT3_MB_BITMAP(e3b)); ++ J_ASSERT(mb_test_bit(block, EXT3_MB_BITMAP(e3b))); ++ mb_clear_bit(block, EXT3_MB_BITMAP(e3b)); + e3b->bd_bd->bb_counters[order]++; + + /* start of the buddy */ @@ -433,8 +438,8 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + + do { + block &= ~1UL; -+ if (!mb_test_bit(block, buddy) || -+ !mb_test_bit(block + 1, buddy)) ++ if (mb_test_bit(block, buddy) || ++ mb_test_bit(block + 1, buddy)) + break; + + /* both the buddies are free, try to coalesce them */ @@ -444,10 +449,10 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + break; + + if (order > 0) { -+ /* for special purposes, we don't clear ++ /* for special purposes, we don't set + * free bits in bitmap */ -+ mb_clear_bit(block, buddy); -+ mb_clear_bit(block + 1, buddy); ++ mb_set_bit(block, buddy); ++ mb_set_bit(block + 1, buddy); + } + e3b->bd_bd->bb_counters[order]--; + e3b->bd_bd->bb_counters[order]--; @@ -456,7 +461,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + order++; + e3b->bd_bd->bb_counters[order]++; + -+ mb_set_bit(block, buddy2); ++ mb_clear_bit(block, buddy2); + buddy = buddy2; + } while (1); + } @@ -466,7 +471,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c +} + +static int mb_find_extent(struct ext3_buddy *e3b, int order, int block, -+ int needed, struct ext3_free_extent *ex) ++ int needed, struct ext3_free_extent *ex) +{ + int next, max, ord; + void *buddy; @@ -476,7 +481,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + buddy = mb_find_buddy(e3b, order, &max); + J_ASSERT(buddy); + J_ASSERT(block < max); -+ if (!mb_test_bit(block, buddy)) { ++ if (mb_test_bit(block, buddy)) { + ex->fe_len = 0; + ex->fe_start = 0; + ex->fe_group = 0; @@ -499,7 +504,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + break; + + next = (block + 1) * (1 << order); -+ if (!mb_test_bit(next, EXT3_MB_BITMAP(e3b))) ++ if (mb_test_bit(next, EXT3_MB_BITMAP(e3b))) + break; + + ord = mb_find_order_for_block(e3b, next); @@ -533,7 +538,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + mlen = 1 << ord; + buddy = mb_find_buddy(e3b, ord, &max); + J_ASSERT((start >> ord) < max); -+ mb_clear_bit(start >> ord, buddy); ++ mb_set_bit(start >> ord, buddy); + e3b->bd_bd->bb_counters[ord]--; + start += mlen; + len -= mlen; @@ -544,20 +549,20 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + /* we have to split large buddy */ + J_ASSERT(ord > 0); + buddy = mb_find_buddy(e3b, ord, &max); -+ mb_clear_bit(start >> ord, buddy); ++ mb_set_bit(start >> ord, buddy); + e3b->bd_bd->bb_counters[ord]--; + + ord--; + cur = (start >> ord) & ~1U; + buddy = mb_find_buddy(e3b, ord, &max); -+ mb_set_bit(cur, buddy); -+ mb_set_bit(cur + 1, buddy); ++ mb_clear_bit(cur, buddy); ++ mb_clear_bit(cur + 1, buddy); + e3b->bd_bd->bb_counters[ord]++; + e3b->bd_bd->bb_counters[ord]++; + } + + /* now drop all the bits in bitmap */ -+ mb_clear_bits(EXT3_MB_BITMAP(e3b), ex->fe_start, len0); ++ mb_set_bits(EXT3_MB_BITMAP(e3b), ex->fe_start, len0); + + mb_check_buddy(e3b); + @@ -733,7 +738,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + i = e3b->bd_bd->bb_first_free; + + while (free && ac->ac_status != AC_STATUS_FOUND) { -+ i = find_next_bit(bitmap, sb->s_blocksize * 8, i); ++ i = ext2_find_next_zero_bit(bitmap, sb->s_blocksize * 8, i); + if (i >= sb->s_blocksize * 8) { + J_ASSERT(free == 0); + break; @@ -951,7 +956,6 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + /* + * We aren't lucky definitely + */ -+ J_ASSERT(ac.ac_b_ex.fe_len == 0); + DQUOT_FREE_BLOCK(inode, *len); + *errp = -ENOSPC; + block = 0; @@ -1020,8 +1024,8 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + ext3_error(sb, "ext3_new_block", + "Allocating block in system zone - " + "block = %u", block); -+#if AGGRESSIVE_CHECK -+ for (i = 0; i < ac.ac_b_len; i++) ++#ifdef AGGRESSIVE_CHECK ++ for (i = 0; i < ac.ac_b_ex.fe_len; i++) + J_ASSERT(!mb_test_bit(ac.ac_b_ex.fe_start + i, bitmap_bh->b_data)); +#endif + mb_set_bits(bitmap_bh->b_data, ac.ac_b_ex.fe_start, ac.ac_b_ex.fe_len); @@ -1141,7 +1145,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + + e3b->bd_bd->bb_first_free = grp->mgd_first_free; + e3b->bd_bd->bb_free = grp->mgd_free; -+ for (i = 0; i < e3b->bd_blkbits; i++) { ++ for (i = 0; i <= e3b->bd_blkbits + 1; i++) { + J_ASSERT(i < 16); + e3b->bd_bd->bb_counters[i] = grp->mgd_counters[i]; + } @@ -1155,7 +1159,6 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + printk(KERN_ERR "EXT3-fs: mbgroup %d corrupted (%d != %d)\n", + e3b->bd_group, e3b->bd_bd->bb_free, + le16_to_cpu(gdp->bg_free_blocks_count)); -+ BUG(); + return -ENODATA; + } + @@ -1166,20 +1169,19 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c +int ext3_mb_update_descr(struct ext3_buddy *e3b) +{ + struct ext3_mb_group_descr *grp; -+ struct ext3_group_desc *ogdp; ++ struct ext3_group_desc *gdp; + struct buffer_head *bh; + handle_t *handle; + int err, i; + + /* additional checks against old group descriptor */ -+ ogdp = ext3_get_group_desc(e3b->bd_sb, e3b->bd_group, NULL); -+ if (!ogdp) ++ gdp = ext3_get_group_desc(e3b->bd_sb, e3b->bd_group, NULL); ++ if (!gdp) + return -EIO; -+ if (e3b->bd_bd->bb_free != le16_to_cpu(ogdp->bg_free_blocks_count)) { ++ if (e3b->bd_bd->bb_free != le16_to_cpu(gdp->bg_free_blocks_count)) { + printk(KERN_ERR "EXT3-fs: mbgroup %d corrupted (%d != %d)\n", + e3b->bd_group, e3b->bd_bd->bb_free, -+ le16_to_cpu(ogdp->bg_free_blocks_count)); -+ BUG(); ++ le16_to_cpu(gdp->bg_free_blocks_count)); + return -ENODATA; + } + @@ -1187,7 +1189,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + if (err) + return err; + -+ handle = journal_start(EXT3_SB(e3b->bd_sb)->s_journal, 1); ++ handle = ext3_journal_start(EXT3_SB(e3b->bd_sb)->s_buddy, 1); + if (IS_ERR(handle)) { + err = PTR_ERR(handle); + handle = NULL; @@ -1199,7 +1201,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + goto out; + grp->mgd_first_free = e3b->bd_bd->bb_first_free; + grp->mgd_free = e3b->bd_bd->bb_free; -+ for (i = 0; i < e3b->bd_blkbits; i++) { ++ for (i = 0; i <= e3b->bd_blkbits + 1; i++) { + J_ASSERT(i < 16); + grp->mgd_counters[i] = e3b->bd_bd->bb_counters[i]; + } @@ -1219,16 +1221,24 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + struct super_block *sb = e3b->bd_sb; + struct buffer_head *bh; + int i, count = 0; -+ -+ memset(e3b->bd_bh->b_data, 0, sb->s_blocksize); -+ memset(e3b->bd_bh2->b_data, 0, sb->s_blocksize); ++ ++ mb_debug("generate buddy for group %d\n", e3b->bd_group); ++ memset(e3b->bd_bh->b_data, 0xff, sb->s_blocksize); ++ memset(e3b->bd_bh2->b_data, 0xff, sb->s_blocksize); + + bh = read_block_bitmap(sb, e3b->bd_group); + if (bh == NULL) + return -EIO; + + /* mb_free_blocks will set real free */ ++ e3b->bd_bd->bb_free = 0; + e3b->bd_bd->bb_first_free = 1 << 15; ++ /* ++ * if change bb_counters size, don't forget about ++ * ext3_mb_init_backend() -bzzz ++ */ ++ memset(e3b->bd_bd->bb_counters, 0, ++ sizeof(unsigned) * (sb->s_blocksize_bits + 2)); + + /* loop over the blocks, and create buddies for free ones */ + for (i = 0; i < sb->s_blocksize * 8; i++) { @@ -1291,7 +1301,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + } + db->d_inode->i_flags |= S_IMMUTABLE | S_NOATIME; + *created = 1; -+ printk("EXT3-fs: no buddy file, regenerate\n"); ++ mb_debug("no buddy file, regenerate\n"); + } + up(&root->i_sem); + sbi->s_buddy = igrab(db->d_inode); @@ -1304,8 +1314,10 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + len = sbi->s_groups_count * sb->s_blocksize * 2 + + buddy_offset * sb->s_blocksize; + if (len != i_size_read(sbi->s_buddy)) { -+ printk("EXT3-fs: wrong i_size (%u != %u), regenerate\n", -+ (unsigned) len, (unsigned) i_size_read(sbi->s_buddy)); ++ if (*created == 0) ++ printk("EXT3-fs: wrong i_size (%u != %u), regenerate\n", ++ (unsigned) len, ++ (unsigned) i_size_read(sbi->s_buddy)); + *created = 1; + } + @@ -1313,14 +1325,14 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + for (i = 0; i < buddy_offset; i++) { + handle = ext3_journal_start(sbi->s_buddy, MB_CREDITS); + if (IS_ERR(handle)) { -+ printk(KERN_ERR "EXT3-fs: can't start transaction\n"); ++ printk(KERN_ERR "EXT3-fs: cant start transaction\n"); + err = PTR_ERR(handle); + goto err_out; + } + + bh = ext3_bread(handle, sbi->s_buddy, i, 1, &err); + if (bh == NULL) { -+ printk(KERN_ERR "EXT3-fs: can't getblk grp: %d\n", err); ++ printk(KERN_ERR "EXT3-fs: cant getblk grp: %d\n", err); + goto err_out; + } + hdr = (struct ext3_mb_grp_header *) bh->b_data; @@ -1328,9 +1340,11 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + err = ext3_journal_get_write_access(handle, bh); + if (err) + goto err_out; ++ if (*created == 0) ++ printk(KERN_ERR ++ "EXT3-fs: invalid header 0x%x in %d," ++ "regenerate\n", hdr->mh_magic, i); + *created = 1; -+ printk("EXT3-fs: invalid header %#x in %d regenerate\n", -+ hdr->mh_magic, i); + hdr->mh_magic = EXT3_MB_MAGIC_V1; + err = ext3_journal_dirty_metadata(handle, bh); + if (err) @@ -1340,12 +1354,16 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + ext3_journal_stop(handle); + } + ++ /* ++ * if change bb_counters size, don't forget about ext3_mb_generate_buddy() ++ */ + len = sizeof(struct ext3_buddy_group_blocks); + len += sizeof(unsigned) * (sb->s_blocksize_bits + 2); + for (i = 0; i < sbi->s_groups_count; i++) { ++ + sbi->s_buddy_blocks[i] = kmalloc(len, GFP_KERNEL); + if (sbi->s_buddy_blocks[i] == NULL) { -+ printk(KERN_ERR "EXT3-fs: can't allocate buddy mem\n"); ++ printk(KERN_ERR "EXT3-fs: cant allocate mem for buddy\n"); + err = -ENOMEM; + goto out2; + } @@ -1353,7 +1371,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + + handle = ext3_journal_start(sbi->s_buddy, MB_CREDITS); + if (IS_ERR(handle)) { -+ printk(KERN_ERR "EXT3-fs: can't start transaction\n"); ++ printk(KERN_ERR "EXT3-fs: cant start transaction\n"); + err = PTR_ERR(handle); + goto out2; + } @@ -1362,8 +1380,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + block = buddy_offset + i * 2; + bh = ext3_getblk(handle, sbi->s_buddy, block, 1, &err); + if (bh == NULL) { -+ printk(KERN_ERR "EXT3-fs: can't getblk bitmap: %d\n", -+ err); ++ printk(KERN_ERR "EXT3-fs: cant getblk bitmap: %d\n", err); + goto out2; + } + sbi->s_buddy_blocks[i]->bb_bitmap = bh->b_blocknr; @@ -1373,7 +1390,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + block = buddy_offset + i * 2 + 1; + bh = ext3_getblk(handle, sbi->s_buddy, block, 1, &err); + if (bh == NULL) { -+ printk(KERN_ERR "EXT3-fs: can't getblk for buddy: %d\n",+ err); ++ printk(KERN_ERR "EXT3-fs: cant getblk for buddy: %d\n", err); + goto out2; + } + sbi->s_buddy_blocks[i]->bb_buddy = bh->b_blocknr; @@ -1736,6 +1753,19 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + if (err) + goto error_return; + ++#ifdef AGGRESSIVE_CHECK ++ { ++ int i; ++ for (i = 0; i < count; i++) ++ J_ASSERT(mb_test_bit(bit + i, bitmap_bh->b_data)); ++ } ++#endif ++ mb_clear_bits(bitmap_bh->b_data, bit, count); ++ ++ /* We dirtied the bitmap block */ ++ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); ++ err = ext3_journal_dirty_metadata(handle, bitmap_bh); ++ + if (metadata) { + /* blocks being freed are metadata. these blocks shouldn't + * be used until this transaction is committed */ @@ -1745,21 +1775,18 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + mb_free_blocks(&e3b, bit, count); + ext3_unlock_group(sb, block_group); + } ++ + spin_lock(sb_bgl_lock(sbi, block_group)); + gdp->bg_free_blocks_count = + cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) + count); + spin_unlock(sb_bgl_lock(sbi, block_group)); ++ percpu_counter_mod(&sbi->s_freeblocks_counter, count); + + ext3_mb_dirty_buddy(&e3b); + ext3_mb_release_desc(&e3b); + -+ mb_clear_bits(bitmap_bh->b_data, bit, count); + *freed = count; + -+ /* We dirtied the bitmap block */ -+ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); -+ err = ext3_journal_dirty_metadata(handle, bitmap_bh); -+ + /* And the group descriptor block */ + BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); + ret = ext3_journal_dirty_metadata(handle, gd_bh); @@ -1821,6 +1848,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + return ret; +} + ++ +extern void ext3_free_blocks_old(handle_t *, struct inode *, + unsigned long, unsigned long); +void ext3_free_blocks(handle_t *handle, struct inode * inode, @@ -1838,19 +1866,19 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + return; +} + -Index: linux-2.6.5-sles9/fs/ext3/super.c +Index: linux-2.6.5-suse/fs/ext3/super.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/super.c 2005-02-23 01:47:15.291333736 +0300 -+++ linux-2.6.5-sles9/fs/ext3/super.c 2005-02-23 01:48:54.515249408 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/super.c 2005-02-26 18:40:25.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/super.c 2005-02-26 18:40:26.000000000 +0300 @@ -389,6 +389,7 @@ struct ext3_super_block *es = sbi->s_es; int i; + ext3_mb_release(sb); - ext3_ext_release(sb); + ext3_ext_release(sb); ext3_xattr_put_super(sb); journal_destroy(sbi->s_journal); -@@ -540,6 +541,7 @@ +@@ -543,6 +544,7 @@ Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, Opt_ignore, Opt_barrier, Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, @@ -1858,7 +1886,7 @@ Index: linux-2.6.5-sles9/fs/ext3/super.c Opt_err, Opt_extents, Opt_extdebug }; -@@ -587,6 +589,8 @@ +@@ -590,6 +592,8 @@ {Opt_iopen_nopriv, "iopen_nopriv"}, {Opt_extents, "extents"}, {Opt_extdebug, "extdebug"}, @@ -1867,7 +1895,7 @@ Index: linux-2.6.5-sles9/fs/ext3/super.c {Opt_err, NULL} }; -@@ -808,6 +812,16 @@ +@@ -811,6 +815,16 @@ case Opt_extdebug: set_opt (sbi->s_mount_opt, EXTDEBUG); break; @@ -1884,20 +1912,18 @@ Index: linux-2.6.5-sles9/fs/ext3/super.c default: printk (KERN_ERR "EXT3-fs: Unrecognized mount option \"%s\" " -@@ -1461,7 +1475,8 @@ +@@ -1464,6 +1478,7 @@ ext3_count_dirs(sb)); - ext3_ext_init(sb); -- + ext3_ext_init(sb); + ext3_mb_init(sb, needs_recovery); -+ + return 0; - failed_mount3: -Index: linux-2.6.5-sles9/fs/ext3/Makefile +Index: linux-2.6.5-suse/fs/ext3/Makefile =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/Makefile 2005-02-23 01:02:37.405434272 +0300 -+++ linux-2.6.5-sles9/fs/ext3/Makefile 2005-02-23 01:48:54.517249104 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/Makefile 2005-02-26 18:40:25.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/Makefile 2005-02-26 18:40:26.000000000 +0300 @@ -5,7 +5,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o @@ -1907,10 +1933,10 @@ Index: linux-2.6.5-sles9/fs/ext3/Makefile ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o -Index: linux-2.6.5-sles9/fs/ext3/balloc.c +Index: linux-2.6.5-suse/fs/ext3/balloc.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/balloc.c 2004-11-03 08:36:51.000000000 +0300 -+++ linux-2.6.5-sles9/fs/ext3/balloc.c 2005-02-23 01:48:54.520248648 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/balloc.c 2005-02-02 00:55:47.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/balloc.c 2005-02-26 18:40:26.000000000 +0300 @@ -78,7 +78,7 @@ * * Return buffer_head on success or NULL in case of failure. @@ -1938,10 +1964,10 @@ Index: linux-2.6.5-sles9/fs/ext3/balloc.c unsigned long goal, int *errp) { struct buffer_head *bitmap_bh = NULL; -Index: linux-2.6.5-sles9/fs/ext3/namei.c +Index: linux-2.6.5-suse/fs/ext3/namei.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/namei.c 2005-02-23 01:01:46.551165296 +0300 -+++ linux-2.6.5-sles9/fs/ext3/namei.c 2005-02-23 01:48:54.523248192 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/namei.c 2005-02-26 18:40:19.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/namei.c 2005-02-26 18:40:26.000000000 +0300 @@ -1640,7 +1640,7 @@ * If the create succeeds, we fill in the inode information * with d_instantiate(). @@ -1951,10 +1977,10 @@ Index: linux-2.6.5-sles9/fs/ext3/namei.c struct nameidata *nd) { handle_t *handle; -Index: linux-2.6.5-sles9/fs/ext3/inode.c +Index: linux-2.6.5-suse/fs/ext3/inode.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/inode.c 2005-02-23 01:02:37.404434424 +0300 -+++ linux-2.6.5-sles9/fs/ext3/inode.c 2005-02-23 01:48:54.529247280 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/inode.c 2005-02-26 18:40:25.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/inode.c 2005-02-26 18:40:26.000000000 +0300 @@ -572,7 +572,7 @@ ext3_journal_forget(handle, branch[i].bh); } @@ -1973,7 +1999,7 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c return err; } -@@ -1829,7 +1829,7 @@ +@@ -1830,7 +1830,7 @@ } } @@ -1982,7 +2008,7 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c } /** -@@ -2000,7 +2000,7 @@ +@@ -2001,7 +2001,7 @@ ext3_journal_test_restart(handle, inode); } @@ -1991,10 +2017,10 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c if (parent_bh) { /* -Index: linux-2.6.5-sles9/fs/ext3/extents.c +Index: linux-2.6.5-suse/fs/ext3/extents.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/extents.c 2005-02-23 01:02:37.396435640 +0300 -+++ linux-2.6.5-sles9/fs/ext3/extents.c 2005-02-23 01:48:54.533246672 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/extents.c 2005-02-26 18:40:25.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/extents.c 2005-02-26 18:40:26.000000000 +0300 @@ -774,7 +774,7 @@ for (i = 0; i < depth; i++) { if (!ablocks[i]) @@ -2036,10 +2062,10 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { printk("strange request: removal %lu-%lu from %u:%u\n", from, to, ex->ee_block, ex->ee_len); -Index: linux-2.6.5-sles9/fs/ext3/xattr.c +Index: linux-2.6.5-suse/fs/ext3/xattr.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/xattr.c 2005-02-23 01:01:52.387278072 +0300 -+++ linux-2.6.5-sles9/fs/ext3/xattr.c 2005-02-23 01:48:54.537246064 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/xattr.c 2005-02-26 18:40:22.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/xattr.c 2005-02-26 18:40:26.000000000 +0300 @@ -1366,7 +1366,7 @@ new_bh = sb_getblk(sb, block); if (!new_bh) { @@ -2067,10 +2093,10 @@ Index: linux-2.6.5-sles9/fs/ext3/xattr.c get_bh(bh); ext3_forget(handle, 1, inode, bh, EXT3_I(inode)->i_file_acl); } else { -Index: linux-2.6.5-sles9/include/linux/ext3_fs.h +Index: linux-2.6.5-suse/include/linux/ext3_fs.h =================================================================== ---- linux-2.6.5-sles9.orig/include/linux/ext3_fs.h 2005-02-23 01:02:37.414432904 +0300 -+++ linux-2.6.5-sles9/include/linux/ext3_fs.h 2005-02-23 01:48:54.539245760 +0300 +--- linux-2.6.5-suse.orig/include/linux/ext3_fs.h 2005-02-26 18:40:25.000000000 +0300 ++++ linux-2.6.5-suse/include/linux/ext3_fs.h 2005-02-26 18:40:26.000000000 +0300 @@ -57,6 +57,14 @@ #define ext3_debug(f, a...) do {} while (0) #endif @@ -2090,7 +2116,7 @@ Index: linux-2.6.5-sles9/include/linux/ext3_fs.h #define EXT3_MOUNT_IOPEN_NOPRIV 0x80000 /* Make iopen world-readable */ #define EXT3_MOUNT_EXTENTS 0x100000/* Extents support */ #define EXT3_MOUNT_EXTDEBUG 0x200000/* Extents debug */ -+#define EXT3_MOUNT_MBALLOC 0x100000/* Buddy allocation support */ ++#define EXT3_MOUNT_MBALLOC 0x400000/* Buddy allocation support */ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef clear_opt @@ -2141,10 +2167,10 @@ Index: linux-2.6.5-sles9/include/linux/ext3_fs.h #endif /* __KERNEL__ */ #define EXT3_IOC_CREATE_INUM _IOW('f', 5, long) -Index: linux-2.6.5-sles9/include/linux/ext3_fs_sb.h +Index: linux-2.6.5-suse/include/linux/ext3_fs_sb.h =================================================================== ---- linux-2.6.5-sles9.orig/include/linux/ext3_fs_sb.h 2005-02-23 01:01:48.242908112 +0300 -+++ linux-2.6.5-sles9/include/linux/ext3_fs_sb.h 2005-02-23 01:48:54.541245456 +0300 +--- linux-2.6.5-suse.orig/include/linux/ext3_fs_sb.h 2005-02-26 18:40:20.000000000 +0300 ++++ linux-2.6.5-suse/include/linux/ext3_fs_sb.h 2005-02-26 18:40:26.000000000 +0300 @@ -23,10 +23,30 @@ #define EXT_INCLUDE #include diff --git a/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch b/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch index fcceb30..dc6ffe3 100644 --- a/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch +++ b/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch @@ -2,7 +2,7 @@ Index: linux-stage/fs/ext3/mballoc.c =================================================================== --- linux-stage.orig/fs/ext3/mballoc.c 2005-02-25 17:28:41.836311072 +0200 +++ linux-stage/fs/ext3/mballoc.c 2005-02-25 17:28:41.859307576 +0200 -@@ -0,0 +1,1847 @@ +@@ -0,0 +1,1860 @@ +/* + * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas @@ -39,6 +39,7 @@ Index: linux-stage/fs/ext3/mballoc.c + +/* + * TODO: ++ * - bitmap/buddy read-ahead (proposed by Oleg Drokin aka green) + * - track min/max extents in each group for better group selection + * - is it worthwhile to use buddies directly if req is 2^N blocks? + * - mb_mark_used() may allocate chunk right after splitting buddy @@ -96,7 +97,7 @@ Index: linux-stage/fs/ext3/mballoc.c + __u32 mh_magic; +}; + -+#define EXT3_MB_MAGIC_V1 0xbaad16fc ++#define EXT3_MB_MAGIC_V1 0xbabd16fd + + +struct ext3_free_extent { @@ -148,47 +149,50 @@ Index: linux-stage/fs/ext3/mballoc.c +void ext3_mb_poll_new_transaction(struct super_block *, handle_t *); +void ext3_mb_free_committed_blocks(struct super_block *); + -+#define mb_correct_addr_and_bit(bit,addr) \ -+{ \ -+ if ((unsigned long)addr & 1) { \ -+ bit += 8; \ -+ addr--; \ -+ } \ -+ if ((unsigned long)addr & 2) { \ -+ bit += 16; \ -+ addr--; \ -+ addr--; \ -+ } \ ++#if BITS_PER_LONG == 64 ++#define mb_correct_addr_and_bit(bit,addr) \ ++{ \ ++ bit += ((unsigned long) addr & 7UL) << 3; \ ++ addr = (void *) ((unsigned long) addr & ~7UL); \ +} ++#elif BITS_PER_LONG == 32 ++#define mb_correct_addr_and_bit(bit,addr) \ ++{ \ ++ bit += ((unsigned long) addr & 3UL) << 3; \ ++ addr = (void *) ((unsigned long) addr & ~3UL); \ ++} ++#else ++#error "how many bits you are?!" ++#endif + +static inline int mb_test_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ return test_bit(bit, addr); ++ return ext2_test_bit(bit, addr); +} + +static inline void mb_set_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ __set_bit(bit, addr); ++ ext2_set_bit(bit, addr); +} + +static inline void mb_set_bit_atomic(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ set_bit(bit, addr); ++ ext2_set_bit_atomic(NULL, bit, addr); +} + +static inline void mb_clear_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ __clear_bit(bit, addr); ++ ext2_clear_bit(bit, addr); +} + +static inline void mb_clear_bit_atomic(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ clear_bit(bit, addr); ++ ext2_clear_bit_atomic(NULL, bit, addr); +} + +static inline void *mb_find_buddy(struct ext3_buddy *e3b, int order, int *max) @@ -199,8 +203,10 @@ Index: linux-stage/fs/ext3/mballoc.c + J_ASSERT(EXT3_MB_BITMAP(e3b) != EXT3_MB_BUDDY(e3b)); + J_ASSERT(max != NULL); + -+ if (order > e3b->bd_blkbits + 1) ++ if (order > e3b->bd_blkbits + 1) { ++ *max = 0; + return NULL; ++ } + + /* at order 0 we see each particular block */ + *max = 1 << (e3b->bd_blkbits + 3); @@ -234,12 +240,6 @@ Index: linux-stage/fs/ext3/mballoc.c + "can't get block for buddy bitmap\n"); + goto out; + } -+ if (!buffer_uptodate(e3b->bd_bh)) { -+ ll_rw_block(READ, 1, &e3b->bd_bh); -+ wait_on_buffer(e3b->bd_bh); -+ } -+ J_ASSERT(buffer_uptodate(e3b->bd_bh)); -+ + /* load buddy */ + e3b->bd_bh2 = sb_getblk(sb, sbi->s_buddy_blocks[group]->bb_buddy); + if (e3b->bd_bh2 == NULL) { @@ -247,10 +247,15 @@ Index: linux-stage/fs/ext3/mballoc.c + "can't get block for buddy bitmap\n"); + goto out; + } -+ if (!buffer_uptodate(e3b->bd_bh2)) { ++ ++ if (!buffer_uptodate(e3b->bd_bh)) ++ ll_rw_block(READ, 1, &e3b->bd_bh); ++ if (!buffer_uptodate(e3b->bd_bh2)) + ll_rw_block(READ, 1, &e3b->bd_bh2); -+ wait_on_buffer(e3b->bd_bh2); -+ } ++ ++ wait_on_buffer(e3b->bd_bh); ++ J_ASSERT(buffer_uptodate(e3b->bd_bh)); ++ wait_on_buffer(e3b->bd_bh2); + J_ASSERT(buffer_uptodate(e3b->bd_bh2)); + + e3b->bd_blkbits = sb->s_blocksize_bits; @@ -300,22 +305,22 @@ Index: linux-stage/fs/ext3/mballoc.c + count = 0; + for (i = 0; i < max; i++) { + -+ if (!mb_test_bit(i, buddy)) { ++ if (mb_test_bit(i, buddy)) { + /* only single bit in buddy2 may be 1 */ -+ if (mb_test_bit(i << 1, buddy2)) -+ J_ASSERT(!mb_test_bit((i<<1)+1, buddy2)); -+ else if (mb_test_bit((i << 1) + 1, buddy2)) -+ J_ASSERT(!mb_test_bit(i << 1, buddy2)); ++ if (!mb_test_bit(i << 1, buddy2)) ++ J_ASSERT(mb_test_bit((i<<1)+1, buddy2)); ++ else if (!mb_test_bit((i << 1) + 1, buddy2)) ++ J_ASSERT(mb_test_bit(i << 1, buddy2)); + continue; + } + + /* both bits in buddy2 must be 0 */ -+ J_ASSERT(!mb_test_bit(i << 1, buddy2)); -+ J_ASSERT(!mb_test_bit((i << 1) + 1, buddy2)); ++ J_ASSERT(mb_test_bit(i << 1, buddy2)); ++ J_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); + + for (j = 0; j < (1 << order); j++) { + k = (i * (1 << order)) + j; -+ J_ASSERT(mb_test_bit(k, EXT3_MB_BITMAP(e3b))); ++ J_ASSERT(!mb_test_bit(k, EXT3_MB_BITMAP(e3b))); + } + count++; + } @@ -325,14 +330,14 @@ Index: linux-stage/fs/ext3/mballoc.c + + buddy = mb_find_buddy(e3b, 0, &max); + for (i = 0; i < max; i++) { -+ if (mb_test_bit(i, buddy)) ++ if (!mb_test_bit(i, buddy)) + continue; + /* check used bits only */ + for (j = 0; j < e3b->bd_blkbits + 1; j++) { + buddy2 = mb_find_buddy(e3b, j, &max2); + k = i >> j; + J_ASSERT(k < max2); -+ J_ASSERT(!mb_test_bit(k, buddy2)); ++ J_ASSERT(mb_test_bit(k, buddy2)); + } + } +} @@ -363,7 +368,7 @@ Index: linux-stage/fs/ext3/mballoc.c + bb = EXT3_MB_BUDDY(e3b); + while (order <= e3b->bd_blkbits + 1) { + block = block >> 1; -+ if (mb_test_bit(block, bb)) { ++ if (!mb_test_bit(block, bb)) { + /* this block is part of buddy of order 'order' */ + return order; + } @@ -424,8 +429,8 @@ Index: linux-stage/fs/ext3/mballoc.c + block = first++; + order = 0; + -+ J_ASSERT(!mb_test_bit(block, EXT3_MB_BITMAP(e3b))); -+ mb_set_bit(block, EXT3_MB_BITMAP(e3b)); ++ J_ASSERT(mb_test_bit(block, EXT3_MB_BITMAP(e3b))); ++ mb_clear_bit(block, EXT3_MB_BITMAP(e3b)); + e3b->bd_bd->bb_counters[order]++; + + /* start of the buddy */ @@ -433,8 +438,8 @@ Index: linux-stage/fs/ext3/mballoc.c + + do { + block &= ~1UL; -+ if (!mb_test_bit(block, buddy) || -+ !mb_test_bit(block + 1, buddy)) ++ if (mb_test_bit(block, buddy) || ++ mb_test_bit(block + 1, buddy)) + break; + + /* both the buddies are free, try to coalesce them */ @@ -444,10 +449,10 @@ Index: linux-stage/fs/ext3/mballoc.c + break; + + if (order > 0) { -+ /* for special purposes, we don't clear ++ /* for special purposes, we don't set + * free bits in bitmap */ -+ mb_clear_bit(block, buddy); -+ mb_clear_bit(block + 1, buddy); ++ mb_set_bit(block, buddy); ++ mb_set_bit(block + 1, buddy); + } + e3b->bd_bd->bb_counters[order]--; + e3b->bd_bd->bb_counters[order]--; @@ -456,7 +461,7 @@ Index: linux-stage/fs/ext3/mballoc.c + order++; + e3b->bd_bd->bb_counters[order]++; + -+ mb_set_bit(block, buddy2); ++ mb_clear_bit(block, buddy2); + buddy = buddy2; + } while (1); + } @@ -476,7 +481,7 @@ Index: linux-stage/fs/ext3/mballoc.c + buddy = mb_find_buddy(e3b, order, &max); + J_ASSERT(buddy); + J_ASSERT(block < max); -+ if (!mb_test_bit(block, buddy)) { ++ if (mb_test_bit(block, buddy)) { + ex->fe_len = 0; + ex->fe_start = 0; + ex->fe_group = 0; @@ -499,7 +504,7 @@ Index: linux-stage/fs/ext3/mballoc.c + break; + + next = (block + 1) * (1 << order); -+ if (!mb_test_bit(next, EXT3_MB_BITMAP(e3b))) ++ if (mb_test_bit(next, EXT3_MB_BITMAP(e3b))) + break; + + ord = mb_find_order_for_block(e3b, next); @@ -533,7 +538,7 @@ Index: linux-stage/fs/ext3/mballoc.c + mlen = 1 << ord; + buddy = mb_find_buddy(e3b, ord, &max); + J_ASSERT((start >> ord) < max); -+ mb_clear_bit(start >> ord, buddy); ++ mb_set_bit(start >> ord, buddy); + e3b->bd_bd->bb_counters[ord]--; + start += mlen; + len -= mlen; @@ -544,20 +549,20 @@ Index: linux-stage/fs/ext3/mballoc.c + /* we have to split large buddy */ + J_ASSERT(ord > 0); + buddy = mb_find_buddy(e3b, ord, &max); -+ mb_clear_bit(start >> ord, buddy); ++ mb_set_bit(start >> ord, buddy); + e3b->bd_bd->bb_counters[ord]--; + + ord--; + cur = (start >> ord) & ~1U; + buddy = mb_find_buddy(e3b, ord, &max); -+ mb_set_bit(cur, buddy); -+ mb_set_bit(cur + 1, buddy); ++ mb_clear_bit(cur, buddy); ++ mb_clear_bit(cur + 1, buddy); + e3b->bd_bd->bb_counters[ord]++; + e3b->bd_bd->bb_counters[ord]++; + } + + /* now drop all the bits in bitmap */ -+ mb_clear_bits(EXT3_MB_BITMAP(e3b), ex->fe_start, len0); ++ mb_set_bits(EXT3_MB_BITMAP(e3b), ex->fe_start, len0); + + mb_check_buddy(e3b); + @@ -733,7 +738,7 @@ Index: linux-stage/fs/ext3/mballoc.c + i = e3b->bd_bd->bb_first_free; + + while (free && ac->ac_status != AC_STATUS_FOUND) { -+ i = find_next_bit(bitmap, sb->s_blocksize * 8, i); ++ i = ext2_find_next_zero_bit(bitmap, sb->s_blocksize * 8, i); + if (i >= sb->s_blocksize * 8) { + J_ASSERT(free == 0); + break; @@ -951,7 +956,6 @@ Index: linux-stage/fs/ext3/mballoc.c + /* + * We aren't lucky definitely + */ -+ J_ASSERT(ac.ac_b_ex.fe_len == 0); + DQUOT_FREE_BLOCK(inode, *len); + *errp = -ENOSPC; + block = 0; @@ -1020,8 +1024,8 @@ Index: linux-stage/fs/ext3/mballoc.c + ext3_error(sb, "ext3_new_block", + "Allocating block in system zone - " + "block = %u", block); -+#if AGGRESSIVE_CHECK -+ for (i = 0; i < ac.ac_b_len; i++) ++#ifdef AGGRESSIVE_CHECK ++ for (i = 0; i < ac.ac_b_ex.fe_len; i++) + J_ASSERT(!mb_test_bit(ac.ac_b_ex.fe_start + i, bitmap_bh->b_data)); +#endif + mb_set_bits(bitmap_bh->b_data, ac.ac_b_ex.fe_start, ac.ac_b_ex.fe_len); @@ -1141,7 +1145,7 @@ Index: linux-stage/fs/ext3/mballoc.c + + e3b->bd_bd->bb_first_free = grp->mgd_first_free; + e3b->bd_bd->bb_free = grp->mgd_free; -+ for (i = 0; i < e3b->bd_blkbits; i++) { ++ for (i = 0; i <= e3b->bd_blkbits + 1; i++) { + J_ASSERT(i < 16); + e3b->bd_bd->bb_counters[i] = grp->mgd_counters[i]; + } @@ -1197,7 +1201,7 @@ Index: linux-stage/fs/ext3/mballoc.c + goto out; + grp->mgd_first_free = e3b->bd_bd->bb_first_free; + grp->mgd_free = e3b->bd_bd->bb_free; -+ for (i = 0; i < e3b->bd_blkbits; i++) { ++ for (i = 0; i <= e3b->bd_blkbits + 1; i++) { + J_ASSERT(i < 16); + grp->mgd_counters[i] = e3b->bd_bd->bb_counters[i]; + } @@ -1217,9 +1221,10 @@ Index: linux-stage/fs/ext3/mballoc.c + struct super_block *sb = e3b->bd_sb; + struct buffer_head *bh; + int i, count = 0; -+ -+ memset(e3b->bd_bh->b_data, 0, sb->s_blocksize); -+ memset(e3b->bd_bh2->b_data, 0, sb->s_blocksize); ++ ++ mb_debug("generate buddy for group %d\n", e3b->bd_group); ++ memset(e3b->bd_bh->b_data, 0xff, sb->s_blocksize); ++ memset(e3b->bd_bh2->b_data, 0xff, sb->s_blocksize); + + bh = read_block_bitmap(sb, e3b->bd_group); + if (bh == NULL) @@ -1748,6 +1753,19 @@ Index: linux-stage/fs/ext3/mballoc.c + if (err) + goto error_return; + ++#ifdef AGGRESSIVE_CHECK ++ { ++ int i; ++ for (i = 0; i < count; i++) ++ J_ASSERT(mb_test_bit(bit + i, bitmap_bh->b_data)); ++ } ++#endif ++ mb_clear_bits(bitmap_bh->b_data, bit, count); ++ ++ /* We dirtied the bitmap block */ ++ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); ++ err = ext3_journal_dirty_metadata(handle, bitmap_bh); ++ + if (metadata) { + /* blocks being freed are metadata. these blocks shouldn't + * be used until this transaction is committed */ @@ -1757,21 +1775,18 @@ Index: linux-stage/fs/ext3/mballoc.c + mb_free_blocks(&e3b, bit, count); + ext3_unlock_group(sb, block_group); + } ++ + spin_lock(sb_bgl_lock(sbi, block_group)); + gdp->bg_free_blocks_count = + cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) + count); + spin_unlock(sb_bgl_lock(sbi, block_group)); ++ percpu_counter_mod(&sbi->s_freeblocks_counter, count); + + ext3_mb_dirty_buddy(&e3b); + ext3_mb_release_desc(&e3b); + -+ mb_clear_bits(bitmap_bh->b_data, bit, count); + *freed = count; + -+ /* We dirtied the bitmap block */ -+ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); -+ err = ext3_journal_dirty_metadata(handle, bitmap_bh); -+ + /* And the group descriptor block */ + BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); + ret = ext3_journal_dirty_metadata(handle, gd_bh); @@ -1833,7 +1848,6 @@ Index: linux-stage/fs/ext3/mballoc.c + return ret; +} + -+ +void ext3_free_blocks(handle_t *handle, struct inode * inode, + unsigned long block, unsigned long count, int metadata) +{ @@ -1849,7 +1863,6 @@ Index: linux-stage/fs/ext3/mballoc.c + DQUOT_FREE_BLOCK(inode, freed); + return; +} -+ Index: linux-stage/fs/ext3/super.c =================================================================== --- linux-stage.orig/fs/ext3/super.c 2005-02-25 17:27:00.231757312 +0200 @@ -1859,7 +1872,7 @@ Index: linux-stage/fs/ext3/super.c int i; + ext3_mb_release(sb); - ext3_ext_release(sb); + ext3_ext_release(sb); ext3_xattr_put_super(sb); journal_destroy(sbi->s_journal); @@ -592,7 +593,7 @@ @@ -1897,16 +1910,14 @@ Index: linux-stage/fs/ext3/super.c default: printk (KERN_ERR "EXT3-fs: Unrecognized mount option \"%s\" " -@@ -1639,7 +1652,8 @@ +@@ -1639,6 +1652,7 @@ ext3_count_dirs(sb)); - ext3_ext_init(sb); -- + ext3_ext_init(sb); + ext3_mb_init(sb, needs_recovery); -+ + return 0; - failed_mount3: Index: linux-stage/fs/ext3/Makefile =================================================================== --- linux-stage.orig/fs/ext3/Makefile 2005-02-25 17:27:00.228757768 +0200 @@ -2122,8 +2133,8 @@ Index: linux-stage/include/linux/ext3_fs.h #define EXT3_MOUNT_EXTDEBUG 0x200000/* Extents debug */ +#define EXT3_MOUNT_MBALLOC 0x400000/* Buddy allocation support */ - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ + #ifndef _LINUX_EXT2_FS_H @@ -725,7 +734,7 @@ extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group); extern int ext3_new_block (handle_t *, struct inode *, unsigned long, int *); @@ -2184,7 +2195,7 @@ Index: linux-stage/include/linux/ext3_fs_sb.h #endif #include -+#define EXT3_BB_MAX_BLOCKS 30 ++#define EXT3_BB_MAX_BLOCKS 30 +struct ext3_free_metadata { + unsigned short group; + unsigned short num; @@ -2222,7 +2233,7 @@ Index: linux-stage/include/linux/ext3_fs_sb.h + spinlock_t s_md_lock; + tid_t s_last_transaction; + int s_mb_factor; -+ ++ + /* stats for buddy allocator */ + spinlock_t s_bal_lock; + unsigned long s_bal_reqs; /* number of reqs with len > 1 */ diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 3033df3..cbd61f7 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -22,11 +22,18 @@ - fix several locking issues related to i_size (5492,5624,5654,5672) - don't move pending lock onto export if it is already evicted (5683) - fix kernel oops when creating .foo in unlinked directory (5548) + - fix deadlock in obdfilter statistics vs. object create (5811) + - use time_{before,after} to avoid timer jiffies wrap (5882) + - shutdown --force/--failover stability (3607,3651,4797,5203,4834) + - Do not leak request if server was not able to process it (5154) + - If mds_open unable to find parent dir, make that negative lookup(5154) * miscellania - fix lustre/lustrefs init scripts for SuSE (patch from Scali, 5702) - don't hold the pinger_sem in ptlrpc_pinger_sending_on_import - change obd_increase_kms to obd_adjust_kms (up or down) (5654) - lconf, lmc search both /usr/lib and /usr/lib64 for Python libs (5800) + - support for RHEL4 kernel on i686 (5773) + - provide error messages when incompatible logs are encountered (5898) 2005-02-18 Cluster File Systems, Inc. * version 1.4.0.10 (1.4.1 release candidate 1) diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index c816f62..ab926f2 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -261,6 +261,27 @@ fi ]) # +# LC_FUNC_DEV_SET_RDONLY +# +# check for the old-style dev_set_rdonly which took an extra "devno" param +# and can only set a single device to discard writes at one time +# +AC_DEFUN([LC_FUNC_DEV_SET_RDONLY], +[AC_MSG_CHECKING([if kernel has old single-device dev_set_rdonly]) +HAVE_OLD_DSR="`grep -c -s 'dev_set_rdonly.*no_write' $LINUX/drivers/block/ll_rw_blk.c`" +if test x$HAVE_OLD_DSR != "x1" ; then + HAVE_OLD_DSR="`grep -c -s 'dev_set_rdonly.*no_write' $LINUX/drivers/block/blkpg.c`" +fi +if test x$HAVE_OLD_DSR = "x1" ; then + AC_DEFINE(HAVE_OLD_DEV_SET_RDONLY, 1, + [kernel has old single-device dev_set_rdonly]) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi +]) + +# # LC_CONFIG_BACKINGFS # # whether to use extN or ldiskfs instead of ext3 @@ -319,8 +340,7 @@ case $BACKINGFS in LC_FSHOOKS([ LDISKFS_SERIES="2.6-suse.series" ],[ - AC_MSG_ERROR([Only SuSE 2.6 kernels (with fshooks) are supported at this time]) - LDISKFS_SERIES="2.6-vanilla.series" + LDISKFS_SERIES="2.6-rhel4.series" ]) AC_SUBST(LDISKFS_SERIES) ;; @@ -381,6 +401,7 @@ LC_HEADER_MM_INLINE LC_STRUCT_INODE LC_FUNC_REGISTER_CACHE LC_FUNC_GRAB_CACHE_PAGE_NOWAIT_GFP +LC_FUNC_DEV_SET_RDONLY ]) # @@ -460,6 +481,7 @@ lustre/include/linux/Makefile lustre/include/lustre/Makefile lustre/kernel_patches/targets/2.6-suse.target lustre/kernel_patches/targets/2.6-vanilla.target +lustre/kernel_patches/targets/2.6-rhel4.target lustre/kernel_patches/targets/hp_pnnl-2.4.target lustre/kernel_patches/targets/rh-2.4.target lustre/kernel_patches/targets/rhel-2.4.target diff --git a/lustre/autoconf/lustre-version.ac b/lustre/autoconf/lustre-version.ac index 907a11d..68e6b6d 100644 --- a/lustre/autoconf/lustre-version.ac +++ b/lustre/autoconf/lustre-version.ac @@ -1 +1 @@ -m4_define([LUSTRE_VERSION],[1.4.0.10]) +m4_define([LUSTRE_VERSION],[1.4.1]) diff --git a/lustre/conf/modules.conf b/lustre/conf/modules.conf index 0fb0a35..a5bdefa 100644 --- a/lustre/conf/modules.conf +++ b/lustre/conf/modules.conf @@ -1,6 +1,8 @@ # sample modules.conf for autoloading lustre modules on zeroconf clients add below kptlrouter portals +#add below ksocknal kptlrouter +#add below kqswnal kptlrouter add below ptlrpc ksocknal add below llite lov osc alias lustre llite diff --git a/lustre/include/liblustre.h b/lustre/include/liblustre.h index bbadd08..8e130d0 100644 --- a/lustre/include/liblustre.h +++ b/lustre/include/liblustre.h @@ -620,6 +620,7 @@ static inline int schedule_timeout(signed long t) }) #define time_after(a, b) ((long)(b) - (long)(a) < 0) #define time_before(a, b) time_after(b,a) +#define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0) struct timer_list { struct list_head tl_list; @@ -630,7 +631,7 @@ struct timer_list { static inline int timer_pending(struct timer_list *l) { - if (l->expires > jiffies) + if (time_after(l->expires, jiffies)) return 1; else return 0; diff --git a/lustre/include/linux/lprocfs_status.h b/lustre/include/linux/lprocfs_status.h index bc79915b..6c0adbd 100644 --- a/lustre/include/linux/lprocfs_status.h +++ b/lustre/include/linux/lprocfs_status.h @@ -216,6 +216,8 @@ extern int lprocfs_obd_cleanup(struct obd_device *obd); extern int lprocfs_rd_u64(char *page, char **start, off_t off, int count, int *eof, void *data); +extern int lprocfs_rd_atomic(char *page, char **start, off_t off, + int count, int *eof, void *data); extern int lprocfs_rd_uuid(char *page, char **start, off_t off, int count, int *eof, void *data); extern int lprocfs_rd_name(char *page, char **start, off_t off, diff --git a/lustre/include/linux/lustre_dlm.h b/lustre/include/linux/lustre_dlm.h index bf4e9e2..77c5f05 100644 --- a/lustre/include/linux/lustre_dlm.h +++ b/lustre/include/linux/lustre_dlm.h @@ -163,7 +163,8 @@ struct ldlm_namespace { char *ns_name; __u32 ns_client; /* is this a client-side lock tree? */ struct list_head *ns_hash; /* hash table for ns */ - __u32 ns_refcount; /* count of resources in the hash */ + wait_queue_head_t ns_refcount_waitq; /* for cleanup */ + atomic_t ns_refcount; /* count of resources in the hash */ struct list_head ns_root_list; /* all root resources in ns */ struct lustre_lock ns_lock; /* protects hash, refcount, list */ struct list_head ns_list_chain; /* position in global NS list */ @@ -174,11 +175,10 @@ struct ldlm_namespace { struct list_head ns_unused_list; /* all root resources in ns */ int ns_nr_unused; unsigned int ns_max_unused; - unsigned long ns_next_dump; /* next dump time */ + unsigned long ns_next_dump; /* next debug dump, jiffies */ spinlock_t ns_counter_lock; __u64 ns_locks; - __u64 ns_resources; ldlm_res_policy ns_policy; struct ldlm_valblock_ops *ns_lvbo; void *ns_lvbp; @@ -248,18 +248,11 @@ struct ldlm_lock { /* Server-side-only members */ struct list_head l_pending_chain; /* callbacks pending */ - unsigned long l_callback_timeout; + unsigned long l_callback_timeout; /* jiffies */ __u32 l_pid; /* pid which created this lock */ }; -#define LDLM_PLAIN 10 -#define LDLM_EXTENT 11 -#define LDLM_FLOCK 12 - -#define LDLM_MIN_TYPE 10 -#define LDLM_MAX_TYPE 12 - struct ldlm_resource { struct ldlm_namespace *lr_namespace; struct list_head lr_hash; diff --git a/lustre/include/linux/lustre_fsfilt.h b/lustre/include/linux/lustre_fsfilt.h index cb257e7..4e55481 100644 --- a/lustre/include/linux/lustre_fsfilt.h +++ b/lustre/include/linux/lustre_fsfilt.h @@ -112,7 +112,12 @@ static inline void *fsfilt_start_log(struct obd_device *obd, { unsigned long now = jiffies; void *parent_handle = oti ? oti->oti_handle : NULL; - void *handle = obd->obd_fsops->fs_start(inode, op, parent_handle, logs); + void *handle; + + if (obd->obd_fail) + return ERR_PTR(-EROFS); + + handle = obd->obd_fsops->fs_start(inode, op, parent_handle, logs); CDEBUG(D_INFO, "started handle %p (%p)\n", handle, parent_handle); if (oti != NULL) { @@ -142,8 +147,13 @@ static inline void *fsfilt_brw_start_log(struct obd_device *obd, { unsigned long now = jiffies; void *parent_handle = oti ? oti->oti_handle : NULL; - void *handle = obd->obd_fsops->fs_brw_start(objcount, fso, niocount, nb, - parent_handle, logs); + void *handle; + + if (obd->obd_fail) + return ERR_PTR(-EROFS); + + handle = obd->obd_fsops->fs_brw_start(objcount, fso, niocount, nb, + parent_handle, logs); CDEBUG(D_INFO, "started handle %p (%p)\n", handle, parent_handle); if (oti != NULL) { @@ -236,11 +246,10 @@ static inline int fsfilt_send_bio(int rw, struct obd_device *obd, struct inode *inode, void *bio) { LASSERTF(rw == OBD_BRW_WRITE || rw == OBD_BRW_READ, "%x\n", rw); - + if (rw == OBD_BRW_READ) return obd->obd_fsops->fs_send_bio(READ, inode, bio); - else - return obd->obd_fsops->fs_send_bio(WRITE, inode, bio); + return obd->obd_fsops->fs_send_bio(WRITE, inode, bio); } static inline ssize_t fsfilt_readpage(struct obd_device *obd, diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index e1aa3c9..63c0b4d 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -669,6 +669,15 @@ typedef enum { LCK_NL = 32 } ldlm_mode_t; +typedef enum { + LDLM_PLAIN = 10, + LDLM_EXTENT = 11, + LDLM_FLOCK = 12, + LDLM_MAX_TYPE +} ldlm_type_t; + +#define LDLM_MIN_TYPE LDLM_PLAIN + struct ldlm_extent { __u64 start; __u64 end; @@ -702,7 +711,7 @@ struct ldlm_intent { extern void lustre_swab_ldlm_intent (struct ldlm_intent *i); struct ldlm_resource_desc { - __u32 lr_type; + ldlm_type_t lr_type; __u32 lr_padding; struct ldlm_res_id lr_name; }; diff --git a/lustre/include/linux/lustre_import.h b/lustre/include/linux/lustre_import.h index db1cd90..481f082 100644 --- a/lustre/include/linux/lustre_import.h +++ b/lustre/include/linux/lustre_import.h @@ -68,8 +68,8 @@ struct obd_import { __u64 imp_peer_committed_transno; struct obd_uuid imp_target_uuid; /* XXX -> lustre_name */ struct lustre_handle imp_remote_handle; - unsigned long imp_next_ping; - + unsigned long imp_next_ping; /* jiffies */ + /* Protects flags, level, generation, conn_cnt, *_list */ spinlock_t imp_lock; diff --git a/lustre/include/linux/lustre_lib.h b/lustre/include/linux/lustre_lib.h index 3e04929..380629a 100644 --- a/lustre/include/linux/lustre_lib.h +++ b/lustre/include/linux/lustre_lib.h @@ -412,7 +412,7 @@ static inline void obd_ioctl_freedata(char *buf, int len) #define OBD_IOC_STATFS _IOWR('f', 113, long) -#define OBD_IOC_SYNC _IOR ('f', 114, long) +#define OBD_IOC_SYNC _IOW ('f', 114, long) #define OBD_IOC_READ2 _IOWR('f', 115, long) #define OBD_IOC_FORMAT _IOWR('f', 116, long) #define OBD_IOC_PARTITION _IOWR('f', 117, long) diff --git a/lustre/include/linux/lustre_lite.h b/lustre/include/linux/lustre_lite.h index 9316230..c5c045d 100644 --- a/lustre/include/linux/lustre_lite.h +++ b/lustre/include/linux/lustre_lite.h @@ -31,82 +31,6 @@ /* careful, this is easy to screw up */ #define PAGE_CACHE_MAXBYTES ((__u64)(~0UL) << PAGE_CACHE_SHIFT) - -/* -struct lustre_intent_data { - __u64 it_lock_handle[2]; - __u32 it_disposition; - __u32 it_status; - __u32 it_lock_mode; - }; */ - -#define LL_IT2STR(it) ((it) ? ldlm_it2str((it)->it_op) : "0") - -static inline struct lookup_intent *ll_nd2it(struct nameidata *nd) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) - return &nd->intent; -#else - return nd->intent; -#endif -} - -struct ll_dentry_data { - int lld_cwd_count; - int lld_mnt_count; - struct obd_client_handle lld_cwd_och; - struct obd_client_handle lld_mnt_och; -}; - -#define ll_d2d(de) ((struct ll_dentry_data*) de->d_fsdata) - -extern struct file_operations ll_pgcache_seq_fops; - -#define LLI_INODE_MAGIC 0x111d0de5 -#define LLI_INODE_DEAD 0xdeadd00d -#define LLI_F_HAVE_OST_SIZE_LOCK 0 -#define LLI_F_HAVE_MDS_SIZE_LOCK 1 -struct ll_inode_info { - int lli_inode_magic; - struct lov_stripe_md *lli_smd; - char *lli_symlink_name; - struct semaphore lli_open_sem; - struct semaphore lli_size_sem; - __u64 lli_maxbytes; - __u64 lli_io_epoch; - unsigned long lli_flags; - - /* this lock protects s_d_w and p_w_ll and mmap_cnt */ - spinlock_t lli_lock; - int lli_send_done_writing; - struct list_head lli_pending_write_llaps; - atomic_t lli_mmap_cnt; - - struct list_head lli_close_item; - - /* for writepage() only to communicate to fsync */ - int lli_async_rc; - - struct file_operations *ll_save_ifop; - struct file_operations *ll_save_ffop; - struct file_operations *ll_save_wfop; - struct file_operations *ll_save_wrfop; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) - struct inode lli_vfs_inode; -#endif -}; - -// FIXME: replace the name of this with LL_I to conform to kernel stuff -// static inline struct ll_inode_info *LL_I(struct inode *inode) -static inline struct ll_inode_info *ll_i2info(struct inode *inode) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) - return container_of(inode, struct ll_inode_info, lli_vfs_inode); -#else - return (struct ll_inode_info *)&(inode->u.generic_ip); -#endif -} - /* lprocfs.c */ enum { LPROC_LL_DIRTY_HITS = 0, diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h index 20843f5..6beb16c 100644 --- a/lustre/include/linux/lustre_mds.h +++ b/lustre/include/linux/lustre_mds.h @@ -153,7 +153,7 @@ int mds_update_server_data(struct obd_device *, int force_sync); /* mds/mds_fs.c */ int mds_fs_setup(struct obd_device *obddev, struct vfsmount *mnt); -int mds_fs_cleanup(struct obd_device *obddev, int failover); +int mds_fs_cleanup(struct obd_device *obddev); #endif /* mds/mds_lov.c */ diff --git a/lustre/include/linux/lustre_net.h b/lustre/include/linux/lustre_net.h index 21ddb59..7fccdef 100644 --- a/lustre/include/linux/lustre_net.h +++ b/lustre/include/linux/lustre_net.h @@ -297,7 +297,7 @@ struct ptlrpc_request { int rq_reqlen; struct lustre_msg *rq_reqmsg; - int rq_timeout; + int rq_timeout; /* seconds */ int rq_replen; struct lustre_msg *rq_repmsg; __u64 rq_transno; @@ -336,7 +336,7 @@ struct ptlrpc_request { void *rq_cb_data; struct ptlrpc_bulk_desc *rq_bulk; /* client side bulk */ - time_t rq_sent; /* when the request was sent */ + time_t rq_sent; /* when request sent, seconds */ /* Multi-rpc bits */ struct list_head rq_set_chain; @@ -738,10 +738,10 @@ ptlrpc_rs_decref(struct ptlrpc_reply_state *rs) /* ldlm/ldlm_lib.c */ int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf); -int client_obd_cleanup(struct obd_device * obddev, int flags); +int client_obd_cleanup(struct obd_device * obddev); int client_connect_import(struct lustre_handle *conn, struct obd_device *obd, struct obd_uuid *cluuid); -int client_disconnect_export(struct obd_export *exp, int failover); +int client_disconnect_export(struct obd_export *exp); /* ptlrpc/pinger.c */ int ptlrpc_pinger_add_import(struct obd_import *imp); diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index 9f24687..c6146bd 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -485,7 +485,8 @@ struct obd_device { int obd_minor; unsigned int obd_attached:1, obd_set_up:1, obd_recovering:1, obd_abort_recovery:1, obd_replayable:1, obd_no_transno:1, - obd_no_recov:1, obd_stopping:1, obd_starting:1; + obd_no_recov:1, obd_stopping:1, obd_starting:1, + obd_force:1, obd_fail:1; atomic_t obd_refcount; wait_queue_head_t obd_refcount_waitq; struct proc_dir_entry *obd_proc_entry; @@ -499,7 +500,7 @@ struct obd_device { struct fsfilt_operations *obd_fsops; spinlock_t obd_osfs_lock; struct obd_statfs obd_osfs; - unsigned long obd_osfs_age; + unsigned long obd_osfs_age; /* jiffies */ struct obd_run_ctxt obd_ctxt; struct llog_ctxt *obd_llog_ctxt[LLOG_MAX_CTXTS]; struct obd_device *obd_observer; @@ -560,12 +561,12 @@ struct obd_ops { int (*o_attach)(struct obd_device *dev, obd_count len, void *data); int (*o_detach)(struct obd_device *dev); int (*o_setup) (struct obd_device *dev, obd_count len, void *data); - int (*o_precleanup)(struct obd_device *dev, int flags); - int (*o_cleanup)(struct obd_device *dev, int flags); + int (*o_precleanup)(struct obd_device *dev); + int (*o_cleanup)(struct obd_device *dev); int (*o_postrecov)(struct obd_device *dev); int (*o_connect)(struct lustre_handle *conn, struct obd_device *src, struct obd_uuid *cluuid); - int (*o_disconnect)(struct obd_export *exp, int flags); + int (*o_disconnect)(struct obd_export *exp); int (*o_statfs)(struct obd_device *obd, struct obd_statfs *osfs, unsigned long max_age); diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index cfbd032..d7b340f 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -84,6 +84,7 @@ int class_attach(struct lustre_cfg *lcfg); int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg); int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg); int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg); +void class_decref(struct obd_device *obd); /* Passed as data param to class_config_parse_llog */ struct config_llog_instance { @@ -137,9 +138,9 @@ struct obd_type *class_get_type(char *name); void class_put_type(struct obd_type *type); int class_connect(struct lustre_handle *conn, struct obd_device *obd, struct obd_uuid *cluuid); -int class_disconnect(struct obd_export *exp, int failover); -void class_disconnect_exports(struct obd_device *obddev, int failover); -void class_disconnect_stale_exports(struct obd_device *obddev, int failover); +int class_disconnect(struct obd_export *exp); +void class_disconnect_exports(struct obd_device *obddev); +void class_disconnect_stale_exports(struct obd_device *obddev); /* generic operations shared by various OBD types */ int class_multi_setup(struct obd_device *obddev, uint32_t len, void *data); int class_multi_cleanup(struct obd_device *obddev); @@ -170,22 +171,6 @@ do { \ } \ } while (0) -#define OBD_CHECK_DEV_STOPPING(obd) \ -do { \ - OBD_CHECK_DEV(obd); \ - if (!(obd)->obd_set_up) { \ - CERROR("Device %d not setup\n", \ - (obd)->obd_minor); \ - RETURN(-ENODEV); \ - } \ - \ - if (!(obd)->obd_stopping) { \ - CERROR("Device %d not stopping\n", \ - (obd)->obd_minor); \ - RETURN(-ENODEV); \ - } \ -} while (0) - /* ensure obd_setup and !obd_stopping */ #define OBD_CHECK_DEV_ACTIVE(obd) \ do { \ @@ -292,7 +277,7 @@ static inline int obd_setup(struct obd_device *obd, int datalen, void *data) RETURN(rc); } -static inline int obd_precleanup(struct obd_device *obd, int flags) +static inline int obd_precleanup(struct obd_device *obd) { int rc; ENTRY; @@ -300,20 +285,20 @@ static inline int obd_precleanup(struct obd_device *obd, int flags) OBD_CHECK_OP(obd, precleanup, 0); OBD_COUNTER_INCREMENT(obd, precleanup); - rc = OBP(obd, precleanup)(obd, flags); + rc = OBP(obd, precleanup)(obd); RETURN(rc); } -static inline int obd_cleanup(struct obd_device *obd, int flags) +static inline int obd_cleanup(struct obd_device *obd) { int rc; ENTRY; - - OBD_CHECK_DEV_STOPPING(obd); + + OBD_CHECK_DEV(obd); OBD_CHECK_OP(obd, cleanup, 0); OBD_COUNTER_INCREMENT(obd, cleanup); - rc = OBP(obd, cleanup)(obd, flags); + rc = OBP(obd, cleanup)(obd); RETURN(rc); } @@ -483,7 +468,7 @@ static inline int obd_connect(struct lustre_handle *conn, RETURN(rc); } -static inline int obd_disconnect(struct obd_export *exp, int flags) +static inline int obd_disconnect(struct obd_export *exp) { int rc; ENTRY; @@ -491,7 +476,7 @@ static inline int obd_disconnect(struct obd_export *exp, int flags) EXP_CHECK_OP(exp, disconnect); OBD_COUNTER_INCREMENT(exp->exp_obd, disconnect); - rc = OBP(exp->exp_obd, disconnect)(exp, flags); + rc = OBP(exp->exp_obd, disconnect)(exp); RETURN(rc); } diff --git a/lustre/include/linux/obd_support.h b/lustre/include/linux/obd_support.h index fb35c49..5ced170 100644 --- a/lustre/include/linux/obd_support.h +++ b/lustre/include/linux/obd_support.h @@ -126,6 +126,7 @@ extern wait_queue_head_t obd_race_waitq; #define OBD_FAIL_LDLM_CREATE_RESOURCE 0x30a #define OBD_FAIL_LDLM_ENQUEUE_BLOCKED 0x30b #define OBD_FAIL_LDLM_REPLY 0x30c +#define OBD_FAIL_LDLM_RECOV_CLIENTS 0x30d #define OBD_FAIL_OSC 0x400 #define OBD_FAIL_OSC_BRW_READ_BULK 0x401 @@ -203,7 +204,7 @@ do { \ do { \ if (OBD_FAIL_CHECK_ONCE(id)) { \ CERROR("obd_race id %x sleeping\n", (id)); \ - sleep_on(&obd_race_waitq); \ + interruptible_sleep_on(&obd_race_waitq); \ CERROR("obd_fail_race id %x awake\n", (id)); \ } else if ((obd_fail_loc & OBD_FAIL_MASK_LOC) == \ ((id) & OBD_FAIL_MASK_LOC)) { \ @@ -225,18 +226,55 @@ do { \ # if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) # define BDEVNAME_DECLARE_STORAGE(foo) char foo[BDEVNAME_SIZE] # define ll_bdevname(SB, STORAGE) __bdevname(kdev_t_to_nr(SB->s_dev), STORAGE) -# define ll_lock_kernel lock_kernel() -# define ll_sbdev(SB) ((SB)->s_bdev) -void dev_set_rdonly(struct block_device *, int); +# define ll_sbdev(SB) ((SB)->s_bdev) +# define ll_sbdev_type struct block_device * + int fsync_bdev(struct block_device *); +# define ll_sbdev_sync fsync_bdev +# define ll_lock_kernel lock_kernel() # else # define BDEVNAME_DECLARE_STORAGE(foo) char __unused_##foo -# define ll_sbdev(SB) (kdev_t_to_nr((SB)->s_dev)) # define ll_bdevname(SB,STORAGE) ((void)__unused_##STORAGE,bdevname(ll_sbdev(SB))) +# define ll_sbdev(SB) (kdev_t_to_nr((SB)->s_dev)) +# define ll_sbdev_type kdev_t +# define ll_sbdev_sync fsync_dev # define ll_lock_kernel -void dev_set_rdonly(kdev_t, int); # endif -void dev_clear_rdonly(int); + +#ifdef HAVE_OLD_DEV_SET_RDONLY + void dev_set_rdonly(ll_sbdev_type, int no_write); + void dev_clear_rdonly(int no_write); +#else + void dev_set_rdonly(ll_sbdev_type); + void dev_clear_rdonly(ll_sbdev_type); +#endif +int dev_check_rdonly(ll_sbdev_type); +#define ll_check_rdonly dev_check_rdonly + +static inline void ll_set_rdonly(ll_sbdev_type dev) +{ + CDEBUG(D_IOCTL | D_HA, "set dev %ld rdonly\n", (long)dev); + ll_sbdev_sync(dev); +#ifdef HAVE_OLD_DEV_SET_RDONLY + dev_set_rdonly(dev, 2); +#else + dev_set_rdonly(dev); +#endif +} + +static inline void ll_clear_rdonly(ll_sbdev_type dev) +{ + CDEBUG(D_IOCTL | D_HA, "unset dev %ld rdonly\n", (long)dev); + if (dev_check_rdonly(dev)) { + ll_sbdev_sync(dev); +#ifdef HAVE_OLD_DEV_SET_RDONLY + dev_clear_rdonly(2); +#else + dev_clear_rdonly(dev); +#endif + } +} + static inline void OBD_FAIL_WRITE(int id, struct super_block *sb) { @@ -244,7 +282,7 @@ static inline void OBD_FAIL_WRITE(int id, struct super_block *sb) BDEVNAME_DECLARE_STORAGE(tmp); CERROR("obd_fail_loc=%x, fail write operation on %s\n", id, ll_bdevname(sb, tmp)); - dev_set_rdonly(ll_sbdev(sb), 2); + ll_set_rdonly(ll_sbdev(sb)); /* We set FAIL_ONCE because we never "un-fail" a device */ obd_fail_loc |= OBD_FAILED | OBD_FAIL_ONCE; } diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-i686-smp.config b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-i686-smp.config new file mode 100644 index 0000000..f8e83ec --- /dev/null +++ b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-i686-smp.config @@ -0,0 +1,2740 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +CONFIG_SMP=y +# CONFIG_HOTPLUG_CPU is not set +CONFIG_LOCALVERSION="" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_POSIX_MQUEUE=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y +CONFIG_MODULE_SIG=y +# CONFIG_MODULE_SIG_FORCE is not set + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_NAMES is not set +CONFIG_ISA=y +# CONFIG_EISA is not set +# CONFIG_MCA is not set +# CONFIG_SCx200 is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_YENTA=y +CONFIG_CARDBUS=y +# CONFIG_I82092 is not set +CONFIG_I82365=m +CONFIG_PD6729=m +CONFIG_TCIC=m +CONFIG_PCMCIA_PROBE=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_FW_LOADER=y + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=m +CONFIG_MTD_CONCAT=m +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_PARTITIONS=y +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_FTL=m +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PNC2000 is not set +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_NETSC520=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_ELAN_104NC=m +CONFIG_MTD_SCx200_DOCFLASH=m +# CONFIG_MTD_AMD76XROM is not set +# CONFIG_MTD_SCB2_FLASH is not set +# CONFIG_MTD_NETtel is not set +# CONFIG_MTD_DILNETPC is not set +# CONFIG_MTD_L440GX is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +# CONFIG_MTD_SLRAM is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_DOCPROBE=m +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=m + +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CFI_AMDSTD_RETRY=3 +# CONFIG_MTD_ICHXROM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set + + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_ATIIXP=y +CONFIG_BLK_DEV_DELKIN=y +CONFIG_BLK_DEV_IT8212=y +CONFIG_LBD=y +# CONFIG_DCSSBLK is not set + + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_IDE_GENERIC=y +# CONFIG_HPT34X_AUTODMA is not set + +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set +# CONFIG_BLK_DEV_IDE_SATA is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_RZ1000=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_AEC62XX=y +CONFIG_BLK_DEV_ALI15X3=y +# CONFIG_WDC_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +CONFIG_BLK_DEV_CMD64X=y +CONFIG_BLK_DEV_TRIFLEX=y +CONFIG_BLK_DEV_CY82C693=y +CONFIG_BLK_DEV_CS5520=y +CONFIG_BLK_DEV_CS5530=y +CONFIG_BLK_DEV_HPT34X=y +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_NS87415 is not set +CONFIG_BLK_DEV_PDC202XX_OLD=y +# CONFIG_PDC202XX_BURST is not set +CONFIG_BLK_DEV_PDC202XX_NEW=y +CONFIG_PDC202XX_FORCE=y +CONFIG_BLK_DEV_SVWKS=y +CONFIG_BLK_DEV_SIIMAGE=y +CONFIG_BLK_DEV_SIS5513=y +CONFIG_BLK_DEV_SLC90E66=y +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_CHIPSETS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SPI_ATTRS=y +CONFIG_SCSI_FC_ATTRS=y + +# +# SCSI low-level drivers +# +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +# CONFIG_SCSI_7000FASST is not set +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AHA152X=m +# CONFIG_SCSI_AHA1542 is not set +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_PROBE_EISA_VL is not set +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC7XXX_OLD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=4 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_BUILD_FIRMWARE is not set +# CONFIG_AIC79XX_ENABLE_RD_STRM is not set +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_SCSI_SATA=y +CONFIG_SCSI_SATA_SVW=m +CONFIG_SCSI_ATA_PIIX=m +CONFIG_SCSI_SATA_PROMISE=m +CONFIG_SCSI_SATA_VIA=m +CONFIG_BLK_DEV_SX8=m +CONFIG_SCSI_SATA_VITESSE=m +CONFIG_SCSI_SATA_SIL=m +CONFIG_SCSI_SATA_SIS=m +CONFIG_SCSI_SATA_SX4=m +CONFIG_SCSI_SATA_NV=m +CONFIG_SCSI_SATA_AHCI=m + +# CONFIG_SCSI_BUSLOGIC is not set +CONFIG_SCSI_INITIO=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +CONFIG_SCSI_IPS=m +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set +CONFIG_SCSI_QLOGIC_1280=m +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_ULTRASTOR is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DC390T is not set +CONFIG_SCSI_QLA2XXX=m +CONFIG_SCSI_QLA21XX=m +CONFIG_SCSI_QLA22XX=m +CONFIG_SCSI_QLA2300=m +CONFIG_SCSI_QLA2322=m +CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_QLA6322=m +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_DPT_I2O is not set + +CONFIG_SCSI_LPFC=m + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_AHA152X is not set +CONFIG_PCMCIA_FDOMAIN=m +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID5=m +CONFIG_MD_RAID6=m +CONFIG_MD_RAID10=m +CONFIG_MD_MULTIPATH=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_CRYPT=m + +# +# Fusion MPT device support +# +CONFIG_FUSION=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_OUI_DB=y + +# +# Device Drivers +# +# CONFIG_IEEE1394_PCILYNX is not set +CONFIG_IEEE1394_OHCI1394=m + +# +# Protocol Drivers +# +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_ETH1394 is not set +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_CMP=m +CONFIG_IEEE1394_AMDTP=m +# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set + +# +# I2O device support +# +CONFIG_I2O=m + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_INET_TUNNEL=m +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_NETCONSOLE=m +# CONFIG_NETPOLL_RX is not set +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NETDUMP=m +CONFIG_DISKDUMP=m +CONFIG_SCSI_DUMP=m +CONFIG_SD_IOSTATS=y + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m + + +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_TUNNEL=m +# CONFIG_DECNET is not set +CONFIG_BRIDGE=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_PHYSDEV=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +CONFIG_IP_NF_MATCH_SCTP=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_NAT_LOCAL=y +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CT_PROTO_SCTP=m +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_LENGTH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_PHYSDEV=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +CONFIG_IP6_NF_RAW=m + + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_XFRM=y +CONFIG_XFRM_USER=y + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_ATM=m +CONFIG_VLAN_8021Q=m +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_IPX_INTERN is not set +# CONFIG_ATALK is not set +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +# CONFIG_IPDDP is not set +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +CONFIG_NET_DIVERT=y +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_ACT_POLICE is not set +CONFIG_CLS_U32_PERF=y +CONFIG_NET_CLS_IND=y +# CONFIG_NET_CLS_ACT is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +CONFIG_DUMMY=m +CONFIG_BONDING=m +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +CONFIG_ETHERTAP=m +# CONFIG_NET_SB1000 is not set + +# +# ATM +# +CONFIG_ATM_CLIP=m +CONFIG_ATM_LANE=m +CONFIG_ATM_BR2684=m +CONFIG_NET_SCH_ATM=m +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +CONFIG_ATM_FIRESTREAM=m +# CONFIG_ATM_ZATM is not set +CONFIG_ATM_IDT77252=m +CONFIG_ATM_AMBASSADOR=m +CONFIG_ATM_HORIZON=m +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_HE=m +CONFIG_PPPOATM=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_IA is not set + + +# CONFIG_ATM_CLIP_NO_ICMP is not set +# CONFIG_ATM_MPOA is not set +# CONFIG_ATM_BR2684_IPFILTER is not set +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +# CONFIG_ATM_ZATM_DEBUG is not set +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +# CONFIG_ATM_HORIZON_DEBUG is not set +# CONFIG_ATM_FORE200E_PCA is not set +# CONFIG_ATM_HE_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_IA_DEBUG is not set + + + + + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_NET_VENDOR_3COM=y +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +# CONFIG_3C515 is not set +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +# CONFIG_LANCE is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +# CONFIG_ULTRA is not set +CONFIG_SMC9194=m +CONFIG_NET_VENDOR_RACAL=y +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_TULIP=m +# CONFIG_TULIP_NAPI is not set + +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_NI5010 is not set +# CONFIG_PCMCIA_XIRTULIP is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_PCMCIA_XIRCOM=m +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +CONFIG_HP100=m +# CONFIG_NET_ISA is not set +# CONFIG_EWRK3 is not set +CONFIG_E2100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_HPLAN_PLUS=m +CONFIG_HPLAN=m +CONFIG_LP486E=m +CONFIG_ETH16I=m +CONFIG_NE2000=m +CONFIG_ZNET=m +CONFIG_SEEQ8005=m +CONFIG_LNE390=m +CONFIG_NE3210=m +CONFIG_ES3210=m +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +CONFIG_AMD8111_ETH=m +CONFIG_AMD8111E_NAPI=y +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADAPTEC_STARFIRE_NAPI=y +# CONFIG_AC3200 is not set +CONFIG_APRICOT=m +CONFIG_B44=m +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +CONFIG_EEPRO100=m +# CONFIG_EEPRO100_PIO is not set +CONFIG_E100=m +CONFIG_E100_NAPI=y +CONFIG_FEALNX=m +CONFIG_FORCEDETH=m +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_SIS900=m +CONFIG_EPIC100=m +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_TLAN=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_VELOCITY=m +CONFIG_NET_POCKET=y +# CONFIG_ATP is not set +# CONFIG_DE600 is not set +# CONFIG_DE620 is not set + +# +# Ethernet (1000 Mbit) +# +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000_NAPI=y +CONFIG_NS83820=m +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=m +CONFIG_R8169_NAPI=y +CONFIG_SK98LIN=m +CONFIG_TIGON3=m + +# +# Ethernet (10000 Mbit) +# +CONFIG_IXGB=m +CONFIG_IXGB_NAPI=y +CONFIG_S2IO=m +CONFIG_S2IO_NAPI=y +CONFIG_FDDI=y +# CONFIG_DEFXX is not set +# CONFIG_SKFP is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_IPPP_FILTER=y +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +CONFIG_WAVELAN=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_NETWAVE=m + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT=m +CONFIG_IEEE80211_WPA=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IPW2100=m +# CONFIG_IPW_DEBUG is not set +CONFIG_IPW2100_PROMISC=y +# CONFIG_IPW2100_LEGACY_FW_LOAD is not set +CONFIG_IPW2200=m +CONFIG_AIRO=m +CONFIG_HERMES=m +CONFIG_PLX_HERMES=m +CONFIG_TMD_HERMES=m +CONFIG_PCI_HERMES=m +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +CONFIG_PRISM54=m + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=m +CONFIG_AIRO_CS=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_WL3501=m +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +CONFIG_TR=y +CONFIG_IBMOL=m +CONFIG_3C359=m +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +CONFIG_ABYSS=m +CONFIG_IBMTR=m +CONFIG_IBMLS=m +CONFIG_SKISA=m +CONFIG_PROTEON=m +CONFIG_SMCTR=m +CONFIG_PCMCIA_IBMTR=m + + +CONFIG_NET_FC=y +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set +# CONFIG_IRDA is not set +# CONFIG_IRDA_DEBUG is not set +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRTTY_SIR=m +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_IRPORT_SIR=m +# CONFIG_DONGLE_OLD is not set +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m + +CONFIG_USB_IRDA=m +CONFIG_NSC_FIR=m +CONFIG_SIGMATEL_FIR=m +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set +# CONFIG_VIA_FIR is not set + + + +# +# Bluetooth support +# +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_CMTP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_BCSP_TXCRC=y +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_USB_BLUETOOTH_TTY=m + +# +# ISDN subsystem +# + +CONFIG_ISDN=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_C4=m + +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +# CONFIG_ISDN_PPP_BSDCOMP is not set +CONFIG_ISDN_TTY_FAX=y +CONFIG_DE_AOC=y + +CONFIG_ISDN_AUDIO=y + +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_TPAM=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m + +CONFIG_ISDN_CAPI_CAPIDRV=m + +CONFIG_HISAX_EURO=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_NO_SENDCOMPLETE=y +CONFIG_HISAX_NO_LLC=y +CONFIG_HISAX_NO_KEYPAD=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_TELES_CS=m + +CONFIG_ISDN_DRV_LOOP=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y + + +# +# CAPI subsystem +# +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_CAPIFS=m + +# +# CAPI hardware drivers +# + +# +# Active AVM cards +# +CONFIG_CAPI_AVM=y + +# +# Active Eicon DIVA Server cards +# +CONFIG_CAPI_EICON=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVAS_MAINT=m + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_VORTEX=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_CS461x=m +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_RAW is not set + +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_ATIXL=y +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_IFORCE_USB=y +# CONFIG_JOYSTICK_IFORCE_232=y +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDDLER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_UINPUT=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_ROCKETPORT is not set +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_N_HDLC=m +CONFIG_STALDRV=y +# CONFIG_FTAPE is not set +CONFIG_IBM_ASM=m + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_ACPI is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_MULTIPORT=y +CONFIG_SERIAL_8250_RSA=y +# CONFIG_COMPUTONE is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALLION is not set +# CONFIG_ISTALLION is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_PRINTER=m +CONFIG_LP_CONSOLE=y +CONFIG_PPDEV=m +# CONFIG_TIPAR is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_DEBUG_ALGO is not set +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m + +# +# I2C Hardware Bus support +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +# CONFIG_SCx200_ACB is not set +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +# CONFIG_I2C_ELEKTOR is not set +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_PARPORT is not set +CONFIG_I2C_ALI1563=m +# CONFIG_I2C_PARPORT_LIGHT is not set +CONFIG_I2C_ALGOPCA=m +# CONFIG_I2C_PCA_ISA is not set + + + +# +# I2C Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_RTC8564=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_SMSC47M1=m + +# CONFIG_W1 is not set + +# +# Mice +# +CONFIG_CRASH=m + +# +# IPMI +# +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_POWEROFF=m + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_SOFT_WATCHDOG=m +CONFIG_WDT=m +# CONFIG_WDT_501 is not set +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y +CONFIG_PCWATCHDOG=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ADVANTECH_WDT=m +CONFIG_EUROTECH_WDT=m +CONFIG_IB700_WDT=m +CONFIG_I8XX_TCO=m +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +CONFIG_W83877F_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_MACHZ_WDT=m +CONFIG_SC520_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALIM1535_WDT=m +CONFIG_SC1200_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_CPU5_WDT=m +CONFIG_PCIPCWATCHDOG=m +CONFIG_USBPCWATCHDOG=m + + +CONFIG_HW_RANDOM=m +CONFIG_NVRAM=m +CONFIG_RTC=y +CONFIG_DTLK=m +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +CONFIG_SONYPI=m + +# +# Ftape, the floppy tape device driver +# +CONFIG_AGP=y +CONFIG_AGP_ALI=y +CONFIG_AGP_ATI=y +CONFIG_AGP_AMD=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=y +CONFIG_AGP_INTEL_MCH=y +CONFIG_AGP_NVIDIA=y +CONFIG_AGP_SIS=y +CONFIG_AGP_SWORKS=y +CONFIG_AGP_VIA=y +CONFIG_AGP_EFFICEON=y +CONFIG_DRM=y +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_MGA=m +# CONFIG_DRM_SIS is not set +CONFIG_DRM_I915=m + + + +# +# PCMCIA character devices +# +CONFIG_SYNCLINK_CS=m + + + +# CONFIG_MWAVE is not set +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +CONFIG_HANGCHECK_TIMER=m + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA_PP is not set +# CONFIG_VIDEO_CPIA_USB is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_DC30 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZORAN_LML33R10 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_SAA5246A is not set +CONFIG_VIDEO_OVCAMCHIP=m + + +# +# Radio Adapters +# +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_TYPHOON_PROC_FS=y +# CONFIG_RADIO_ZOLTRIX is not set + + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +CONFIG_DVB_CORE=m + +# +# Supported Frontend Modules +# +CONFIG_DVB_STV0299=m +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_ALPS_TDLB7 is not set +CONFIG_DVB_ALPS_TDMB7=m +CONFIG_DVB_ATMEL_AT76C651=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_GRUNDIG_29504_491=m +CONFIG_DVB_GRUNDIG_29504_401=m +CONFIG_DVB_MT312=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TWINHAN_DST=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_BT8XX=m +# CONFIG_DVB_TDA1004X is not set +CONFIG_DVB_NXT6000=m + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +# CONFIG_DVB_AV7110_FIRMWARE is not set +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m + +# +# Supported USB Adapters +# +CONFIG_DVB_TTUSB_BUDGET=m + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_SKYSTAR=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_VIDEOBUF=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BTCX=m + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_VGA16=m +CONFIG_FB_VESA=y +CONFIG_VIDEO_SELECT=y +# CONFIG_FB_HGA is not set +CONFIG_FB_RIVA=m +# CONFIG_FB_RIVA_DEBUG is not set +# CONFIG_FB_RIVA_I2C is not set +CONFIG_FB_I810=m +CONFIG_FB_I810_GTF=y +# CONFIG_FB_MATROX is not set +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G450=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MULTIHEAD=y +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RADEON_DEBUG is not set +# CONFIG_FB_RADEON_OLD is not set +CONFIG_FB_RADEON_I2C=y +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GX=y +# CONFIG_FB_ATY_XL_INIT is not set +# CONFIG_FB_SIS is not set +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_KYRO=m +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM2_FIFO_DISCONNECT is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_HGA_ACCEL is not set +# CONFIG_FB_3DFX_ACCEL is not set +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_CIRRUS=m + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_MDA_CONSOLE=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set + + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_RTCTIMER=m +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_BIT32_EMUL=y + +# +# Generic devices +# +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +# CONFIG_SND_SERIAL_U16550 is not set +CONFIG_SND_MPU401=m + +# +# ISA devices +# +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_SB16_CSP=y +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_DT019X is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set + +# +# PCI devices +# +CONFIG_SND_ALI5451=m +CONFIG_SND_AZT3328=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS4281=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_KORG1212=m +CONFIG_SND_NM256=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_HDSP=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_ALS4000=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_FM801=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VX222=m +CONFIG_SND_BT87X=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_MIXART=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_PDAUDIOCF=m + + +# +# ALSA USB devices +# +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m + +# +# PCMCIA devices +# +# CONFIG_SND_VXPOCKET is not set +# CONFIG_SND_VXP440 is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_UHCI_HCD=m + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set + +# +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# +CONFIG_USB_MIDI=m +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_HP8200e=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_RW_DETECT=y + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +CONFIG_HID_FF=y +CONFIG_HID_PID=y +CONFIG_LOGITECH_FF=y +CONFIG_THRUSTMASTER_FF=y +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +CONFIG_USB_AIPTEK=m +CONFIG_USB_WACOM=m +CONFIG_USB_KBTAB=m +CONFIG_USB_POWERMATE=m +CONFIG_USB_XPAD=m + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_HPUSBSCSI=m + +# +# USB Multimedia devices +# +CONFIG_USB_DABUSB=m +CONFIG_USB_VICAM=m +CONFIG_USB_DSBR=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_STV680=m +CONFIG_USB_SN9C102=m + +# +# USB Network adaptors +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_SPEEDTOUCH=m + +# +# USB Host-to-Host Cables +# +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_GENESYS=y +CONFIG_USB_NET1080=y +CONFIG_USB_PL2301=y + +# +# Intelligent USB Devices/Gadgets +# +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_ZAURUS=y +CONFIG_USB_CDCETHER=y + +# +# USB Network Adapters +# +CONFIG_USB_AX8817X=y + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_EZUSB=y +CONFIG_USB_EMI62=m +CONFIG_USB_LED=m +CONFIG_USB_G_SERIAL=m + + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +CONFIG_USB_AUERSWALD=m +CONFIG_USB_RIO500=m +CONFIG_USB_LCD=m +CONFIG_USB_TEST=m +# CONFIG_USB_GADGET is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_SA1100 is not set +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_W9968CF=m +CONFIG_USB_PWC=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_MTOUCH=m +CONFIG_USB_ATI_REMOTE=m +CONFIG_USB_ALI_M5632=y +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_EGALAX=m +CONFIG_USB_PHIDGETSERVO=m + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_JFS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_XFS_RT is not set +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_SECURITY=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_QUOTA=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +CONFIG_UDF_FS=m + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_TMPFS_SECURITY=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not seta +# CONFIG_AFFS_FS is not set +# uses sleepon and needs a major update +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_NAND=y +CONFIG_CRAMFS=m +CONFIG_VXFS_FS=m +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_NCP_FS is not set +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_SMALLDOS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_RXRPC is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +CONFIG_OSF_PARTITION=y +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_SUN_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_NLS_ASCII=y + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m + +# +# Tux +# +CONFIG_TUX=m +CONFIG_TUX_EXTCGI=y +# CONFIG_TUX_EXTENDED_LOG is not set +# CONFIG_TUX_DEBUG is not set + + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_HIGHMEM=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_FRAME_POINTER is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_DEBUG_DRIVER is not set + +# +# Security options +# +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +# CONFIG_SECURITY_SELINUX_MLS is not set +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_TEST is not set +CONFIG_LIBCRC32C=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_SIGNATURE_DSA=y +CONFIG_CRYPTO_MPILIB=y +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_WP512=m + +# +# Library routines +# +CONFIG_CRC32=m +CONFIG_CRC_CCITT=m + +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_PC=y +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_ATALK is not set +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_IPX is not set +# CONFIG_IPDDP is not set +# CONFIG_IRDA is not set +# CONFIG_NCP_FS is not set +# CONFIG_ISAPNP is not set +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_IEEE1394 is not set +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_WD80x3 is not set +# CONFIG_IRDA is not set +# CONFIG_GAMEPORT is not set +# CONFIG_DVB is not set +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_SB16_CSP=y +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_DT019X is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_BINFMT_AOUT is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_MWAVE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_R3964 is not set +# CONFIG_TIPAR is not set +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_IFORCE_USB=y +# CONFIG_JOYSTICK_IFORCE_232=y +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDDLER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_TYPHOON_PROC_FS=y +# CONFIG_RADIO_ZOLTRIX is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_PLIP is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AHA1542 is not set +CONFIG_SCSI_FUTURE_DOMAIN=m +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA_PP is not set +# CONFIG_VIDEO_CPIA_USB is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_DC30 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZORAN_LML33R10 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_I82092 is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SUNDANCE is not set +# CONFIG_ULTRA is not set +# CONFIG_SKFP is not set +# CONFIG_DE600 is not set +# CONFIG_DE620 is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_AC3200 is not set +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set +# CONFIG_LANCE is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +# CONFIG_3C515 is not set +# CONFIG_HAMACHI is not set +CONFIG_HP100=m +# CONFIG_EQUALIZER is not set +# CONFIG_NET_SB1000 is not set +# CONFIG_DEPCA is not set +# CONFIG_ATP is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_INFTL is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PCI is not set +# CONFIG_PCMCIA_SYM53C500 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_HGA_ACCEL is not set +# CONFIG_FB_3DFX_ACCEL is not set +# CONFIG_FB_TRIDENT_ACCEL is not set +# CONFIG_SCSI_DC390T is not set +CONFIG_AUDIT=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_I2C_PCA_ISA is not set +CONFIG_RAW_DRIVER=y +# CONFIG_MTD_SCB2_FLASH is not set +CONFIG_UID16=y +# CONFIG_X86_PC is not set +# CONFIG_X86_ELAN is not set +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_NUMAQ is not set +# CONFIG_X86_SUMMIT is not set +# CONFIG_X86_BIGSMP is not set +# CONFIG_X86_VISWS is not set +CONFIG_X86_GENERICARCH=y +# CONFIG_X86_ES7000 is not set +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586TSC is not set +# CONFIG_M586MMX is not set +CONFIG_M686=y +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_MWINCHIP2 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set +CONFIG_X86_GENERIC=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_XADD=y +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_X86_PPRO_FENCE=y +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_INVLPG=y +CONFIG_X86_BSWAP=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_GOOD_APIC=y +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +# CONFIG_HPET is not set +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_NR_CPUS=32 +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_TSC=y +CONFIG_X86_MCE=y +# CONFIG_X86_MCE_NONFATAL is not set +CONFIG_X86_MCE_P4THERMAL=y +CONFIG_TOSHIBA=m +CONFIG_I8K=m +CONFIG_SONYPI=m +CONFIG_MICROCODE=m +CONFIG_X86_MSR=m +CONFIG_X86_CPUID=m +CONFIG_EDD=m +# CONFIG_NUMA is not set +# CONFIG_NOHIGHMEM is not set +CONFIG_HIGHMEM4G=y +CONFIG_HIGHMEM64G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +# CONFIG_MATH_EMULATION is not set +CONFIG_MTRR=y +CONFIG_HAVE_DEC_LOCK=y +# CONFIG_X86_UP_APIC is not set +CONFIG_X86_PM_TIMER=y +# CONFIG_X86_4G is not set +# CONFIG_EFI is not set +CONFIG_REGPARM=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set +CONFIG_PCI_GOANY=y +CONFIG_MDA_CONSOLE=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_HP100=m +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_CRASH=m +CONFIG_CAPI_EICON=y +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +CONFIG_I2O_CONFIG=y +CONFIG_APM=y +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_DO_ENABLE is not set +CONFIG_APM_CPU_IDLE=y +# CONFIG_APM_DISPLAY_BLANK is not set +CONFIG_APM_RTC_IS_GMT=y +# CONFIG_APM_ALLOW_INTS is not set +# CONFIG_APM_REAL_MODE_POWER_OFF is not set +CONFIG_X86_FIND_SMP_CONFIG=y +CONFIG_X86_MPPARSE=y +CONFIG_ACPI=y +CONFIG_ACPI_BOOT=y +CONFIG_ACPI_INTERPRETER=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_FAN=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_TOSHIBA=m +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_BUS=y +CONFIG_ACPI_EC=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PCI=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_BLACKLIST_YEAR=2001 +CONFIG_X86_ACPI_CPUFREQ=y +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_X86_POWERNOW_K6=m +CONFIG_X86_POWERNOW_K7=y +CONFIG_X86_POWERNOW_K8=m +# CONFIG_X86_GX_SUSPMOD is not set +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +CONFIG_X86_SPEEDSTEP_ICH=y +CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_SPEEDSTEP_LIB=y +# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set +CONFIG_X86_P4_CLOCKMOD=m +CONFIG_X86_LONGRUN=y +CONFIG_X86_LONGHAUL=y +CONFIG_X86_SMP=y +CONFIG_X86_HT=y +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_TRAMPOLINE=y +CONFIG_TUX=m +CONFIG_NVRAM=m +CONFIG_IBM_ASM=m +CONFIG_CRYPTO_AES_586=m +CONFIG_GENERIC_ISA_DMA=y +CONFIG_SCHED_SMT=y +# CONFIG_IRQBALANCE is not set +# CONFIG_SOFTWARE_SUSPEND is not set +# CONFIG_PM_DEBUG is not set +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_PROC_INTF is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +# CONFIG_CPU_FREQ_24_API is not set +CONFIG_CPU_FREQ_TABLE=y +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_DEBUG_STACK_USAGE=y +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_KPROBES is not set +CONFIG_KEXEC=y +CONFIG_NETDUMP=m +# CONFIG_SCHEDSTATS is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_BIOS=y +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +CONFIG_HOTPLUG_PCI_COMPAQ=m +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +# CONFIG_HOTPLUG_PCI_CPCI is not set +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_HOTPLUG_PCI_SHPC=m +# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set +# CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY is not set +CONFIG_PM=y +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT=m +CONFIG_IEEE80211_WPA=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IPW2100=m +# CONFIG_IPW_DEBUG is not set +CONFIG_IPW2100_PROMISC=y +# CONFIG_IPW2100_LEGACY_FW_LOAD is not set +CONFIG_IPW2200=m +CONFIG_M686=y +# CONFIG_NOHIGHMEM is not set +CONFIG_HIGHMEM64G=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_COMPAQ=m +CONFIG_HOTPLUG_PCI_IBM=m +# CONFIG_HIGHMEM64G is not set +# CONFIG_EWRK3 is not set +CONFIG_NR_CPUS=32 +# CONFIG_X86_PC is not set +CONFIG_X86_GENERICARCH=y diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-i686.config b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-i686.config new file mode 100644 index 0000000..8d66567 --- /dev/null +++ b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-i686.config @@ -0,0 +1,2735 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +# CONFIG_SMP is not set +# CONFIG_HOTPLUG_CPU is not set +CONFIG_LOCALVERSION="" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_POSIX_MQUEUE=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y +CONFIG_MODULE_SIG=y +# CONFIG_MODULE_SIG_FORCE is not set + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_NAMES is not set +CONFIG_ISA=y +# CONFIG_EISA is not set +# CONFIG_MCA is not set +# CONFIG_SCx200 is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_YENTA=y +CONFIG_CARDBUS=y +# CONFIG_I82092 is not set +CONFIG_I82365=m +CONFIG_PD6729=m +CONFIG_TCIC=m +CONFIG_PCMCIA_PROBE=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_FW_LOADER=y + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=m +CONFIG_MTD_CONCAT=m +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_PARTITIONS=y +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_FTL=m +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PNC2000 is not set +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_NETSC520=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_ELAN_104NC=m +CONFIG_MTD_SCx200_DOCFLASH=m +# CONFIG_MTD_AMD76XROM is not set +# CONFIG_MTD_SCB2_FLASH is not set +# CONFIG_MTD_NETtel is not set +# CONFIG_MTD_DILNETPC is not set +# CONFIG_MTD_L440GX is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +# CONFIG_MTD_SLRAM is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_DOCPROBE=m +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=m + +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CFI_AMDSTD_RETRY=3 +# CONFIG_MTD_ICHXROM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set + + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_ATIIXP=y +CONFIG_BLK_DEV_DELKIN=y +CONFIG_BLK_DEV_IT8212=y +CONFIG_LBD=y +# CONFIG_DCSSBLK is not set + + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_IDE_GENERIC=y +# CONFIG_HPT34X_AUTODMA is not set + +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set +# CONFIG_BLK_DEV_IDE_SATA is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_RZ1000=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_AEC62XX=y +CONFIG_BLK_DEV_ALI15X3=y +# CONFIG_WDC_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +CONFIG_BLK_DEV_CMD64X=y +CONFIG_BLK_DEV_TRIFLEX=y +CONFIG_BLK_DEV_CY82C693=y +CONFIG_BLK_DEV_CS5520=y +CONFIG_BLK_DEV_CS5530=y +CONFIG_BLK_DEV_HPT34X=y +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_NS87415 is not set +CONFIG_BLK_DEV_PDC202XX_OLD=y +# CONFIG_PDC202XX_BURST is not set +CONFIG_BLK_DEV_PDC202XX_NEW=y +CONFIG_PDC202XX_FORCE=y +CONFIG_BLK_DEV_SVWKS=y +CONFIG_BLK_DEV_SIIMAGE=y +CONFIG_BLK_DEV_SIS5513=y +CONFIG_BLK_DEV_SLC90E66=y +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_CHIPSETS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SPI_ATTRS=y +CONFIG_SCSI_FC_ATTRS=y + +# +# SCSI low-level drivers +# +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +# CONFIG_SCSI_7000FASST is not set +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AHA152X=m +# CONFIG_SCSI_AHA1542 is not set +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_PROBE_EISA_VL is not set +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC7XXX_OLD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=4 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_BUILD_FIRMWARE is not set +# CONFIG_AIC79XX_ENABLE_RD_STRM is not set +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_SCSI_SATA=y +CONFIG_SCSI_SATA_SVW=m +CONFIG_SCSI_ATA_PIIX=m +CONFIG_SCSI_SATA_PROMISE=m +CONFIG_SCSI_SATA_VIA=m +CONFIG_BLK_DEV_SX8=m +CONFIG_SCSI_SATA_VITESSE=m +CONFIG_SCSI_SATA_SIL=m +CONFIG_SCSI_SATA_SIS=m +CONFIG_SCSI_SATA_SX4=m +CONFIG_SCSI_SATA_NV=m +CONFIG_SCSI_SATA_AHCI=m + +# CONFIG_SCSI_BUSLOGIC is not set +CONFIG_SCSI_INITIO=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +CONFIG_SCSI_IPS=m +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set +CONFIG_SCSI_QLOGIC_1280=m +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_ULTRASTOR is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DC390T is not set +CONFIG_SCSI_QLA2XXX=m +CONFIG_SCSI_QLA21XX=m +CONFIG_SCSI_QLA22XX=m +CONFIG_SCSI_QLA2300=m +CONFIG_SCSI_QLA2322=m +CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_QLA6322=m +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_DPT_I2O is not set + +CONFIG_SCSI_LPFC=m + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_AHA152X is not set +CONFIG_PCMCIA_FDOMAIN=m +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID5=m +CONFIG_MD_RAID6=m +CONFIG_MD_RAID10=m +CONFIG_MD_MULTIPATH=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_CRYPT=m + +# +# Fusion MPT device support +# +CONFIG_FUSION=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_OUI_DB=y + +# +# Device Drivers +# +# CONFIG_IEEE1394_PCILYNX is not set +CONFIG_IEEE1394_OHCI1394=m + +# +# Protocol Drivers +# +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_ETH1394 is not set +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_CMP=m +CONFIG_IEEE1394_AMDTP=m +# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set + +# +# I2O device support +# +CONFIG_I2O=m + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_INET_TUNNEL=m +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_NETCONSOLE=m +# CONFIG_NETPOLL_RX is not set +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NETDUMP=m +CONFIG_DISKDUMP=m +CONFIG_SCSI_DUMP=m +CONFIG_SD_IOSTATS=y + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m + + +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_TUNNEL=m +# CONFIG_DECNET is not set +CONFIG_BRIDGE=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_PHYSDEV=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +CONFIG_IP_NF_MATCH_SCTP=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_NAT_LOCAL=y +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CT_PROTO_SCTP=m +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_LENGTH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_PHYSDEV=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +CONFIG_IP6_NF_RAW=m + + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_XFRM=y +CONFIG_XFRM_USER=y + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_ATM=m +CONFIG_VLAN_8021Q=m +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_IPX_INTERN is not set +# CONFIG_ATALK is not set +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +# CONFIG_IPDDP is not set +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +CONFIG_NET_DIVERT=y +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_ACT_POLICE is not set +CONFIG_CLS_U32_PERF=y +CONFIG_NET_CLS_IND=y +# CONFIG_NET_CLS_ACT is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +CONFIG_DUMMY=m +CONFIG_BONDING=m +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +CONFIG_ETHERTAP=m +# CONFIG_NET_SB1000 is not set + +# +# ATM +# +CONFIG_ATM_CLIP=m +CONFIG_ATM_LANE=m +CONFIG_ATM_BR2684=m +CONFIG_NET_SCH_ATM=m +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +CONFIG_ATM_FIRESTREAM=m +# CONFIG_ATM_ZATM is not set +CONFIG_ATM_IDT77252=m +CONFIG_ATM_AMBASSADOR=m +CONFIG_ATM_HORIZON=m +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_HE=m +CONFIG_PPPOATM=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_IA is not set + + +# CONFIG_ATM_CLIP_NO_ICMP is not set +# CONFIG_ATM_MPOA is not set +# CONFIG_ATM_BR2684_IPFILTER is not set +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +# CONFIG_ATM_ZATM_DEBUG is not set +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +# CONFIG_ATM_HORIZON_DEBUG is not set +# CONFIG_ATM_FORE200E_PCA is not set +# CONFIG_ATM_HE_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_IA_DEBUG is not set + + + + + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_NET_VENDOR_3COM=y +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +# CONFIG_3C515 is not set +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +# CONFIG_LANCE is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +# CONFIG_ULTRA is not set +CONFIG_SMC9194=m +CONFIG_NET_VENDOR_RACAL=y +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_TULIP=m +# CONFIG_TULIP_NAPI is not set + +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_NI5010 is not set +# CONFIG_PCMCIA_XIRTULIP is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_PCMCIA_XIRCOM=m +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +CONFIG_HP100=m +# CONFIG_NET_ISA is not set +CONFIG_EWRK3=m +CONFIG_E2100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_HPLAN_PLUS=m +CONFIG_HPLAN=m +CONFIG_LP486E=m +CONFIG_ETH16I=m +CONFIG_NE2000=m +CONFIG_ZNET=m +CONFIG_SEEQ8005=m +CONFIG_LNE390=m +CONFIG_NE3210=m +CONFIG_ES3210=m +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +CONFIG_AMD8111_ETH=m +CONFIG_AMD8111E_NAPI=y +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADAPTEC_STARFIRE_NAPI=y +# CONFIG_AC3200 is not set +CONFIG_APRICOT=m +CONFIG_B44=m +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +CONFIG_EEPRO100=m +# CONFIG_EEPRO100_PIO is not set +CONFIG_E100=m +CONFIG_E100_NAPI=y +CONFIG_FEALNX=m +CONFIG_FORCEDETH=m +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_SIS900=m +CONFIG_EPIC100=m +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_TLAN=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_VELOCITY=m +CONFIG_NET_POCKET=y +# CONFIG_ATP is not set +# CONFIG_DE600 is not set +# CONFIG_DE620 is not set + +# +# Ethernet (1000 Mbit) +# +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000_NAPI=y +CONFIG_NS83820=m +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=m +CONFIG_R8169_NAPI=y +CONFIG_SK98LIN=m +CONFIG_TIGON3=m + +# +# Ethernet (10000 Mbit) +# +CONFIG_IXGB=m +CONFIG_IXGB_NAPI=y +CONFIG_S2IO=m +CONFIG_S2IO_NAPI=y +CONFIG_FDDI=y +# CONFIG_DEFXX is not set +# CONFIG_SKFP is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_IPPP_FILTER=y +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +CONFIG_WAVELAN=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_NETWAVE=m + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT=m +CONFIG_IEEE80211_WPA=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IPW2100=m +# CONFIG_IPW_DEBUG is not set +CONFIG_IPW2100_PROMISC=y +# CONFIG_IPW2100_LEGACY_FW_LOAD is not set +CONFIG_IPW2200=m +CONFIG_AIRO=m +CONFIG_HERMES=m +CONFIG_PLX_HERMES=m +CONFIG_TMD_HERMES=m +CONFIG_PCI_HERMES=m +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +CONFIG_PRISM54=m + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=m +CONFIG_AIRO_CS=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_WL3501=m +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +CONFIG_TR=y +CONFIG_IBMOL=m +CONFIG_3C359=m +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +CONFIG_ABYSS=m +CONFIG_IBMTR=m +CONFIG_IBMLS=m +CONFIG_SKISA=m +CONFIG_PROTEON=m +CONFIG_SMCTR=m +CONFIG_PCMCIA_IBMTR=m + + +CONFIG_NET_FC=y +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set +# CONFIG_IRDA is not set +# CONFIG_IRDA_DEBUG is not set +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRTTY_SIR=m +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_IRPORT_SIR=m +# CONFIG_DONGLE_OLD is not set +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m + +CONFIG_USB_IRDA=m +CONFIG_NSC_FIR=m +CONFIG_SIGMATEL_FIR=m +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set +# CONFIG_VIA_FIR is not set + + + +# +# Bluetooth support +# +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_CMTP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_BCSP_TXCRC=y +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_USB_BLUETOOTH_TTY=m + +# +# ISDN subsystem +# + +CONFIG_ISDN=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_C4=m + +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +# CONFIG_ISDN_PPP_BSDCOMP is not set +CONFIG_ISDN_TTY_FAX=y +CONFIG_DE_AOC=y + +CONFIG_ISDN_AUDIO=y + +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_TPAM=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m + +CONFIG_ISDN_CAPI_CAPIDRV=m + +CONFIG_HISAX_EURO=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_NO_SENDCOMPLETE=y +CONFIG_HISAX_NO_LLC=y +CONFIG_HISAX_NO_KEYPAD=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_TELES_CS=m + +CONFIG_ISDN_DRV_LOOP=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y + + +# +# CAPI subsystem +# +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_CAPIFS=m + +# +# CAPI hardware drivers +# + +# +# Active AVM cards +# +CONFIG_CAPI_AVM=y + +# +# Active Eicon DIVA Server cards +# +CONFIG_CAPI_EICON=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVAS_MAINT=m + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_VORTEX=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_CS461x=m +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_RAW is not set + +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_ATIXL=y +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_IFORCE_USB=y +# CONFIG_JOYSTICK_IFORCE_232=y +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDDLER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_UINPUT=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_ROCKETPORT is not set +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_N_HDLC=m +CONFIG_STALDRV=y +# CONFIG_FTAPE is not set +CONFIG_IBM_ASM=m + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_ACPI is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_MULTIPORT=y +CONFIG_SERIAL_8250_RSA=y +# CONFIG_COMPUTONE is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALLION is not set +# CONFIG_ISTALLION is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_PRINTER=m +CONFIG_LP_CONSOLE=y +CONFIG_PPDEV=m +# CONFIG_TIPAR is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_DEBUG_ALGO is not set +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m + +# +# I2C Hardware Bus support +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +# CONFIG_SCx200_ACB is not set +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +# CONFIG_I2C_ELEKTOR is not set +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_PARPORT is not set +CONFIG_I2C_ALI1563=m +# CONFIG_I2C_PARPORT_LIGHT is not set +CONFIG_I2C_ALGOPCA=m +# CONFIG_I2C_PCA_ISA is not set + + + +# +# I2C Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_RTC8564=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_SMSC47M1=m + +# CONFIG_W1 is not set + +# +# Mice +# +CONFIG_CRASH=m + +# +# IPMI +# +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_POWEROFF=m + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_SOFT_WATCHDOG=m +CONFIG_WDT=m +# CONFIG_WDT_501 is not set +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y +CONFIG_PCWATCHDOG=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ADVANTECH_WDT=m +CONFIG_EUROTECH_WDT=m +CONFIG_IB700_WDT=m +CONFIG_I8XX_TCO=m +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +CONFIG_W83877F_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_MACHZ_WDT=m +CONFIG_SC520_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALIM1535_WDT=m +CONFIG_SC1200_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_CPU5_WDT=m +CONFIG_PCIPCWATCHDOG=m +CONFIG_USBPCWATCHDOG=m + + +CONFIG_HW_RANDOM=m +CONFIG_NVRAM=m +CONFIG_RTC=y +CONFIG_DTLK=m +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +CONFIG_SONYPI=m + +# +# Ftape, the floppy tape device driver +# +CONFIG_AGP=y +CONFIG_AGP_ALI=y +CONFIG_AGP_ATI=y +CONFIG_AGP_AMD=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=y +CONFIG_AGP_INTEL_MCH=y +CONFIG_AGP_NVIDIA=y +CONFIG_AGP_SIS=y +CONFIG_AGP_SWORKS=y +CONFIG_AGP_VIA=y +CONFIG_AGP_EFFICEON=y +CONFIG_DRM=y +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_MGA=m +# CONFIG_DRM_SIS is not set +CONFIG_DRM_I915=m + + + +# +# PCMCIA character devices +# +CONFIG_SYNCLINK_CS=m + + + +# CONFIG_MWAVE is not set +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +CONFIG_HANGCHECK_TIMER=m + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA_PP is not set +# CONFIG_VIDEO_CPIA_USB is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_DC30 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZORAN_LML33R10 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_SAA5246A is not set +CONFIG_VIDEO_OVCAMCHIP=m + + +# +# Radio Adapters +# +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_TYPHOON_PROC_FS=y +# CONFIG_RADIO_ZOLTRIX is not set + + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +CONFIG_DVB_CORE=m + +# +# Supported Frontend Modules +# +CONFIG_DVB_STV0299=m +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_ALPS_TDLB7 is not set +CONFIG_DVB_ALPS_TDMB7=m +CONFIG_DVB_ATMEL_AT76C651=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_GRUNDIG_29504_491=m +CONFIG_DVB_GRUNDIG_29504_401=m +CONFIG_DVB_MT312=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TWINHAN_DST=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_BT8XX=m +# CONFIG_DVB_TDA1004X is not set +CONFIG_DVB_NXT6000=m + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +# CONFIG_DVB_AV7110_FIRMWARE is not set +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m + +# +# Supported USB Adapters +# +CONFIG_DVB_TTUSB_BUDGET=m + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_SKYSTAR=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_VIDEOBUF=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BTCX=m + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_VGA16=m +CONFIG_FB_VESA=y +CONFIG_VIDEO_SELECT=y +# CONFIG_FB_HGA is not set +CONFIG_FB_RIVA=m +# CONFIG_FB_RIVA_DEBUG is not set +# CONFIG_FB_RIVA_I2C is not set +CONFIG_FB_I810=m +CONFIG_FB_I810_GTF=y +# CONFIG_FB_MATROX is not set +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G450=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MULTIHEAD=y +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RADEON_DEBUG is not set +# CONFIG_FB_RADEON_OLD is not set +CONFIG_FB_RADEON_I2C=y +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GX=y +# CONFIG_FB_ATY_XL_INIT is not set +# CONFIG_FB_SIS is not set +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_KYRO=m +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM2_FIFO_DISCONNECT is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_HGA_ACCEL is not set +# CONFIG_FB_3DFX_ACCEL is not set +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_CIRRUS=m + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_MDA_CONSOLE=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set + + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_RTCTIMER=m +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_BIT32_EMUL=y + +# +# Generic devices +# +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +# CONFIG_SND_SERIAL_U16550 is not set +CONFIG_SND_MPU401=m + +# +# ISA devices +# +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_SB16_CSP=y +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_DT019X is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set + +# +# PCI devices +# +CONFIG_SND_ALI5451=m +CONFIG_SND_AZT3328=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS4281=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_KORG1212=m +CONFIG_SND_NM256=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_HDSP=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_ALS4000=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_FM801=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VX222=m +CONFIG_SND_BT87X=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_MIXART=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_PDAUDIOCF=m + + +# +# ALSA USB devices +# +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m + +# +# PCMCIA devices +# +# CONFIG_SND_VXPOCKET is not set +# CONFIG_SND_VXP440 is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_UHCI_HCD=m + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set + +# +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# +CONFIG_USB_MIDI=m +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_HP8200e=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_RW_DETECT=y + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +CONFIG_HID_FF=y +CONFIG_HID_PID=y +CONFIG_LOGITECH_FF=y +CONFIG_THRUSTMASTER_FF=y +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +CONFIG_USB_AIPTEK=m +CONFIG_USB_WACOM=m +CONFIG_USB_KBTAB=m +CONFIG_USB_POWERMATE=m +CONFIG_USB_XPAD=m + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_HPUSBSCSI=m + +# +# USB Multimedia devices +# +CONFIG_USB_DABUSB=m +CONFIG_USB_VICAM=m +CONFIG_USB_DSBR=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_STV680=m +CONFIG_USB_SN9C102=m + +# +# USB Network adaptors +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_SPEEDTOUCH=m + +# +# USB Host-to-Host Cables +# +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_GENESYS=y +CONFIG_USB_NET1080=y +CONFIG_USB_PL2301=y + +# +# Intelligent USB Devices/Gadgets +# +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_ZAURUS=y +CONFIG_USB_CDCETHER=y + +# +# USB Network Adapters +# +CONFIG_USB_AX8817X=y + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_EZUSB=y +CONFIG_USB_EMI62=m +CONFIG_USB_LED=m +CONFIG_USB_G_SERIAL=m + + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +CONFIG_USB_AUERSWALD=m +CONFIG_USB_RIO500=m +CONFIG_USB_LCD=m +CONFIG_USB_TEST=m +# CONFIG_USB_GADGET is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_SA1100 is not set +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_W9968CF=m +CONFIG_USB_PWC=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_MTOUCH=m +CONFIG_USB_ATI_REMOTE=m +CONFIG_USB_ALI_M5632=y +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_EGALAX=m +CONFIG_USB_PHIDGETSERVO=m + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_JFS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_XFS_RT is not set +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_SECURITY=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_QUOTA=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +CONFIG_UDF_FS=m + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_TMPFS_SECURITY=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not seta +# CONFIG_AFFS_FS is not set +# uses sleepon and needs a major update +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_NAND=y +CONFIG_CRAMFS=m +CONFIG_VXFS_FS=m +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_NCP_FS is not set +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_SMALLDOS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_RXRPC is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +CONFIG_OSF_PARTITION=y +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_SUN_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_NLS_ASCII=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set +# CONFIG_OPROFILE is not set + +# +# Tux +# +CONFIG_TUX=m +CONFIG_TUX_EXTCGI=y +# CONFIG_TUX_EXTENDED_LOG is not set +# CONFIG_TUX_DEBUG is not set + + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_HIGHMEM=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_FRAME_POINTER is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_DEBUG_DRIVER is not set + +# +# Security options +# +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +# CONFIG_SECURITY_SELINUX_MLS is not set +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_TEST is not set +CONFIG_LIBCRC32C=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_SIGNATURE_DSA=y +CONFIG_CRYPTO_MPILIB=y +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_WP512=m + +# +# Library routines +# +CONFIG_CRC32=m +CONFIG_CRC_CCITT=m + +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_PC=y +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_ATALK is not set +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_IPX is not set +# CONFIG_IPDDP is not set +# CONFIG_IRDA is not set +# CONFIG_NCP_FS is not set +# CONFIG_ISAPNP is not set +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_IEEE1394 is not set +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_WD80x3 is not set +# CONFIG_IRDA is not set +# CONFIG_GAMEPORT is not set +# CONFIG_DVB is not set +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_SB16_CSP=y +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_DT019X is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_BINFMT_AOUT is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_MWAVE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_R3964 is not set +# CONFIG_TIPAR is not set +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_IFORCE_USB=y +# CONFIG_JOYSTICK_IFORCE_232=y +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDDLER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_TYPHOON_PROC_FS=y +# CONFIG_RADIO_ZOLTRIX is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_PLIP is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AHA1542 is not set +CONFIG_SCSI_FUTURE_DOMAIN=m +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA_PP is not set +# CONFIG_VIDEO_CPIA_USB is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_DC30 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZORAN_LML33R10 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_I82092 is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SUNDANCE is not set +# CONFIG_ULTRA is not set +# CONFIG_SKFP is not set +# CONFIG_DE600 is not set +# CONFIG_DE620 is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_AC3200 is not set +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set +# CONFIG_LANCE is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +# CONFIG_3C515 is not set +# CONFIG_HAMACHI is not set +CONFIG_HP100=m +# CONFIG_EQUALIZER is not set +# CONFIG_NET_SB1000 is not set +# CONFIG_DEPCA is not set +# CONFIG_ATP is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_INFTL is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PCI is not set +# CONFIG_PCMCIA_SYM53C500 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_HGA_ACCEL is not set +# CONFIG_FB_3DFX_ACCEL is not set +# CONFIG_FB_TRIDENT_ACCEL is not set +# CONFIG_SCSI_DC390T is not set +CONFIG_AUDIT=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_I2C_PCA_ISA is not set +CONFIG_RAW_DRIVER=y +# CONFIG_MTD_SCB2_FLASH is not set +CONFIG_UID16=y +CONFIG_X86_PC=y +# CONFIG_X86_ELAN is not set +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_NUMAQ is not set +# CONFIG_X86_SUMMIT is not set +# CONFIG_X86_BIGSMP is not set +# CONFIG_X86_VISWS is not set +# CONFIG_X86_GENERICARCH is not set +# CONFIG_X86_ES7000 is not set +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586TSC is not set +# CONFIG_M586MMX is not set +CONFIG_M686=y +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_MWINCHIP2 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set +CONFIG_X86_GENERIC=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_XADD=y +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_X86_PPRO_FENCE=y +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_INVLPG=y +CONFIG_X86_BSWAP=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_GOOD_APIC=y +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +# CONFIG_HPET is not set +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_NR_CPUS=8 +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_TSC=y +CONFIG_X86_MCE=y +# CONFIG_X86_MCE_NONFATAL is not set +CONFIG_X86_MCE_P4THERMAL=y +CONFIG_TOSHIBA=m +CONFIG_I8K=m +CONFIG_SONYPI=m +CONFIG_MICROCODE=m +CONFIG_X86_MSR=m +CONFIG_X86_CPUID=m +CONFIG_EDD=m +# CONFIG_NUMA is not set +# CONFIG_NOHIGHMEM is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +# CONFIG_MATH_EMULATION is not set +CONFIG_MTRR=y +CONFIG_HAVE_DEC_LOCK=y +# CONFIG_X86_UP_APIC is not set +CONFIG_X86_PM_TIMER=y +# CONFIG_X86_4G is not set +# CONFIG_EFI is not set +CONFIG_REGPARM=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set +CONFIG_PCI_GOANY=y +CONFIG_MDA_CONSOLE=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_HP100=m +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_CRASH=m +CONFIG_CAPI_EICON=y +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +CONFIG_I2O_CONFIG=y +CONFIG_APM=y +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_DO_ENABLE is not set +CONFIG_APM_CPU_IDLE=y +# CONFIG_APM_DISPLAY_BLANK is not set +CONFIG_APM_RTC_IS_GMT=y +# CONFIG_APM_ALLOW_INTS is not set +# CONFIG_APM_REAL_MODE_POWER_OFF is not set +CONFIG_X86_FIND_SMP_CONFIG=y +CONFIG_X86_MPPARSE=y +CONFIG_ACPI=y +CONFIG_ACPI_BOOT=y +CONFIG_ACPI_INTERPRETER=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_FAN=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_TOSHIBA=m +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_BUS=y +CONFIG_ACPI_EC=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PCI=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_BLACKLIST_YEAR=2001 +CONFIG_X86_ACPI_CPUFREQ=y +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_X86_POWERNOW_K6=m +CONFIG_X86_POWERNOW_K7=y +CONFIG_X86_POWERNOW_K8=m +# CONFIG_X86_GX_SUSPMOD is not set +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +CONFIG_X86_SPEEDSTEP_ICH=y +CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_SPEEDSTEP_LIB=y +# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set +CONFIG_X86_P4_CLOCKMOD=m +CONFIG_X86_LONGRUN=y +CONFIG_X86_LONGHAUL=y +CONFIG_X86_SMP=y +CONFIG_X86_HT=y +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_TRAMPOLINE=y +CONFIG_TUX=m +CONFIG_NVRAM=m +CONFIG_IBM_ASM=m +CONFIG_CRYPTO_AES_586=m +CONFIG_GENERIC_ISA_DMA=y +CONFIG_SCHED_SMT=y +# CONFIG_IRQBALANCE is not set +# CONFIG_SOFTWARE_SUSPEND is not set +# CONFIG_PM_DEBUG is not set +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_PROC_INTF is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +# CONFIG_CPU_FREQ_24_API is not set +CONFIG_CPU_FREQ_TABLE=y +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_DEBUG_STACK_USAGE=y +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_KPROBES is not set +CONFIG_KEXEC=y +CONFIG_NETDUMP=m +# CONFIG_SCHEDSTATS is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_BIOS=y +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +CONFIG_HOTPLUG_PCI_COMPAQ=m +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +# CONFIG_HOTPLUG_PCI_CPCI is not set +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_HOTPLUG_PCI_SHPC=m +# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set +# CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY is not set +CONFIG_PM=y +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT=m +CONFIG_IEEE80211_WPA=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IPW2100=m +# CONFIG_IPW_DEBUG is not set +CONFIG_IPW2100_PROMISC=y +# CONFIG_IPW2100_LEGACY_FW_LOAD is not set +CONFIG_IPW2200=m +CONFIG_M686=y +# CONFIG_NOHIGHMEM is not set +# CONFIG_SMP is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +# CONFIG_PROFILING is not set +# CONFIG_OPROFILE is not set diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-ia64-smp.config b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-ia64-smp.config new file mode 100644 index 0000000..611ce45 --- /dev/null +++ b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-ia64-smp.config @@ -0,0 +1,1908 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.9-5.0.3.EL_lustre-b1_4_rhel4.200503031449smp +# Thu Mar 3 14:52:42 2005 +# + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_HOTPLUG=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +# CONFIG_TINY_SHMEM is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SIG=y +# CONFIG_MODULE_SIG_FORCE is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y + +# +# Processor type and features +# +CONFIG_IA64=y +CONFIG_64BIT=y +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_TIME_INTERPOLATION=y +CONFIG_EFI=y +CONFIG_GENERIC_IOMAP=y +CONFIG_IA64_GENERIC=y +# CONFIG_IA64_DIG is not set +# CONFIG_IA64_HP_ZX1 is not set +# CONFIG_IA64_SGI_SN2 is not set +# CONFIG_IA64_HP_SIM is not set +# CONFIG_ITANIUM is not set +CONFIG_MCKINLEY=y +# CONFIG_IA64_PAGE_SIZE_4KB is not set +# CONFIG_IA64_PAGE_SIZE_8KB is not set +CONFIG_IA64_PAGE_SIZE_16KB=y +# CONFIG_IA64_PAGE_SIZE_64KB is not set +CONFIG_IA64_L1_CACHE_SHIFT=7 +CONFIG_NUMA=y +CONFIG_VIRTUAL_MEM_MAP=y +CONFIG_DISCONTIGMEM=y +CONFIG_IA64_CYCLONE=y +CONFIG_IOSAPIC=y +CONFIG_FORCE_MAX_ZONEORDER=18 +CONFIG_SMP=y +CONFIG_NR_CPUS=64 +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_PREEMPT is not set +CONFIG_HAVE_DEC_LOCK=y +# CONFIG_IA32_SUPPORT is not set +CONFIG_IA64_MCA_RECOVERY=m +CONFIG_PERFMON=y +CONFIG_IA64_PALINFO=y + +# +# Firmware Drivers +# +CONFIG_EFI_VARS=y +CONFIG_EFI_PCDP=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y + +# +# Power management and ACPI +# +CONFIG_PM=y +CONFIG_ACPI=y + +# +# ACPI (Advanced Configuration and Power Interface) Support +# +CONFIG_ACPI_BOOT=y +CONFIG_ACPI_INTERPRETER=y +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_FAN=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_BLACKLIST_YEAR=2001 +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_BUS=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PCI=y +CONFIG_ACPI_SYSTEM=y + +# +# Bus options (PCI, PCMCIA) +# +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_MSI=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_NAMES is not set + +# +# PCI Hotplug Support +# +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +# CONFIG_HOTPLUG_PCI_CPCI is not set +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_HOTPLUG_PCI_SHPC=m +# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_YENTA=m +CONFIG_CARDBUS=y +CONFIG_PD6729=m +# CONFIG_I82092 is not set +CONFIG_TCIC=m + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_PARIDE is not set +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_SX8=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_INITRD=y +CONFIG_DISKDUMP=m + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_AEC62XX=y +CONFIG_BLK_DEV_ALI15X3=y +# CONFIG_WDC_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +CONFIG_BLK_DEV_CMD64X=y +CONFIG_BLK_DEV_TRIFLEX=y +CONFIG_BLK_DEV_CY82C693=y +CONFIG_BLK_DEV_CS5520=y +CONFIG_BLK_DEV_CS5530=y +CONFIG_BLK_DEV_HPT34X=y +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_PIIX=y +CONFIG_BLK_DEV_IT8212=y +# CONFIG_BLK_DEV_NS87415 is not set +CONFIG_BLK_DEV_PDC202XX_OLD=y +# CONFIG_PDC202XX_BURST is not set +CONFIG_BLK_DEV_PDC202XX_NEW=y +CONFIG_PDC202XX_FORCE=y +CONFIG_BLK_DEV_SVWKS=y +CONFIG_BLK_DEV_SGIIOC4=m +CONFIG_BLK_DEV_SIIMAGE=y +CONFIG_BLK_DEV_SLC90E66=y +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_SCSI_DUMP=m +CONFIG_SD_IOSTATS=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m + +# +# SCSI low-level drivers +# +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC7XXX_OLD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=4 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_ENABLE_RD_STRM is not set +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_SCSI_SATA=y +CONFIG_SCSI_SATA_AHCI=m +CONFIG_SCSI_SATA_SVW=m +CONFIG_SCSI_ATA_PIIX=m +CONFIG_SCSI_SATA_NV=m +CONFIG_SCSI_SATA_PROMISE=m +CONFIG_SCSI_SATA_SX4=m +CONFIG_SCSI_SATA_SIL=m +CONFIG_SCSI_SATA_SIS=m +CONFIG_SCSI_SATA_VIA=m +CONFIG_SCSI_SATA_VITESSE=m +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA2XXX=m +CONFIG_SCSI_QLA21XX=m +CONFIG_SCSI_QLA22XX=m +CONFIG_SCSI_QLA2300=m +CONFIG_SCSI_QLA2322=m +CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_QLA6322=m +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID5=m +CONFIG_MD_RAID6=m +CONFIG_MD_MULTIPATH=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m + +# +# Fusion MPT device support +# +CONFIG_FUSION=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_TUNNEL=m + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_TUNNEL=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CT_PROTO_SCTP=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_PHYSDEV=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +CONFIG_IP_NF_MATCH_SCTP=m +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_LOCAL=y +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_LENGTH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_PHYSDEV=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +CONFIG_IP6_NF_RAW=m + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_XFRM=y +CONFIG_XFRM_USER=y + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +# CONFIG_ATM_MPOA is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +# CONFIG_DECNET is not set +CONFIG_LLC=y +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +CONFIG_NET_DIVERT=y +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CLK_JIFFIES=y +# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set +# CONFIG_NET_SCH_CLK_CPU is not set +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_NET_CLS_IND=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_POLICE=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_BCSP_TXCRC=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_TUX=m + +# +# TUX options +# +CONFIG_TUX_EXTCGI=y +# CONFIG_TUX_EXTENDED_LOG is not set +# CONFIG_TUX_DEBUG is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +CONFIG_BONDING=m +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +CONFIG_ETHERTAP=m + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_VORTEX=m +CONFIG_TYPHOON=m + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_TULIP_NAPI is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_PCMCIA_XIRCOM=m +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +CONFIG_AMD8111_ETH=m +CONFIG_AMD8111E_NAPI=y +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADAPTEC_STARFIRE_NAPI=y +CONFIG_B44=m +CONFIG_FORCEDETH=m +# CONFIG_DGRS is not set +CONFIG_EEPRO100=m +# CONFIG_EEPRO100_PIO is not set +CONFIG_E100=m +CONFIG_E100_NAPI=y +CONFIG_FEALNX=m +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_SIS900=m +CONFIG_EPIC100=m +# CONFIG_SUNDANCE is not set +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y + +# +# Ethernet (1000 Mbit) +# +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000_NAPI=y +CONFIG_NS83820=m +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=m +CONFIG_R8169_NAPI=y +CONFIG_SK98LIN=m +CONFIG_VIA_VELOCITY=m +CONFIG_TIGON3=m + +# +# Ethernet (10000 Mbit) +# +CONFIG_IXGB=m +CONFIG_IXGB_NAPI=y +CONFIG_S2IO=m +CONFIG_S2IO_NAPI=y + +# +# Token Ring devices +# +CONFIG_TR=y +CONFIG_IBMOL=m +CONFIG_3C359=m +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +CONFIG_ABYSS=m + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_NETWAVE=m + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_IEEE80211 is not set +CONFIG_HERMES=m +CONFIG_PLX_HERMES=m +CONFIG_TMD_HERMES=m +CONFIG_PCI_HERMES=m +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=m +CONFIG_AIRO_CS=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_WL3501=m + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +CONFIG_PRISM54=m +CONFIG_NET_WIRELESS=y + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# ATM drivers +# +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +# CONFIG_ATM_ZATM is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_FORE200E_MAYBE=m +# CONFIG_ATM_FORE200E_PCA is not set +CONFIG_ATM_HE=m +# CONFIG_ATM_HE_USE_SUNI is not set +CONFIG_FDDI=y +# CONFIG_DEFXX is not set +# CONFIG_SKFP is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +# CONFIG_SLIP is not set +CONFIG_NET_FC=y +# CONFIG_SHAPER is not set +CONFIG_NETCONSOLE=m +CONFIG_NETDUMP=m + +# +# ISDN subsystem +# +CONFIG_ISDN=m + +# +# Old ISDN4Linux +# +CONFIG_ISDN_I4L=m +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +CONFIG_IPPP_FILTER=y +# CONFIG_ISDN_PPP_BSDCOMP is not set +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_TTY_FAX=y + +# +# ISDN feature submodules +# + +# +# ISDN4Linux hardware drivers +# + +# +# Passive cards +# +CONFIG_ISDN_DRV_HISAX=m + +# +# D-channel protocol features +# +CONFIG_HISAX_EURO=y +CONFIG_DE_AOC=y +CONFIG_HISAX_NO_SENDCOMPLETE=y +CONFIG_HISAX_NO_LLC=y +CONFIG_HISAX_NO_KEYPAD=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 + +# +# HiSax supported cards +# +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set + +# +# HiSax PCMCIA card service modules +# +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_TELES_CS=m + +# +# HiSax sub driver modules +# +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_HDLC=y + +# +# Active cards +# +CONFIG_ISDN_DRV_TPAM=m + +# +# CAPI subsystem +# +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIDRV=m + +# +# CAPI hardware drivers +# + +# +# Active AVM cards +# +CONFIG_CAPI_AVM=y + +# +# Active Eicon DIVA Server cards +# +# CONFIG_CAPI_EICON is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDDLER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +CONFIG_N_HDLC=m +CONFIG_STALDRV=y +CONFIG_SGI_SNSC=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_ACPI=y +CONFIG_SERIAL_8250_NR_UARTS=20 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_MULTIPORT=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_SGI_L1_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_CRASH is not set +CONFIG_PRINTER=m +CONFIG_LP_CONSOLE=y +CONFIG_PPDEV=m +# CONFIG_TIPAR is not set + +# +# IPMI +# +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_I8XX_TCO=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +# CONFIG_HW_RANDOM is not set +CONFIG_EFI_RTC=y +CONFIG_DTLK=m +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +CONFIG_AGP=y +CONFIG_AGP_I460=y +CONFIG_AGP_HP_ZX1=y +CONFIG_DRM=y +# CONFIG_DRM_TDFX is not set +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_MGA=m +# CONFIG_DRM_SIS is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +CONFIG_RAW_DRIVER=y +# CONFIG_HPET is not set +CONFIG_MAX_RAW_DEVS=8192 +# CONFIG_MMTIMER is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +# CONFIG_SCx200_ACB is not set +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83627HF=m + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_RTC8564=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +CONFIG_VIDEO_OVCAMCHIP=m + +# +# Radio Adapters +# +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_CIRRUS=m +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_RIVA=m +# CONFIG_FB_RIVA_I2C is not set +# CONFIG_FB_RIVA_DEBUG is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +CONFIG_FB_KYRO=m +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +# CONFIG_SND_SERIAL_U16550 is not set +CONFIG_SND_MPU401=m + +# +# PCI devices +# +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS4281=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_KORG1212=m +CONFIG_SND_MIXART=m +CONFIG_SND_NM256=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_HDSP=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_ALS4000=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VX222=m + +# +# ALSA USB devices +# +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m + +# +# PCMCIA devices +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_UHCI_HCD=m + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set + +# +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# +CONFIG_USB_MIDI=m +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_RW_DETECT=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_HP8200e=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +CONFIG_HID_FF=y +CONFIG_HID_PID=y +CONFIG_LOGITECH_FF=y +CONFIG_THRUSTMASTER_FF=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_AIPTEK=m +CONFIG_USB_WACOM=m +CONFIG_USB_KBTAB=m +CONFIG_USB_POWERMATE=m +CONFIG_USB_MTOUCH=m +CONFIG_USB_EGALAX=m +CONFIG_USB_XPAD=m +CONFIG_USB_ATI_REMOTE=m + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_HPUSBSCSI=m + +# +# USB Multimedia devices +# +CONFIG_USB_DABUSB=m +CONFIG_USB_VICAM=m +CONFIG_USB_DSBR=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_W9968CF=m +CONFIG_USB_PWC=m + +# +# USB Network adaptors +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m + +# +# USB Host-to-Host Cables +# +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_GENESYS=y +CONFIG_USB_NET1080=y +CONFIG_USB_PL2301=y + +# +# Intelligent USB Devices/Gadgets +# +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_ZAURUS=y +CONFIG_USB_CDCETHER=y + +# +# USB Network Adapters +# +CONFIG_USB_AX8817X=y + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_EZUSB=y + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +CONFIG_USB_AUERSWALD=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_LED=m +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_TEST=m + +# +# USB ATM/DSL drivers +# +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_QUOTA=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_TMPFS_SECURITY=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=m +CONFIG_VXFS_FS=m +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +CONFIG_OSF_PARTITION=y +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_SUN_PARTITION=y +CONFIG_EFI_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m + +# +# HP Simulator drivers +# +# CONFIG_HP_SIMETH is not set +# CONFIG_HP_SIMSERIAL is not set +# CONFIG_HP_SIMSCSI is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_INFO is not set +CONFIG_IA64_GRANULE_16MB=y +# CONFIG_IA64_GRANULE_64MB is not set +# CONFIG_IA64_PRINT_HAZARDS is not set +# CONFIG_DISABLE_VHPT is not set +# CONFIG_IA64_DEBUG_CMPXCHG is not set +# CONFIG_IA64_DEBUG_IRQ is not set + +# +# Security options +# +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +# CONFIG_SECURITY_SELINUX_MLS is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_SIGNATURE=y +CONFIG_CRYPTO_SIGNATURE_DSA=y +CONFIG_CRYPTO_MPILIB=y diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-ia64.config b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-ia64.config new file mode 100644 index 0000000..611ce45 --- /dev/null +++ b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-ia64.config @@ -0,0 +1,1908 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.9-5.0.3.EL_lustre-b1_4_rhel4.200503031449smp +# Thu Mar 3 14:52:42 2005 +# + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_HOTPLUG=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +# CONFIG_TINY_SHMEM is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SIG=y +# CONFIG_MODULE_SIG_FORCE is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y + +# +# Processor type and features +# +CONFIG_IA64=y +CONFIG_64BIT=y +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_TIME_INTERPOLATION=y +CONFIG_EFI=y +CONFIG_GENERIC_IOMAP=y +CONFIG_IA64_GENERIC=y +# CONFIG_IA64_DIG is not set +# CONFIG_IA64_HP_ZX1 is not set +# CONFIG_IA64_SGI_SN2 is not set +# CONFIG_IA64_HP_SIM is not set +# CONFIG_ITANIUM is not set +CONFIG_MCKINLEY=y +# CONFIG_IA64_PAGE_SIZE_4KB is not set +# CONFIG_IA64_PAGE_SIZE_8KB is not set +CONFIG_IA64_PAGE_SIZE_16KB=y +# CONFIG_IA64_PAGE_SIZE_64KB is not set +CONFIG_IA64_L1_CACHE_SHIFT=7 +CONFIG_NUMA=y +CONFIG_VIRTUAL_MEM_MAP=y +CONFIG_DISCONTIGMEM=y +CONFIG_IA64_CYCLONE=y +CONFIG_IOSAPIC=y +CONFIG_FORCE_MAX_ZONEORDER=18 +CONFIG_SMP=y +CONFIG_NR_CPUS=64 +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_PREEMPT is not set +CONFIG_HAVE_DEC_LOCK=y +# CONFIG_IA32_SUPPORT is not set +CONFIG_IA64_MCA_RECOVERY=m +CONFIG_PERFMON=y +CONFIG_IA64_PALINFO=y + +# +# Firmware Drivers +# +CONFIG_EFI_VARS=y +CONFIG_EFI_PCDP=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y + +# +# Power management and ACPI +# +CONFIG_PM=y +CONFIG_ACPI=y + +# +# ACPI (Advanced Configuration and Power Interface) Support +# +CONFIG_ACPI_BOOT=y +CONFIG_ACPI_INTERPRETER=y +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_FAN=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_BLACKLIST_YEAR=2001 +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_BUS=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PCI=y +CONFIG_ACPI_SYSTEM=y + +# +# Bus options (PCI, PCMCIA) +# +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_MSI=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_NAMES is not set + +# +# PCI Hotplug Support +# +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +# CONFIG_HOTPLUG_PCI_CPCI is not set +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_HOTPLUG_PCI_SHPC=m +# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_YENTA=m +CONFIG_CARDBUS=y +CONFIG_PD6729=m +# CONFIG_I82092 is not set +CONFIG_TCIC=m + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_PARIDE is not set +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_SX8=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_INITRD=y +CONFIG_DISKDUMP=m + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_AEC62XX=y +CONFIG_BLK_DEV_ALI15X3=y +# CONFIG_WDC_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +CONFIG_BLK_DEV_CMD64X=y +CONFIG_BLK_DEV_TRIFLEX=y +CONFIG_BLK_DEV_CY82C693=y +CONFIG_BLK_DEV_CS5520=y +CONFIG_BLK_DEV_CS5530=y +CONFIG_BLK_DEV_HPT34X=y +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_PIIX=y +CONFIG_BLK_DEV_IT8212=y +# CONFIG_BLK_DEV_NS87415 is not set +CONFIG_BLK_DEV_PDC202XX_OLD=y +# CONFIG_PDC202XX_BURST is not set +CONFIG_BLK_DEV_PDC202XX_NEW=y +CONFIG_PDC202XX_FORCE=y +CONFIG_BLK_DEV_SVWKS=y +CONFIG_BLK_DEV_SGIIOC4=m +CONFIG_BLK_DEV_SIIMAGE=y +CONFIG_BLK_DEV_SLC90E66=y +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_SCSI_DUMP=m +CONFIG_SD_IOSTATS=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m + +# +# SCSI low-level drivers +# +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC7XXX_OLD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=4 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_ENABLE_RD_STRM is not set +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_SCSI_SATA=y +CONFIG_SCSI_SATA_AHCI=m +CONFIG_SCSI_SATA_SVW=m +CONFIG_SCSI_ATA_PIIX=m +CONFIG_SCSI_SATA_NV=m +CONFIG_SCSI_SATA_PROMISE=m +CONFIG_SCSI_SATA_SX4=m +CONFIG_SCSI_SATA_SIL=m +CONFIG_SCSI_SATA_SIS=m +CONFIG_SCSI_SATA_VIA=m +CONFIG_SCSI_SATA_VITESSE=m +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA2XXX=m +CONFIG_SCSI_QLA21XX=m +CONFIG_SCSI_QLA22XX=m +CONFIG_SCSI_QLA2300=m +CONFIG_SCSI_QLA2322=m +CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_QLA6322=m +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID5=m +CONFIG_MD_RAID6=m +CONFIG_MD_MULTIPATH=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m + +# +# Fusion MPT device support +# +CONFIG_FUSION=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_TUNNEL=m + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_TUNNEL=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CT_PROTO_SCTP=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_PHYSDEV=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +CONFIG_IP_NF_MATCH_SCTP=m +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_LOCAL=y +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_LENGTH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_PHYSDEV=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +CONFIG_IP6_NF_RAW=m + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_XFRM=y +CONFIG_XFRM_USER=y + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +# CONFIG_ATM_MPOA is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +# CONFIG_DECNET is not set +CONFIG_LLC=y +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +CONFIG_NET_DIVERT=y +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CLK_JIFFIES=y +# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set +# CONFIG_NET_SCH_CLK_CPU is not set +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_NET_CLS_IND=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_POLICE=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_BCSP_TXCRC=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_TUX=m + +# +# TUX options +# +CONFIG_TUX_EXTCGI=y +# CONFIG_TUX_EXTENDED_LOG is not set +# CONFIG_TUX_DEBUG is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +CONFIG_BONDING=m +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +CONFIG_ETHERTAP=m + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_VORTEX=m +CONFIG_TYPHOON=m + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_TULIP_NAPI is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_PCMCIA_XIRCOM=m +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +CONFIG_AMD8111_ETH=m +CONFIG_AMD8111E_NAPI=y +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADAPTEC_STARFIRE_NAPI=y +CONFIG_B44=m +CONFIG_FORCEDETH=m +# CONFIG_DGRS is not set +CONFIG_EEPRO100=m +# CONFIG_EEPRO100_PIO is not set +CONFIG_E100=m +CONFIG_E100_NAPI=y +CONFIG_FEALNX=m +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_SIS900=m +CONFIG_EPIC100=m +# CONFIG_SUNDANCE is not set +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y + +# +# Ethernet (1000 Mbit) +# +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000_NAPI=y +CONFIG_NS83820=m +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=m +CONFIG_R8169_NAPI=y +CONFIG_SK98LIN=m +CONFIG_VIA_VELOCITY=m +CONFIG_TIGON3=m + +# +# Ethernet (10000 Mbit) +# +CONFIG_IXGB=m +CONFIG_IXGB_NAPI=y +CONFIG_S2IO=m +CONFIG_S2IO_NAPI=y + +# +# Token Ring devices +# +CONFIG_TR=y +CONFIG_IBMOL=m +CONFIG_3C359=m +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +CONFIG_ABYSS=m + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_NETWAVE=m + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_IEEE80211 is not set +CONFIG_HERMES=m +CONFIG_PLX_HERMES=m +CONFIG_TMD_HERMES=m +CONFIG_PCI_HERMES=m +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=m +CONFIG_AIRO_CS=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_WL3501=m + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +CONFIG_PRISM54=m +CONFIG_NET_WIRELESS=y + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# ATM drivers +# +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +# CONFIG_ATM_ZATM is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_FORE200E_MAYBE=m +# CONFIG_ATM_FORE200E_PCA is not set +CONFIG_ATM_HE=m +# CONFIG_ATM_HE_USE_SUNI is not set +CONFIG_FDDI=y +# CONFIG_DEFXX is not set +# CONFIG_SKFP is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +# CONFIG_SLIP is not set +CONFIG_NET_FC=y +# CONFIG_SHAPER is not set +CONFIG_NETCONSOLE=m +CONFIG_NETDUMP=m + +# +# ISDN subsystem +# +CONFIG_ISDN=m + +# +# Old ISDN4Linux +# +CONFIG_ISDN_I4L=m +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +CONFIG_IPPP_FILTER=y +# CONFIG_ISDN_PPP_BSDCOMP is not set +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_TTY_FAX=y + +# +# ISDN feature submodules +# + +# +# ISDN4Linux hardware drivers +# + +# +# Passive cards +# +CONFIG_ISDN_DRV_HISAX=m + +# +# D-channel protocol features +# +CONFIG_HISAX_EURO=y +CONFIG_DE_AOC=y +CONFIG_HISAX_NO_SENDCOMPLETE=y +CONFIG_HISAX_NO_LLC=y +CONFIG_HISAX_NO_KEYPAD=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 + +# +# HiSax supported cards +# +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set + +# +# HiSax PCMCIA card service modules +# +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_TELES_CS=m + +# +# HiSax sub driver modules +# +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_HDLC=y + +# +# Active cards +# +CONFIG_ISDN_DRV_TPAM=m + +# +# CAPI subsystem +# +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIDRV=m + +# +# CAPI hardware drivers +# + +# +# Active AVM cards +# +CONFIG_CAPI_AVM=y + +# +# Active Eicon DIVA Server cards +# +# CONFIG_CAPI_EICON is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDDLER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +CONFIG_N_HDLC=m +CONFIG_STALDRV=y +CONFIG_SGI_SNSC=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_ACPI=y +CONFIG_SERIAL_8250_NR_UARTS=20 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_MULTIPORT=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_SGI_L1_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_CRASH is not set +CONFIG_PRINTER=m +CONFIG_LP_CONSOLE=y +CONFIG_PPDEV=m +# CONFIG_TIPAR is not set + +# +# IPMI +# +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_I8XX_TCO=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +# CONFIG_HW_RANDOM is not set +CONFIG_EFI_RTC=y +CONFIG_DTLK=m +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +CONFIG_AGP=y +CONFIG_AGP_I460=y +CONFIG_AGP_HP_ZX1=y +CONFIG_DRM=y +# CONFIG_DRM_TDFX is not set +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_MGA=m +# CONFIG_DRM_SIS is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +CONFIG_RAW_DRIVER=y +# CONFIG_HPET is not set +CONFIG_MAX_RAW_DEVS=8192 +# CONFIG_MMTIMER is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +# CONFIG_SCx200_ACB is not set +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83627HF=m + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_RTC8564=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +CONFIG_VIDEO_OVCAMCHIP=m + +# +# Radio Adapters +# +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_CIRRUS=m +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_RIVA=m +# CONFIG_FB_RIVA_I2C is not set +# CONFIG_FB_RIVA_DEBUG is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +CONFIG_FB_KYRO=m +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +# CONFIG_SND_SERIAL_U16550 is not set +CONFIG_SND_MPU401=m + +# +# PCI devices +# +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS4281=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_KORG1212=m +CONFIG_SND_MIXART=m +CONFIG_SND_NM256=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_HDSP=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_ALS4000=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VX222=m + +# +# ALSA USB devices +# +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m + +# +# PCMCIA devices +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_UHCI_HCD=m + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set + +# +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# +CONFIG_USB_MIDI=m +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_RW_DETECT=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_HP8200e=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +CONFIG_HID_FF=y +CONFIG_HID_PID=y +CONFIG_LOGITECH_FF=y +CONFIG_THRUSTMASTER_FF=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_AIPTEK=m +CONFIG_USB_WACOM=m +CONFIG_USB_KBTAB=m +CONFIG_USB_POWERMATE=m +CONFIG_USB_MTOUCH=m +CONFIG_USB_EGALAX=m +CONFIG_USB_XPAD=m +CONFIG_USB_ATI_REMOTE=m + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_HPUSBSCSI=m + +# +# USB Multimedia devices +# +CONFIG_USB_DABUSB=m +CONFIG_USB_VICAM=m +CONFIG_USB_DSBR=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_W9968CF=m +CONFIG_USB_PWC=m + +# +# USB Network adaptors +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m + +# +# USB Host-to-Host Cables +# +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_GENESYS=y +CONFIG_USB_NET1080=y +CONFIG_USB_PL2301=y + +# +# Intelligent USB Devices/Gadgets +# +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_ZAURUS=y +CONFIG_USB_CDCETHER=y + +# +# USB Network Adapters +# +CONFIG_USB_AX8817X=y + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_EZUSB=y + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +CONFIG_USB_AUERSWALD=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_LED=m +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_TEST=m + +# +# USB ATM/DSL drivers +# +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_QUOTA=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_TMPFS_SECURITY=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=m +CONFIG_VXFS_FS=m +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +CONFIG_OSF_PARTITION=y +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_SUN_PARTITION=y +CONFIG_EFI_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m + +# +# HP Simulator drivers +# +# CONFIG_HP_SIMETH is not set +# CONFIG_HP_SIMSERIAL is not set +# CONFIG_HP_SIMSCSI is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_INFO is not set +CONFIG_IA64_GRANULE_16MB=y +# CONFIG_IA64_GRANULE_64MB is not set +# CONFIG_IA64_PRINT_HAZARDS is not set +# CONFIG_DISABLE_VHPT is not set +# CONFIG_IA64_DEBUG_CMPXCHG is not set +# CONFIG_IA64_DEBUG_IRQ is not set + +# +# Security options +# +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +# CONFIG_SECURITY_SELINUX_MLS is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_SIGNATURE=y +CONFIG_CRYPTO_SIGNATURE_DSA=y +CONFIG_CRYPTO_MPILIB=y diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-x86_64-smp.config b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-x86_64-smp.config new file mode 100644 index 0000000..9d35318 --- /dev/null +++ b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-x86_64-smp.config @@ -0,0 +1,2632 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +CONFIG_SMP=y +# CONFIG_HOTPLUG_CPU is not set +CONFIG_LOCALVERSION="" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_POSIX_MQUEUE=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y +CONFIG_MODULE_SIG=y +# CONFIG_MODULE_SIG_FORCE is not set + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_NAMES is not set +CONFIG_ISA=y +# CONFIG_EISA is not set +# CONFIG_MCA is not set +# CONFIG_SCx200 is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_YENTA=y +CONFIG_CARDBUS=y +# CONFIG_I82092 is not set +CONFIG_I82365=m +CONFIG_PD6729=m +CONFIG_TCIC=m +CONFIG_PCMCIA_PROBE=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_FW_LOADER=y + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=m +CONFIG_MTD_CONCAT=m +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_PARTITIONS=y +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_FTL=m +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PNC2000 is not set +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_NETSC520=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_ELAN_104NC=m +CONFIG_MTD_SCx200_DOCFLASH=m +# CONFIG_MTD_AMD76XROM is not set +# CONFIG_MTD_SCB2_FLASH is not set +# CONFIG_MTD_NETtel is not set +# CONFIG_MTD_DILNETPC is not set +# CONFIG_MTD_L440GX is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +# CONFIG_MTD_SLRAM is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_DOCPROBE=m +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=m + +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CFI_AMDSTD_RETRY=3 +# CONFIG_MTD_ICHXROM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set + + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_ATIIXP=y +CONFIG_BLK_DEV_DELKIN=y +CONFIG_BLK_DEV_IT8212=y +CONFIG_LBD=y +# CONFIG_DCSSBLK is not set + + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_IDE_GENERIC=y +# CONFIG_HPT34X_AUTODMA is not set + +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set +# CONFIG_BLK_DEV_IDE_SATA is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_RZ1000=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_AEC62XX=y +CONFIG_BLK_DEV_ALI15X3=y +# CONFIG_WDC_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +CONFIG_BLK_DEV_CMD64X=y +CONFIG_BLK_DEV_TRIFLEX=y +CONFIG_BLK_DEV_CY82C693=y +CONFIG_BLK_DEV_CS5520=y +CONFIG_BLK_DEV_CS5530=y +CONFIG_BLK_DEV_HPT34X=y +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_NS87415 is not set +CONFIG_BLK_DEV_PDC202XX_OLD=y +# CONFIG_PDC202XX_BURST is not set +CONFIG_BLK_DEV_PDC202XX_NEW=y +CONFIG_PDC202XX_FORCE=y +CONFIG_BLK_DEV_SVWKS=y +CONFIG_BLK_DEV_SIIMAGE=y +CONFIG_BLK_DEV_SIS5513=y +CONFIG_BLK_DEV_SLC90E66=y +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_CHIPSETS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SPI_ATTRS=y +CONFIG_SCSI_FC_ATTRS=y + +# +# SCSI low-level drivers +# +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +# CONFIG_SCSI_7000FASST is not set +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AHA152X=m +# CONFIG_SCSI_AHA1542 is not set +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_PROBE_EISA_VL is not set +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC7XXX_OLD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=4 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_BUILD_FIRMWARE is not set +# CONFIG_AIC79XX_ENABLE_RD_STRM is not set +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_SCSI_SATA=y +CONFIG_SCSI_SATA_SVW=m +CONFIG_SCSI_ATA_PIIX=m +CONFIG_SCSI_SATA_PROMISE=m +CONFIG_SCSI_SATA_VIA=m +CONFIG_BLK_DEV_SX8=m +CONFIG_SCSI_SATA_VITESSE=m +CONFIG_SCSI_SATA_SIL=m +CONFIG_SCSI_SATA_SIS=m +CONFIG_SCSI_SATA_SX4=m +CONFIG_SCSI_SATA_NV=m +CONFIG_SCSI_SATA_AHCI=m + +# CONFIG_SCSI_BUSLOGIC is not set +CONFIG_SCSI_INITIO=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_GDTH=m +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +CONFIG_SCSI_IPS=m +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set +CONFIG_SCSI_QLOGIC_1280=m +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_ULTRASTOR is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DC390T is not set +CONFIG_SCSI_QLA2XXX=m +CONFIG_SCSI_QLA21XX=m +CONFIG_SCSI_QLA22XX=m +CONFIG_SCSI_QLA2300=m +CONFIG_SCSI_QLA2322=m +CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_QLA6322=m +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_DPT_I2O is not set + +CONFIG_SCSI_LPFC=m + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID5=m +CONFIG_MD_RAID6=m +CONFIG_MD_RAID10=m +CONFIG_MD_MULTIPATH=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_CRYPT=m + +# +# Fusion MPT device support +# +CONFIG_FUSION=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_OUI_DB=y + +# +# Device Drivers +# +# CONFIG_IEEE1394_PCILYNX is not set +CONFIG_IEEE1394_OHCI1394=m + +# +# Protocol Drivers +# +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_ETH1394 is not set +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_CMP=m +CONFIG_IEEE1394_AMDTP=m +# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set + +# +# I2O device support +# +CONFIG_I2O=m + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_INET_TUNNEL=m +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_NETCONSOLE=m +# CONFIG_NETPOLL_RX is not set +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NETDUMP=m +CONFIG_DISKDUMP=m +CONFIG_SCSI_DUMP=m +CONFIG_SD_IOSTATS=y + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m + + +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_TUNNEL=m +# CONFIG_DECNET is not set +CONFIG_BRIDGE=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_PHYSDEV=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +CONFIG_IP_NF_MATCH_SCTP=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_NAT_LOCAL=y +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CT_PROTO_SCTP=m +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_LENGTH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_PHYSDEV=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +CONFIG_IP6_NF_RAW=m + + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_XFRM=y +CONFIG_XFRM_USER=y + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_ATM=m +CONFIG_VLAN_8021Q=m +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_IPX_INTERN is not set +# CONFIG_ATALK is not set +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +# CONFIG_IPDDP is not set +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +CONFIG_NET_DIVERT=y +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_ACT_POLICE is not set +CONFIG_CLS_U32_PERF=y +CONFIG_NET_CLS_IND=y +# CONFIG_NET_CLS_ACT is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +CONFIG_DUMMY=m +CONFIG_BONDING=m +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +CONFIG_ETHERTAP=m +# CONFIG_NET_SB1000 is not set + +# +# ATM +# +CONFIG_ATM_CLIP=m +CONFIG_ATM_LANE=m +CONFIG_ATM_BR2684=m +CONFIG_NET_SCH_ATM=m +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +CONFIG_ATM_FIRESTREAM=m +# CONFIG_ATM_ZATM is not set +CONFIG_ATM_IDT77252=m +CONFIG_ATM_AMBASSADOR=m +CONFIG_ATM_HORIZON=m +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_HE=m +CONFIG_PPPOATM=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_IA is not set + + +# CONFIG_ATM_CLIP_NO_ICMP is not set +# CONFIG_ATM_MPOA is not set +# CONFIG_ATM_BR2684_IPFILTER is not set +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +# CONFIG_ATM_ZATM_DEBUG is not set +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +# CONFIG_ATM_HORIZON_DEBUG is not set +# CONFIG_ATM_FORE200E_PCA is not set +# CONFIG_ATM_HE_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_IA_DEBUG is not set + + + + + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_NET_VENDOR_3COM=y +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +# CONFIG_3C515 is not set +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +# CONFIG_LANCE is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +# CONFIG_ULTRA is not set +CONFIG_SMC9194=m +CONFIG_NET_VENDOR_RACAL=y +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_TULIP=m +# CONFIG_TULIP_NAPI is not set + +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_NI5010 is not set +# CONFIG_PCMCIA_XIRTULIP is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_PCMCIA_XIRCOM=m +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_EWRK3=m +CONFIG_E2100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_HPLAN_PLUS=m +CONFIG_HPLAN=m +CONFIG_LP486E=m +CONFIG_ETH16I=m +CONFIG_NE2000=m +CONFIG_ZNET=m +CONFIG_SEEQ8005=m +CONFIG_LNE390=m +CONFIG_NE3210=m +CONFIG_ES3210=m +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +CONFIG_AMD8111_ETH=m +CONFIG_AMD8111E_NAPI=y +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADAPTEC_STARFIRE_NAPI=y +# CONFIG_AC3200 is not set +CONFIG_APRICOT=m +CONFIG_B44=m +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +CONFIG_EEPRO100=m +# CONFIG_EEPRO100_PIO is not set +CONFIG_E100=m +CONFIG_E100_NAPI=y +CONFIG_FEALNX=m +CONFIG_FORCEDETH=m +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_SIS900=m +CONFIG_EPIC100=m +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_TLAN=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_VELOCITY=m +CONFIG_NET_POCKET=y +# CONFIG_ATP is not set +# CONFIG_DE600 is not set +# CONFIG_DE620 is not set + +# +# Ethernet (1000 Mbit) +# +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000_NAPI=y +CONFIG_NS83820=m +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=m +CONFIG_R8169_NAPI=y +CONFIG_SK98LIN=m +CONFIG_TIGON3=m + +# +# Ethernet (10000 Mbit) +# +CONFIG_IXGB=m +CONFIG_IXGB_NAPI=y +CONFIG_S2IO=m +CONFIG_S2IO_NAPI=y +CONFIG_FDDI=y +# CONFIG_DEFXX is not set +# CONFIG_SKFP is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_IPPP_FILTER=y +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +CONFIG_WAVELAN=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_NETWAVE=m + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT=m +CONFIG_IEEE80211_WPA=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IPW2100=m +# CONFIG_IPW_DEBUG is not set +CONFIG_IPW2100_PROMISC=y +# CONFIG_IPW2100_LEGACY_FW_LOAD is not set +CONFIG_IPW2200=m +CONFIG_AIRO=m +CONFIG_HERMES=m +CONFIG_PLX_HERMES=m +CONFIG_TMD_HERMES=m +CONFIG_PCI_HERMES=m +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +CONFIG_PRISM54=m + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=m +CONFIG_AIRO_CS=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_WL3501=m +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +CONFIG_TR=y +CONFIG_IBMOL=m +CONFIG_3C359=m +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +CONFIG_ABYSS=m +CONFIG_IBMTR=m +CONFIG_IBMLS=m +CONFIG_SKISA=m +CONFIG_PROTEON=m +CONFIG_SMCTR=m +CONFIG_PCMCIA_IBMTR=m + + +CONFIG_NET_FC=y +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set +# CONFIG_IRDA is not set +# CONFIG_IRDA_DEBUG is not set +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRTTY_SIR=m +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_IRPORT_SIR=m +# CONFIG_DONGLE_OLD is not set +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m + +CONFIG_USB_IRDA=m +CONFIG_NSC_FIR=m +CONFIG_SIGMATEL_FIR=m +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set +# CONFIG_VIA_FIR is not set + + + +# +# Bluetooth support +# +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_CMTP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_BCSP_TXCRC=y +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_USB_BLUETOOTH_TTY=m + +# +# ISDN subsystem +# + +CONFIG_ISDN=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_C4=m + +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +# CONFIG_ISDN_PPP_BSDCOMP is not set +CONFIG_ISDN_TTY_FAX=y +CONFIG_DE_AOC=y + +CONFIG_ISDN_AUDIO=y + +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_TPAM=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m + +CONFIG_ISDN_CAPI_CAPIDRV=m + +CONFIG_HISAX_EURO=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_NO_SENDCOMPLETE=y +CONFIG_HISAX_NO_LLC=y +CONFIG_HISAX_NO_KEYPAD=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_TELES_CS=m + +CONFIG_ISDN_DRV_LOOP=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y + + +# +# CAPI subsystem +# +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_CAPIFS=m + +# +# CAPI hardware drivers +# + +# +# Active AVM cards +# +CONFIG_CAPI_AVM=y + +# +# Active Eicon DIVA Server cards +# +# CONFIG_CAPI_EICON is not set +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVAS_MAINT=m + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_VORTEX=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_CS461x=m +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_RAW is not set + +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_ATIXL=y +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_IFORCE_USB=y +# CONFIG_JOYSTICK_IFORCE_232=y +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDDLER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_UINPUT=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_ROCKETPORT is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +CONFIG_N_HDLC=m +CONFIG_STALDRV=y +# CONFIG_FTAPE is not set +# CONFIG_IBM_ASM is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_ACPI is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_MULTIPORT=y +CONFIG_SERIAL_8250_RSA=y +# CONFIG_COMPUTONE is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALLION is not set +# CONFIG_ISTALLION is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_PRINTER=m +CONFIG_LP_CONSOLE=y +CONFIG_PPDEV=m +# CONFIG_TIPAR is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_DEBUG_ALGO is not set +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m + +# +# I2C Hardware Bus support +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +# CONFIG_SCx200_ACB is not set +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +# CONFIG_I2C_ELEKTOR is not set +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_PARPORT is not set +CONFIG_I2C_ALI1563=m +# CONFIG_I2C_PARPORT_LIGHT is not set +CONFIG_I2C_ALGOPCA=m +# CONFIG_I2C_PCA_ISA is not set + + + +# +# I2C Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_RTC8564=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_SMSC47M1=m + +# CONFIG_W1 is not set + +# +# Mice +# +CONFIG_CRASH=m + +# +# IPMI +# +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_POWEROFF=m + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_SOFT_WATCHDOG=m +CONFIG_WDT=m +# CONFIG_WDT_501 is not set +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y +CONFIG_PCWATCHDOG=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ADVANTECH_WDT=m +CONFIG_EUROTECH_WDT=m +CONFIG_IB700_WDT=m +CONFIG_I8XX_TCO=m +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +CONFIG_W83877F_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_MACHZ_WDT=m +CONFIG_SC520_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALIM1535_WDT=m +CONFIG_SC1200_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_CPU5_WDT=m +CONFIG_PCIPCWATCHDOG=m +CONFIG_USBPCWATCHDOG=m + + +CONFIG_HW_RANDOM=m +# CONFIG_NVRAM is not set +CONFIG_RTC=y +CONFIG_DTLK=m +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_SONYPI is not set + +# +# Ftape, the floppy tape device driver +# +CONFIG_AGP=y +CONFIG_AGP_ALI=y +CONFIG_AGP_ATI=y +CONFIG_AGP_AMD=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=y +CONFIG_AGP_INTEL_MCH=y +CONFIG_AGP_NVIDIA=y +CONFIG_AGP_SIS=y +CONFIG_AGP_SWORKS=y +CONFIG_AGP_VIA=y +CONFIG_AGP_EFFICEON=y +CONFIG_DRM=y +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_MGA=m +# CONFIG_DRM_SIS is not set +CONFIG_DRM_I915=m + + + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set + + + +# CONFIG_MWAVE is not set +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +CONFIG_HANGCHECK_TIMER=m + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA_PP is not set +# CONFIG_VIDEO_CPIA_USB is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_DC30 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZORAN_LML33R10 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_SAA5246A is not set +CONFIG_VIDEO_OVCAMCHIP=m + + +# +# Radio Adapters +# +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_TYPHOON_PROC_FS=y +# CONFIG_RADIO_ZOLTRIX is not set + + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +CONFIG_DVB_CORE=m + +# +# Supported Frontend Modules +# +CONFIG_DVB_STV0299=m +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_ALPS_TDLB7 is not set +CONFIG_DVB_ALPS_TDMB7=m +CONFIG_DVB_ATMEL_AT76C651=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_GRUNDIG_29504_491=m +CONFIG_DVB_GRUNDIG_29504_401=m +CONFIG_DVB_MT312=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TWINHAN_DST=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_BT8XX=m +# CONFIG_DVB_TDA1004X is not set +CONFIG_DVB_NXT6000=m + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +# CONFIG_DVB_AV7110_FIRMWARE is not set +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m + +# +# Supported USB Adapters +# +CONFIG_DVB_TTUSB_BUDGET=m + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_SKYSTAR=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_VIDEOBUF=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BTCX=m + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_VGA16=m +CONFIG_FB_VESA=y +CONFIG_VIDEO_SELECT=y +# CONFIG_FB_HGA is not set +CONFIG_FB_RIVA=m +# CONFIG_FB_RIVA_DEBUG is not set +# CONFIG_FB_RIVA_I2C is not set +CONFIG_FB_I810=m +CONFIG_FB_I810_GTF=y +# CONFIG_FB_MATROX is not set +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G450=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MULTIHEAD=y +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RADEON_DEBUG is not set +# CONFIG_FB_RADEON_OLD is not set +CONFIG_FB_RADEON_I2C=y +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GX=y +# CONFIG_FB_ATY_XL_INIT is not set +# CONFIG_FB_SIS is not set +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_KYRO=m +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM2_FIFO_DISCONNECT is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_HGA_ACCEL is not set +# CONFIG_FB_3DFX_ACCEL is not set +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_CIRRUS=m + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set + + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_RTCTIMER=m +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_BIT32_EMUL=y + +# +# Generic devices +# +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +# CONFIG_SND_SERIAL_U16550 is not set +CONFIG_SND_MPU401=m + +# +# ISA devices +# +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_SB16_CSP=y +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_DT019X is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set + +# +# PCI devices +# +CONFIG_SND_ALI5451=m +CONFIG_SND_AZT3328=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS4281=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_KORG1212=m +CONFIG_SND_NM256=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_HDSP=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_ALS4000=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_FM801=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VX222=m +CONFIG_SND_BT87X=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_MIXART=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_PDAUDIOCF=m + + +# +# ALSA USB devices +# +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m + +# +# PCMCIA devices +# +# CONFIG_SND_VXPOCKET is not set +# CONFIG_SND_VXP440 is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_UHCI_HCD=m + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set + +# +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# +CONFIG_USB_MIDI=m +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_HP8200e=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_RW_DETECT=y + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +CONFIG_HID_FF=y +CONFIG_HID_PID=y +CONFIG_LOGITECH_FF=y +CONFIG_THRUSTMASTER_FF=y +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +CONFIG_USB_AIPTEK=m +CONFIG_USB_WACOM=m +CONFIG_USB_KBTAB=m +CONFIG_USB_POWERMATE=m +CONFIG_USB_XPAD=m + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_HPUSBSCSI=m + +# +# USB Multimedia devices +# +CONFIG_USB_DABUSB=m +CONFIG_USB_VICAM=m +CONFIG_USB_DSBR=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_STV680=m +CONFIG_USB_SN9C102=m + +# +# USB Network adaptors +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_SPEEDTOUCH=m + +# +# USB Host-to-Host Cables +# +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_GENESYS=y +CONFIG_USB_NET1080=y +CONFIG_USB_PL2301=y + +# +# Intelligent USB Devices/Gadgets +# +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_ZAURUS=y +CONFIG_USB_CDCETHER=y + +# +# USB Network Adapters +# +CONFIG_USB_AX8817X=y + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_EZUSB=y +CONFIG_USB_EMI62=m +CONFIG_USB_LED=m +CONFIG_USB_G_SERIAL=m + + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +CONFIG_USB_AUERSWALD=m +CONFIG_USB_RIO500=m +CONFIG_USB_LCD=m +CONFIG_USB_TEST=m +# CONFIG_USB_GADGET is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_SA1100 is not set +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_W9968CF=m +CONFIG_USB_PWC=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_MTOUCH=m +CONFIG_USB_ATI_REMOTE=m +CONFIG_USB_ALI_M5632=y +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_EGALAX=m +CONFIG_USB_PHIDGETSERVO=m + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_JFS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_XFS_RT is not set +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_SECURITY=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_QUOTA=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +CONFIG_UDF_FS=m + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_TMPFS_SECURITY=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not seta +# CONFIG_AFFS_FS is not set +# uses sleepon and needs a major update +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_NAND=y +CONFIG_CRAMFS=m +CONFIG_VXFS_FS=m +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_NCP_FS is not set +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_SMALLDOS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_RXRPC is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +CONFIG_OSF_PARTITION=y +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_SUN_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_NLS_ASCII=y + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m + +# +# Tux +# +CONFIG_TUX=m +CONFIG_TUX_EXTCGI=y +# CONFIG_TUX_EXTENDED_LOG is not set +# CONFIG_TUX_DEBUG is not set + + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_HIGHMEM=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_FRAME_POINTER is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_DEBUG_DRIVER is not set + +# +# Security options +# +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +# CONFIG_SECURITY_SELINUX_MLS is not set +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_TEST is not set +CONFIG_LIBCRC32C=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_SIGNATURE_DSA=y +CONFIG_CRYPTO_MPILIB=y +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_WP512=m + +# +# Library routines +# +CONFIG_CRC32=m +CONFIG_CRC_CCITT=m + +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_PC=y +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_ATALK is not set +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_IPX is not set +# CONFIG_IPDDP is not set +# CONFIG_IRDA is not set +# CONFIG_NCP_FS is not set +# CONFIG_ISAPNP is not set +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_IEEE1394 is not set +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_WD80x3 is not set +# CONFIG_IRDA is not set +# CONFIG_GAMEPORT is not set +# CONFIG_DVB is not set +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_SB16_CSP=y +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_DT019X is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_BINFMT_AOUT is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_MWAVE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_R3964 is not set +# CONFIG_TIPAR is not set +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_IFORCE_USB=y +# CONFIG_JOYSTICK_IFORCE_232=y +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDDLER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_TYPHOON_PROC_FS=y +# CONFIG_RADIO_ZOLTRIX is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_PLIP is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA_PP is not set +# CONFIG_VIDEO_CPIA_USB is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_DC30 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZORAN_LML33R10 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_I82092 is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SUNDANCE is not set +# CONFIG_ULTRA is not set +# CONFIG_SKFP is not set +# CONFIG_DE600 is not set +# CONFIG_DE620 is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_AC3200 is not set +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set +# CONFIG_LANCE is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +# CONFIG_3C515 is not set +# CONFIG_HAMACHI is not set +# CONFIG_HP100 is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_SB1000 is not set +# CONFIG_DEPCA is not set +# CONFIG_ATP is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_INFTL is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PCI is not set +# CONFIG_PCMCIA_SYM53C500 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_HGA_ACCEL is not set +# CONFIG_FB_3DFX_ACCEL is not set +# CONFIG_FB_TRIDENT_ACCEL is not set +# CONFIG_SCSI_DC390T is not set +CONFIG_AUDIT=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_I2C_PCA_ISA is not set +CONFIG_RAW_DRIVER=y +# CONFIG_MTD_SCB2_FLASH is not set +CONFIG_UID16=y +# CONFIG_MK8 is not set +# CONFIG_MPSC is not set +CONFIG_GENERIC_CPU=y +CONFIG_X86_MSR=y +CONFIG_X86_CPUID=y +CONFIG_MTRR=y +CONFIG_NUMA=y +CONFIG_K8_NUMA=y +CONFIG_NR_CPUS=8 +CONFIG_GART_IOMMU=y +CONFIG_X86_POWERNOW_K8=y +CONFIG_IA32_EMULATION=y +# CONFIG_IA32_AOUT is not set +CONFIG_INIT_DEBUG=y +# CONFIG_IOMMU_DEBUG is not set +# CONFIG_CHECKING is not set +CONFIG_MICROCODE=m +CONFIG_SWIOTLB=y +CONFIG_X86_PM_TIMER=y +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +CONFIG_I2O_CONFIG=y +CONFIG_TUX=m +# CONFIG_UNORDERED_IO is not set +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +CONFIG_X86_ACPI_CPUFREQ=y +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_SCHED_SMT=y +# CONFIG_SOFTWARE_SUSPEND is not set +# CONFIG_PM_DEBUG is not set +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_PROC_INTF is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +# CONFIG_CPU_FREQ_24_API is not set +CONFIG_CPU_FREQ_TABLE=y +CONFIG_ACPI=y +CONFIG_ACPI_BOOT=y +CONFIG_ACPI_INTERPRETER=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_FAN=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_TOSHIBA=m +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_BUS=y +CONFIG_ACPI_EC=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PCI=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_BLACKLIST_YEAR=2001 +# CONFIG_SCHEDSTATS is not set +CONFIG_EDD=m +CONFIG_PCI_BIOS=y +CONFIG_PCI_MMCONFIG=y +CONFIG_KEXEC=y +CONFIG_NETDUMP=m +CONFIG_CRASH=m +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +CONFIG_HOTPLUG_PCI_COMPAQ=m +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +# CONFIG_HOTPLUG_PCI_CPCI is not set +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_HOTPLUG_PCI_SHPC=m +# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set +# CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY is not set +# CONFIG_HPET is not set +CONFIG_PM=y +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT=m +CONFIG_IEEE80211_WPA=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IPW2100=m +# CONFIG_IPW_DEBUG is not set +CONFIG_IPW2100_PROMISC=y +# CONFIG_IPW2100_LEGACY_FW_LOAD is not set +CONFIG_IPW2200=m diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-x86_64.config b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-x86_64.config new file mode 100644 index 0000000..2c33da7 --- /dev/null +++ b/lustre/kernel_patches/kernel_configs/kernel-2.6.9-2.6-rhel4-x86_64.config @@ -0,0 +1,2633 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +# CONFIG_SMP is not set +# CONFIG_HOTPLUG_CPU is not set +CONFIG_LOCALVERSION="" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_POSIX_MQUEUE=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y +CONFIG_MODULE_SIG=y +# CONFIG_MODULE_SIG_FORCE is not set + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_NAMES is not set +CONFIG_ISA=y +# CONFIG_EISA is not set +# CONFIG_MCA is not set +# CONFIG_SCx200 is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_YENTA=y +CONFIG_CARDBUS=y +# CONFIG_I82092 is not set +CONFIG_I82365=m +CONFIG_PD6729=m +CONFIG_TCIC=m +CONFIG_PCMCIA_PROBE=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_FW_LOADER=y + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=m +CONFIG_MTD_CONCAT=m +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_PARTITIONS=y +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_FTL=m +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PNC2000 is not set +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_NETSC520=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_ELAN_104NC=m +CONFIG_MTD_SCx200_DOCFLASH=m +# CONFIG_MTD_AMD76XROM is not set +# CONFIG_MTD_SCB2_FLASH is not set +# CONFIG_MTD_NETtel is not set +# CONFIG_MTD_DILNETPC is not set +# CONFIG_MTD_L440GX is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +# CONFIG_MTD_SLRAM is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_DOCPROBE=m +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=m + +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CFI_AMDSTD_RETRY=3 +# CONFIG_MTD_ICHXROM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set + + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_ATIIXP=y +CONFIG_BLK_DEV_DELKIN=y +CONFIG_BLK_DEV_IT8212=y +CONFIG_LBD=y +# CONFIG_DCSSBLK is not set + + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_IDE_GENERIC=y +# CONFIG_HPT34X_AUTODMA is not set + +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set +# CONFIG_BLK_DEV_IDE_SATA is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_RZ1000=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_AEC62XX=y +CONFIG_BLK_DEV_ALI15X3=y +# CONFIG_WDC_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +CONFIG_BLK_DEV_CMD64X=y +CONFIG_BLK_DEV_TRIFLEX=y +CONFIG_BLK_DEV_CY82C693=y +CONFIG_BLK_DEV_CS5520=y +CONFIG_BLK_DEV_CS5530=y +CONFIG_BLK_DEV_HPT34X=y +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_NS87415 is not set +CONFIG_BLK_DEV_PDC202XX_OLD=y +# CONFIG_PDC202XX_BURST is not set +CONFIG_BLK_DEV_PDC202XX_NEW=y +CONFIG_PDC202XX_FORCE=y +CONFIG_BLK_DEV_SVWKS=y +CONFIG_BLK_DEV_SIIMAGE=y +CONFIG_BLK_DEV_SIS5513=y +CONFIG_BLK_DEV_SLC90E66=y +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_CHIPSETS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SPI_ATTRS=y +CONFIG_SCSI_FC_ATTRS=y + +# +# SCSI low-level drivers +# +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +# CONFIG_SCSI_7000FASST is not set +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AHA152X=m +# CONFIG_SCSI_AHA1542 is not set +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_PROBE_EISA_VL is not set +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC7XXX_OLD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=4 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_BUILD_FIRMWARE is not set +# CONFIG_AIC79XX_ENABLE_RD_STRM is not set +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_SCSI_SATA=y +CONFIG_SCSI_SATA_SVW=m +CONFIG_SCSI_ATA_PIIX=m +CONFIG_SCSI_SATA_PROMISE=m +CONFIG_SCSI_SATA_VIA=m +CONFIG_BLK_DEV_SX8=m +CONFIG_SCSI_SATA_VITESSE=m +CONFIG_SCSI_SATA_SIL=m +CONFIG_SCSI_SATA_SIS=m +CONFIG_SCSI_SATA_SX4=m +CONFIG_SCSI_SATA_NV=m +CONFIG_SCSI_SATA_AHCI=m + +# CONFIG_SCSI_BUSLOGIC is not set +CONFIG_SCSI_INITIO=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_GDTH=m +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +CONFIG_SCSI_IPS=m +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set +CONFIG_SCSI_QLOGIC_1280=m +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_ULTRASTOR is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DC390T is not set +CONFIG_SCSI_QLA2XXX=m +CONFIG_SCSI_QLA21XX=m +CONFIG_SCSI_QLA22XX=m +CONFIG_SCSI_QLA2300=m +CONFIG_SCSI_QLA2322=m +CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_QLA6322=m +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_DPT_I2O is not set + +CONFIG_SCSI_LPFC=m + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID5=m +CONFIG_MD_RAID6=m +CONFIG_MD_RAID10=m +CONFIG_MD_MULTIPATH=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_CRYPT=m + +# +# Fusion MPT device support +# +CONFIG_FUSION=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_OUI_DB=y + +# +# Device Drivers +# +# CONFIG_IEEE1394_PCILYNX is not set +CONFIG_IEEE1394_OHCI1394=m + +# +# Protocol Drivers +# +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_ETH1394 is not set +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_CMP=m +CONFIG_IEEE1394_AMDTP=m +# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set + +# +# I2O device support +# +CONFIG_I2O=m + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_INET_TUNNEL=m +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_NETCONSOLE=m +# CONFIG_NETPOLL_RX is not set +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NETDUMP=m +CONFIG_DISKDUMP=m +CONFIG_SCSI_DUMP=m +CONFIG_SD_IOSTATS=y + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m + + +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_TUNNEL=m +# CONFIG_DECNET is not set +CONFIG_BRIDGE=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_PHYSDEV=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +CONFIG_IP_NF_MATCH_SCTP=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_NAT_LOCAL=y +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CT_PROTO_SCTP=m +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_LENGTH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_PHYSDEV=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +CONFIG_IP6_NF_RAW=m + + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_XFRM=y +CONFIG_XFRM_USER=y + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_ATM=m +CONFIG_VLAN_8021Q=m +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_IPX_INTERN is not set +# CONFIG_ATALK is not set +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +# CONFIG_IPDDP is not set +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +CONFIG_NET_DIVERT=y +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_ACT_POLICE is not set +CONFIG_CLS_U32_PERF=y +CONFIG_NET_CLS_IND=y +# CONFIG_NET_CLS_ACT is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +CONFIG_DUMMY=m +CONFIG_BONDING=m +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +CONFIG_ETHERTAP=m +# CONFIG_NET_SB1000 is not set + +# +# ATM +# +CONFIG_ATM_CLIP=m +CONFIG_ATM_LANE=m +CONFIG_ATM_BR2684=m +CONFIG_NET_SCH_ATM=m +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +CONFIG_ATM_FIRESTREAM=m +# CONFIG_ATM_ZATM is not set +CONFIG_ATM_IDT77252=m +CONFIG_ATM_AMBASSADOR=m +CONFIG_ATM_HORIZON=m +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_HE=m +CONFIG_PPPOATM=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_IA is not set + + +# CONFIG_ATM_CLIP_NO_ICMP is not set +# CONFIG_ATM_MPOA is not set +# CONFIG_ATM_BR2684_IPFILTER is not set +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +# CONFIG_ATM_ZATM_DEBUG is not set +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +# CONFIG_ATM_HORIZON_DEBUG is not set +# CONFIG_ATM_FORE200E_PCA is not set +# CONFIG_ATM_HE_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_IA_DEBUG is not set + + + + + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_NET_VENDOR_3COM=y +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +# CONFIG_3C515 is not set +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +# CONFIG_LANCE is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +# CONFIG_ULTRA is not set +CONFIG_SMC9194=m +CONFIG_NET_VENDOR_RACAL=y +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_TULIP=m +# CONFIG_TULIP_NAPI is not set + +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_NI5010 is not set +# CONFIG_PCMCIA_XIRTULIP is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_PCMCIA_XIRCOM=m +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_EWRK3=m +CONFIG_E2100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_HPLAN_PLUS=m +CONFIG_HPLAN=m +CONFIG_LP486E=m +CONFIG_ETH16I=m +CONFIG_NE2000=m +CONFIG_ZNET=m +CONFIG_SEEQ8005=m +CONFIG_LNE390=m +CONFIG_NE3210=m +CONFIG_ES3210=m +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +CONFIG_AMD8111_ETH=m +CONFIG_AMD8111E_NAPI=y +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADAPTEC_STARFIRE_NAPI=y +# CONFIG_AC3200 is not set +CONFIG_APRICOT=m +CONFIG_B44=m +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +CONFIG_EEPRO100=m +# CONFIG_EEPRO100_PIO is not set +CONFIG_E100=m +CONFIG_E100_NAPI=y +CONFIG_FEALNX=m +CONFIG_FORCEDETH=m +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_SIS900=m +CONFIG_EPIC100=m +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_TLAN=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_VELOCITY=m +CONFIG_NET_POCKET=y +# CONFIG_ATP is not set +# CONFIG_DE600 is not set +# CONFIG_DE620 is not set + +# +# Ethernet (1000 Mbit) +# +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000_NAPI=y +CONFIG_NS83820=m +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=m +CONFIG_R8169_NAPI=y +CONFIG_SK98LIN=m +CONFIG_TIGON3=m + +# +# Ethernet (10000 Mbit) +# +CONFIG_IXGB=m +CONFIG_IXGB_NAPI=y +CONFIG_S2IO=m +CONFIG_S2IO_NAPI=y +CONFIG_FDDI=y +# CONFIG_DEFXX is not set +# CONFIG_SKFP is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_IPPP_FILTER=y +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +CONFIG_WAVELAN=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_NETWAVE=m + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT=m +CONFIG_IEEE80211_WPA=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IPW2100=m +# CONFIG_IPW_DEBUG is not set +CONFIG_IPW2100_PROMISC=y +# CONFIG_IPW2100_LEGACY_FW_LOAD is not set +CONFIG_IPW2200=m +CONFIG_AIRO=m +CONFIG_HERMES=m +CONFIG_PLX_HERMES=m +CONFIG_TMD_HERMES=m +CONFIG_PCI_HERMES=m +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +CONFIG_PRISM54=m + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=m +CONFIG_AIRO_CS=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_WL3501=m +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +CONFIG_TR=y +CONFIG_IBMOL=m +CONFIG_3C359=m +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +CONFIG_ABYSS=m +CONFIG_IBMTR=m +CONFIG_IBMLS=m +CONFIG_SKISA=m +CONFIG_PROTEON=m +CONFIG_SMCTR=m +CONFIG_PCMCIA_IBMTR=m + + +CONFIG_NET_FC=y +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set +# CONFIG_IRDA is not set +# CONFIG_IRDA_DEBUG is not set +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRTTY_SIR=m +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_IRPORT_SIR=m +# CONFIG_DONGLE_OLD is not set +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m + +CONFIG_USB_IRDA=m +CONFIG_NSC_FIR=m +CONFIG_SIGMATEL_FIR=m +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set +# CONFIG_VIA_FIR is not set + + + +# +# Bluetooth support +# +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_CMTP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_BCSP_TXCRC=y +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_USB_BLUETOOTH_TTY=m + +# +# ISDN subsystem +# + +CONFIG_ISDN=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_C4=m + +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +# CONFIG_ISDN_PPP_BSDCOMP is not set +CONFIG_ISDN_TTY_FAX=y +CONFIG_DE_AOC=y + +CONFIG_ISDN_AUDIO=y + +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_TPAM=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m + +CONFIG_ISDN_CAPI_CAPIDRV=m + +CONFIG_HISAX_EURO=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_NO_SENDCOMPLETE=y +CONFIG_HISAX_NO_LLC=y +CONFIG_HISAX_NO_KEYPAD=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_TELES_CS=m + +CONFIG_ISDN_DRV_LOOP=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y + + +# +# CAPI subsystem +# +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_CAPIFS=m + +# +# CAPI hardware drivers +# + +# +# Active AVM cards +# +CONFIG_CAPI_AVM=y + +# +# Active Eicon DIVA Server cards +# +# CONFIG_CAPI_EICON is not set +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVAS_MAINT=m + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_VORTEX=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_CS461x=m +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_RAW is not set + +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_ATIXL=y +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_IFORCE_USB=y +# CONFIG_JOYSTICK_IFORCE_232=y +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDDLER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_UINPUT=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_ROCKETPORT is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +CONFIG_N_HDLC=m +CONFIG_STALDRV=y +# CONFIG_FTAPE is not set +# CONFIG_IBM_ASM is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_ACPI is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_MULTIPORT=y +CONFIG_SERIAL_8250_RSA=y +# CONFIG_COMPUTONE is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALLION is not set +# CONFIG_ISTALLION is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_PRINTER=m +CONFIG_LP_CONSOLE=y +CONFIG_PPDEV=m +# CONFIG_TIPAR is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_DEBUG_ALGO is not set +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m + +# +# I2C Hardware Bus support +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +# CONFIG_SCx200_ACB is not set +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +# CONFIG_I2C_ELEKTOR is not set +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_PARPORT is not set +CONFIG_I2C_ALI1563=m +# CONFIG_I2C_PARPORT_LIGHT is not set +CONFIG_I2C_ALGOPCA=m +# CONFIG_I2C_PCA_ISA is not set + + + +# +# I2C Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_RTC8564=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_SMSC47M1=m + +# CONFIG_W1 is not set + +# +# Mice +# +CONFIG_CRASH=m + +# +# IPMI +# +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_POWEROFF=m + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_SOFT_WATCHDOG=m +CONFIG_WDT=m +# CONFIG_WDT_501 is not set +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y +CONFIG_PCWATCHDOG=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ADVANTECH_WDT=m +CONFIG_EUROTECH_WDT=m +CONFIG_IB700_WDT=m +CONFIG_I8XX_TCO=m +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +CONFIG_W83877F_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_MACHZ_WDT=m +CONFIG_SC520_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALIM1535_WDT=m +CONFIG_SC1200_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_CPU5_WDT=m +CONFIG_PCIPCWATCHDOG=m +CONFIG_USBPCWATCHDOG=m + + +CONFIG_HW_RANDOM=m +# CONFIG_NVRAM is not set +CONFIG_RTC=y +CONFIG_DTLK=m +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_SONYPI is not set + +# +# Ftape, the floppy tape device driver +# +CONFIG_AGP=y +CONFIG_AGP_ALI=y +CONFIG_AGP_ATI=y +CONFIG_AGP_AMD=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=y +CONFIG_AGP_INTEL_MCH=y +CONFIG_AGP_NVIDIA=y +CONFIG_AGP_SIS=y +CONFIG_AGP_SWORKS=y +CONFIG_AGP_VIA=y +CONFIG_AGP_EFFICEON=y +CONFIG_DRM=y +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_MGA=m +# CONFIG_DRM_SIS is not set +CONFIG_DRM_I915=m + + + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set + + + +# CONFIG_MWAVE is not set +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +CONFIG_HANGCHECK_TIMER=m + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA_PP is not set +# CONFIG_VIDEO_CPIA_USB is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_DC30 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZORAN_LML33R10 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_SAA5246A is not set +CONFIG_VIDEO_OVCAMCHIP=m + + +# +# Radio Adapters +# +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_TYPHOON_PROC_FS=y +# CONFIG_RADIO_ZOLTRIX is not set + + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +CONFIG_DVB_CORE=m + +# +# Supported Frontend Modules +# +CONFIG_DVB_STV0299=m +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_ALPS_TDLB7 is not set +CONFIG_DVB_ALPS_TDMB7=m +CONFIG_DVB_ATMEL_AT76C651=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_GRUNDIG_29504_491=m +CONFIG_DVB_GRUNDIG_29504_401=m +CONFIG_DVB_MT312=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TWINHAN_DST=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_BT8XX=m +# CONFIG_DVB_TDA1004X is not set +CONFIG_DVB_NXT6000=m + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +# CONFIG_DVB_AV7110_FIRMWARE is not set +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m + +# +# Supported USB Adapters +# +CONFIG_DVB_TTUSB_BUDGET=m + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_SKYSTAR=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_VIDEOBUF=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BTCX=m + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_VGA16=m +CONFIG_FB_VESA=y +CONFIG_VIDEO_SELECT=y +# CONFIG_FB_HGA is not set +CONFIG_FB_RIVA=m +# CONFIG_FB_RIVA_DEBUG is not set +# CONFIG_FB_RIVA_I2C is not set +CONFIG_FB_I810=m +CONFIG_FB_I810_GTF=y +# CONFIG_FB_MATROX is not set +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G450=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MULTIHEAD=y +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RADEON_DEBUG is not set +# CONFIG_FB_RADEON_OLD is not set +CONFIG_FB_RADEON_I2C=y +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GX=y +# CONFIG_FB_ATY_XL_INIT is not set +# CONFIG_FB_SIS is not set +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_KYRO=m +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM2_FIFO_DISCONNECT is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_HGA_ACCEL is not set +# CONFIG_FB_3DFX_ACCEL is not set +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_CIRRUS=m + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set + + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_RTCTIMER=m +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_BIT32_EMUL=y + +# +# Generic devices +# +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +# CONFIG_SND_SERIAL_U16550 is not set +CONFIG_SND_MPU401=m + +# +# ISA devices +# +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_SB16_CSP=y +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_DT019X is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set + +# +# PCI devices +# +CONFIG_SND_ALI5451=m +CONFIG_SND_AZT3328=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS4281=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_KORG1212=m +CONFIG_SND_NM256=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_HDSP=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_ALS4000=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_FM801=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VX222=m +CONFIG_SND_BT87X=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_MIXART=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_PDAUDIOCF=m + + +# +# ALSA USB devices +# +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m + +# +# PCMCIA devices +# +# CONFIG_SND_VXPOCKET is not set +# CONFIG_SND_VXP440 is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_UHCI_HCD=m + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set + +# +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# +CONFIG_USB_MIDI=m +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_HP8200e=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_RW_DETECT=y + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +CONFIG_HID_FF=y +CONFIG_HID_PID=y +CONFIG_LOGITECH_FF=y +CONFIG_THRUSTMASTER_FF=y +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +CONFIG_USB_AIPTEK=m +CONFIG_USB_WACOM=m +CONFIG_USB_KBTAB=m +CONFIG_USB_POWERMATE=m +CONFIG_USB_XPAD=m + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_HPUSBSCSI=m + +# +# USB Multimedia devices +# +CONFIG_USB_DABUSB=m +CONFIG_USB_VICAM=m +CONFIG_USB_DSBR=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_STV680=m +CONFIG_USB_SN9C102=m + +# +# USB Network adaptors +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_SPEEDTOUCH=m + +# +# USB Host-to-Host Cables +# +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_GENESYS=y +CONFIG_USB_NET1080=y +CONFIG_USB_PL2301=y + +# +# Intelligent USB Devices/Gadgets +# +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_ZAURUS=y +CONFIG_USB_CDCETHER=y + +# +# USB Network Adapters +# +CONFIG_USB_AX8817X=y + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_EZUSB=y +CONFIG_USB_EMI62=m +CONFIG_USB_LED=m +CONFIG_USB_G_SERIAL=m + + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +CONFIG_USB_AUERSWALD=m +CONFIG_USB_RIO500=m +CONFIG_USB_LCD=m +CONFIG_USB_TEST=m +# CONFIG_USB_GADGET is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_SA1100 is not set +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_W9968CF=m +CONFIG_USB_PWC=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_MTOUCH=m +CONFIG_USB_ATI_REMOTE=m +CONFIG_USB_ALI_M5632=y +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_EGALAX=m +CONFIG_USB_PHIDGETSERVO=m + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_JFS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_XFS_RT is not set +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_SECURITY=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_QUOTA=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +CONFIG_UDF_FS=m + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_TMPFS_SECURITY=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not seta +# CONFIG_AFFS_FS is not set +# uses sleepon and needs a major update +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_NAND=y +CONFIG_CRAMFS=m +CONFIG_VXFS_FS=m +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_NCP_FS is not set +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_SMALLDOS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_RXRPC is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +CONFIG_OSF_PARTITION=y +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_SUN_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_NLS_ASCII=y + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m + +# +# Tux +# +CONFIG_TUX=m +CONFIG_TUX_EXTCGI=y +# CONFIG_TUX_EXTENDED_LOG is not set +# CONFIG_TUX_DEBUG is not set + + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_HIGHMEM=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_FRAME_POINTER is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_DEBUG_DRIVER is not set + +# +# Security options +# +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +# CONFIG_SECURITY_SELINUX_MLS is not set +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_TEST is not set +CONFIG_LIBCRC32C=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_SIGNATURE_DSA=y +CONFIG_CRYPTO_MPILIB=y +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_WP512=m + +# +# Library routines +# +CONFIG_CRC32=m +CONFIG_CRC_CCITT=m + +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_PC=y +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_ATALK is not set +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_IPX is not set +# CONFIG_IPDDP is not set +# CONFIG_IRDA is not set +# CONFIG_NCP_FS is not set +# CONFIG_ISAPNP is not set +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_IEEE1394 is not set +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_WD80x3 is not set +# CONFIG_IRDA is not set +# CONFIG_GAMEPORT is not set +# CONFIG_DVB is not set +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_SB16_CSP=y +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_DT019X is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_BINFMT_AOUT is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_MWAVE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_R3964 is not set +# CONFIG_TIPAR is not set +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_IFORCE_USB=y +# CONFIG_JOYSTICK_IFORCE_232=y +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDDLER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_TYPHOON_PROC_FS=y +# CONFIG_RADIO_ZOLTRIX is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_PLIP is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA_PP is not set +# CONFIG_VIDEO_CPIA_USB is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_DC30 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZORAN_LML33R10 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_I82092 is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SUNDANCE is not set +# CONFIG_ULTRA is not set +# CONFIG_SKFP is not set +# CONFIG_DE600 is not set +# CONFIG_DE620 is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_AC3200 is not set +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set +# CONFIG_LANCE is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +# CONFIG_3C515 is not set +# CONFIG_HAMACHI is not set +# CONFIG_HP100 is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_SB1000 is not set +# CONFIG_DEPCA is not set +# CONFIG_ATP is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_INFTL is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PCI is not set +# CONFIG_PCMCIA_SYM53C500 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_HGA_ACCEL is not set +# CONFIG_FB_3DFX_ACCEL is not set +# CONFIG_FB_TRIDENT_ACCEL is not set +# CONFIG_SCSI_DC390T is not set +CONFIG_AUDIT=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_I2C_PCA_ISA is not set +CONFIG_RAW_DRIVER=y +# CONFIG_MTD_SCB2_FLASH is not set +CONFIG_UID16=y +# CONFIG_MK8 is not set +# CONFIG_MPSC is not set +CONFIG_GENERIC_CPU=y +CONFIG_X86_MSR=y +CONFIG_X86_CPUID=y +CONFIG_MTRR=y +CONFIG_NUMA=y +CONFIG_K8_NUMA=y +CONFIG_NR_CPUS=8 +CONFIG_GART_IOMMU=y +CONFIG_X86_POWERNOW_K8=y +CONFIG_IA32_EMULATION=y +# CONFIG_IA32_AOUT is not set +CONFIG_INIT_DEBUG=y +# CONFIG_IOMMU_DEBUG is not set +# CONFIG_CHECKING is not set +CONFIG_MICROCODE=m +CONFIG_SWIOTLB=y +CONFIG_X86_PM_TIMER=y +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +CONFIG_I2O_CONFIG=y +CONFIG_TUX=m +# CONFIG_UNORDERED_IO is not set +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +CONFIG_X86_ACPI_CPUFREQ=y +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_SCHED_SMT=y +# CONFIG_SOFTWARE_SUSPEND is not set +# CONFIG_PM_DEBUG is not set +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_PROC_INTF is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +# CONFIG_CPU_FREQ_24_API is not set +CONFIG_CPU_FREQ_TABLE=y +CONFIG_ACPI=y +CONFIG_ACPI_BOOT=y +CONFIG_ACPI_INTERPRETER=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_FAN=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_TOSHIBA=m +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_BUS=y +CONFIG_ACPI_EC=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PCI=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_BLACKLIST_YEAR=2001 +# CONFIG_SCHEDSTATS is not set +CONFIG_EDD=m +CONFIG_PCI_BIOS=y +CONFIG_PCI_MMCONFIG=y +CONFIG_KEXEC=y +CONFIG_NETDUMP=m +CONFIG_CRASH=m +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +CONFIG_HOTPLUG_PCI_COMPAQ=m +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +# CONFIG_HOTPLUG_PCI_CPCI is not set +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_HOTPLUG_PCI_SHPC=m +# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set +# CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY is not set +# CONFIG_HPET is not set +CONFIG_PM=y +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT=m +CONFIG_IEEE80211_WPA=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IPW2100=m +# CONFIG_IPW_DEBUG is not set +CONFIG_IPW2100_PROMISC=y +# CONFIG_IPW2100_LEGACY_FW_LOAD is not set +CONFIG_IPW2200=m +# CONFIG_SMP is not set diff --git a/lustre/kernel_patches/patches/configurable-x86-stack-2.4.20-rh.patch b/lustre/kernel_patches/patches/configurable-x86-stack-2.4.20-rh.patch deleted file mode 100644 index f70b0d4..0000000 --- a/lustre/kernel_patches/patches/configurable-x86-stack-2.4.20-rh.patch +++ /dev/null @@ -1,311 +0,0 @@ -Index: linux-2.4.20-rh-20.9/arch/i386/kernel/entry.S -=================================================================== ---- linux-2.4.20-rh-20.9.orig/arch/i386/kernel/entry.S 2003-09-13 19:34:35.000000000 +0400 -+++ linux-2.4.20-rh-20.9/arch/i386/kernel/entry.S 2003-12-01 18:02:14.000000000 +0300 -@@ -45,6 +45,7 @@ - #include - #include - #include -+#include - - EBX = 0x00 - ECX = 0x04 -@@ -130,10 +131,6 @@ - .long 3b,6b; \ - .previous - --#define GET_CURRENT(reg) \ -- movl $-8192, reg; \ -- andl %esp, reg -- - ENTRY(lcall7) - pushfl # We get a different stack layout with call gates, - pushl %eax # which has to be cleaned up later.. -@@ -149,7 +146,7 @@ - movl %ecx,CS(%esp) # - movl %esp,%ebx - pushl %ebx -- andl $-8192,%ebx # GET_CURRENT -+ andl $-THREAD_SIZE,%ebx # GET_CURRENT - movl exec_domain(%ebx),%edx # Get the execution domain - movl 4(%edx),%edx # Get the lcall7 handler for the domain - pushl $0x7 -@@ -173,7 +170,7 @@ - movl %ecx,CS(%esp) # - movl %esp,%ebx - pushl %ebx -- andl $-8192,%ebx # GET_CURRENT -+ andl $-THREAD_SIZE,%ebx # GET_CURRENT - movl exec_domain(%ebx),%edx # Get the execution domain - movl 4(%edx),%edx # Get the lcall7 handler for the domain - pushl $0x27 -Index: linux-2.4.20-rh-20.9/arch/i386/kernel/smpboot.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/arch/i386/kernel/smpboot.c 2003-09-13 19:34:35.000000000 +0400 -+++ linux-2.4.20-rh-20.9/arch/i386/kernel/smpboot.c 2003-12-01 18:02:14.000000000 +0300 -@@ -811,7 +811,7 @@ - - /* So we see what's up */ - printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); -- stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle); -+ stack_start.esp = (void *)idle->thread.esp; - - /* - * This grunge runs the startup process for -@@ -884,7 +884,7 @@ - Dprintk("CPU has booted.\n"); - } else { - boot_error= 1; -- if (*((volatile unsigned char *)phys_to_virt(8192)) -+ if (*((volatile unsigned char *)phys_to_virt(THREAD_SIZE)) - == 0xA5) - /* trampoline started but...? */ - printk("Stuck ??\n"); -@@ -907,7 +907,7 @@ - } - - /* mark "stuck" area as not stuck */ -- *((volatile unsigned long *)phys_to_virt(8192)) = 0; -+ *((volatile unsigned long *)phys_to_virt(THREAD_SIZE)) = 0; - - if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ) { - printk("Restoring NMI vector\n"); -Index: linux-2.4.20-rh-20.9/arch/i386/kernel/traps.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/arch/i386/kernel/traps.c 2003-09-13 19:34:35.000000000 +0400 -+++ linux-2.4.20-rh-20.9/arch/i386/kernel/traps.c 2003-12-01 18:02:14.000000000 +0300 -@@ -161,7 +161,7 @@ - unsigned long esp = tsk->thread.esp; - - /* User space on another CPU? */ -- if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1)) -+ if ((esp ^ (unsigned long)tsk) & ~(THREAD_SIZE - 1)) - return; - show_trace((unsigned long *)esp); - } -Index: linux-2.4.20-rh-20.9/arch/i386/kernel/head.S -=================================================================== ---- linux-2.4.20-rh-20.9.orig/arch/i386/kernel/head.S 2003-09-13 19:34:35.000000000 +0400 -+++ linux-2.4.20-rh-20.9/arch/i386/kernel/head.S 2003-12-01 18:02:14.000000000 +0300 -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #define OLD_CL_MAGIC_ADDR 0x90020 - #define OLD_CL_MAGIC 0xA33F -@@ -315,7 +316,7 @@ - ret - - ENTRY(stack_start) -- .long SYMBOL_NAME(init_task_union)+8192 -+ .long SYMBOL_NAME(init_task_union)+THREAD_SIZE - .long __KERNEL_DS - - /* This is the default interrupt "handler" :-) */ -Index: linux-2.4.20-rh-20.9/arch/i386/kernel/irq.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/arch/i386/kernel/irq.c 2003-12-01 17:42:59.000000000 +0300 -+++ linux-2.4.20-rh-20.9/arch/i386/kernel/irq.c 2003-12-01 18:02:14.000000000 +0300 -@@ -581,7 +581,10 @@ - long esp; - - /* Debugging check for stack overflow: is there less than 1KB free? */ -- __asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (8191)); -+ __asm__ __volatile__( -+ "andl %%esp,%0" -+ : "=r" (esp) : "0" (THREAD_SIZE-1)); -+ - if (unlikely(esp < (sizeof(struct task_struct) + 1024))) { - extern void show_stack(unsigned long *); - -Index: linux-2.4.20-rh-20.9/arch/i386/lib/getuser.S -=================================================================== ---- linux-2.4.20-rh-20.9.orig/arch/i386/lib/getuser.S 1998-01-13 00:42:52.000000000 +0300 -+++ linux-2.4.20-rh-20.9/arch/i386/lib/getuser.S 2003-12-01 18:02:14.000000000 +0300 -@@ -21,6 +21,10 @@ - * as they get called from within inline assembly. - */ - -+/* Duplicated from asm/processor.h */ -+#include -+#include -+ - addr_limit = 12 - - .text -@@ -28,7 +32,7 @@ - .globl __get_user_1 - __get_user_1: - movl %esp,%edx -- andl $0xffffe000,%edx -+ andl $~(THREAD_SIZE - 1),%edx - cmpl addr_limit(%edx),%eax - jae bad_get_user - 1: movzbl (%eax),%edx -@@ -41,7 +45,7 @@ - addl $1,%eax - movl %esp,%edx - jc bad_get_user -- andl $0xffffe000,%edx -+ andl $~(THREAD_SIZE - 1),%edx - cmpl addr_limit(%edx),%eax - jae bad_get_user - 2: movzwl -1(%eax),%edx -@@ -54,7 +58,7 @@ - addl $3,%eax - movl %esp,%edx - jc bad_get_user -- andl $0xffffe000,%edx -+ andl $~(THREAD_SIZE - 1),%edx - cmpl addr_limit(%edx),%eax - jae bad_get_user - 3: movl -3(%eax),%edx -Index: linux-2.4.20-rh-20.9/arch/i386/config.in -=================================================================== ---- linux-2.4.20-rh-20.9.orig/arch/i386/config.in 2003-09-13 19:34:34.000000000 +0400 -+++ linux-2.4.20-rh-20.9/arch/i386/config.in 2003-12-01 18:02:14.000000000 +0300 -@@ -266,6 +266,29 @@ - if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then - define_bool CONFIG_HAVE_DEC_LOCK y - fi -+ -+choice 'Bigger Stack Size Support' \ -+ "off CONFIG_NOBIGSTACK \ -+ 16KB CONFIG_STACK_SIZE_16KB \ -+ 32KB CONFIG_STACK_SIZE_32KB \ -+ 64KB CONFIG_STACK_SIZE_64KB" off -+ -+if [ "$CONFIG_NOBIGSTACK" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 1 -+else -+ if [ "$CONFIG_STACK_SIZE_16KB" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 2 -+ else -+ if [ "$CONFIG_STACK_SIZE_32KB" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 3 -+ else -+ if [ "$CONFIG_STACK_SIZE_64KB" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 4 -+ fi -+ fi -+ fi -+fi -+ - endmenu - - mainmenu_option next_comment -Index: linux-2.4.20-rh-20.9/arch/i386/vmlinux.lds -=================================================================== ---- linux-2.4.20-rh-20.9.orig/arch/i386/vmlinux.lds 2003-09-13 19:34:24.000000000 +0400 -+++ linux-2.4.20-rh-20.9/arch/i386/vmlinux.lds 2003-12-01 18:02:14.000000000 +0300 -@@ -38,7 +38,8 @@ - - _edata = .; /* End of data section */ - -- . = ALIGN(8192); /* init_task */ -+/* chose the biggest of the possible stack sizes here? */ -+ . = ALIGN(65536); /* init_task */ - .data.init_task : { *(.data.init_task) } - - . = ALIGN(4096); /* Init code and data */ -Index: linux-2.4.20-rh-20.9/include/asm-i386/current.h -=================================================================== ---- linux-2.4.20-rh-20.9.orig/include/asm-i386/current.h 1998-08-15 03:35:22.000000000 +0400 -+++ linux-2.4.20-rh-20.9/include/asm-i386/current.h 2003-12-01 18:03:28.000000000 +0300 -@@ -1,15 +1,43 @@ - #ifndef _I386_CURRENT_H - #define _I386_CURRENT_H -+#include -+ -+/* -+ * Configurable page sizes on i386, mainly for debugging purposes. -+ * (c) Balbir Singh -+ */ -+ -+#ifdef __ASSEMBLY__ -+ -+#define PAGE_SIZE 4096 /* as cannot handle 1UL << 12 */ -+#define THREAD_SIZE ((1 << CONFIG_STACK_SIZE_SHIFT) * PAGE_SIZE) -+ -+#define GET_CURRENT(reg) \ -+ movl $-THREAD_SIZE, reg; \ -+ andl %esp, reg -+ -+#else /* __ASSEMBLY__ */ -+ -+#define THREAD_SIZE ((1 << CONFIG_STACK_SIZE_SHIFT) * PAGE_SIZE) -+#define __alloc_task_struct() \ -+ ((struct task_struct *) __get_free_pages(GFP_KERNEL,CONFIG_STACK_SIZE_SHIFT)) -+ -+#define __free_task_struct(p) \ -+ free_pages((unsigned long) (p), CONFIG_STACK_SIZE_SHIFT) -+ -+#define INIT_TASK_SIZE THREAD_SIZE - - struct task_struct; - - static inline struct task_struct * get_current(void) - { - struct task_struct *current; -- __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL)); -+ __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~(THREAD_SIZE - 1))); - return current; - } - - #define current get_current() - -+#endif /* __ASSEMBLY__ */ -+ - #endif /* !(_I386_CURRENT_H) */ -Index: linux-2.4.20-rh-20.9/include/asm-i386/hw_irq.h -=================================================================== ---- linux-2.4.20-rh-20.9.orig/include/asm-i386/hw_irq.h 2003-11-13 17:35:48.000000000 +0300 -+++ linux-2.4.20-rh-20.9/include/asm-i386/hw_irq.h 2003-12-01 18:02:14.000000000 +0300 -@@ -116,10 +116,6 @@ - #define IRQ_NAME2(nr) nr##_interrupt(void) - #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) - --#define GET_CURRENT \ -- "movl %esp, %ebx\n\t" \ -- "andl $-8192, %ebx\n\t" -- - /* - * SMP has a few special interrupts for IPI messages - */ -Index: linux-2.4.20-rh-20.9/include/asm-i386/processor.h -=================================================================== ---- linux-2.4.20-rh-20.9.orig/include/asm-i386/processor.h 2003-10-08 12:29:57.000000000 +0400 -+++ linux-2.4.20-rh-20.9/include/asm-i386/processor.h 2003-12-01 18:02:14.000000000 +0300 -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -469,10 +470,6 @@ - #define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) - #define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) - --#define THREAD_SIZE (2*PAGE_SIZE) --#define __alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) --#define __free_task_struct(p) do { BUG_ON((p)->state < TASK_ZOMBIE); free_pages((unsigned long) (p), 1); } while (0) -- - #define init_task (init_task_union.task) - #define init_stack (init_task_union.stack) - -Index: linux-2.4.20-rh-20.9/include/linux/sched.h -=================================================================== ---- linux-2.4.20-rh-20.9.orig/include/linux/sched.h 2003-11-13 17:35:48.000000000 +0300 -+++ linux-2.4.20-rh-20.9/include/linux/sched.h 2003-12-01 18:02:14.000000000 +0300 -@@ -2,6 +2,7 @@ - #define _LINUX_SCHED_H - - #include /* for HZ */ -+#include /* maybe for INIT_TASK_SIZE */ - - extern unsigned long event; - diff --git a/lustre/kernel_patches/patches/configurable-x86-stack-2.4.22-rh.patch b/lustre/kernel_patches/patches/configurable-x86-stack-2.4.22-rh.patch deleted file mode 100644 index 856425a..0000000 --- a/lustre/kernel_patches/patches/configurable-x86-stack-2.4.22-rh.patch +++ /dev/null @@ -1,311 +0,0 @@ -Index: linux-2.4.22-ac1/arch/i386/kernel/entry.S -=================================================================== ---- linux-2.4.22-ac1.orig/arch/i386/kernel/entry.S 2003-09-25 14:16:34.000000000 +0400 -+++ linux-2.4.22-ac1/arch/i386/kernel/entry.S 2003-12-01 18:34:08.000000000 +0300 -@@ -46,6 +46,7 @@ - #include - #include - #include -+#include - - EBX = 0x00 - ECX = 0x04 -@@ -131,10 +132,6 @@ - .long 3b,6b; \ - .previous - --#define GET_CURRENT(reg) \ -- movl $-8192, reg; \ -- andl %esp, reg -- - ENTRY(lcall7) - pushfl # We get a different stack layout with call gates, - pushl %eax # which has to be cleaned up later.. -@@ -150,7 +147,7 @@ - movl %ecx,CS(%esp) # - movl %esp,%ebx - pushl %ebx -- andl $-8192,%ebx # GET_CURRENT -+ andl $-THREAD_SIZE,%ebx # GET_CURRENT - movl exec_domain(%ebx),%edx # Get the execution domain - movl 4(%edx),%edx # Get the lcall7 handler for the domain - pushl $0x7 -@@ -174,7 +171,7 @@ - movl %ecx,CS(%esp) # - movl %esp,%ebx - pushl %ebx -- andl $-8192,%ebx # GET_CURRENT -+ andl $-THREAD_SIZE,%ebx # GET_CURRENT - movl exec_domain(%ebx),%edx # Get the execution domain - movl 4(%edx),%edx # Get the lcall7 handler for the domain - pushl $0x27 -Index: linux-2.4.22-ac1/arch/i386/kernel/smpboot.c -=================================================================== ---- linux-2.4.22-ac1.orig/arch/i386/kernel/smpboot.c 2003-09-25 14:16:28.000000000 +0400 -+++ linux-2.4.22-ac1/arch/i386/kernel/smpboot.c 2003-12-01 18:34:08.000000000 +0300 -@@ -814,7 +814,7 @@ - - /* So we see what's up */ - printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); -- stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle); -+ stack_start.esp = (void *)idle->thread.esp; - - /* - * This grunge runs the startup process for -@@ -887,7 +887,7 @@ - Dprintk("CPU has booted.\n"); - } else { - boot_error= 1; -- if (*((volatile unsigned char *)phys_to_virt(8192)) -+ if (*((volatile unsigned char *)phys_to_virt(THREAD_SIZE)) - == 0xA5) - /* trampoline started but...? */ - printk("Stuck ??\n"); -@@ -910,7 +910,7 @@ - } - - /* mark "stuck" area as not stuck */ -- *((volatile unsigned long *)phys_to_virt(8192)) = 0; -+ *((volatile unsigned long *)phys_to_virt(THREAD_SIZE)) = 0; - - if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ) { - printk("Restoring NMI vector\n"); -Index: linux-2.4.22-ac1/arch/i386/kernel/traps.c -=================================================================== ---- linux-2.4.22-ac1.orig/arch/i386/kernel/traps.c 2003-09-25 14:16:29.000000000 +0400 -+++ linux-2.4.22-ac1/arch/i386/kernel/traps.c 2003-12-01 18:34:08.000000000 +0300 -@@ -161,7 +161,7 @@ - unsigned long esp = tsk->thread.esp; - - /* User space on another CPU? */ -- if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1)) -+ if ((esp ^ (unsigned long)tsk) & ~(THREAD_SIZE - 1)) - return; - show_trace((unsigned long *)esp); - } -Index: linux-2.4.22-ac1/arch/i386/kernel/head.S -=================================================================== ---- linux-2.4.22-ac1.orig/arch/i386/kernel/head.S 2003-09-25 14:16:27.000000000 +0400 -+++ linux-2.4.22-ac1/arch/i386/kernel/head.S 2003-12-01 18:34:08.000000000 +0300 -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #define OLD_CL_MAGIC_ADDR 0x90020 - #define OLD_CL_MAGIC 0xA33F -@@ -315,7 +316,7 @@ - ret - - ENTRY(stack_start) -- .long SYMBOL_NAME(init_task_union)+8192 -+ .long SYMBOL_NAME(init_task_union)+THREAD_SIZE - .long __KERNEL_DS - - /* This is the default interrupt "handler" :-) */ -Index: linux-2.4.22-ac1/arch/i386/kernel/irq.c -=================================================================== ---- linux-2.4.22-ac1.orig/arch/i386/kernel/irq.c 2003-09-25 14:16:18.000000000 +0400 -+++ linux-2.4.22-ac1/arch/i386/kernel/irq.c 2003-12-01 18:34:08.000000000 +0300 -@@ -581,7 +581,10 @@ - long esp; - - /* Debugging check for stack overflow: is there less than 1KB free? */ -- __asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (8191)); -+ __asm__ __volatile__( -+ "andl %%esp,%0" -+ : "=r" (esp) : "0" (THREAD_SIZE-1)); -+ - if (unlikely(esp < (sizeof(struct task_struct) + 1024))) { - extern void show_stack(unsigned long *); - -Index: linux-2.4.22-ac1/arch/i386/lib/getuser.S -=================================================================== ---- linux-2.4.22-ac1.orig/arch/i386/lib/getuser.S 1998-01-13 00:42:52.000000000 +0300 -+++ linux-2.4.22-ac1/arch/i386/lib/getuser.S 2003-12-01 18:34:08.000000000 +0300 -@@ -21,6 +21,10 @@ - * as they get called from within inline assembly. - */ - -+/* Duplicated from asm/processor.h */ -+#include -+#include -+ - addr_limit = 12 - - .text -@@ -28,7 +32,7 @@ - .globl __get_user_1 - __get_user_1: - movl %esp,%edx -- andl $0xffffe000,%edx -+ andl $~(THREAD_SIZE - 1),%edx - cmpl addr_limit(%edx),%eax - jae bad_get_user - 1: movzbl (%eax),%edx -@@ -41,7 +45,7 @@ - addl $1,%eax - movl %esp,%edx - jc bad_get_user -- andl $0xffffe000,%edx -+ andl $~(THREAD_SIZE - 1),%edx - cmpl addr_limit(%edx),%eax - jae bad_get_user - 2: movzwl -1(%eax),%edx -@@ -54,7 +58,7 @@ - addl $3,%eax - movl %esp,%edx - jc bad_get_user -- andl $0xffffe000,%edx -+ andl $~(THREAD_SIZE - 1),%edx - cmpl addr_limit(%edx),%eax - jae bad_get_user - 3: movl -3(%eax),%edx -Index: linux-2.4.22-ac1/arch/i386/config.in -=================================================================== ---- linux-2.4.22-ac1.orig/arch/i386/config.in 2003-09-25 14:16:34.000000000 +0400 -+++ linux-2.4.22-ac1/arch/i386/config.in 2003-12-01 18:34:08.000000000 +0300 -@@ -304,6 +304,29 @@ - if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then - define_bool CONFIG_HAVE_DEC_LOCK y - fi -+ -+choice 'Bigger Stack Size Support' \ -+ "off CONFIG_NOBIGSTACK \ -+ 16KB CONFIG_STACK_SIZE_16KB \ -+ 32KB CONFIG_STACK_SIZE_32KB \ -+ 64KB CONFIG_STACK_SIZE_64KB" off -+ -+if [ "$CONFIG_NOBIGSTACK" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 1 -+else -+ if [ "$CONFIG_STACK_SIZE_16KB" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 2 -+ else -+ if [ "$CONFIG_STACK_SIZE_32KB" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 3 -+ else -+ if [ "$CONFIG_STACK_SIZE_64KB" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 4 -+ fi -+ fi -+ fi -+fi -+ - endmenu - - mainmenu_option next_comment -Index: linux-2.4.22-ac1/arch/i386/vmlinux.lds -=================================================================== ---- linux-2.4.22-ac1.orig/arch/i386/vmlinux.lds 2003-09-25 14:16:28.000000000 +0400 -+++ linux-2.4.22-ac1/arch/i386/vmlinux.lds 2003-12-01 18:34:08.000000000 +0300 -@@ -38,7 +38,8 @@ - - _edata = .; /* End of data section */ - -- . = ALIGN(8192); /* init_task */ -+/* chose the biggest of the possible stack sizes here? */ -+ . = ALIGN(65536); /* init_task */ - .data.init_task : { *(.data.init_task) } - - . = ALIGN(4096); /* Init code and data */ -Index: linux-2.4.22-ac1/include/asm-i386/current.h -=================================================================== ---- linux-2.4.22-ac1.orig/include/asm-i386/current.h 1998-08-15 03:35:22.000000000 +0400 -+++ linux-2.4.22-ac1/include/asm-i386/current.h 2003-12-01 18:34:16.000000000 +0300 -@@ -1,15 +1,43 @@ - #ifndef _I386_CURRENT_H - #define _I386_CURRENT_H -+#include -+ -+/* -+ * Configurable page sizes on i386, mainly for debugging purposes. -+ * (c) Balbir Singh -+ */ -+ -+#ifdef __ASSEMBLY__ -+ -+#define PAGE_SIZE 4096 /* as cannot handle 1UL << 12 */ -+#define THREAD_SIZE ((1 << CONFIG_STACK_SIZE_SHIFT) * PAGE_SIZE) -+ -+#define GET_CURRENT(reg) \ -+ movl $-THREAD_SIZE, reg; \ -+ andl %esp, reg -+ -+#else /* __ASSEMBLY__ */ -+ -+#define THREAD_SIZE ((1 << CONFIG_STACK_SIZE_SHIFT) * PAGE_SIZE) -+#define __alloc_task_struct() \ -+ ((struct task_struct *) __get_free_pages(GFP_KERNEL,CONFIG_STACK_SIZE_SHIFT)) -+ -+#define __free_task_struct(p) \ -+ free_pages((unsigned long) (p), CONFIG_STACK_SIZE_SHIFT) -+ -+#define INIT_TASK_SIZE THREAD_SIZE - - struct task_struct; - - static inline struct task_struct * get_current(void) - { - struct task_struct *current; -- __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL)); -+ __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~(THREAD_SIZE - 1))); - return current; - } - - #define current get_current() - -+#endif /* __ASSEMBLY__ */ -+ - #endif /* !(_I386_CURRENT_H) */ -Index: linux-2.4.22-ac1/include/asm-i386/hw_irq.h -=================================================================== ---- linux-2.4.22-ac1.orig/include/asm-i386/hw_irq.h 2003-09-26 00:54:45.000000000 +0400 -+++ linux-2.4.22-ac1/include/asm-i386/hw_irq.h 2003-12-01 18:34:08.000000000 +0300 -@@ -114,10 +114,6 @@ - #define IRQ_NAME2(nr) nr##_interrupt(void) - #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) - --#define GET_CURRENT \ -- "movl %esp, %ebx\n\t" \ -- "andl $-8192, %ebx\n\t" -- - /* - * SMP has a few special interrupts for IPI messages - */ -Index: linux-2.4.22-ac1/include/asm-i386/processor.h -=================================================================== ---- linux-2.4.22-ac1.orig/include/asm-i386/processor.h 2003-09-26 00:54:44.000000000 +0400 -+++ linux-2.4.22-ac1/include/asm-i386/processor.h 2003-12-01 18:34:08.000000000 +0300 -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -465,10 +466,6 @@ - #define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) - #define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) - --#define THREAD_SIZE (2*PAGE_SIZE) --#define __alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) --#define __free_task_struct(p) do { BUG_ON((p)->state < TASK_ZOMBIE); free_pages((unsigned long) (p), 1); } while (0) -- - #define init_task (init_task_union.task) - #define init_stack (init_task_union.stack) - -Index: linux-2.4.22-ac1/include/linux/sched.h -=================================================================== ---- linux-2.4.22-ac1.orig/include/linux/sched.h 2003-11-13 18:21:42.000000000 +0300 -+++ linux-2.4.22-ac1/include/linux/sched.h 2003-12-01 18:34:08.000000000 +0300 -@@ -2,6 +2,7 @@ - #define _LINUX_SCHED_H - - #include /* for HZ */ -+#include /* maybe for INIT_TASK_SIZE */ - - extern unsigned long event; - diff --git a/lustre/kernel_patches/patches/dev_read_only-2.6-lnxi.patch b/lustre/kernel_patches/patches/dev_read_only-2.6-lnxi.patch new file mode 100644 index 0000000..75062ea --- /dev/null +++ b/lustre/kernel_patches/patches/dev_read_only-2.6-lnxi.patch @@ -0,0 +1,150 @@ +--- linux-2.6.5.orig/drivers/block/ll_rw_blk.c 2005-03-16 10:09:28.000000000 -0800 ++++ linux-2.6.5/drivers/block/ll_rw_blk.c 2005-03-16 10:57:38.197357003 -0800 +@@ -2458,7 +2458,7 @@ static inline void blk_partition_remap(s + } + } + +-int dev_check_rdonly(dev_t dev); ++int dev_check_rdonly(struct block_device *bdev); + + /** + * generic_make_request: hand a buffer to its device driver for I/O +@@ -2550,9 +2550,9 @@ end_io: + + /* this is cfs's dev_rdonly check */ + if (bio->bi_rw == WRITE && +- dev_check_rdonly(bio->bi_bdev->bd_dev)) { +- bio_endio(bio, bio->bi_size, 0); +- break; ++ dev_check_rdonly(bio->bi_bdev)) { ++ bio_endio(bio, bio->bi_size, 0); ++ break; + } + + /* +@@ -3086,53 +3086,85 @@ void swap_io_context(struct io_context * + *ioc2 = temp; + } + +-#define MAX_RDONLY_DEVS 16 +- +-static dev_t rdonly_devs[MAX_RDONLY_DEVS] = {0, }; +- + /* + * Debug code for turning block devices "read-only" (will discard writes + * silently). This is for filesystem crash/recovery testing. + */ +-void dev_set_rdonly(struct block_device *bdev, int no_write) +-{ +- if (no_write >= MAX_RDONLY_DEVS) { +- printk(KERN_ALERT "%s:%d illegal arg %d (max %d)\n", +- __FILE__, __LINE__, no_write, MAX_RDONLY_DEVS); +- return; +- } +- +- if (bdev) { +- printk(KERN_WARNING "Turning device %s read-only at %d\n", +- bdev->bd_disk ? bdev->bd_disk->disk_name : "?", +- no_write); +- rdonly_devs[no_write] = bdev->bd_dev; +- } +-} ++struct deventry { ++ dev_t dev; ++ struct deventry *next; ++}; + +-void dev_clear_rdonly(int no_write) +-{ +- if (no_write >= MAX_RDONLY_DEVS) { +- printk(KERN_ALERT "%s:%d illegal arg %d (max %d)\n", +- __FILE__, __LINE__, no_write, MAX_RDONLY_DEVS); +- return; +- } ++static struct deventry *devlist = NULL; ++static spinlock_t devlock = SPIN_LOCK_UNLOCKED; + +- if (rdonly_devs[no_write] == 0) +- return; +- +- printk(KERN_WARNING "Clearing read-only at %d\n", no_write); +- rdonly_devs[no_write] = 0; +-} +- +-int dev_check_rdonly(dev_t dev) ++int dev_check_rdonly(struct block_device *bdev) + { +- int i; +- +- for (i = 0; i < MAX_RDONLY_DEVS; i++) +- if (rdonly_devs[i] == dev) +- return 1; +- return 0; ++ struct deventry *cur; ++ if (!bdev) return 0; ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (bdev->bd_dev == cur->dev) { ++ spin_unlock(&devlock); ++ return 1; ++ } ++ cur = cur->next; ++ } ++ spin_unlock(&devlock); ++ return 0; ++} ++ ++void dev_set_rdonly(struct block_device *bdev) ++{ ++ struct deventry *newdev, *cur; ++ ++ if (!bdev) ++ return; ++ newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL); ++ if (!newdev) ++ return; ++ ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (bdev->bd_dev == cur->dev) { ++ spin_unlock(&devlock); ++ kfree(newdev); ++ return; ++ } ++ cur = cur->next; ++ } ++ newdev->dev = bdev->bd_dev; ++ newdev->next = devlist; ++ devlist = newdev; ++ spin_unlock(&devlock); ++ printk(KERN_WARNING "Turning device %s read-only\n", ++ bdev->bd_disk ? bdev->bd_disk->disk_name : "?"); ++} ++ ++void dev_clear_rdonly(struct block_device *bdev) ++{ ++ struct deventry *cur, *last = NULL; ++ if (!bdev) return; ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (bdev->bd_dev == cur->dev) { ++ if (last) ++ last->next = cur->next; ++ else ++ devlist = cur->next; ++ spin_unlock(&devlock); ++ kfree(cur); ++ printk(KERN_WARNING "Removing read-only on %s\n", ++ bdev->bd_disk ? bdev->bd_disk->disk_name : "?"); ++ return; ++ } ++ last = cur; ++ cur = cur->next; ++ } ++ spin_unlock(&devlock); + } + + EXPORT_SYMBOL(dev_set_rdonly); diff --git a/lustre/kernel_patches/patches/dev_read_only-2.6-suse.patch b/lustre/kernel_patches/patches/dev_read_only-2.6-suse.patch index 9639f28..db6b72d 100644 --- a/lustre/kernel_patches/patches/dev_read_only-2.6-suse.patch +++ b/lustre/kernel_patches/patches/dev_read_only-2.6-suse.patch @@ -1,81 +1,117 @@ - drivers/block/ll_rw_blk.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/blkdev.h | 1 - 2 files changed, 50 insertions(+) - -Index: linux-2.6.0/drivers/block/ll_rw_blk.c -=================================================================== ---- linux-2.6.0.orig/drivers/block/ll_rw_blk.c 2004-01-04 15:27:35.000000000 +0300 -+++ linux-2.6.0/drivers/block/ll_rw_blk.c 2004-01-07 17:35:57.000000000 +0300 -@@ -2298,6 +2298,13 @@ +--- linux-2.6.5.orig/drivers/block/ll_rw_blk.c 2005-03-16 11:08:47.404935605 -0800 ++++ linux-2.6.5/drivers/block/ll_rw_blk.c 2005-03-16 10:57:38.197357003 -0800 +@@ -2458,6 +2458,8 @@ static inline void blk_partition_remap(s + } + } + ++int dev_check_rdonly(struct block_device *bdev); ++ + /** + * generic_make_request: hand a buffer to its device driver for I/O + * @bio: The bio describing the location in memory and on the device. +@@ -2546,6 +2548,13 @@ end_io: if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) goto end_io; + /* this is cfs's dev_rdonly check */ + if (bio->bi_rw == WRITE && -+ dev_check_rdonly(bio->bi_bdev->bd_dev)) { -+ bio_endio(bio, bio->bi_size, 0); -+ break; ++ dev_check_rdonly(bio->bi_bdev)) { ++ bio_endio(bio, bio->bi_size, 0); ++ break; + } + /* * If this device has partitions, remap block n * of partition p to block n+start(p) of the disk. -@@ -2805,6 +2812,58 @@ - *ioc2 = temp; +@@ -3078,6 +3087,91 @@ void swap_io_context(struct io_context * } -+#define MAX_RDONLY_DEVS 16 -+ -+static dev_t rdonly_devs[MAX_RDONLY_DEVS] = {0, }; -+ -+/* + /* + * Debug code for turning block devices "read-only" (will discard writes + * silently). This is for filesystem crash/recovery testing. + */ -+void dev_set_rdonly(struct block_device *bdev, int no_write) -+{ -+ if (no_write >= MAX_RDONLY_DEVS) { -+ printk(KERN_ALERT "%s:%d illegal arg %d (max %d)\n", -+ __FILE__, __LINE__, no_write, MAX_RDONLY_DEVS); -+ return; -+ } ++struct deventry { ++ dev_t dev; ++ struct deventry *next; ++}; + -+ if (bdev) { -+ printk(KERN_WARNING "Turning device %s read-only at %d\n", -+ bdev->bd_disk ? bdev->bd_disk->disk_name : "?", -+ no_write); -+ rdonly_devs[no_write] = bdev->bd_dev; -+ } ++static struct deventry *devlist = NULL; ++static spinlock_t devlock = SPIN_LOCK_UNLOCKED; ++ ++int dev_check_rdonly(struct block_device *bdev) ++{ ++ struct deventry *cur; ++ if (!bdev) return 0; ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (bdev->bd_dev == cur->dev) { ++ spin_unlock(&devlock); ++ return 1; ++ } ++ cur = cur->next; ++ } ++ spin_unlock(&devlock); ++ return 0; +} + -+void dev_clear_rdonly(int no_write) ++void dev_set_rdonly(struct block_device *bdev) +{ -+ if (no_write >= MAX_RDONLY_DEVS) { -+ printk(KERN_ALERT "%s:%d illegal arg %d (max %d)\n", -+ __FILE__, __LINE__, no_write, MAX_RDONLY_DEVS); -+ return; -+ } ++ struct deventry *newdev, *cur; + -+ if (rdonly_devs[no_write] == 0) -+ return; -+ -+ printk(KERN_WARNING "Clearing read-only at %d\n", no_write); -+ rdonly_devs[no_write] = 0; ++ if (!bdev) ++ return; ++ newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL); ++ if (!newdev) ++ return; ++ ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (bdev->bd_dev == cur->dev) { ++ spin_unlock(&devlock); ++ kfree(newdev); ++ return; ++ } ++ cur = cur->next; ++ } ++ newdev->dev = bdev->bd_dev; ++ newdev->next = devlist; ++ devlist = newdev; ++ spin_unlock(&devlock); ++ printk(KERN_WARNING "Turning device %s read-only\n", ++ bdev->bd_disk ? bdev->bd_disk->disk_name : "?"); +} + -+int dev_check_rdonly(dev_t dev) ++void dev_clear_rdonly(struct block_device *bdev) +{ -+ int i; -+ -+ for (i = 0; i < MAX_RDONLY_DEVS; i++) -+ if (rdonly_devs[i] == dev) -+ return 1; -+ return 0; ++ struct deventry *cur, *last = NULL; ++ if (!bdev) return; ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (bdev->bd_dev == cur->dev) { ++ if (last) ++ last->next = cur->next; ++ else ++ devlist = cur->next; ++ spin_unlock(&devlock); ++ kfree(cur); ++ printk(KERN_WARNING "Removing read-only on %s\n", ++ bdev->bd_disk ? bdev->bd_disk->disk_name : "?"); ++ return; ++ } ++ last = cur; ++ cur = cur->next; ++ } ++ spin_unlock(&devlock); +} + +EXPORT_SYMBOL(dev_set_rdonly); +EXPORT_SYMBOL(dev_clear_rdonly); +EXPORT_SYMBOL(dev_check_rdonly); - - /* ++ ++/* * sysfs parts below + */ + struct queue_sysfs_entry { diff --git a/lustre/kernel_patches/patches/dev_read_only_2.4.20-rh.patch b/lustre/kernel_patches/patches/dev_read_only_2.4.20-rh.patch index d3fa230..b411c92 100644 --- a/lustre/kernel_patches/patches/dev_read_only_2.4.20-rh.patch +++ b/lustre/kernel_patches/patches/dev_read_only_2.4.20-rh.patch @@ -1,51 +1,93 @@ -Index: linux-2.4.20-rh/drivers/block/blkpg.c -=================================================================== ---- linux-2.4.20-rh.orig/drivers/block/blkpg.c 2003-07-22 16:02:29.000000000 +0800 -+++ linux-2.4.20-rh/drivers/block/blkpg.c 2003-12-09 17:33:09.000000000 +0800 -@@ -297,3 +297,38 @@ +--- linux-2.4.20-rh.orig/drivers/block/ll_rw_blk.c 2005-01-19 10:59:48.000000000 -0800 ++++ linux-2.4.20-rh/drivers/block/ll_rw_blk.c 2005-01-19 12:13:39.325347995 -0800 +@@ -645,6 +645,86 @@ void set_device_ro(kdev_t dev,int flag) + else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31)); } - 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. ++ * Debug code for turning block devices read-only *silently* (will ++ * discard writes silently). This is only 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; -+ } -+} ++struct deventry { ++ kdev_t dev; ++ struct deventry *next; ++}; ++ ++static struct deventry *devlist = NULL; ++static spinlock_t devlock = SPIN_LOCK_UNLOCKED; + +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; ++ struct deventry *cur; ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (dev == cur->dev) { ++ spin_unlock(&devlock); ++ return 1; ++ } ++ cur = cur->next; ++ } ++ spin_unlock(&devlock); ++ return 0; +} + -+void dev_clear_rdonly(int no_write) { -+ dev_no_write[no_write] = 0; ++void dev_set_rdonly(kdev_t dev) ++{ ++ struct deventry *newdev, *cur; ++ newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL); ++ if (!newdev) return; ++ ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (dev == cur->dev) { ++ spin_unlock(&devlock); ++ kfree(newdev); ++ return; ++ } ++ cur = cur->next; ++ } ++ newdev->dev = dev; ++ newdev->next = devlist; ++ devlist = newdev; ++ spin_unlock(&devlock); ++ printk(KERN_WARNING "Turning device %s read-only\n", ++ bdevname(dev)); ++} ++ ++void dev_clear_rdonly(kdev_t dev) { ++ struct deventry *cur, *last = NULL; ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (dev == cur->dev) { ++ if (last) ++ last->next = cur->next; ++ else ++ devlist = cur->next; ++ spin_unlock(&devlock); ++ kfree(cur); ++ printk(KERN_WARNING "Removing read-only on %s\n", ++ bdevname(dev)); ++ return; ++ } ++ last = cur; ++ cur = cur->next; ++ } ++ spin_unlock(&devlock); +} + +EXPORT_SYMBOL(dev_set_rdonly); +EXPORT_SYMBOL(dev_check_rdonly); +EXPORT_SYMBOL(dev_clear_rdonly); -Index: linux-2.4.20-rh/drivers/block/ll_rw_blk.c -=================================================================== ---- linux-2.4.20-rh.orig/drivers/block/ll_rw_blk.c 2003-07-22 16:02:34.000000000 +0800 -+++ linux-2.4.20-rh/drivers/block/ll_rw_blk.c 2003-12-09 17:39:38.000000000 +0800 -@@ -1183,6 +1183,10 @@ ++ ++ + inline void drive_stat_acct (kdev_t dev, int rw, + unsigned long nr_sectors, int new_io) + { +@@ -1183,6 +1263,10 @@ void generic_make_request (int rw, struc buffer_IO_error(bh); break; } diff --git a/lustre/kernel_patches/patches/dev_read_only_2.4.21-chaos.patch b/lustre/kernel_patches/patches/dev_read_only_2.4.21-chaos.patch index 801431c..5ec75ce 100644 --- a/lustre/kernel_patches/patches/dev_read_only_2.4.21-chaos.patch +++ b/lustre/kernel_patches/patches/dev_read_only_2.4.21-chaos.patch @@ -1,78 +1,100 @@ - drivers/block/blkpg.c | 35 +++++++++++++++++++++++++++++++++++ - drivers/block/loop.c | 3 +++ - drivers/ide/ide-disk.c | 5 +++++ - 3 files changed, 43 insertions(+) - -Index: linux-2.4.21-chaos/drivers/block/blkpg.c -=================================================================== ---- linux-2.4.21-chaos.orig/drivers/block/blkpg.c 2003-09-19 03:49:42.000000000 +0400 -+++ linux-2.4.21-chaos/drivers/block/blkpg.c 2003-12-12 16:17:49.000000000 +0300 -@@ -535,3 +535,38 @@ +--- linux-2.4.21-p4smp-75chaos/drivers/block/ll_rw_blk.c.orig 2004-10-28 14:41:07.000000000 -0700 ++++ linux-2.4.21-p4smp-75chaos/drivers/block/ll_rw_blk.c 2005-01-19 12:24:53.946853178 -0800 +@@ -679,6 +679,86 @@ void set_device_ro(kdev_t dev,int flag) + else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31)); + } - #endif /* CONFIG_IA64 */ - -+ -+#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. ++ * Debug code for turning block devices read-only *silently* (will ++ * discard writes silently). This is only 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; -+ } -+} ++struct deventry { ++ kdev_t dev; ++ struct deventry *next; ++}; ++ ++static struct deventry *devlist = NULL; ++static spinlock_t devlock = SPIN_LOCK_UNLOCKED; + +int dev_check_rdonly(kdev_t dev) { -+ int i; ++ struct deventry *cur; ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (dev == cur->dev) { ++ spin_unlock(&devlock); ++ return 1; ++ } ++ cur = cur->next; ++ } ++ spin_unlock(&devlock); ++ return 0; ++} + -+ 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_set_rdonly(kdev_t dev) ++{ ++ struct deventry *newdev, *cur; ++ newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL); ++ if (!newdev) return; ++ ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (dev == cur->dev) { ++ spin_unlock(&devlock); ++ kfree(newdev); ++ return; ++ } ++ cur = cur->next; ++ } ++ newdev->dev = dev; ++ newdev->next = devlist; ++ devlist = newdev; ++ spin_unlock(&devlock); ++ printk(KERN_WARNING "Turning device %s read-only\n", ++ bdevname(dev)); +} + -+void dev_clear_rdonly(int no_write) { -+ dev_no_write[no_write] = 0; ++void dev_clear_rdonly(kdev_t dev) { ++ struct deventry *cur, *last = NULL; ++ spin_lock(&devlock); ++ cur = devlist; ++ while(cur) { ++ if (dev == cur->dev) { ++ if (last) ++ last->next = cur->next; ++ else ++ devlist = cur->next; ++ spin_unlock(&devlock); ++ kfree(cur); ++ printk(KERN_WARNING "Removing read-only on %s\n", ++ bdevname(dev)); ++ return; ++ } ++ last = cur; ++ cur = cur->next; ++ } ++ spin_unlock(&devlock); +} + +EXPORT_SYMBOL(dev_set_rdonly); +EXPORT_SYMBOL(dev_check_rdonly); +EXPORT_SYMBOL(dev_clear_rdonly); -Index: linux-2.4.21-chaos/drivers/block/loop.c -=================================================================== ---- linux-2.4.21-chaos.orig/drivers/block/loop.c 2003-09-19 03:49:42.000000000 +0400 -+++ linux-2.4.21-chaos/drivers/block/loop.c 2003-12-12 16:17:49.000000000 +0300 -@@ -491,6 +491,9 @@ - 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) { -Index: linux-2.4.21-chaos/drivers/ide/ide-disk.c -=================================================================== ---- linux-2.4.21-chaos.orig/drivers/ide/ide-disk.c 2003-07-15 02:08:42.000000000 +0400 -+++ linux-2.4.21-chaos/drivers/ide/ide-disk.c 2003-12-12 16:17:49.000000000 +0300 -@@ -371,6 +371,11 @@ - if (driver_blocked) - panic("Request while ide driver is blocked?"); - -+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { -+ ide_end_request(drive, 1); -+ return ide_stopped; -+ } + - if (IDE_CONTROL_REG) - hwif->OUTB(drive->ctl, IDE_CONTROL_REG); + inline void drive_stat_acct (kdev_t dev, int rw, + unsigned long nr_sectors, int new_io) + { +@@ -1257,6 +1337,10 @@ void generic_make_request (int rw, struc + break; + } + ++ if ((rw & WRITE)&&(dev_check_rdonly(bh->b_rdev))) { ++ bh->b_end_io(bh, 0); ++ break; ++ } + } while (q->make_request_fn(q, rw, bh)); + } diff --git a/lustre/kernel_patches/patches/dev_read_only_hp_2.4.20.patch b/lustre/kernel_patches/patches/dev_read_only_hp_2.4.20.patch deleted file mode 100644 index 60081db..0000000 --- a/lustre/kernel_patches/patches/dev_read_only_hp_2.4.20.patch +++ /dev/null @@ -1,77 +0,0 @@ - drivers/block/blkpg.c | 36 ++++++++++++++++++++++++++++++++++++ - drivers/block/loop.c | 3 +++ - drivers/ide/ide-disk.c | 4 ++++ - 3 files changed, 43 insertions(+) - ---- linux/drivers/block/blkpg.c~dev_read_only_hp_2.4.20 Mon May 19 07:07:52 2003 -+++ linux-mmonroe/drivers/block/blkpg.c Mon May 19 07:37:22 2003 -@@ -310,6 +310,42 @@ 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/drivers/block/loop.c~dev_read_only_hp_2.4.20 Thu Nov 28 15:53:12 2002 -+++ linux-mmonroe/drivers/block/loop.c Mon May 19 07:28:29 2003 -@@ -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/drivers/ide/ide-disk.c~dev_read_only_hp_2.4.20 Thu Nov 28 15:53:13 2002 -+++ linux-mmonroe/drivers/ide/ide-disk.c Mon May 19 07:28:29 2003 -@@ -558,6 +558,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/dsp.patch b/lustre/kernel_patches/patches/dsp.patch deleted file mode 100644 index d072af9..0000000 --- a/lustre/kernel_patches/patches/dsp.patch +++ /dev/null @@ -1,142 +0,0 @@ - arch/i386/kernel/crash.c | 24 +++++++++++++++++------- - arch/i386/kernel/nmi.c | 2 +- - include/asm-i386/apic.h | 1 + - include/linux/crash.h | 2 +- - kernel/bootimg.c | 13 ++++++++++++- - kernel/bootimg_pic.c | 6 ++++-- - 6 files changed, 36 insertions(+), 12 deletions(-) - -Index: linux-2.4.20-rh/kernel/bootimg.c -=================================================================== ---- linux-2.4.20-rh.orig/kernel/bootimg.c 2003-10-29 23:56:02.000000000 +0800 -+++ linux-2.4.20-rh/kernel/bootimg.c 2003-10-29 23:56:17.000000000 +0800 -@@ -238,9 +238,20 @@ - int error = -ENOMEM; - - if (bootimg_checksum(__va(bootimg_dsc.page_dir),bootimg_dsc.pages) -- != bootimg_dsc.csum) -+ != bootimg_dsc.csum) { - printk("Checksum of kernel image failed. Rebooting via BIOS\n"); - -+ /* Before calling machine_restart(), make sure it will not -+ * simply call this function recursively. -+ */ -+ bootimg_dsc.page_dir = NULL; -+ machine_restart(NULL); -+ -+ /* We should never get here, but just in case... */ -+ for (; ; ) -+ __asm__ __volatile__ ("hlt"); -+ } -+ - code_page = get_identity_mapped_page(); - if (!code_page) goto out3; - code = (relocate_and_jump_t) virt_to_phys((void *) code_page); -Index: linux-2.4.20-rh/kernel/bootimg_pic.c -=================================================================== ---- linux-2.4.20-rh.orig/kernel/bootimg_pic.c 2003-10-29 23:56:02.000000000 +0800 -+++ linux-2.4.20-rh/kernel/bootimg_pic.c 2003-10-29 23:56:17.000000000 +0800 -@@ -69,7 +69,8 @@ - for (j = i+1; j < dsc.pages; j++) { - table = dsc.page_dir+FROM_TABLE(j); - if (((unsigned long) *table) == to) { -- copy_and_swap(*table,dsc.scratch); -+ copy_and_swap((unsigned long) (*table), -+ dsc.scratch); - break; - } - if ((*table)[PAGE_NR(j)] == to) { -@@ -79,7 +80,8 @@ - } - table = dsc.page_dir+TO_TABLE(j); - if (((unsigned long) *table) == to) { -- copy_and_swap(*table,dsc.scratch); -+ copy_and_swap((unsigned long) (*table), -+ dsc.scratch); - break; - } - } -Index: linux-2.4.20-rh/include/asm-i386/apic.h -=================================================================== ---- linux-2.4.20-rh.orig/include/asm-i386/apic.h 2003-10-29 23:58:49.000000000 +0800 -+++ linux-2.4.20-rh/include/asm-i386/apic.h 2003-10-29 23:59:40.000000000 +0800 -@@ -86,6 +86,9 @@ - extern void apic_pm_unregister(struct pm_dev*); - - extern int check_nmi_watchdog (void); -+extern void disable_apic_nmi_watchdog(void); -+ -+ - - extern unsigned int nmi_watchdog; - #define NMI_NONE 0 -Index: linux-2.4.20-rh/include/linux/crash.h -=================================================================== ---- linux-2.4.20-rh.orig/include/linux/crash.h 2003-10-29 23:56:02.000000000 +0800 -+++ linux-2.4.20-rh/include/linux/crash.h 2003-10-29 23:56:17.000000000 +0800 -@@ -71,7 +71,7 @@ - #define CRASH_ZALLOC_PAGES 16*5*2 /* 2 to handle crash in crash */ - #define CRASH_LOW_WATER_PAGES 100 - --#define CRASH_CPU_TIMEOUT 5000 /* 5 sec wait for other cpus to stop */ -+#define CRASH_CPU_TIMEOUT 15000 /* 15 sec wait for other cpus to stop */ - - #define CRASH_MARK_RESERVED(addr) (set_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags)) - #define CRASH_CLEAR_RESERVED(addr) (clear_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags)) -Index: linux-2.4.20-rh/arch/i386/kernel/crash.c -=================================================================== ---- linux-2.4.20-rh.orig/arch/i386/kernel/crash.c 2003-10-29 23:56:02.000000000 +0800 -+++ linux-2.4.20-rh/arch/i386/kernel/crash.c 2003-10-29 23:56:17.000000000 +0800 -@@ -9,6 +9,8 @@ - #include - #include - #include -+#include -+#include - - inline void crash_save_regs(void) { - static unsigned long regs[8]; -@@ -30,15 +32,23 @@ - */ - void crash_save_current_state(struct task_struct *tp) - { -+ if (tp != NULL) { -+ /* -+ * Here we save ebp instead of esp just in case the compiler -+ * decides to put an extra push in before we execute this -+ * instruction (thus invalidating our frame pointer). -+ */ -+ asm volatile("movl %%ebp,%0":"=m" (*(u_long *)&tp->thread.esp)); -+ tp->thread.eip = (u_long)crash_save_current_state; -+ panic_ksp[smp_processor_id()] = tp->thread.esp; -+ mb(); -+ } -+ - /* -- * Here we save ebp instead of esp just in case the compiler -- * decides to put an extra push in before we execute this -- * instruction (thus invalidating our frame pointer). -+ * Just to be safe, disable the NMI watchdog on the calling CPU so it -+ * doesn't get in the way while we are trying to save a dump. - */ -- asm volatile("movl %%ebp,%0":"=m" (*(u_long *)&tp->thread.esp)); -- tp->thread.eip = (u_long)crash_save_current_state; -- panic_ksp[smp_processor_id()] = tp->thread.esp; -- mb(); -+ disable_apic_nmi_watchdog(); - - save_core(); - -Index: linux-2.4.20-rh/arch/i386/kernel/nmi.c -=================================================================== ---- linux-2.4.20-rh.orig/arch/i386/kernel/nmi.c 2003-10-29 23:56:02.000000000 +0800 -+++ linux-2.4.20-rh/arch/i386/kernel/nmi.c 2003-10-29 23:56:17.000000000 +0800 -@@ -138,7 +138,7 @@ - - struct pm_dev *nmi_pmdev; - --static void disable_apic_nmi_watchdog(void) -+void disable_apic_nmi_watchdog(void) - { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: diff --git a/lustre/kernel_patches/patches/dynamic-locks-2.4.20-rh.patch b/lustre/kernel_patches/patches/dynamic-locks-2.4.20-rh.patch deleted file mode 100644 index 59f0a3e..0000000 --- a/lustre/kernel_patches/patches/dynamic-locks-2.4.20-rh.patch +++ /dev/null @@ -1,217 +0,0 @@ - include/linux/dynlocks.h | 33 ++++++++++ - lib/Makefile | 4 - - lib/dynlocks.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 187 insertions(+), 2 deletions(-) - -Index: linux-2.4.20-rh/include/linux/dynlocks.h -=================================================================== ---- linux-2.4.20-rh.orig/include/linux/dynlocks.h 2003-09-04 18:25:49.000000000 +0800 -+++ linux-2.4.20-rh/include/linux/dynlocks.h 2003-09-04 18:25:49.000000000 +0800 -@@ -0,0 +1,33 @@ -+#ifndef _LINUX_DYNLOCKS_H -+#define _LINUX_DYNLOCKS_H -+ -+#include -+#include -+ -+struct dynlock_member { -+ struct list_head dl_list; -+ unsigned long dl_value; /* lock value */ -+ int dl_refcount; /* number of users */ -+ int dl_readers; -+ int dl_writers; -+ int dl_pid; /* holder of the lock */ -+ wait_queue_head_t dl_wait; -+}; -+ -+/* -+ * lock's namespace: -+ * - list of locks -+ * - lock to protect this list -+ */ -+struct dynlock { -+ struct list_head dl_list; -+ spinlock_t dl_list_lock; -+}; -+ -+void dynlock_init(struct dynlock *dl); -+void *dynlock_lock(struct dynlock *dl, unsigned long value, int rw, int gfp); -+void dynlock_unlock(struct dynlock *dl, void *lock); -+ -+ -+#endif -+ -Index: linux-2.4.20-rh/lib/dynlocks.c -=================================================================== ---- linux-2.4.20-rh.orig/lib/dynlocks.c 2003-09-04 18:25:49.000000000 +0800 -+++ linux-2.4.20-rh/lib/dynlocks.c 2003-09-04 18:25:49.000000000 +0800 -@@ -0,0 +1,152 @@ -+/* -+ * Dynamic Locks -+ * -+ * struct dynlock is lockspace -+ * one may request lock (exclusive or shared) for some value -+ * in that lockspace -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+/* -+ * dynlock_init -+ * -+ * initialize lockspace -+ * -+ */ -+void dynlock_init(struct dynlock *dl) -+{ -+ spin_lock_init(&dl->dl_list_lock); -+ INIT_LIST_HEAD(&dl->dl_list); -+} -+ -+/* -+ * dynlock_lock -+ * -+ * acquires lock (exclusive or shared) in specified lockspace -+ * each lock in lockspace is allocated separately, so user have -+ * to specify GFP flags. -+ * routine returns pointer to lock. this pointer is intended to -+ * be passed to dynlock_unlock -+ * -+ */ -+void *dynlock_lock(struct dynlock *dl, unsigned long value, int rw, int gfp) -+{ -+ struct dynlock_member *nhl = NULL; -+ struct dynlock_member *hl; -+ struct list_head *cur; -+ -+repeat: -+ /* find requested lock in lockspace */ -+ spin_lock(&dl->dl_list_lock); -+ list_for_each(cur, &dl->dl_list) { -+ hl = list_entry(cur, struct dynlock_member, dl_list); -+ if (hl->dl_value == value) { -+ /* lock is found */ -+ if (nhl) { -+ /* someone else just allocated -+ * lock we didn't find and just created -+ * so, we drop our lock -+ */ -+ kfree(nhl); -+ nhl = NULL; -+ } -+ hl->dl_refcount++; -+ goto found; -+ } -+ } -+ /* lock not found */ -+ if (nhl) { -+ /* we already have allocated lock. use it */ -+ hl = nhl; -+ nhl = NULL; -+ list_add(&hl->dl_list, &dl->dl_list); -+ goto found; -+ } -+ spin_unlock(&dl->dl_list_lock); -+ -+ /* lock not found and we haven't allocated lock yet. allocate it */ -+ nhl = kmalloc(sizeof(struct dynlock_member), gfp); -+ if (nhl == NULL) -+ return NULL; -+ nhl->dl_refcount = 1; -+ nhl->dl_value = value; -+ nhl->dl_readers = 0; -+ nhl->dl_writers = 0; -+ init_waitqueue_head(&nhl->dl_wait); -+ -+ /* while lock is being allocated, someone else may allocate it -+ * and put onto to list. check this situation -+ */ -+ goto repeat; -+ -+found: -+ if (rw) { -+ /* exclusive lock: user don't want to share lock at all -+ * NOTE: one process may take the same lock several times -+ * this functionaly is useful for rename operations */ -+ while ((hl->dl_writers && hl->dl_pid != current->pid) || -+ hl->dl_readers) { -+ spin_unlock(&dl->dl_list_lock); -+ wait_event(hl->dl_wait, -+ hl->dl_writers == 0 && hl->dl_readers == 0); -+ spin_lock(&dl->dl_list_lock); -+ } -+ hl->dl_writers++; -+ } else { -+ /* shared lock: user do not want to share lock with writer */ -+ while (hl->dl_writers) { -+ spin_unlock(&dl->dl_list_lock); -+ wait_event(hl->dl_wait, hl->dl_writers == 0); -+ spin_lock(&dl->dl_list_lock); -+ } -+ hl->dl_readers++; -+ } -+ hl->dl_pid = current->pid; -+ spin_unlock(&dl->dl_list_lock); -+ -+ return hl; -+} -+ -+ -+/* -+ * dynlock_unlock -+ * -+ * user have to specify lockspace (dl) and pointer to lock structure -+ * returned by dynlock_lock() -+ * -+ */ -+void dynlock_unlock(struct dynlock *dl, void *lock) -+{ -+ struct dynlock_member *hl = lock; -+ int wakeup = 0; -+ -+ spin_lock(&dl->dl_list_lock); -+ if (hl->dl_writers) { -+ hl->dl_writers--; -+ if (hl->dl_writers == 0) -+ wakeup = 1; -+ } else { -+ hl->dl_readers--; -+ if (hl->dl_readers == 0) -+ wakeup = 1; -+ } -+ if (wakeup) { -+ hl->dl_pid = 0; -+ wake_up(&hl->dl_wait); -+ } -+ if (--(hl->dl_refcount) == 0) -+ list_del(&hl->dl_list); -+ spin_unlock(&dl->dl_list_lock); -+ if (hl->dl_refcount == 0) -+ kfree(hl); -+} -+ -+EXPORT_SYMBOL(dynlock_init); -+EXPORT_SYMBOL(dynlock_lock); -+EXPORT_SYMBOL(dynlock_unlock); -+ -Index: linux-2.4.20-rh/lib/Makefile -=================================================================== ---- linux-2.4.20-rh.orig/lib/Makefile 2002-11-29 07:53:15.000000000 +0800 -+++ linux-2.4.20-rh/lib/Makefile 2003-09-04 18:27:26.000000000 +0800 -@@ -8,10 +8,10 @@ - - L_TARGET := lib.a - --export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o -+export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o dynlocks.o - - obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o \ -- bust_spinlocks.o rbtree.o dump_stack.o -+ bust_spinlocks.o rbtree.o dump_stack.o dynlocks.o - - obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o - obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o diff --git a/lustre/kernel_patches/patches/exports.patch b/lustre/kernel_patches/patches/exports.patch deleted file mode 100644 index 33e0b6c..0000000 --- a/lustre/kernel_patches/patches/exports.patch +++ /dev/null @@ -1,57 +0,0 @@ - - - - fs/ext3/Makefile | 2 ++ - fs/ext3/super.c | 2 +- - include/linux/fs.h | 1 + - kernel/ksyms.c | 5 +++++ - 4 files changed, 9 insertions(+), 1 deletion(-) - ---- linux-2.4.18-18/fs/ext3/Makefile~exports Sat Apr 5 02:51:27 2003 -+++ linux-2.4.18-18-braam/fs/ext3/Makefile Sat Apr 5 02:54:45 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-2.4.18-18/fs/ext3/super.c~exports Sat Apr 5 02:51:27 2003 -+++ linux-2.4.18-18-braam/fs/ext3/super.c Sat Apr 5 02:54:28 2003 -@@ -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-18/include/linux/fs.h~exports Sat Apr 5 02:51:27 2003 -+++ linux-2.4.18-18-braam/include/linux/fs.h Sat Apr 5 02:54:29 2003 -@@ -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-18/kernel/ksyms.c~exports Sat Apr 5 02:51:27 2003 -+++ linux-2.4.18-18-braam/kernel/ksyms.c Sat Apr 5 02:54:29 2003 -@@ -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/ext3-delete_thread-suse.patch b/lustre/kernel_patches/patches/ext3-delete_thread-suse.patch deleted file mode 100644 index f3d7f3c..0000000 --- a/lustre/kernel_patches/patches/ext3-delete_thread-suse.patch +++ /dev/null @@ -1,496 +0,0 @@ - fs/ext3/file.c | 4 - fs/ext3/inode.c | 116 ++++++++++++++++++++++ - fs/ext3/super.c | 230 +++++++++++++++++++++++++++++++++++++++++++++ - include/linux/ext3_fs.h | 5 - include/linux/ext3_fs_sb.h | 10 + - 5 files changed, 365 insertions(+) - -Index: linux-2.4.21-suse/fs/ext3/super.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/super.c 2004-01-12 19:49:25.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/super.c 2004-01-13 17:39:59.000000000 +0300 -@@ -400,6 +400,221 @@ - } - } - -+#ifdef EXT3_DELETE_THREAD -+/* -+ * Delete inodes in a loop until there are no more to be deleted. -+ * Normally, we run in the background doing the deletes and sleeping again, -+ * and clients just add new inodes to be deleted onto the end of the list. -+ * If someone is concerned about free space (e.g. block allocation or similar) -+ * then they can sleep on s_delete_waiter_queue and be woken up when space -+ * has been freed. -+ */ -+int ext3_delete_thread(void *data) -+{ -+ struct super_block *sb = data; -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ struct task_struct *tsk = current; -+ -+ /* Almost like daemonize, but not quite */ -+ exit_mm(current); -+ tsk->session = 1; -+ tsk->pgrp = 1; -+ tsk->tty = NULL; -+ exit_files(current); -+ reparent_to_init(); -+ -+ sprintf(tsk->comm, "kdelext3-%s", kdevname(sb->s_dev)); -+ sigfillset(&tsk->blocked); -+ -+ /*tsk->flags |= PF_KERNTHREAD;*/ -+ -+ INIT_LIST_HEAD(&sbi->s_delete_list); -+ wake_up(&sbi->s_delete_waiter_queue); -+ ext3_debug("delete thread on %s started\n", kdevname(sb->s_dev)); -+ -+ /* main loop */ -+ for (;;) { -+ wait_event_interruptible(sbi->s_delete_thread_queue, -+ !list_empty(&sbi->s_delete_list) || -+ !test_opt(sb, ASYNCDEL)); -+ ext3_debug("%s woken up: %lu inodes, %lu blocks\n", -+ tsk->comm,sbi->s_delete_inodes,sbi->s_delete_blocks); -+ -+ spin_lock(&sbi->s_delete_lock); -+ if (list_empty(&sbi->s_delete_list)) { -+ clear_opt(sbi->s_mount_opt, ASYNCDEL); -+ memset(&sbi->s_delete_list, 0, -+ sizeof(sbi->s_delete_list)); -+ spin_unlock(&sbi->s_delete_lock); -+ ext3_debug("delete thread on %s exiting\n", -+ kdevname(sb->s_dev)); -+ wake_up(&sbi->s_delete_waiter_queue); -+ break; -+ } -+ -+ while (!list_empty(&sbi->s_delete_list)) { -+ struct inode *inode=list_entry(sbi->s_delete_list.next, -+ struct inode, i_dentry); -+ unsigned long blocks = inode->i_blocks >> -+ (inode->i_blkbits - 9); -+ -+ list_del_init(&inode->i_dentry); -+ spin_unlock(&sbi->s_delete_lock); -+ ext3_debug("%s delete ino %lu blk %lu\n", -+ tsk->comm, inode->i_ino, blocks); -+ -+ iput(inode); -+ -+ spin_lock(&sbi->s_delete_lock); -+ sbi->s_delete_blocks -= blocks; -+ sbi->s_delete_inodes--; -+ } -+ if (sbi->s_delete_blocks != 0 || sbi->s_delete_inodes != 0) { -+ ext3_warning(sb, __FUNCTION__, -+ "%lu blocks, %lu inodes on list?\n", -+ sbi->s_delete_blocks,sbi->s_delete_inodes); -+ sbi->s_delete_blocks = 0; -+ sbi->s_delete_inodes = 0; -+ } -+ spin_unlock(&sbi->s_delete_lock); -+ wake_up(&sbi->s_delete_waiter_queue); -+ } -+ -+ return 0; -+} -+ -+static void ext3_start_delete_thread(struct super_block *sb) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ int rc; -+ -+ spin_lock_init(&sbi->s_delete_lock); -+ init_waitqueue_head(&sbi->s_delete_thread_queue); -+ init_waitqueue_head(&sbi->s_delete_waiter_queue); -+ -+ if (!test_opt(sb, ASYNCDEL)) -+ return; -+ -+ rc = kernel_thread(ext3_delete_thread, sb, CLONE_VM | CLONE_FILES); -+ if (rc < 0) -+ printk(KERN_ERR "EXT3-fs: cannot start delete thread: rc %d\n", -+ rc); -+ else -+ wait_event(sbi->s_delete_waiter_queue, sbi->s_delete_list.next); -+} -+ -+static void ext3_stop_delete_thread(struct ext3_sb_info *sbi) -+{ -+ if (sbi->s_delete_list.next == 0) /* thread never started */ -+ return; -+ -+ clear_opt(sbi->s_mount_opt, ASYNCDEL); -+ wake_up(&sbi->s_delete_thread_queue); -+ wait_event(sbi->s_delete_waiter_queue, -+ sbi->s_delete_list.next == 0 && sbi->s_delete_inodes == 0); -+} -+ -+/* Instead of playing games with the inode flags, destruction, etc we just -+ * create a new inode locally and put it on a list for the truncate thread. -+ * We need large parts of the inode struct in order to complete the -+ * truncate and unlink, so we may as well just have a real inode to do it. -+ * -+ * If we have any problem deferring the delete, just delete it right away. -+ * If we defer it, we also mark how many blocks it would free, so that we -+ * can keep the statfs data correct, and we know if we should sleep on the -+ * delete thread when we run out of space. -+ */ -+static void ext3_delete_inode_thread(struct inode *old_inode) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb); -+ struct ext3_inode_info *nei, *oei = EXT3_I(old_inode); -+ struct inode *new_inode; -+ unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9); -+ -+ if (is_bad_inode(old_inode)) { -+ clear_inode(old_inode); -+ return; -+ } -+ -+ if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next) -+ goto out_delete; -+ -+ /* We may want to delete the inode immediately and not defer it */ -+ if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS) -+ goto out_delete; -+ -+ /* We can't use the delete thread as-is during real orphan recovery, -+ * as we add to the orphan list here, causing ext3_orphan_cleanup() -+ * to loop endlessly. It would be nice to do so, but needs work. -+ */ -+ if (oei->i_state & EXT3_STATE_DELETE || -+ sbi->s_mount_state & EXT3_ORPHAN_FS) { -+ ext3_debug("doing deferred inode %lu delete (%lu blocks)\n", -+ old_inode->i_ino, blocks); -+ goto out_delete; -+ } -+ -+ /* We can iget this inode again here, because our caller has unhashed -+ * old_inode, so new_inode will be in a different inode struct. -+ * -+ * We need to ensure that the i_orphan pointers in the other inodes -+ * point at the new inode copy instead of the old one so the orphan -+ * list doesn't get corrupted when the old orphan inode is freed. -+ */ -+ down(&sbi->s_orphan_lock); -+ -+ sbi->s_mount_state |= EXT3_ORPHAN_FS; -+ new_inode = iget(old_inode->i_sb, old_inode->i_ino); -+ sbi->s_mount_state &= ~EXT3_ORPHAN_FS; -+ if (is_bad_inode(new_inode)) { -+ printk(KERN_WARNING "read bad inode %lu\n", old_inode->i_ino); -+ iput(new_inode); -+ new_inode = NULL; -+ } -+ if (!new_inode) { -+ up(&sbi->s_orphan_lock); -+ ext3_debug("delete inode %lu directly (bad read)\n", -+ old_inode->i_ino); -+ goto out_delete; -+ } -+ J_ASSERT(new_inode != old_inode); -+ -+ J_ASSERT(!list_empty(&oei->i_orphan)); -+ -+ nei = EXT3_I(new_inode); -+ /* Ugh. We need to insert new_inode into the same spot on the list -+ * as old_inode was, to ensure the in-memory orphan list is still -+ * in the same order as the on-disk orphan list (badness otherwise). -+ */ -+ nei->i_orphan = oei->i_orphan; -+ nei->i_orphan.next->prev = &nei->i_orphan; -+ nei->i_orphan.prev->next = &nei->i_orphan; -+ nei->i_state |= EXT3_STATE_DELETE; -+ up(&sbi->s_orphan_lock); -+ -+ clear_inode(old_inode); -+ -+ spin_lock(&sbi->s_delete_lock); -+ J_ASSERT(list_empty(&new_inode->i_dentry)); -+ list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list); -+ sbi->s_delete_blocks += blocks; -+ sbi->s_delete_inodes++; -+ spin_unlock(&sbi->s_delete_lock); -+ -+ ext3_debug("delete inode %lu (%lu blocks) by thread\n", -+ new_inode->i_ino, blocks); -+ -+ wake_up(&sbi->s_delete_thread_queue); -+ return; -+ -+out_delete: -+ ext3_delete_inode(old_inode); -+} -+#else -+#define ext3_start_delete_thread(sbi) do {} while(0) -+#define ext3_stop_delete_thread(sbi) do {} while(0) -+#endif /* EXT3_DELETE_THREAD */ -+ - void ext3_put_super (struct super_block * sb) - { - struct ext3_sb_info *sbi = EXT3_SB(sb); -@@ -407,6 +622,7 @@ - kdev_t j_dev = sbi->s_journal->j_dev; - int i; - -+ J_ASSERT(sbi->s_delete_inodes == 0); - ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { -@@ -455,7 +671,11 @@ - write_inode: ext3_write_inode, /* BKL not held. Don't need */ - dirty_inode: ext3_dirty_inode, /* BKL not held. We take it */ - put_inode: ext3_put_inode, /* BKL not held. Don't need */ -+#ifdef EXT3_DELETE_THREAD -+ delete_inode: ext3_delete_inode_thread,/* BKL not held. We take it */ -+#else - delete_inode: ext3_delete_inode, /* BKL not held. We take it */ -+#endif - put_super: ext3_put_super, /* BKL held */ - write_super: ext3_write_super, /* BKL held */ - sync_fs: ext3_sync_fs, -@@ -524,6 +744,13 @@ - clear_opt (*mount_options, XATTR_USER); - else - #endif -+#ifdef EXT3_DELETE_THREAD -+ if (!strcmp(this_char, "asyncdel")) -+ set_opt(*mount_options, ASYNCDEL); -+ else if (!strcmp(this_char, "noasyncdel")) -+ clear_opt(*mount_options, ASYNCDEL); -+ else -+#endif - if (!strcmp (this_char, "bsddf")) - clear_opt (*mount_options, MINIX_DF); - else if (!strcmp (this_char, "nouid32")) { -@@ -1223,6 +1450,7 @@ - } - - ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); -+ ext3_start_delete_thread(sb); - /* - * akpm: core read_super() calls in here with the superblock locked. - * That deadlocks, because orphan cleanup needs to lock the superblock -@@ -1614,7 +1842,12 @@ - static int ext3_sync_fs(struct super_block *sb) - { - tid_t target; -- -+ -+ if (atomic_read(&sb->s_active) == 0) { -+ /* fs is being umounted: time to stop delete thread */ -+ ext3_stop_delete_thread(EXT3_SB(sb)); -+ } -+ - sb->s_dirt = 0; - target = log_start_commit(EXT3_SB(sb)->s_journal, NULL); - log_wait_commit(EXT3_SB(sb)->s_journal, target); -@@ -1678,6 +1911,9 @@ - if (!parse_options(data, &tmp, sbi, &tmp, 1)) - return -EINVAL; - -+ if (!test_opt(sb, ASYNCDEL) || (*flags & MS_RDONLY)) -+ ext3_stop_delete_thread(sbi); -+ - if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) - ext3_abort(sb, __FUNCTION__, "Abort forced by user"); - -Index: linux-2.4.21-suse/fs/ext3/inode.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/inode.c 2004-01-13 17:38:09.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/inode.c 2004-01-13 17:38:10.000000000 +0300 -@@ -2552,6 +2552,118 @@ - return err; - } - -+#ifdef EXT3_DELETE_THREAD -+/* Move blocks from to-be-truncated inode over to a new inode, and delete -+ * that one from the delete thread instead. This avoids a lot of latency -+ * when truncating large files. -+ * -+ * If we have any problem deferring the truncate, just truncate it right away. -+ * If we defer it, we also mark how many blocks it would free, so that we -+ * can keep the statfs data correct, and we know if we should sleep on the -+ * delete thread when we run out of space. -+ */ -+void ext3_truncate_thread(struct inode *old_inode) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb); -+ struct ext3_inode_info *nei, *oei = EXT3_I(old_inode); -+ struct inode *new_inode; -+ handle_t *handle; -+ unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9); -+ -+ if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next) -+ goto out_truncate; -+ -+ /* XXX This is a temporary limitation for code simplicity. -+ * We could truncate to arbitrary sizes at some later time. -+ */ -+ if (old_inode->i_size != 0) -+ goto out_truncate; -+ -+ /* We may want to truncate the inode immediately and not defer it */ -+ if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS || -+ old_inode->i_size > oei->i_disksize) -+ goto out_truncate; -+ -+ /* We can't use the delete thread as-is during real orphan recovery, -+ * as we add to the orphan list here, causing ext3_orphan_cleanup() -+ * to loop endlessly. It would be nice to do so, but needs work. -+ */ -+ if (oei->i_state & EXT3_STATE_DELETE || -+ sbi->s_mount_state & EXT3_ORPHAN_FS) { -+ ext3_debug("doing deferred inode %lu delete (%lu blocks)\n", -+ old_inode->i_ino, blocks); -+ goto out_truncate; -+ } -+ -+ ext3_discard_prealloc(old_inode); -+ -+ /* old_inode = 1 -+ * new_inode = sb + GDT + ibitmap -+ * orphan list = 1 inode/superblock for add, 2 inodes for del -+ * quota files = 2 * EXT3_SINGLEDATA_TRANS_BLOCKS -+ */ -+ handle = ext3_journal_start(old_inode, 7); -+ if (IS_ERR(handle)) -+ goto out_truncate; -+ -+ new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode); -+ if (IS_ERR(new_inode)) { -+ ext3_debug("truncate inode %lu directly (no new inodes)\n", -+ old_inode->i_ino); -+ goto out_journal; -+ } -+ -+ nei = EXT3_I(new_inode); -+ -+ down_write(&oei->truncate_sem); -+ new_inode->i_size = old_inode->i_size; -+ new_inode->i_blocks = old_inode->i_blocks; -+ new_inode->i_uid = old_inode->i_uid; -+ new_inode->i_gid = old_inode->i_gid; -+ new_inode->i_nlink = 0; -+ -+ /* FIXME when we do arbitrary truncates */ -+ old_inode->i_blocks = oei->i_file_acl ? old_inode->i_blksize / 512 : 0; -+ old_inode->i_mtime = old_inode->i_ctime = CURRENT_TIME; -+ -+ memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data)); -+ memset(oei->i_data, 0, sizeof(oei->i_data)); -+ -+ nei->i_disksize = oei->i_disksize; -+ nei->i_state |= EXT3_STATE_DELETE; -+ up_write(&oei->truncate_sem); -+ -+ if (ext3_orphan_add(handle, new_inode) < 0) -+ goto out_journal; -+ -+ if (ext3_orphan_del(handle, old_inode) < 0) { -+ ext3_orphan_del(handle, new_inode); -+ iput(new_inode); -+ goto out_journal; -+ } -+ -+ ext3_journal_stop(handle, old_inode); -+ -+ spin_lock(&sbi->s_delete_lock); -+ J_ASSERT(list_empty(&new_inode->i_dentry)); -+ list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list); -+ sbi->s_delete_blocks += blocks; -+ sbi->s_delete_inodes++; -+ spin_unlock(&sbi->s_delete_lock); -+ -+ ext3_debug("delete inode %lu (%lu blocks) by thread\n", -+ new_inode->i_ino, blocks); -+ -+ wake_up(&sbi->s_delete_thread_queue); -+ return; -+ -+out_journal: -+ ext3_journal_stop(handle, old_inode); -+out_truncate: -+ ext3_truncate(old_inode); -+} -+#endif /* EXT3_DELETE_THREAD */ -+ - /* - * On success, We end up with an outstanding reference count against - * iloc->bh. This _must_ be cleaned up later. -Index: linux-2.4.21-suse/fs/ext3/file.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/file.c 2004-01-12 19:49:25.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/file.c 2004-01-13 17:38:10.000000000 +0300 -@@ -125,7 +125,11 @@ - }; - - struct inode_operations ext3_file_inode_operations = { -+#ifdef EXT3_DELETE_THREAD -+ truncate: ext3_truncate_thread, /* BKL held */ -+#else - truncate: ext3_truncate, /* BKL held */ -+#endif - setattr: ext3_setattr, /* BKL held */ - setxattr: ext3_setxattr, /* BKL held */ - getxattr: ext3_getxattr, /* BKL held */ -Index: linux-2.4.21-suse/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.21-suse.orig/include/linux/ext3_fs.h 2004-01-13 17:38:09.000000000 +0300 -+++ linux-2.4.21-suse/include/linux/ext3_fs.h 2004-01-13 17:38:10.000000000 +0300 -@@ -193,6 +193,7 @@ - */ - #define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */ - #define EXT3_STATE_NEW 0x00000002 /* inode is newly created */ -+#define EXT3_STATE_DELETE 0x00000010 /* deferred delete inode */ - - /* - * ioctl commands -@@ -320,6 +321,7 @@ - #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ - #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ - #define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ -+#define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -697,6 +699,9 @@ - extern void ext3_dirty_inode(struct inode *); - extern int ext3_change_inode_journal_flag(struct inode *, int); - extern void ext3_truncate (struct inode *); -+#ifdef EXT3_DELETE_THREAD -+extern void ext3_truncate_thread(struct inode *inode); -+#endif - extern void ext3_set_inode_flags(struct inode *); - - /* ioctl.c */ -Index: linux-2.4.21-suse/include/linux/ext3_fs_sb.h -=================================================================== ---- linux-2.4.21-suse.orig/include/linux/ext3_fs_sb.h 2004-01-12 19:49:25.000000000 +0300 -+++ linux-2.4.21-suse/include/linux/ext3_fs_sb.h 2004-01-13 17:38:10.000000000 +0300 -@@ -29,6 +29,8 @@ - - #define EXT3_MAX_GROUP_LOADED 8 - -+#define EXT3_DELETE_THREAD -+ - /* - * third extended-fs super-block data in memory - */ -@@ -76,6 +78,14 @@ - struct timer_list turn_ro_timer; /* For turning read-only (crash simulation) */ - wait_queue_head_t ro_wait_queue; /* For people waiting for the fs to go read-only */ - #endif -+#ifdef EXT3_DELETE_THREAD -+ spinlock_t s_delete_lock; -+ struct list_head s_delete_list; -+ unsigned long s_delete_blocks; -+ unsigned long s_delete_inodes; -+ wait_queue_head_t s_delete_thread_queue; -+ wait_queue_head_t s_delete_waiter_queue; -+#endif - }; - - #endif /* _LINUX_EXT3_FS_SB */ diff --git a/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.21-suse2.patch b/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.21-suse2.patch new file mode 100644 index 0000000..5980fd9 --- /dev/null +++ b/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.21-suse2.patch @@ -0,0 +1,760 @@ + fs/ext3/ialloc.c | 6 + fs/ext3/inode.c | 12 + fs/ext3/super.c | 6 + fs/ext3/xattr.c | 597 +++++++++++++++++++++++++++++++++++++++++++++- + include/linux/ext3_fs.h | 2 + include/linux/ext3_fs_i.h | 3 + 6 files changed, 615 insertions(+), 11 deletions(-) + +Index: linux-2.4.21-chaos/fs/ext3/ialloc.c +=================================================================== +--- linux-2.4.21-chaos.orig/fs/ext3/ialloc.c 2003-12-12 17:39:10.000000000 +0300 ++++ linux-2.4.21-chaos/fs/ext3/ialloc.c 2003-12-12 17:39:55.000000000 +0300 +@@ -580,6 +580,12 @@ + insert_inode_hash(inode); + inode->i_generation = sbi->s_next_generation++; + ++ if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) { ++ EXT3_I(inode)->i_extra_isize = sizeof(__u16) /* i_extra_isize */ ++ + sizeof(__u16); /* i_pad1 */ ++ } else ++ EXT3_I(inode)->i_extra_isize = 0; ++ + inode->u.ext3_i.i_state = EXT3_STATE_NEW; + err = ext3_get_inode_loc_new(inode, &iloc, 1); + if (err) goto fail; +Index: linux-2.4.21-chaos/fs/ext3/inode.c +=================================================================== +--- linux-2.4.21-chaos.orig/fs/ext3/inode.c 2003-12-12 17:39:11.000000000 +0300 ++++ linux-2.4.21-chaos/fs/ext3/inode.c 2003-12-12 17:39:55.000000000 +0300 +@@ -2502,6 +2502,12 @@ + ei->i_data[block] = iloc.raw_inode->i_block[block]; + INIT_LIST_HEAD(&ei->i_orphan); + ++ if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ++ EXT3_I(inode)->i_extra_isize = ++ le16_to_cpu(raw_inode->i_extra_isize); ++ else ++ EXT3_I(inode)->i_extra_isize = 0; ++ + if (S_ISREG(inode->i_mode)) { + inode->i_op = &ext3_file_inode_operations; + inode->i_fop = &ext3_file_operations; +@@ -2564,6 +2570,8 @@ + if (err) + goto out_brelse; + } ++ if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) ++ memset(raw_inode, 0, EXT3_INODE_SIZE(inode->i_sb)); + raw_inode->i_mode = cpu_to_le16(inode->i_mode); + if(!(test_opt(inode->i_sb, NO_UID32))) { + raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); +@@ -2646,6 +2654,10 @@ + else for (block = 0; block < EXT3_N_BLOCKS; block++) + raw_inode->i_block[block] = ei->i_data[block]; + ++ if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ++ raw_inode->i_extra_isize = ++ cpu_to_le16(EXT3_I(inode)->i_extra_isize); ++ + BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); + rc = ext3_journal_dirty_metadata(handle, bh); + if (!err) +Index: linux-2.4.21-chaos/fs/ext3/xattr.c +=================================================================== +--- linux-2.4.21-chaos.orig/fs/ext3/xattr.c 2003-12-12 17:38:44.000000000 +0300 ++++ linux-2.4.21-chaos/fs/ext3/xattr.c 2003-12-12 17:42:58.000000000 +0300 +@@ -88,6 +88,9 @@ + struct buffer_head *, + struct ext3_xattr_header *); + ++int ext3_xattr_block_set(handle_t *, struct inode *, int, const char *, ++ const void *, size_t, int); ++ + #ifdef CONFIG_EXT3_FS_XATTR_SHARING + + static int ext3_xattr_cache_insert(struct buffer_head *); +@@ -256,17 +259,12 @@ + } + + /* +- * 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. ++ * ext3_xattr_block_get() + * +- * Returns a negative error number on failure, or the number of bytes +- * used / required on success. ++ * routine looks for attribute in EA block and returns it's value and size + */ + int +-ext3_xattr_get(struct inode *inode, int name_index, const char *name, ++ext3_xattr_block_get(struct inode *inode, int name_index, const char *name, + void *buffer, size_t buffer_size) + { + struct buffer_head *bh = NULL; +@@ -359,6 +357,94 @@ + } + + /* ++ * ext3_xattr_ibody_get() ++ * ++ * routine looks for attribute in inode body and returns it's value and size ++ */ ++int ++ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name, ++ void *buffer, size_t buffer_size) ++{ ++ int size, name_len = strlen(name), storage_size; ++ struct ext3_xattr_entry *last; ++ struct ext3_inode *raw_inode; ++ struct ext3_iloc iloc; ++ char *start, *end; ++ int ret = -ENOENT; ++ ++ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) ++ return -ENOENT; ++ ++ ret = ext3_get_inode_loc(inode, &iloc); ++ if (ret) ++ return ret; ++ raw_inode = iloc.raw_inode; ++ ++ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - ++ EXT3_GOOD_OLD_INODE_SIZE - ++ EXT3_I(inode)->i_extra_isize - ++ sizeof(__u32); ++ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + ++ EXT3_I(inode)->i_extra_isize; ++ if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) { ++ brelse(iloc.bh); ++ return -ENOENT; ++ } ++ start += sizeof(__u32); ++ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; ++ ++ last = (struct ext3_xattr_entry *) start; ++ while (!IS_LAST_ENTRY(last)) { ++ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); ++ if (le32_to_cpu(last->e_value_size) > storage_size || ++ (char *) next >= end) { ++ ext3_error(inode->i_sb, "ext3_xattr_ibody_get", ++ "inode %ld", inode->i_ino); ++ brelse(iloc.bh); ++ return -EIO; ++ } ++ if (name_index == last->e_name_index && ++ name_len == last->e_name_len && ++ !memcmp(name, last->e_name, name_len)) ++ goto found; ++ last = next; ++ } ++ ++ /* can't find EA */ ++ brelse(iloc.bh); ++ return -ENOENT; ++ ++found: ++ size = le32_to_cpu(last->e_value_size); ++ if (buffer) { ++ ret = -ERANGE; ++ if (buffer_size >= size) { ++ memcpy(buffer, start + le16_to_cpu(last->e_value_offs), ++ size); ++ ret = size; ++ } ++ } else ++ ret = size; ++ brelse(iloc.bh); ++ return ret; ++} ++ ++int ext3_xattr_get(struct inode *inode, int name_index, const char *name, ++ void *buffer, size_t buffer_size) ++{ ++ int err; ++ ++ /* try to find attribute in inode body */ ++ err = ext3_xattr_ibody_get(inode, name_index, name, ++ buffer, buffer_size); ++ if (err < 0) ++ /* search was unsuccessful, try to find EA in dedicated block */ ++ err = ext3_xattr_block_get(inode, name_index, name, ++ buffer, buffer_size); ++ return err; ++} ++ ++/* + * ext3_xattr_list() + * + * Copy a list of attribute names into the buffer +@@ -369,7 +455,7 @@ + * used / required on success. + */ + int +-ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) ++ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size) + { + struct buffer_head *bh = NULL; + struct ext3_xattr_entry *entry; +@@ -446,6 +532,131 @@ + return error; + } + ++/* ext3_xattr_ibody_list() ++ * ++ * generate list of attributes stored in inode body ++ */ ++int ++ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size) ++{ ++ struct ext3_xattr_entry *last; ++ struct ext3_inode *raw_inode; ++ char *start, *end, *buf; ++ struct ext3_iloc iloc; ++ int storage_size; ++ int ret; ++ int size = 0; ++ ++ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) ++ return 0; ++ ++ ret = ext3_get_inode_loc(inode, &iloc); ++ if (ret) ++ return ret; ++ raw_inode = iloc.raw_inode; ++ ++ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - ++ EXT3_GOOD_OLD_INODE_SIZE - ++ EXT3_I(inode)->i_extra_isize - ++ sizeof(__u32); ++ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + ++ EXT3_I(inode)->i_extra_isize; ++ if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) { ++ brelse(iloc.bh); ++ return 0; ++ } ++ start += sizeof(__u32); ++ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; ++ ++ last = (struct ext3_xattr_entry *) start; ++ while (!IS_LAST_ENTRY(last)) { ++ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); ++ struct ext3_xattr_handler *handler; ++ if (le32_to_cpu(last->e_value_size) > storage_size || ++ (char *) next >= end) { ++ ext3_error(inode->i_sb, "ext3_xattr_ibody_list", ++ "inode %ld", inode->i_ino); ++ brelse(iloc.bh); ++ return -EIO; ++ } ++ handler = ext3_xattr_handler(last->e_name_index); ++ if (handler) ++ size += handler->list(NULL, inode, last->e_name, ++ last->e_name_len); ++ last = next; ++ } ++ ++ if (!buffer) { ++ ret = size; ++ goto cleanup; ++ } else { ++ ret = -ERANGE; ++ if (size > buffer_size) ++ goto cleanup; ++ } ++ ++ last = (struct ext3_xattr_entry *) start; ++ buf = buffer; ++ while (!IS_LAST_ENTRY(last)) { ++ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); ++ struct ext3_xattr_handler *handler; ++ handler = ext3_xattr_handler(last->e_name_index); ++ if (handler) ++ buf += handler->list(buf, inode, last->e_name, ++ last->e_name_len); ++ last = next; ++ } ++ ret = size; ++cleanup: ++ brelse(iloc.bh); ++ return ret; ++} ++ ++/* ++ * 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) ++{ ++ int error; ++ int size = buffer_size; ++ ++ /* get list of attributes stored in inode body */ ++ error = ext3_xattr_ibody_list(inode, buffer, buffer_size); ++ if (error < 0) { ++ /* some error occured while collecting ++ * attributes in inode body */ ++ size = 0; ++ goto cleanup; ++ } ++ size = error; ++ ++ /* get list of attributes stored in dedicated block */ ++ if (buffer) { ++ buffer_size -= error; ++ if (buffer_size <= 0) { ++ buffer = NULL; ++ buffer_size = 0; ++ } else ++ buffer += error; ++ } ++ ++ error = ext3_xattr_block_list(inode, buffer, buffer_size); ++ if (error < 0) ++ /* listing was successful, so we return len */ ++ size = 0; ++ ++cleanup: ++ return error + size; ++} ++ + /* + * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is + * not set, set it. +@@ -480,6 +691,102 @@ + */ + int + ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, ++ const char *name, const void *value, size_t value_len, ++ int flags) ++{ ++ struct ext3_xattr_entry entry; ++ int err, where = 0, found = 0, total; ++ int free1 = -1, free2 = -1; ++ int name_len; ++ ++ 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 > inode->i_sb->s_blocksize) ++ return -ERANGE; ++ ++ /* try to find attribute in inode body */ ++ err = ext3_xattr_ibody_find(inode, name_index, name, &entry, &free1); ++ if (err == 0) { ++ /* found EA in inode */ ++ found = 1; ++ where = 0; ++ } else if (err == -ENOENT) { ++ /* there is no such attribute in inode body */ ++ /* try to find attribute in dedicated block */ ++ err = ext3_xattr_block_find(inode, name_index, name, ++ &entry, &free2); ++ if (err != 0 && err != -ENOENT) { ++ /* not found EA in block */ ++ goto finish; ++ } else if (err == 0) { ++ /* found EA in block */ ++ where = 1; ++ found = 1; ++ } ++ } else ++ goto finish; ++ ++ /* check flags: may replace? may create ? */ ++ if (found && (flags & XATTR_CREATE)) { ++ err = -EEXIST; ++ goto finish; ++ } else if (!found && (flags & XATTR_REPLACE)) { ++ err = -ENODATA; ++ goto finish; ++ } ++ ++ /* check if we have enough space to store attribute */ ++ total = EXT3_XATTR_LEN(strlen(name)) + value_len; ++ if (free1 >= 0 && total > free1 && free2 >= 0 && total > free2) { ++ /* have no enough space */ ++ err = -ENOSPC; ++ goto finish; ++ } ++ ++ /* time to remove attribute */ ++ if (found) { ++ if (where == 0) { ++ /* EA is stored in inode body */ ++ ext3_xattr_ibody_set(handle, inode, name_index, name, ++ NULL, 0, flags); ++ } else { ++ /* EA is stored in separated block */ ++ ext3_xattr_block_set(handle, inode, name_index, name, ++ NULL, 0, flags); ++ } ++ } ++ ++ /* try to store EA in inode body */ ++ err = ext3_xattr_ibody_set(handle, inode, name_index, name, ++ value, value_len, flags); ++ if (err) { ++ /* can't store EA in inode body */ ++ /* try to store in block */ ++ err = ext3_xattr_block_set(handle, inode, name_index, ++ name, value, value_len, flags); ++ } ++ ++finish: ++ return err; ++} ++ ++/* ++ * ext3_xattr_block_set() ++ * ++ * this routine add/remove/replace attribute in EA block ++ */ ++int ++ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index, + const char *name, const void *value, size_t value_len, + int flags) + { +@@ -868,6 +1174,279 @@ + } + + /* ++ * ext3_xattr_ibody_find() ++ * ++ * search attribute and calculate free space in inode body ++ * NOTE: free space includes space our attribute hold ++ */ ++int ++ext3_xattr_ibody_find(struct inode *inode, int name_index, ++ const char *name, struct ext3_xattr_entry *rentry, int *free) ++{ ++ struct ext3_xattr_entry *last; ++ struct ext3_inode *raw_inode; ++ int name_len = strlen(name); ++ int err, storage_size; ++ struct ext3_iloc iloc; ++ char *start, *end; ++ int ret = -ENOENT; ++ ++ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) ++ return ret; ++ ++ err = ext3_get_inode_loc(inode, &iloc); ++ if (err) ++ return -EIO; ++ raw_inode = iloc.raw_inode; ++ ++ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - ++ EXT3_GOOD_OLD_INODE_SIZE - ++ EXT3_I(inode)->i_extra_isize - ++ sizeof(__u32); ++ *free = storage_size - sizeof(__u32); ++ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + ++ EXT3_I(inode)->i_extra_isize; ++ if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) { ++ brelse(iloc.bh); ++ return -ENOENT; ++ } ++ start += sizeof(__u32); ++ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; ++ ++ last = (struct ext3_xattr_entry *) start; ++ while (!IS_LAST_ENTRY(last)) { ++ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); ++ if (le32_to_cpu(last->e_value_size) > storage_size || ++ (char *) next >= end) { ++ ext3_error(inode->i_sb, "ext3_xattr_ibody_find", ++ "inode %ld", inode->i_ino); ++ brelse(iloc.bh); ++ return -EIO; ++ } ++ ++ if (name_index == last->e_name_index && ++ name_len == last->e_name_len && ++ !memcmp(name, last->e_name, name_len)) { ++ memcpy(rentry, last, sizeof(struct ext3_xattr_entry)); ++ ret = 0; ++ } else { ++ *free -= EXT3_XATTR_LEN(last->e_name_len); ++ *free -= le32_to_cpu(last->e_value_size); ++ } ++ last = next; ++ } ++ ++ brelse(iloc.bh); ++ return ret; ++} ++ ++/* ++ * ext3_xattr_block_find() ++ * ++ * search attribute and calculate free space in EA block (if it allocated) ++ * NOTE: free space includes space our attribute hold ++ */ ++int ++ext3_xattr_block_find(struct inode *inode, int name_index, const char *name, ++ struct ext3_xattr_entry *rentry, int *free) ++{ ++ struct buffer_head *bh = NULL; ++ struct ext3_xattr_entry *entry; ++ char *end; ++ int name_len, error = -ENOENT; ++ ++ if (!EXT3_I(inode)->i_file_acl) { ++ *free = inode->i_sb->s_blocksize - ++ sizeof(struct ext3_xattr_header) - ++ sizeof(__u32); ++ return -ENOENT; ++ } ++ ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl); ++ bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl); ++ 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, ++ EXT3_I(inode)->i_file_acl); ++ brelse(bh); ++ return -EIO; ++ } ++ /* find named attribute */ ++ name_len = strlen(name); ++ *free = bh->b_size - sizeof(__u32); ++ ++ 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) { ++ memcpy(rentry, entry, sizeof(struct ext3_xattr_entry)); ++ error = 0; ++ } else { ++ *free -= EXT3_XATTR_LEN(entry->e_name_len); ++ *free -= le32_to_cpu(entry->e_value_size); ++ } ++ entry = next; ++ } ++ brelse(bh); ++ ++ return error; ++} ++ ++/* ++ * ext3_xattr_inode_set() ++ * ++ * this routine add/remove/replace attribute in inode body ++ */ ++int ++ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, int name_index, ++ const char *name, const void *value, size_t value_len, ++ int flags) ++{ ++ struct ext3_xattr_entry *last, *next, *here = NULL; ++ struct ext3_inode *raw_inode; ++ int name_len = strlen(name); ++ int esize = EXT3_XATTR_LEN(name_len); ++ struct buffer_head *bh; ++ int err, storage_size; ++ struct ext3_iloc iloc; ++ int free, min_offs; ++ char *start, *end; ++ ++ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) ++ return -ENOSPC; ++ ++ err = ext3_get_inode_loc(inode, &iloc); ++ if (err) ++ return err; ++ raw_inode = iloc.raw_inode; ++ bh = iloc.bh; ++ ++ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - ++ EXT3_GOOD_OLD_INODE_SIZE - ++ EXT3_I(inode)->i_extra_isize - ++ sizeof(__u32); ++ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + ++ EXT3_I(inode)->i_extra_isize; ++ if ((*(__u32*) start) != EXT3_XATTR_MAGIC) { ++ /* inode had no attributes before */ ++ *((__u32*) start) = cpu_to_le32(EXT3_XATTR_MAGIC); ++ } ++ start += sizeof(__u32); ++ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; ++ min_offs = storage_size; ++ free = storage_size - sizeof(__u32); ++ ++ last = (struct ext3_xattr_entry *) start; ++ while (!IS_LAST_ENTRY(last)) { ++ next = EXT3_XATTR_NEXT(last); ++ if (le32_to_cpu(last->e_value_size) > storage_size || ++ (char *) next >= end) { ++ ext3_error(inode->i_sb, "ext3_xattr_ibody_set", ++ "inode %ld", inode->i_ino); ++ brelse(bh); ++ return -EIO; ++ } ++ ++ if (last->e_value_size) { ++ int offs = le16_to_cpu(last->e_value_offs); ++ if (offs < min_offs) ++ min_offs = offs; ++ } ++ if (name_index == last->e_name_index && ++ name_len == last->e_name_len && ++ !memcmp(name, last->e_name, name_len)) ++ here = last; ++ else { ++ /* we calculate all but our attribute ++ * because it will be removed before changing */ ++ free -= EXT3_XATTR_LEN(last->e_name_len); ++ free -= le32_to_cpu(last->e_value_size); ++ } ++ last = next; ++ } ++ ++ if (value && (esize + value_len > free)) { ++ brelse(bh); ++ return -ENOSPC; ++ } ++ ++ err = ext3_reserve_inode_write(handle, inode, &iloc); ++ if (err) { ++ brelse(bh); ++ return err; ++ } ++ ++ if (here) { ++ /* time to remove old value */ ++ struct ext3_xattr_entry *e; ++ int size = le32_to_cpu(here->e_value_size); ++ int border = le16_to_cpu(here->e_value_offs); ++ char *src; ++ ++ /* move tail */ ++ memmove(start + min_offs + size, start + min_offs, ++ border - min_offs); ++ ++ /* recalculate offsets */ ++ e = (struct ext3_xattr_entry *) start; ++ while (!IS_LAST_ENTRY(e)) { ++ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(e); ++ int offs = le16_to_cpu(e->e_value_offs); ++ if (offs < border) ++ e->e_value_offs = ++ cpu_to_le16(offs + size); ++ e = next; ++ } ++ min_offs += size; ++ ++ /* remove entry */ ++ border = EXT3_XATTR_LEN(here->e_name_len); ++ src = (char *) here + EXT3_XATTR_LEN(here->e_name_len); ++ size = (char *) last - src; ++ if ((char *) here + size > end) ++ printk("ALERT at %s:%d: 0x%p + %d > 0x%p\n", ++ __FILE__, __LINE__, here, size, end); ++ memmove(here, src, size); ++ last = (struct ext3_xattr_entry *) ((char *) last - border); ++ *((__u32 *) last) = 0; ++ } ++ ++ if (value) { ++ int offs = min_offs - value_len; ++ /* use last to create new entry */ ++ last->e_name_len = strlen(name); ++ last->e_name_index = name_index; ++ last->e_value_offs = cpu_to_le16(offs); ++ last->e_value_size = cpu_to_le32(value_len); ++ last->e_hash = last->e_value_block = 0; ++ memset(last->e_name, 0, esize); ++ memcpy(last->e_name, name, last->e_name_len); ++ if (start + offs + value_len > end) ++ printk("ALERT at %s:%d: 0x%p + %d + %d > 0x%p\n", ++ __FILE__, __LINE__, start, offs, ++ value_len, end); ++ memcpy(start + offs, value, value_len); ++ last = EXT3_XATTR_NEXT(last); ++ *((__u32 *) last) = 0; ++ } ++ ++ ext3_mark_iloc_dirty(handle, inode, &iloc); ++ brelse(bh); ++ ++ return 0; ++} ++ ++/* + * ext3_xattr_set_trans() + * + * Like ext3_xattr_set_handle, but start from an inode. This extended +Index: linux-2.4.21-chaos/fs/ext3/super.c +=================================================================== +--- linux-2.4.21-chaos.orig/fs/ext3/super.c 2003-12-12 17:39:11.000000000 +0300 ++++ linux-2.4.21-chaos/fs/ext3/super.c 2003-12-12 17:39:55.000000000 +0300 +@@ -1354,8 +1354,10 @@ + } else { + sbi->s_inode_size = le16_to_cpu(es->s_inode_size); + sbi->s_first_ino = le32_to_cpu(es->s_first_ino); +- if (sbi->s_inode_size != EXT3_GOOD_OLD_INODE_SIZE) { +- printk (KERN_ERR ++ if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) || ++ (sbi->s_inode_size & (sbi->s_inode_size - 1)) || ++ (sbi->s_inode_size > blocksize)) { ++ printk (KERN_ERR + "EXT3-fs: unsupported inode size: %d\n", + sbi->s_inode_size); + goto failed_mount; +Index: linux-2.4.21-chaos/include/linux/ext3_fs.h +=================================================================== +--- linux-2.4.21-chaos.orig/include/linux/ext3_fs.h 2003-12-12 17:39:10.000000000 +0300 ++++ linux-2.4.21-chaos/include/linux/ext3_fs.h 2003-12-12 17:39:55.000000000 +0300 +@@ -268,6 +268,8 @@ + __u32 m_i_reserved2[2]; + } masix2; + } osd2; /* OS dependent 2 */ ++ __u16 i_extra_isize; ++ __u16 i_pad1; + }; + + #define i_size_high i_dir_acl +Index: linux-2.4.21-chaos/include/linux/ext3_fs_i.h +=================================================================== +--- linux-2.4.21-chaos.orig/include/linux/ext3_fs_i.h 2003-12-05 16:54:33.000000000 +0300 ++++ linux-2.4.21-chaos/include/linux/ext3_fs_i.h 2003-12-12 17:39:55.000000000 +0300 +@@ -76,6 +76,9 @@ + */ + loff_t i_disksize; + ++ /* on-disk additional length */ ++ __u16 i_extra_isize; ++ + /* + * truncate_sem is for serialising ext3_truncate() against + * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.20-rh.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.20-rh.patch deleted file mode 100644 index c5af18c..0000000 --- a/lustre/kernel_patches/patches/ext3-extents-2.4.20-rh.patch +++ /dev/null @@ -1,2807 +0,0 @@ -Index: linux-2.4.20-rh-20.9/fs/ext3/extents.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/fs/ext3/extents.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.20-rh-20.9/fs/ext3/extents.c 2004-11-03 00:31:41.927134640 +0300 -@@ -0,0 +1,2269 @@ -+/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com -+ * Written by Alex Tomas -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program 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 Licens -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- -+ */ -+ -+/* -+ * Extents support for EXT3 -+ * -+ * TODO: -+ * - ext3_ext_walk_space() sould not use ext3_ext_find_extent() -+ * - ext3_ext_calc_credits() could take 'mergable' into account -+ * - ext3*_error() should be used in some situations -+ * - find_goal() [to be tested and improved] -+ * - smart tree reduction -+ * - arch-independence -+ * common on-disk format for big/little-endian arch -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static handle_t *ext3_ext_journal_restart(handle_t *handle, int needed) -+{ -+ int err; -+ -+ if (handle->h_buffer_credits > needed) -+ return handle; -+ if (!ext3_journal_extend(handle, needed)) -+ return handle; -+ err = ext3_journal_restart(handle, needed); -+ -+ return handle; -+} -+ -+static int inline -+ext3_ext_get_access_for_root(handle_t *h, struct ext3_extents_tree *tree) -+{ -+ if (tree->ops->get_write_access) -+ return tree->ops->get_write_access(h,tree->buffer); -+ else -+ return 0; -+} -+ -+static int inline -+ext3_ext_mark_root_dirty(handle_t *h, struct ext3_extents_tree *tree) -+{ -+ if (tree->ops->mark_buffer_dirty) -+ return tree->ops->mark_buffer_dirty(h,tree->buffer); -+ else -+ return 0; -+} -+ -+/* -+ * could return: -+ * - EROFS -+ * - ENOMEM -+ */ -+static int ext3_ext_get_access(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ int err; -+ -+ if (path->p_bh) { -+ /* path points to block */ -+ err = ext3_journal_get_write_access(handle, path->p_bh); -+ } else { -+ /* path points to leaf/index in inode body */ -+ err = ext3_ext_get_access_for_root(handle, tree); -+ } -+ return err; -+} -+ -+/* -+ * could return: -+ * - EROFS -+ * - ENOMEM -+ * - EIO -+ */ -+static int ext3_ext_dirty(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ int err; -+ if (path->p_bh) { -+ /* path points to block */ -+ err =ext3_journal_dirty_metadata(handle, path->p_bh); -+ } else { -+ /* path points to leaf/index in inode body */ -+ err = ext3_ext_mark_root_dirty(handle, tree); -+ } -+ return err; -+} -+ -+static int inline -+ext3_ext_new_block(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, struct ext3_extent *ex, -+ int *err) -+{ -+ int goal, depth, newblock; -+ struct inode *inode; -+ -+ EXT_ASSERT(tree); -+ if (tree->ops->new_block) -+ return tree->ops->new_block(handle, tree, path, ex, err); -+ -+ inode = tree->inode; -+ depth = EXT_DEPTH(tree); -+ if (path && depth > 0) { -+ goal = path[depth-1].p_block; -+ } else { -+ struct ext3_inode_info *ei = EXT3_I(inode); -+ unsigned long bg_start; -+ unsigned long colour; -+ -+ bg_start = (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); -+ colour = (current->pid % 16) * -+ (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); -+ goal = bg_start + colour; -+ } -+ -+ newblock = ext3_new_block(handle, inode, goal, 0, 0, err); -+ return newblock; -+} -+ -+static inline void ext3_ext_tree_changed(struct ext3_extents_tree *tree) -+{ -+ struct ext3_extent_header *neh; -+ neh = EXT_ROOT_HDR(tree); -+ neh->eh_generation++; -+} -+ -+static inline int ext3_ext_space_block(struct ext3_extents_tree *tree) -+{ -+ int size; -+ -+ size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); -+#ifdef AGRESSIVE_TEST -+ size = 6; -+#endif -+ return size; -+} -+ -+static inline int ext3_ext_space_block_idx(struct ext3_extents_tree *tree) -+{ -+ int size; -+ -+ size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); -+#ifdef AGRESSIVE_TEST -+ size = 5; -+#endif -+ return size; -+} -+ -+static inline int ext3_ext_space_root(struct ext3_extents_tree *tree) -+{ -+ int size; -+ -+ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); -+#ifdef AGRESSIVE_TEST -+ size = 3; -+#endif -+ return size; -+} -+ -+static inline int ext3_ext_space_root_idx(struct ext3_extents_tree *tree) -+{ -+ int size; -+ -+ size = (tree->buffer_len - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); -+#ifdef AGRESSIVE_TEST -+ size = 4; -+#endif -+ return size; -+} -+ -+static void ext3_ext_show_path(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+#ifdef EXT_DEBUG -+ int k, l = path->p_depth; -+ -+ ext_debug(tree, "path:"); -+ for (k = 0; k <= l; k++, path++) { -+ if (path->p_idx) { -+ ext_debug(tree, " %d->%d", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); -+ } else if (path->p_ext) { -+ ext_debug(tree, " %d:%d:%d", -+ path->p_ext->ee_block, -+ path->p_ext->ee_len, -+ path->p_ext->ee_start); -+ } else -+ ext_debug(tree, " []"); -+ } -+ ext_debug(tree, "\n"); -+#endif -+} -+ -+static void ext3_ext_show_leaf(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+#ifdef EXT_DEBUG -+ int depth = EXT_DEPTH(tree); -+ struct ext3_extent_header *eh; -+ struct ext3_extent *ex; -+ int i; -+ -+ if (!path) -+ return; -+ -+ eh = path[depth].p_hdr; -+ ex = EXT_FIRST_EXTENT(eh); -+ -+ for (i = 0; i < eh->eh_entries; i++, ex++) { -+ ext_debug(tree, "%d:%d:%d ", -+ ex->ee_block, ex->ee_len, ex->ee_start); -+ } -+ ext_debug(tree, "\n"); -+#endif -+} -+ -+static void ext3_ext_drop_refs(struct ext3_ext_path *path) -+{ -+ int depth = path->p_depth; -+ int i; -+ -+ for (i = 0; i <= depth; i++, path++) -+ if (path->p_bh) { -+ brelse(path->p_bh); -+ path->p_bh = NULL; -+ } -+} -+ -+/* -+ * binary search for closest index by given block -+ */ -+static inline void -+ext3_ext_binsearch_idx(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) -+{ -+ struct ext3_extent_header *eh = path->p_hdr; -+ struct ext3_extent_idx *ix; -+ int l = 0, k, r; -+ -+ EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ EXT_ASSERT(eh->eh_entries <= eh->eh_max); -+ EXT_ASSERT(eh->eh_entries > 0); -+ -+ ext_debug(tree, "binsearch for %d(idx): ", block); -+ -+ path->p_idx = ix = EXT_FIRST_INDEX(eh); -+ -+ r = k = eh->eh_entries; -+ while (k > 1) { -+ k = (r - l) / 2; -+ if (block < ix[l + k].ei_block) -+ r -= k; -+ else -+ l += k; -+ ext_debug(tree, "%d:%d:%d ", k, l, r); -+ } -+ -+ ix += l; -+ path->p_idx = ix; -+ ext_debug(tree, " -> %d->%d ", path->p_idx->ei_block, path->p_idx->ei_leaf); -+ -+ while (l++ < r) { -+ if (block < ix->ei_block) -+ break; -+ path->p_idx = ix++; -+ } -+ ext_debug(tree, " -> %d->%d\n", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); -+ -+#ifdef CHECK_BINSEARCH -+ { -+ struct ext3_extent_idx *chix; -+ -+ chix = ix = EXT_FIRST_INDEX(eh); -+ for (k = 0; k < eh->eh_entries; k++, ix++) { -+ if (k != 0 && ix->ei_block <= ix[-1].ei_block) { -+ printk("k=%d, ix=0x%p, first=0x%p\n", k, -+ ix, EXT_FIRST_INDEX(eh)); -+ printk("%u <= %u\n", -+ ix->ei_block,ix[-1].ei_block); -+ } -+ EXT_ASSERT(k == 0 || ix->ei_block > ix[-1].ei_block); -+ if (block < ix->ei_block) -+ break; -+ chix = ix; -+ } -+ EXT_ASSERT(chix == path->p_idx); -+ } -+#endif -+ -+} -+ -+/* -+ * binary search for closest extent by given block -+ */ -+static inline void -+ext3_ext_binsearch(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) -+{ -+ struct ext3_extent_header *eh = path->p_hdr; -+ struct ext3_extent *ex; -+ int l = 0, k, r; -+ -+ EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ EXT_ASSERT(eh->eh_entries <= eh->eh_max); -+ -+ if (eh->eh_entries == 0) { -+ /* -+ * this leaf is empty yet: -+ * we get such a leaf in split/add case -+ */ -+ return; -+ } -+ -+ ext_debug(tree, "binsearch for %d: ", block); -+ -+ path->p_ext = ex = EXT_FIRST_EXTENT(eh); -+ -+ r = k = eh->eh_entries; -+ while (k > 1) { -+ k = (r - l) / 2; -+ if (block < ex[l + k].ee_block) -+ r -= k; -+ else -+ l += k; -+ ext_debug(tree, "%d:%d:%d ", k, l, r); -+ } -+ -+ ex += l; -+ path->p_ext = ex; -+ ext_debug(tree, " -> %d:%d:%d ", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); -+ -+ while (l++ < r) { -+ if (block < ex->ee_block) -+ break; -+ path->p_ext = ex++; -+ } -+ ext_debug(tree, " -> %d:%d:%d\n", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); -+ -+#ifdef CHECK_BINSEARCH -+ { -+ struct ext3_extent *chex; -+ -+ chex = ex = EXT_FIRST_EXTENT(eh); -+ for (k = 0; k < eh->eh_entries; k++, ex++) { -+ EXT_ASSERT(k == 0 || ex->ee_block > ex[-1].ee_block); -+ if (block < ex->ee_block) -+ break; -+ chex = ex; -+ } -+ EXT_ASSERT(chex == path->p_ext); -+ } -+#endif -+ -+} -+ -+int ext3_extent_tree_init(handle_t *handle, struct ext3_extents_tree *tree) -+{ -+ struct ext3_extent_header *eh; -+ -+ BUG_ON(tree->buffer_len == 0); -+ ext3_ext_get_access_for_root(handle, tree); -+ eh = EXT_ROOT_HDR(tree); -+ eh->eh_depth = 0; -+ eh->eh_entries = 0; -+ eh->eh_magic = EXT3_EXT_MAGIC; -+ eh->eh_max = ext3_ext_space_root(tree); -+ ext3_ext_mark_root_dirty(handle, tree); -+ ext3_ext_invalidate_cache(tree); -+ return 0; -+} -+ -+struct ext3_ext_path * -+ext3_ext_find_extent(struct ext3_extents_tree *tree, int block, -+ struct ext3_ext_path *path) -+{ -+ struct ext3_extent_header *eh; -+ struct buffer_head *bh; -+ int depth, i, ppos = 0; -+ -+ EXT_ASSERT(tree); -+ EXT_ASSERT(tree->inode); -+ EXT_ASSERT(tree->root); -+ -+ eh = EXT_ROOT_HDR(tree); -+ EXT_ASSERT(eh); -+ i = depth = EXT_DEPTH(tree); -+ EXT_ASSERT(eh->eh_max); -+ EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ EXT_ASSERT(i == 0 || eh->eh_entries > 0); -+ -+ /* account possible depth increase */ -+ if (!path) { -+ path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2), -+ GFP_NOFS); -+ if (!path) -+ return ERR_PTR(-ENOMEM); -+ } -+ memset(path, 0, sizeof(struct ext3_ext_path) * (depth + 1)); -+ path[0].p_hdr = eh; -+ -+ /* walk through the tree */ -+ while (i) { -+ ext_debug(tree, "depth %d: num %d, max %d\n", -+ ppos, eh->eh_entries, eh->eh_max); -+ ext3_ext_binsearch_idx(tree, path + ppos, block); -+ path[ppos].p_block = path[ppos].p_idx->ei_leaf; -+ path[ppos].p_depth = i; -+ path[ppos].p_ext = NULL; -+ -+ bh = sb_bread(tree->inode->i_sb, path[ppos].p_block); -+ if (!bh) { -+ ext3_ext_drop_refs(path); -+ kfree(path); -+ return ERR_PTR(-EIO); -+ } -+ eh = EXT_BLOCK_HDR(bh); -+ ppos++; -+ EXT_ASSERT(ppos <= depth); -+ path[ppos].p_bh = bh; -+ path[ppos].p_hdr = eh; -+ i--; -+ } -+ -+ path[ppos].p_depth = i; -+ path[ppos].p_hdr = eh; -+ path[ppos].p_ext = NULL; -+ -+ /* find extent */ -+ ext3_ext_binsearch(tree, path + ppos, block); -+ -+ ext3_ext_show_path(tree, path); -+ -+ return path; -+} -+ -+/* -+ * insert new index [logical;ptr] into the block at cupr -+ * it check where to insert: before curp or after curp -+ */ -+static int ext3_ext_insert_index(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *curp, -+ int logical, int ptr) -+{ -+ struct ext3_extent_idx *ix; -+ int len, err; -+ -+ if ((err = ext3_ext_get_access(handle, tree, curp))) -+ return err; -+ -+ EXT_ASSERT(logical != curp->p_idx->ei_block); -+ len = EXT_MAX_INDEX(curp->p_hdr) - curp->p_idx; -+ if (logical > curp->p_idx->ei_block) { -+ /* insert after */ -+ if (curp->p_idx != EXT_LAST_INDEX(curp->p_hdr)) { -+ len = (len - 1) * sizeof(struct ext3_extent_idx); -+ len = len < 0 ? 0 : len; -+ ext_debug(tree, "insert new index %d after: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ (curp->p_idx + 1), (curp->p_idx + 2)); -+ memmove(curp->p_idx + 2, curp->p_idx + 1, len); -+ } -+ ix = curp->p_idx + 1; -+ } else { -+ /* insert before */ -+ len = len * sizeof(struct ext3_extent_idx); -+ len = len < 0 ? 0 : len; -+ ext_debug(tree, "insert new index %d before: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ curp->p_idx, (curp->p_idx + 1)); -+ memmove(curp->p_idx + 1, curp->p_idx, len); -+ ix = curp->p_idx; -+ } -+ -+ ix->ei_block = logical; -+ ix->ei_leaf = ptr; -+ curp->p_hdr->eh_entries++; -+ -+ EXT_ASSERT(curp->p_hdr->eh_entries <= curp->p_hdr->eh_max); -+ EXT_ASSERT(ix <= EXT_LAST_INDEX(curp->p_hdr)); -+ -+ err = ext3_ext_dirty(handle, tree, curp); -+ ext3_std_error(tree->inode->i_sb, err); -+ -+ return err; -+} -+ -+/* -+ * routine inserts new subtree into the path, using free index entry -+ * at depth 'at: -+ * - allocates all needed blocks (new leaf and all intermediate index blocks) -+ * - makes decision where to split -+ * - moves remaining extens and index entries (right to the split point) -+ * into the newly allocated blocks -+ * - initialize subtree -+ */ -+static int ext3_ext_split(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext, int at) -+{ -+ struct buffer_head *bh = NULL; -+ int depth = EXT_DEPTH(tree); -+ struct ext3_extent_header *neh; -+ struct ext3_extent_idx *fidx; -+ struct ext3_extent *ex; -+ int i = at, k, m, a; -+ unsigned long newblock, oldblock, border; -+ int *ablocks = NULL; /* array of allocated blocks */ -+ int err = 0; -+ -+ /* make decision: where to split? */ -+ /* FIXME: now desicion is simplest: at current extent */ -+ -+ /* if current leaf will be splitted, then we should use -+ * border from split point */ -+ EXT_ASSERT(path[depth].p_ext <= EXT_MAX_EXTENT(path[depth].p_hdr)); -+ if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) { -+ border = path[depth].p_ext[1].ee_block; -+ ext_debug(tree, "leaf will be splitted." -+ " next leaf starts at %d\n", -+ (int)border); -+ } else { -+ border = newext->ee_block; -+ ext_debug(tree, "leaf will be added." -+ " next leaf starts at %d\n", -+ (int)border); -+ } -+ -+ /* -+ * if error occurs, then we break processing -+ * and turn filesystem read-only. so, index won't -+ * be inserted and tree will be in consistent -+ * state. next mount will repair buffers too -+ */ -+ -+ /* -+ * get array to track all allocated blocks -+ * we need this to handle errors and free blocks -+ * upon them -+ */ -+ ablocks = kmalloc(sizeof(unsigned long) * depth, GFP_NOFS); -+ if (!ablocks) -+ return -ENOMEM; -+ memset(ablocks, 0, sizeof(unsigned long) * depth); -+ -+ /* allocate all needed blocks */ -+ ext_debug(tree, "allocate %d blocks for indexes/leaf\n", depth - at); -+ for (a = 0; a < depth - at; a++) { -+ newblock = ext3_ext_new_block(handle, tree, path, newext, &err); -+ if (newblock == 0) -+ goto cleanup; -+ ablocks[a] = newblock; -+ } -+ -+ /* initialize new leaf */ -+ newblock = ablocks[--a]; -+ EXT_ASSERT(newblock); -+ bh = sb_getblk(tree->inode->i_sb, newblock); -+ if (!bh) { -+ err = -EIO; -+ goto cleanup; -+ } -+ lock_buffer(bh); -+ -+ if ((err = ext3_journal_get_create_access(handle, bh))) -+ goto cleanup; -+ -+ neh = EXT_BLOCK_HDR(bh); -+ neh->eh_entries = 0; -+ neh->eh_max = ext3_ext_space_block(tree); -+ neh->eh_magic = EXT3_EXT_MAGIC; -+ neh->eh_depth = 0; -+ ex = EXT_FIRST_EXTENT(neh); -+ -+ /* move remain of path[depth] to the new leaf */ -+ EXT_ASSERT(path[depth].p_hdr->eh_entries == path[depth].p_hdr->eh_max); -+ /* start copy from next extent */ -+ /* TODO: we could do it by single memmove */ -+ m = 0; -+ path[depth].p_ext++; -+ while (path[depth].p_ext <= -+ EXT_MAX_EXTENT(path[depth].p_hdr)) { -+ ext_debug(tree, "move %d:%d:%d in new leaf %lu\n", -+ path[depth].p_ext->ee_block, -+ path[depth].p_ext->ee_start, -+ path[depth].p_ext->ee_len, -+ newblock); -+ memmove(ex++, path[depth].p_ext++, -+ sizeof(struct ext3_extent)); -+ neh->eh_entries++; -+ m++; -+ } -+ mark_buffer_uptodate(bh, 1); -+ unlock_buffer(bh); -+ -+ if ((err = ext3_journal_dirty_metadata(handle, bh))) -+ goto cleanup; -+ brelse(bh); -+ bh = NULL; -+ -+ /* correct old leaf */ -+ if (m) { -+ if ((err = ext3_ext_get_access(handle, tree, path + depth))) -+ goto cleanup; -+ path[depth].p_hdr->eh_entries -= m; -+ if ((err = ext3_ext_dirty(handle, tree, path + depth))) -+ goto cleanup; -+ -+ } -+ -+ /* create intermediate indexes */ -+ k = depth - at - 1; -+ EXT_ASSERT(k >= 0); -+ if (k) -+ ext_debug(tree, "create %d intermediate indices\n", k); -+ /* insert new index into current index block */ -+ /* current depth stored in i var */ -+ i = depth - 1; -+ while (k--) { -+ oldblock = newblock; -+ newblock = ablocks[--a]; -+ bh = sb_getblk(tree->inode->i_sb, newblock); -+ if (!bh) { -+ err = -EIO; -+ goto cleanup; -+ } -+ lock_buffer(bh); -+ -+ if ((err = ext3_journal_get_create_access(handle, bh))) -+ goto cleanup; -+ -+ neh = EXT_BLOCK_HDR(bh); -+ neh->eh_entries = 1; -+ neh->eh_magic = EXT3_EXT_MAGIC; -+ neh->eh_max = ext3_ext_space_block_idx(tree); -+ neh->eh_depth = depth - i; -+ fidx = EXT_FIRST_INDEX(neh); -+ fidx->ei_block = border; -+ fidx->ei_leaf = oldblock; -+ -+ ext_debug(tree, "int.index at %d (block %lu): %lu -> %lu\n", -+ i, newblock, border, oldblock); -+ /* copy indexes */ -+ m = 0; -+ path[i].p_idx++; -+ -+ ext_debug(tree, "cur 0x%p, last 0x%p\n", path[i].p_idx, -+ EXT_MAX_INDEX(path[i].p_hdr)); -+ EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) == -+ EXT_LAST_INDEX(path[i].p_hdr)); -+ while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { -+ ext_debug(tree, "%d: move %d:%d in new index %lu\n", -+ i, path[i].p_idx->ei_block, -+ path[i].p_idx->ei_leaf, newblock); -+ memmove(++fidx, path[i].p_idx++, -+ sizeof(struct ext3_extent_idx)); -+ neh->eh_entries++; -+ EXT_ASSERT(neh->eh_entries <= neh->eh_max); -+ m++; -+ } -+ mark_buffer_uptodate(bh, 1); -+ unlock_buffer(bh); -+ -+ if ((err = ext3_journal_dirty_metadata(handle, bh))) -+ goto cleanup; -+ brelse(bh); -+ bh = NULL; -+ -+ /* correct old index */ -+ if (m) { -+ err = ext3_ext_get_access(handle, tree, path + i); -+ if (err) -+ goto cleanup; -+ path[i].p_hdr->eh_entries -= m; -+ err = ext3_ext_dirty(handle, tree, path + i); -+ if (err) -+ goto cleanup; -+ } -+ -+ i--; -+ } -+ -+ /* insert new index */ -+ if (!err) -+ err = ext3_ext_insert_index(handle, tree, path + at, -+ border, newblock); -+ -+cleanup: -+ if (bh) { -+ if (buffer_locked(bh)) -+ unlock_buffer(bh); -+ brelse(bh); -+ } -+ -+ if (err) { -+ /* free all allocated blocks in error case */ -+ for (i = 0; i < depth; i++) { -+ if (!ablocks[i]) -+ continue; -+ ext3_free_blocks(handle, tree->inode, ablocks[i], 1); -+ } -+ } -+ kfree(ablocks); -+ -+ return err; -+} -+ -+/* -+ * routine implements tree growing procedure: -+ * - allocates new block -+ * - moves top-level data (index block or leaf) into the new block -+ * - initialize new top-level, creating index that points to the -+ * just created block -+ */ -+static int ext3_ext_grow_indepth(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) -+{ -+ struct ext3_ext_path *curp = path; -+ struct ext3_extent_header *neh; -+ struct ext3_extent_idx *fidx; -+ struct buffer_head *bh; -+ unsigned long newblock; -+ int err = 0; -+ -+ newblock = ext3_ext_new_block(handle, tree, path, newext, &err); -+ if (newblock == 0) -+ return err; -+ -+ bh = sb_getblk(tree->inode->i_sb, newblock); -+ if (!bh) { -+ err = -EIO; -+ ext3_std_error(tree->inode->i_sb, err); -+ return err; -+ } -+ lock_buffer(bh); -+ -+ if ((err = ext3_journal_get_create_access(handle, bh))) { -+ unlock_buffer(bh); -+ goto out; -+ } -+ -+ /* move top-level index/leaf into new block */ -+ memmove(bh->b_data, curp->p_hdr, tree->buffer_len); -+ -+ /* set size of new block */ -+ neh = EXT_BLOCK_HDR(bh); -+ /* old root could have indexes or leaves -+ * so calculate eh_max right way */ -+ if (EXT_DEPTH(tree)) -+ neh->eh_max = ext3_ext_space_block_idx(tree); -+ else -+ neh->eh_max = ext3_ext_space_block(tree); -+ neh->eh_magic = EXT3_EXT_MAGIC; -+ mark_buffer_uptodate(bh, 1); -+ unlock_buffer(bh); -+ -+ if ((err = ext3_journal_dirty_metadata(handle, bh))) -+ goto out; -+ -+ /* create index in new top-level index: num,max,pointer */ -+ if ((err = ext3_ext_get_access(handle, tree, curp))) -+ goto out; -+ -+ curp->p_hdr->eh_magic = EXT3_EXT_MAGIC; -+ curp->p_hdr->eh_max = ext3_ext_space_root_idx(tree); -+ curp->p_hdr->eh_entries = 1; -+ curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr); -+ /* FIXME: it works, but actually path[0] can be index */ -+ curp->p_idx->ei_block = EXT_FIRST_EXTENT(path[0].p_hdr)->ee_block; -+ curp->p_idx->ei_leaf = newblock; -+ -+ neh = EXT_ROOT_HDR(tree); -+ fidx = EXT_FIRST_INDEX(neh); -+ ext_debug(tree, "new root: num %d(%d), lblock %d, ptr %d\n", -+ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); -+ -+ neh->eh_depth = path->p_depth + 1; -+ err = ext3_ext_dirty(handle, tree, curp); -+out: -+ brelse(bh); -+ -+ return err; -+} -+ -+/* -+ * routine finds empty index and adds new leaf. if no free index found -+ * then it requests in-depth growing -+ */ -+static int ext3_ext_create_new_leaf(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) -+{ -+ struct ext3_ext_path *curp; -+ int depth, i, err = 0; -+ -+repeat: -+ i = depth = EXT_DEPTH(tree); -+ -+ /* walk up to the tree and look for free index entry */ -+ curp = path + depth; -+ while (i > 0 && !EXT_HAS_FREE_INDEX(curp)) { -+ i--; -+ curp--; -+ } -+ -+ /* we use already allocated block for index block -+ * so, subsequent data blocks should be contigoues */ -+ if (EXT_HAS_FREE_INDEX(curp)) { -+ /* if we found index with free entry, then use that -+ * entry: create all needed subtree and add new leaf */ -+ err = ext3_ext_split(handle, tree, path, newext, i); -+ -+ /* refill path */ -+ ext3_ext_drop_refs(path); -+ path = ext3_ext_find_extent(tree, newext->ee_block, path); -+ if (IS_ERR(path)) -+ err = PTR_ERR(path); -+ } else { -+ /* tree is full, time to grow in depth */ -+ err = ext3_ext_grow_indepth(handle, tree, path, newext); -+ -+ /* refill path */ -+ ext3_ext_drop_refs(path); -+ path = ext3_ext_find_extent(tree, newext->ee_block, path); -+ if (IS_ERR(path)) -+ err = PTR_ERR(path); -+ -+ /* -+ * only first (depth 0 -> 1) produces free space -+ * in all other cases we have to split growed tree -+ */ -+ depth = EXT_DEPTH(tree); -+ if (path[depth].p_hdr->eh_entries == path[depth].p_hdr->eh_max) { -+ /* now we need split */ -+ goto repeat; -+ } -+ } -+ -+ if (err) -+ return err; -+ -+ return 0; -+} -+ -+/* -+ * returns allocated block in subsequent extent or EXT_MAX_BLOCK -+ * NOTE: it consider block number from index entry as -+ * allocated block. thus, index entries have to be consistent -+ * with leafs -+ */ -+static unsigned long -+ext3_ext_next_allocated_block(struct ext3_ext_path *path) -+{ -+ int depth; -+ -+ EXT_ASSERT(path != NULL); -+ depth = path->p_depth; -+ -+ if (depth == 0 && path->p_ext == NULL) -+ return EXT_MAX_BLOCK; -+ -+ /* FIXME: what if index isn't full ?! */ -+ while (depth >= 0) { -+ if (depth == path->p_depth) { -+ /* leaf */ -+ if (path[depth].p_ext != -+ EXT_LAST_EXTENT(path[depth].p_hdr)) -+ return path[depth].p_ext[1].ee_block; -+ } else { -+ /* index */ -+ if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) -+ return path[depth].p_idx[1].ei_block; -+ } -+ depth--; -+ } -+ -+ return EXT_MAX_BLOCK; -+} -+ -+/* -+ * returns first allocated block from next leaf or EXT_MAX_BLOCK -+ */ -+static unsigned ext3_ext_next_leaf_block(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ int depth; -+ -+ EXT_ASSERT(path != NULL); -+ depth = path->p_depth; -+ -+ /* zero-tree has no leaf blocks at all */ -+ if (depth == 0) -+ return EXT_MAX_BLOCK; -+ -+ /* go to index block */ -+ depth--; -+ -+ while (depth >= 0) { -+ if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) -+ return path[depth].p_idx[1].ei_block; -+ depth--; -+ } -+ -+ return EXT_MAX_BLOCK; -+} -+ -+/* -+ * if leaf gets modified and modified extent is first in the leaf -+ * then we have to correct all indexes above -+ * TODO: do we need to correct tree in all cases? -+ */ -+int ext3_ext_correct_indexes(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ struct ext3_extent_header *eh; -+ int depth = EXT_DEPTH(tree); -+ struct ext3_extent *ex; -+ unsigned long border; -+ int k, err = 0; -+ -+ eh = path[depth].p_hdr; -+ ex = path[depth].p_ext; -+ EXT_ASSERT(ex); -+ EXT_ASSERT(eh); -+ -+ if (depth == 0) { -+ /* there is no tree at all */ -+ return 0; -+ } -+ -+ if (ex != EXT_FIRST_EXTENT(eh)) { -+ /* we correct tree if first leaf got modified only */ -+ return 0; -+ } -+ -+ /* -+ * TODO: we need correction if border is smaller then current one -+ */ -+ k = depth - 1; -+ border = path[depth].p_ext->ee_block; -+ if ((err = ext3_ext_get_access(handle, tree, path + k))) -+ return err; -+ path[k].p_idx->ei_block = border; -+ if ((err = ext3_ext_dirty(handle, tree, path + k))) -+ return err; -+ -+ while (k--) { -+ /* change all left-side indexes */ -+ if (path[k+1].p_idx != EXT_FIRST_INDEX(path[k+1].p_hdr)) -+ break; -+ if ((err = ext3_ext_get_access(handle, tree, path + k))) -+ break; -+ path[k].p_idx->ei_block = border; -+ if ((err = ext3_ext_dirty(handle, tree, path + k))) -+ break; -+ } -+ -+ return err; -+} -+ -+static int inline -+ext3_can_extents_be_merged(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex1, -+ struct ext3_extent *ex2) -+{ -+ if (ex1->ee_block + ex1->ee_len != ex2->ee_block) -+ return 0; -+ -+#ifdef AGRESSIVE_TEST -+ if (ex1->ee_len >= 4) -+ return 0; -+#endif -+ -+ if (!tree->ops->mergable) -+ return 1; -+ -+ return tree->ops->mergable(ex1, ex2); -+} -+ -+/* -+ * this routine tries to merge requsted extent into the existing -+ * extent or inserts requested extent as new one into the tree, -+ * creating new leaf in no-space case -+ */ -+int ext3_ext_insert_extent(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) -+{ -+ struct ext3_extent_header * eh; -+ struct ext3_extent *ex, *fex; -+ struct ext3_extent *nearex; /* nearest extent */ -+ struct ext3_ext_path *npath = NULL; -+ int depth, len, err, next; -+ -+ EXT_ASSERT(newext->ee_len > 0); -+ EXT_ASSERT(newext->ee_len < EXT_CACHE_MARK); -+ depth = EXT_DEPTH(tree); -+ ex = path[depth].p_ext; -+ EXT_ASSERT(path[depth].p_hdr); -+ -+ /* try to insert block into found extent and return */ -+ if (ex && ext3_can_extents_be_merged(tree, ex, newext)) { -+ ext_debug(tree, "append %d block to %d:%d (from %d)\n", -+ newext->ee_len, ex->ee_block, ex->ee_len, -+ ex->ee_start); -+ if ((err = ext3_ext_get_access(handle, tree, path + depth))) -+ return err; -+ ex->ee_len += newext->ee_len; -+ eh = path[depth].p_hdr; -+ nearex = ex; -+ goto merge; -+ } -+ -+repeat: -+ depth = EXT_DEPTH(tree); -+ eh = path[depth].p_hdr; -+ if (eh->eh_entries < eh->eh_max) -+ goto has_space; -+ -+ /* probably next leaf has space for us? */ -+ fex = EXT_LAST_EXTENT(eh); -+ next = ext3_ext_next_leaf_block(tree, path); -+ if (newext->ee_block > fex->ee_block && next != EXT_MAX_BLOCK) { -+ ext_debug(tree, "next leaf block - %d\n", next); -+ EXT_ASSERT(!npath); -+ npath = ext3_ext_find_extent(tree, next, NULL); -+ if (IS_ERR(npath)) -+ return PTR_ERR(npath); -+ EXT_ASSERT(npath->p_depth == path->p_depth); -+ eh = npath[depth].p_hdr; -+ if (eh->eh_entries < eh->eh_max) { -+ ext_debug(tree, "next leaf isnt full(%d)\n", -+ eh->eh_entries); -+ path = npath; -+ goto repeat; -+ } -+ ext_debug(tree, "next leaf hasno free space(%d,%d)\n", -+ eh->eh_entries, eh->eh_max); -+ } -+ -+ /* -+ * there is no free space in found leaf -+ * we're gonna add new leaf in the tree -+ */ -+ err = ext3_ext_create_new_leaf(handle, tree, path, newext); -+ if (err) -+ goto cleanup; -+ depth = EXT_DEPTH(tree); -+ eh = path[depth].p_hdr; -+ -+has_space: -+ nearex = path[depth].p_ext; -+ -+ if ((err = ext3_ext_get_access(handle, tree, path + depth))) -+ goto cleanup; -+ -+ if (!nearex) { -+ /* there is no extent in this leaf, create first one */ -+ ext_debug(tree, "first extent in the leaf: %d:%d:%d\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len); -+ path[depth].p_ext = EXT_FIRST_EXTENT(eh); -+ } else if (newext->ee_block > nearex->ee_block) { -+ EXT_ASSERT(newext->ee_block != nearex->ee_block); -+ if (nearex != EXT_LAST_EXTENT(eh)) { -+ len = EXT_MAX_EXTENT(eh) - nearex; -+ len = (len - 1) * sizeof(struct ext3_extent); -+ len = len < 0 ? 0 : len; -+ ext_debug(tree, "insert %d:%d:%d after: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); -+ memmove(nearex + 2, nearex + 1, len); -+ } -+ path[depth].p_ext = nearex + 1; -+ } else { -+ EXT_ASSERT(newext->ee_block != nearex->ee_block); -+ len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent); -+ len = len < 0 ? 0 : len; -+ ext_debug(tree, "insert %d:%d:%d before: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); -+ memmove(nearex + 1, nearex, len); -+ path[depth].p_ext = nearex; -+ } -+ -+ eh->eh_entries++; -+ nearex = path[depth].p_ext; -+ nearex->ee_block = newext->ee_block; -+ nearex->ee_start = newext->ee_start; -+ nearex->ee_len = newext->ee_len; -+ /* FIXME: support for large fs */ -+ nearex->ee_start_hi = 0; -+ -+merge: -+ /* try to merge extents to the right */ -+ while (nearex < EXT_LAST_EXTENT(eh)) { -+ if (!ext3_can_extents_be_merged(tree, nearex, nearex + 1)) -+ break; -+ /* merge with next extent! */ -+ nearex->ee_len += nearex[1].ee_len; -+ if (nearex + 1 < EXT_LAST_EXTENT(eh)) { -+ len = (EXT_LAST_EXTENT(eh) - nearex - 1) -+ * sizeof(struct ext3_extent); -+ memmove(nearex + 1, nearex + 2, len); -+ } -+ eh->eh_entries--; -+ EXT_ASSERT(eh->eh_entries > 0); -+ } -+ -+ /* try to merge extents to the left */ -+ -+ /* time to correct all indexes above */ -+ err = ext3_ext_correct_indexes(handle, tree, path); -+ if (err) -+ goto cleanup; -+ -+ err = ext3_ext_dirty(handle, tree, path + depth); -+ -+cleanup: -+ if (npath) { -+ ext3_ext_drop_refs(npath); -+ kfree(npath); -+ } -+ ext3_ext_tree_changed(tree); -+ ext3_ext_invalidate_cache(tree); -+ return err; -+} -+ -+int ext3_ext_walk_space(struct ext3_extents_tree *tree, unsigned long block, -+ unsigned long num, ext_prepare_callback func) -+{ -+ struct ext3_ext_path *path = NULL; -+ struct ext3_extent *ex, cbex; -+ unsigned long next, start = 0, end = 0; -+ unsigned long last = block + num; -+ int depth, exists, err = 0; -+ -+ EXT_ASSERT(tree); -+ EXT_ASSERT(func); -+ EXT_ASSERT(tree->inode); -+ EXT_ASSERT(tree->root); -+ -+ while (block < last && block != EXT_MAX_BLOCK) { -+ num = last - block; -+ /* find extent for this block */ -+ path = ext3_ext_find_extent(tree, block, path); -+ if (IS_ERR(path)) { -+ err = PTR_ERR(path); -+ path = NULL; -+ break; -+ } -+ -+ depth = EXT_DEPTH(tree); -+ EXT_ASSERT(path[depth].p_hdr); -+ ex = path[depth].p_ext; -+ next = ext3_ext_next_allocated_block(path); -+ -+ exists = 0; -+ if (!ex) { -+ /* there is no extent yet, so try to allocate -+ * all requested space */ -+ start = block; -+ end = block + num; -+ } else if (ex->ee_block > block) { -+ /* need to allocate space before found extent */ -+ start = block; -+ end = ex->ee_block; -+ if (block + num < end) -+ end = block + num; -+ } else if (block >= ex->ee_block + ex->ee_len) { -+ /* need to allocate space after found extent */ -+ start = block; -+ end = block + num; -+ if (end >= next) -+ end = next; -+ } else if (block >= ex->ee_block) { -+ /* -+ * some part of requested space is covered -+ * by found extent -+ */ -+ start = block; -+ end = ex->ee_block + ex->ee_len; -+ if (block + num < end) -+ end = block + num; -+ exists = 1; -+ } else { -+ BUG(); -+ } -+ EXT_ASSERT(end > start); -+ -+ if (!exists) { -+ cbex.ee_block = start; -+ cbex.ee_len = end - start; -+ cbex.ee_start = 0; -+ } else -+ cbex = *ex; -+ -+ EXT_ASSERT(path[depth].p_hdr); -+ err = func(tree, path, &cbex, exists); -+ ext3_ext_drop_refs(path); -+ -+ if (err < 0) -+ break; -+ if (err == EXT_REPEAT) -+ continue; -+ else if (err == EXT_BREAK) { -+ err = 0; -+ break; -+ } -+ -+ if (EXT_DEPTH(tree) != depth) { -+ /* depth was changed. we have to realloc path */ -+ kfree(path); -+ path = NULL; -+ } -+ -+ block = cbex.ee_block + cbex.ee_len; -+ } -+ -+ if (path) { -+ ext3_ext_drop_refs(path); -+ kfree(path); -+ } -+ -+ return err; -+} -+ -+static inline void -+ext3_ext_put_in_cache(struct ext3_extents_tree *tree, __u32 block, -+ __u32 len, __u32 start, int type) -+{ -+ EXT_ASSERT(len > 0); -+ if (tree->cex) { -+ tree->cex->ec_type = type; -+ tree->cex->ec_block = block; -+ tree->cex->ec_len = len; -+ tree->cex->ec_start = start; -+ } -+} -+ -+/* -+ * this routine calculate boundaries of the gap requested block fits into -+ * and cache this gap -+ */ -+static inline void -+ext3_ext_put_gap_in_cache(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ unsigned long block) -+{ -+ int depth = EXT_DEPTH(tree); -+ unsigned long lblock, len; -+ struct ext3_extent *ex; -+ -+ if (!tree->cex) -+ return; -+ -+ ex = path[depth].p_ext; -+ if (ex == NULL) { -+ /* there is no extent yet, so gap is [0;-] */ -+ lblock = 0; -+ len = EXT_MAX_BLOCK; -+ ext_debug(tree, "cache gap(whole file):"); -+ } else if (block < ex->ee_block) { -+ lblock = block; -+ len = ex->ee_block - block; -+ ext_debug(tree, "cache gap(before): %lu [%lu:%lu]", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len); -+ } else if (block >= ex->ee_block + ex->ee_len) { -+ lblock = ex->ee_block + ex->ee_len; -+ len = ext3_ext_next_allocated_block(path); -+ ext_debug(tree, "cache gap(after): [%lu:%lu] %lu", -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) block); -+ EXT_ASSERT(len > lblock); -+ len = len - lblock; -+ } else { -+ lblock = len = 0; -+ BUG(); -+ } -+ -+ ext_debug(tree, " -> %lu:%lu\n", (unsigned long) lblock, len); -+ ext3_ext_put_in_cache(tree, lblock, len, 0, EXT3_EXT_CACHE_GAP); -+} -+ -+static inline int -+ext3_ext_in_cache(struct ext3_extents_tree *tree, unsigned long block, -+ struct ext3_extent *ex) -+{ -+ struct ext3_ext_cache *cex = tree->cex; -+ -+ /* is there cache storage at all? */ -+ if (!cex) -+ return EXT3_EXT_CACHE_NO; -+ -+ /* has cache valid data? */ -+ if (cex->ec_type == EXT3_EXT_CACHE_NO) -+ return EXT3_EXT_CACHE_NO; -+ -+ EXT_ASSERT(cex->ec_type == EXT3_EXT_CACHE_GAP || -+ cex->ec_type == EXT3_EXT_CACHE_EXTENT); -+ if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) { -+ ex->ee_block = cex->ec_block; -+ ex->ee_start = cex->ec_start; -+ ex->ee_len = cex->ec_len; -+ ext_debug(tree, "%lu cached by %lu:%lu:%lu\n", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) ex->ee_start); -+ return cex->ec_type; -+ } -+ -+ /* not in cache */ -+ return EXT3_EXT_CACHE_NO; -+} -+ -+/* -+ * routine removes index from the index block -+ * it's used in truncate case only. thus all requests are for -+ * last index in the block only -+ */ -+int ext3_ext_rm_idx(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ struct buffer_head *bh; -+ int err; -+ -+ /* free index block */ -+ path--; -+ EXT_ASSERT(path->p_hdr->eh_entries); -+ if ((err = ext3_ext_get_access(handle, tree, path))) -+ return err; -+ path->p_hdr->eh_entries--; -+ if ((err = ext3_ext_dirty(handle, tree, path))) -+ return err; -+ ext_debug(tree, "index is empty, remove it, free block %d\n", -+ path->p_idx->ei_leaf); -+ bh = sb_get_hash_table(tree->inode->i_sb, path->p_idx->ei_leaf); -+ ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf); -+ ext3_free_blocks(handle, tree->inode, path->p_idx->ei_leaf, 1); -+ return err; -+} -+ -+int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ int depth = EXT_DEPTH(tree); -+ int needed; -+ -+ if (path) { -+ /* probably there is space in leaf? */ -+ if (path[depth].p_hdr->eh_entries < path[depth].p_hdr->eh_max) -+ return 1; -+ } -+ -+ /* -+ * the worste case we're expecting is creation of the -+ * new root (growing in depth) with index splitting -+ * for splitting we have to consider depth + 1 because -+ * previous growing could increase it -+ */ -+ depth = depth + 1; -+ -+ /* -+ * growing in depth: -+ * block allocation + new root + old root -+ */ -+ needed = EXT3_ALLOC_NEEDED + 2; -+ -+ /* index split. we may need: -+ * allocate intermediate indexes and new leaf -+ * change two blocks at each level, but root -+ * modify root block (inode) -+ */ -+ needed += (depth * EXT3_ALLOC_NEEDED) + (2 * depth) + 1; -+ -+ return needed; -+} -+ -+static int -+ext3_ext_split_for_rm(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) -+{ -+ struct ext3_extent *ex, tex; -+ struct ext3_ext_path *npath; -+ int depth, creds, err; -+ -+ depth = EXT_DEPTH(tree); -+ ex = path[depth].p_ext; -+ EXT_ASSERT(ex); -+ EXT_ASSERT(end < ex->ee_block + ex->ee_len - 1); -+ EXT_ASSERT(ex->ee_block < start); -+ -+ /* calculate tail extent */ -+ tex.ee_block = end + 1; -+ EXT_ASSERT(tex.ee_block < ex->ee_block + ex->ee_len); -+ tex.ee_len = ex->ee_block + ex->ee_len - tex.ee_block; -+ -+ creds = ext3_ext_calc_credits_for_insert(tree, path); -+ handle = ext3_ext_journal_restart(handle, creds); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ -+ /* calculate head extent. use primary extent */ -+ err = ext3_ext_get_access(handle, tree, path + depth); -+ if (err) -+ return err; -+ ex->ee_len = start - ex->ee_block; -+ err = ext3_ext_dirty(handle, tree, path + depth); -+ if (err) -+ return err; -+ -+ /* FIXME: some callback to free underlying resource -+ * and correct ee_start? */ -+ ext_debug(tree, "split extent: head %u:%u, tail %u:%u\n", -+ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); -+ -+ npath = ext3_ext_find_extent(tree, ex->ee_block, NULL); -+ if (IS_ERR(npath)) -+ return PTR_ERR(npath); -+ depth = EXT_DEPTH(tree); -+ EXT_ASSERT(npath[depth].p_ext->ee_block == ex->ee_block); -+ EXT_ASSERT(npath[depth].p_ext->ee_len == ex->ee_len); -+ -+ err = ext3_ext_insert_extent(handle, tree, npath, &tex); -+ ext3_ext_drop_refs(npath); -+ kfree(npath); -+ -+ return err; -+ -+} -+ -+static int -+ext3_ext_rm_leaf(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) -+{ -+ struct ext3_extent *ex, *fu = NULL, *lu, *le; -+ int err = 0, correct_index = 0; -+ int depth = EXT_DEPTH(tree), credits; -+ struct ext3_extent_header *eh; -+ unsigned a, b, block, num; -+ -+ ext_debug(tree, "remove [%lu:%lu] in leaf\n", start, end); -+ if (!path[depth].p_hdr) -+ path[depth].p_hdr = EXT_BLOCK_HDR(path[depth].p_bh); -+ eh = path[depth].p_hdr; -+ EXT_ASSERT(eh); -+ EXT_ASSERT(eh->eh_entries <= eh->eh_max); -+ EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ -+ /* find where to start removing */ -+ le = ex = EXT_LAST_EXTENT(eh); -+ while (ex != EXT_FIRST_EXTENT(eh)) { -+ if (ex->ee_block <= end) -+ break; -+ ex--; -+ } -+ -+ if (start > ex->ee_block && end < ex->ee_block + ex->ee_len - 1) { -+ /* removal of internal part of the extent requested -+ * tail and head must be placed in different extent -+ * so, we have to insert one more extent */ -+ path[depth].p_ext = ex; -+ return ext3_ext_split_for_rm(handle, tree, path, start, end); -+ } -+ -+ lu = ex; -+ while (ex >= EXT_FIRST_EXTENT(eh) && -+ ex->ee_block + ex->ee_len > start) { -+ ext_debug(tree, "remove ext %u:%u\n", ex->ee_block, ex->ee_len); -+ path[depth].p_ext = ex; -+ -+ a = ex->ee_block > start ? ex->ee_block : start; -+ b = ex->ee_block + ex->ee_len - 1 < end ? -+ ex->ee_block + ex->ee_len - 1 : end; -+ -+ ext_debug(tree, " border %u:%u\n", a, b); -+ -+ if (a != ex->ee_block && b != ex->ee_block + ex->ee_len - 1) { -+ block = 0; -+ num = 0; -+ BUG(); -+ } else if (a != ex->ee_block) { -+ /* remove tail of the extent */ -+ block = ex->ee_block; -+ num = a - block; -+ } else if (b != ex->ee_block + ex->ee_len - 1) { -+ /* remove head of the extent */ -+ block = a; -+ num = b - a; -+ } else { -+ /* remove whole extent: excelent! */ -+ block = ex->ee_block; -+ num = 0; -+ EXT_ASSERT(a == ex->ee_block && -+ b == ex->ee_block + ex->ee_len - 1); -+ } -+ -+ if (ex == EXT_FIRST_EXTENT(eh)) -+ correct_index = 1; -+ -+ credits = 1; -+ if (correct_index) -+ credits += (EXT_DEPTH(tree) * EXT3_ALLOC_NEEDED) + 1; -+ if (tree->ops->remove_extent_credits) -+ credits+=tree->ops->remove_extent_credits(tree,ex,a,b); -+ -+ handle = ext3_ext_journal_restart(handle, credits); -+ if (IS_ERR(handle)) { -+ err = PTR_ERR(handle); -+ goto out; -+ } -+ -+ err = ext3_ext_get_access(handle, tree, path + depth); -+ if (err) -+ goto out; -+ -+ if (tree->ops->remove_extent) -+ err = tree->ops->remove_extent(tree, ex, a, b); -+ if (err) -+ goto out; -+ -+ if (num == 0) { -+ /* this extent is removed entirely mark slot unused */ -+ ex->ee_start = 0; -+ eh->eh_entries--; -+ fu = ex; -+ } -+ -+ ex->ee_block = block; -+ ex->ee_len = num; -+ -+ err = ext3_ext_dirty(handle, tree, path + depth); -+ if (err) -+ goto out; -+ -+ ext_debug(tree, "new extent: %u:%u:%u\n", -+ ex->ee_block, ex->ee_len, ex->ee_start); -+ ex--; -+ } -+ -+ if (fu) { -+ /* reuse unused slots */ -+ while (lu < le) { -+ if (lu->ee_start) { -+ *fu = *lu; -+ lu->ee_start = 0; -+ fu++; -+ } -+ lu++; -+ } -+ } -+ -+ if (correct_index && eh->eh_entries) -+ err = ext3_ext_correct_indexes(handle, tree, path); -+ -+ /* if this leaf is free, then we should -+ * remove it from index block above */ -+ if (err == 0 && eh->eh_entries == 0 && path[depth].p_bh != NULL) -+ err = ext3_ext_rm_idx(handle, tree, path + depth); -+ -+out: -+ return err; -+} -+ -+ -+static struct ext3_extent_idx * -+ext3_ext_last_covered(struct ext3_extent_header *hdr, unsigned long block) -+{ -+ struct ext3_extent_idx *ix; -+ -+ ix = EXT_LAST_INDEX(hdr); -+ while (ix != EXT_FIRST_INDEX(hdr)) { -+ if (ix->ei_block <= block) -+ break; -+ ix--; -+ } -+ return ix; -+} -+ -+/* -+ * returns 1 if current index have to be freed (even partial) -+ */ -+static int inline -+ext3_ext_more_to_rm(struct ext3_ext_path *path) -+{ -+ EXT_ASSERT(path->p_idx); -+ -+ if (path->p_idx < EXT_FIRST_INDEX(path->p_hdr)) -+ return 0; -+ -+ /* -+ * if truncate on deeper level happened it it wasn't partial -+ * so we have to consider current index for truncation -+ */ -+ if (path->p_hdr->eh_entries == path->p_block) -+ return 0; -+ return 1; -+} -+ -+int ext3_ext_remove_space(struct ext3_extents_tree *tree, -+ unsigned long start, unsigned long end) -+{ -+ struct inode *inode = tree->inode; -+ struct super_block *sb = inode->i_sb; -+ int depth = EXT_DEPTH(tree); -+ struct ext3_ext_path *path; -+ handle_t *handle; -+ int i = 0, err = 0; -+ -+ ext_debug(tree, "space to be removed: %lu:%lu\n", start, end); -+ -+ /* probably first extent we're gonna free will be last in block */ -+ handle = ext3_journal_start(inode, depth + 1); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ -+ ext3_ext_invalidate_cache(tree); -+ -+ /* -+ * we start scanning from right side freeing all the blocks -+ * after i_size and walking into the deep -+ */ -+ path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL); -+ if (IS_ERR(path)) { -+ ext3_error(sb, "ext3_ext_remove_space", -+ "Can't allocate path array"); -+ ext3_journal_stop(handle, inode); -+ return -ENOMEM; -+ } -+ memset(path, 0, sizeof(struct ext3_ext_path) * (depth + 1)); -+ path[i].p_hdr = EXT_ROOT_HDR(tree); -+ -+ while (i >= 0 && err == 0) { -+ if (i == depth) { -+ /* this is leaf block */ -+ err = ext3_ext_rm_leaf(handle, tree, path, start, end); -+ /* root level have p_bh == NULL, brelse() eats this */ -+ brelse(path[i].p_bh); -+ i--; -+ continue; -+ } -+ -+ /* this is index block */ -+ if (!path[i].p_hdr) { -+ ext_debug(tree, "initialize header\n"); -+ path[i].p_hdr = EXT_BLOCK_HDR(path[i].p_bh); -+ } -+ -+ EXT_ASSERT(path[i].p_hdr->eh_entries <= path[i].p_hdr->eh_max); -+ EXT_ASSERT(path[i].p_hdr->eh_magic == EXT3_EXT_MAGIC); -+ -+ if (!path[i].p_idx) { -+ /* this level hasn't touched yet */ -+ path[i].p_idx = -+ ext3_ext_last_covered(path[i].p_hdr, end); -+ path[i].p_block = path[i].p_hdr->eh_entries + 1; -+ ext_debug(tree, "init index ptr: hdr 0x%p, num %d\n", -+ path[i].p_hdr, path[i].p_hdr->eh_entries); -+ } else { -+ /* we've already was here, see at next index */ -+ path[i].p_idx--; -+ } -+ -+ ext_debug(tree, "level %d - index, first 0x%p, cur 0x%p\n", -+ i, EXT_FIRST_INDEX(path[i].p_hdr), -+ path[i].p_idx); -+ if (ext3_ext_more_to_rm(path + i)) { -+ /* go to the next level */ -+ ext_debug(tree, "move to level %d (block %d)\n", -+ i + 1, path[i].p_idx->ei_leaf); -+ memset(path + i + 1, 0, sizeof(*path)); -+ path[i+1].p_bh = sb_bread(sb, path[i].p_idx->ei_leaf); -+ if (!path[i+1].p_bh) { -+ /* should we reset i_size? */ -+ err = -EIO; -+ break; -+ } -+ /* put actual number of indexes to know is this -+ * number got changed at the next iteration */ -+ path[i].p_block = path[i].p_hdr->eh_entries; -+ i++; -+ } else { -+ /* we finish processing this index, go up */ -+ if (path[i].p_hdr->eh_entries == 0 && i > 0) { -+ /* index is empty, remove it -+ * handle must be already prepared by the -+ * truncatei_leaf() */ -+ err = ext3_ext_rm_idx(handle, tree, path + i); -+ } -+ /* root level have p_bh == NULL, brelse() eats this */ -+ brelse(path[i].p_bh); -+ i--; -+ ext_debug(tree, "return to level %d\n", i); -+ } -+ } -+ -+ /* TODO: flexible tree reduction should be here */ -+ if (path->p_hdr->eh_entries == 0) { -+ /* -+ * truncate to zero freed all the tree -+ * so, we need to correct eh_depth -+ */ -+ err = ext3_ext_get_access(handle, tree, path); -+ if (err == 0) { -+ EXT_ROOT_HDR(tree)->eh_depth = 0; -+ EXT_ROOT_HDR(tree)->eh_max = ext3_ext_space_root(tree); -+ err = ext3_ext_dirty(handle, tree, path); -+ } -+ } -+ ext3_ext_tree_changed(tree); -+ -+ kfree(path); -+ ext3_journal_stop(handle, inode); -+ -+ return err; -+} -+ -+/* -+ * called at mount time -+ */ -+void ext3_ext_init(struct super_block *sb) -+{ -+ /* -+ * possible initialization would be here -+ */ -+ -+ if (test_opt(sb, EXTENTS)) { -+ printk("EXT3-fs: file extents enabled"); -+#ifdef AGRESSIVE_TEST -+ printk(", agressive tests"); -+#endif -+#ifdef CHECK_BINSEARCH -+ printk(", check binsearch"); -+#endif -+ printk("\n"); -+ } -+} -+ -+/* -+ * called at umount time -+ */ -+void ext3_ext_release(struct super_block *sb) -+{ -+} -+ -+/************************************************************************ -+ * VFS related routines -+ ************************************************************************/ -+ -+static int ext3_get_inode_write_access(handle_t *handle, void *buffer) -+{ -+ /* we use in-core data, not bh */ -+ return 0; -+} -+ -+static int ext3_mark_buffer_dirty(handle_t *handle, void *buffer) -+{ -+ struct inode *inode = buffer; -+ return ext3_mark_inode_dirty(handle, inode); -+} -+ -+static int ext3_ext_mergable(struct ext3_extent *ex1, -+ struct ext3_extent *ex2) -+{ -+ /* FIXME: support for large fs */ -+ if (ex1->ee_start + ex1->ee_len == ex2->ee_start) -+ return 1; -+ return 0; -+} -+ -+static int -+ext3_remove_blocks_credits(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) -+{ -+ int needed; -+ -+ /* at present, extent can't cross block group */; -+ needed = 4; /* bitmap + group desc + sb + inode */ -+ -+#ifdef CONFIG_QUOTA -+ needed += 2 * EXT3_SINGLEDATA_TRANS_BLOCKS; -+#endif -+ return needed; -+} -+ -+static int -+ext3_remove_blocks(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) -+{ -+ int needed = ext3_remove_blocks_credits(tree, ex, from, to); -+ handle_t *handle = ext3_journal_start(tree->inode, needed); -+ struct buffer_head *bh; -+ int i; -+ -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ if (from >= ex->ee_block && to == ex->ee_block + ex->ee_len - 1) { -+ /* tail removal */ -+ unsigned long num, start; -+ num = ex->ee_block + ex->ee_len - from; -+ start = ex->ee_start + ex->ee_len - num; -+ ext_debug(tree, "free last %lu blocks starting %lu\n", -+ num, start); -+ for (i = 0; i < num; i++) { -+ bh = sb_get_hash_table(tree->inode->i_sb, start + i); -+ ext3_forget(handle, 0, tree->inode, bh, start + i); -+ } -+ ext3_free_blocks(handle, tree->inode, start, num); -+ } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { -+ printk("strange request: removal %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); -+ } else { -+ printk("strange request: removal(2) %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); -+ } -+ ext3_journal_stop(handle, tree->inode); -+ return 0; -+} -+ -+int ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path, -+ unsigned long block) -+{ -+ struct ext3_inode_info *ei = EXT3_I(inode); -+ unsigned long bg_start; -+ unsigned long colour; -+ int depth; -+ -+ if (path) { -+ struct ext3_extent *ex; -+ depth = path->p_depth; -+ -+ /* try to predict block placement */ -+ if ((ex = path[depth].p_ext)) -+ return ex->ee_start + (block - ex->ee_block); -+ -+ /* it looks index is empty -+ * try to find starting from index itself */ -+ if (path[depth].p_bh) -+ return path[depth].p_bh->b_blocknr; -+ } -+ -+ /* OK. use inode's group */ -+ bg_start = (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); -+ colour = (current->pid % 16) * -+ (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); -+ return bg_start + colour + block; -+} -+ -+static int ext3_new_block_cb(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int *err) -+{ -+ struct inode *inode = tree->inode; -+ int newblock, goal; -+ -+ EXT_ASSERT(path); -+ EXT_ASSERT(ex); -+ EXT_ASSERT(ex->ee_start); -+ EXT_ASSERT(ex->ee_len); -+ -+ /* reuse block from the extent to order data/metadata */ -+ newblock = ex->ee_start++; -+ ex->ee_len--; -+ if (ex->ee_len == 0) { -+ ex->ee_len = 1; -+ /* allocate new block for the extent */ -+ goal = ext3_ext_find_goal(inode, path, ex->ee_block); -+ ex->ee_start = ext3_new_block(handle, inode, goal, 0, 0, err); -+ if (ex->ee_start == 0) { -+ /* error occured: restore old extent */ -+ ex->ee_start = newblock; -+ return 0; -+ } -+ } -+ return newblock; -+} -+ -+static struct ext3_extents_helpers ext3_blockmap_helpers = { -+ .get_write_access = ext3_get_inode_write_access, -+ .mark_buffer_dirty = ext3_mark_buffer_dirty, -+ .mergable = ext3_ext_mergable, -+ .new_block = ext3_new_block_cb, -+ .remove_extent = ext3_remove_blocks, -+ .remove_extent_credits = ext3_remove_blocks_credits, -+}; -+ -+void ext3_init_tree_desc(struct ext3_extents_tree *tree, -+ struct inode *inode) -+{ -+ tree->inode = inode; -+ tree->root = (void *) EXT3_I(inode)->i_data; -+ tree->buffer = (void *) inode; -+ tree->buffer_len = sizeof(EXT3_I(inode)->i_data); -+ tree->cex = (struct ext3_ext_cache *) &EXT3_I(inode)->i_cached_extent; -+ tree->ops = &ext3_blockmap_helpers; -+} -+ -+int ext3_ext_get_block(handle_t *handle, struct inode *inode, -+ long iblock, struct buffer_head *bh_result, int create) -+{ -+ struct ext3_ext_path *path = NULL; -+ struct ext3_extent newex; -+ struct ext3_extent *ex; -+ int goal, newblock, err = 0, depth; -+ struct ext3_extents_tree tree; -+ -+ clear_bit(BH_New, &bh_result->b_state); -+ ext3_init_tree_desc(&tree, inode); -+ ext_debug(&tree, "block %d requested for inode %u\n", -+ (int) iblock, (unsigned) inode->i_ino); -+ down_write(&EXT3_I(inode)->truncate_sem); -+ -+ /* check in cache */ -+ if ((goal = ext3_ext_in_cache(&tree, iblock, &newex))) { -+ if (goal == EXT3_EXT_CACHE_GAP) { -+ if (!create) { -+ /* block isn't allocated yet and -+ * user don't want to allocate it */ -+ goto out2; -+ } -+ /* we should allocate requested block */ -+ } else if (goal == EXT3_EXT_CACHE_EXTENT) { -+ /* block is already allocated */ -+ newblock = iblock - newex.ee_block + newex.ee_start; -+ goto out; -+ } else { -+ EXT_ASSERT(0); -+ } -+ } -+ -+ /* find extent for this block */ -+ path = ext3_ext_find_extent(&tree, iblock, NULL); -+ if (IS_ERR(path)) { -+ err = PTR_ERR(path); -+ path = NULL; -+ goto out2; -+ } -+ -+ depth = EXT_DEPTH(&tree); -+ -+ /* -+ * consistent leaf must not be empty -+ * this situations is possible, though, _during_ tree modification -+ * this is why assert can't be put in ext3_ext_find_extent() -+ */ -+ EXT_ASSERT(path[depth].p_ext != NULL || depth == 0); -+ -+ if ((ex = path[depth].p_ext)) { -+ /* if found exent covers block, simple return it */ -+ if (iblock >= ex->ee_block && iblock < ex->ee_block + ex->ee_len) { -+ newblock = iblock - ex->ee_block + ex->ee_start; -+ ext_debug(&tree, "%d fit into %d:%d -> %d\n", -+ (int) iblock, ex->ee_block, ex->ee_len, -+ newblock); -+ ext3_ext_put_in_cache(&tree, ex->ee_block, -+ ex->ee_len, ex->ee_start, -+ EXT3_EXT_CACHE_EXTENT); -+ goto out; -+ } -+ } -+ -+ /* -+ * requested block isn't allocated yet -+ * we couldn't try to create block if create flag is zero -+ */ -+ if (!create) { -+ /* put just found gap into cache to speedup subsequest reqs */ -+ ext3_ext_put_gap_in_cache(&tree, path, iblock); -+ goto out2; -+ } -+ -+ /* allocate new block */ -+ goal = ext3_ext_find_goal(inode, path, iblock); -+ newblock = ext3_new_block(handle, inode, goal, 0, 0, &err); -+ if (!newblock) -+ goto out2; -+ ext_debug(&tree, "allocate new block: goal %d, found %d\n", -+ goal, newblock); -+ -+ /* try to insert new extent into found leaf and return */ -+ newex.ee_block = iblock; -+ newex.ee_start = newblock; -+ newex.ee_len = 1; -+ err = ext3_ext_insert_extent(handle, &tree, path, &newex); -+ if (err) -+ goto out2; -+ -+ if (inode->i_size > EXT3_I(inode)->i_disksize) -+ EXT3_I(inode)->i_disksize = inode->i_size; -+ -+ /* previous routine could use block we allocated */ -+ newblock = newex.ee_start; -+ set_bit(BH_New, &bh_result->b_state); -+ -+ ext3_ext_put_in_cache(&tree, newex.ee_block, newex.ee_len, -+ newex.ee_start, EXT3_EXT_CACHE_EXTENT); -+out: -+ ext3_ext_show_leaf(&tree, path); -+ set_bit(BH_Mapped, &bh_result->b_state); -+ bh_result->b_dev = inode->i_sb->s_dev; -+ bh_result->b_blocknr = newblock; -+out2: -+ if (path) { -+ ext3_ext_drop_refs(path); -+ kfree(path); -+ } -+ up_write(&EXT3_I(inode)->truncate_sem); -+ -+ return err; -+} -+ -+void ext3_ext_truncate(struct inode * inode) -+{ -+ struct address_space *mapping = inode->i_mapping; -+ struct super_block *sb = inode->i_sb; -+ struct ext3_extents_tree tree; -+ unsigned long last_block; -+ handle_t *handle; -+ int err = 0; -+ -+ ext3_init_tree_desc(&tree, inode); -+ -+ /* -+ * probably first extent we're gonna free will be last in block -+ */ -+ err = ext3_writepage_trans_blocks(inode) + 3; -+ handle = ext3_journal_start(inode, err); -+ if (IS_ERR(handle)) -+ return; -+ -+ ext3_block_truncate_page(handle, mapping, inode->i_size); -+ -+ down_write(&EXT3_I(inode)->truncate_sem); -+ ext3_ext_invalidate_cache(&tree); -+ -+ /* -+ * TODO: optimization is possible here -+ * probably we need not scaning at all, -+ * because page truncation is enough -+ */ -+ if (ext3_orphan_add(handle, inode)) -+ goto out_stop; -+ -+ /* we have to know where to truncate from in crash case */ -+ EXT3_I(inode)->i_disksize = inode->i_size; -+ ext3_mark_inode_dirty(handle, inode); -+ -+ last_block = (inode->i_size + sb->s_blocksize - 1) -+ >> EXT3_BLOCK_SIZE_BITS(sb); -+ err = ext3_ext_remove_space(&tree, last_block, EXT_MAX_BLOCK); -+ -+ /* In a multi-transaction truncate, we only make the final -+ * transaction synchronous */ -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ -+out_stop: -+ /* -+ * If this was a simple ftruncate(), and the file will remain alive -+ * then we need to clear up the orphan record which we created above. -+ * However, if this was a real unlink then we were called by -+ * ext3_delete_inode(), and we allow that function to clean up the -+ * orphan info for us. -+ */ -+ if (inode->i_nlink) -+ ext3_orphan_del(handle, inode); -+ -+ up_write(&EXT3_I(inode)->truncate_sem); -+ ext3_journal_stop(handle, inode); -+} -+ -+/* -+ * this routine calculate max number of blocks we could modify -+ * in order to allocate new block for an inode -+ */ -+int ext3_ext_writepage_trans_blocks(struct inode *inode, int num) -+{ -+ struct ext3_extents_tree tree; -+ int needed; -+ -+ ext3_init_tree_desc(&tree, inode); -+ -+ needed = ext3_ext_calc_credits_for_insert(&tree, NULL); -+ -+ /* caller want to allocate num blocks */ -+ needed *= num; -+ -+#ifdef CONFIG_QUOTA -+ /* -+ * FIXME: real calculation should be here -+ * it depends on blockmap format of qouta file -+ */ -+ needed += 2 * EXT3_SINGLEDATA_TRANS_BLOCKS; -+#endif -+ -+ return needed; -+} -+ -+void ext3_extents_initialize_blockmap(handle_t *handle, struct inode *inode) -+{ -+ struct ext3_extents_tree tree; -+ -+ ext3_init_tree_desc(&tree, inode); -+ ext3_extent_tree_init(handle, &tree); -+} -+ -+static int -+ext3_ext_store_extent_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newex, int exist) -+{ -+ struct ext3_extent_buf *buf = (struct ext3_extent_buf *) tree->private; -+ -+ if (!exist) -+ return EXT_CONTINUE; -+ if (buf->err < 0) -+ return EXT_BREAK; -+ if (buf->cur - buf->buffer + sizeof(*newex) > buf->buflen) -+ return EXT_BREAK; -+ -+ if (!copy_to_user(buf->cur, newex, sizeof(*newex))) { -+ buf->err++; -+ buf->cur += sizeof(*newex); -+ } else { -+ buf->err = -EFAULT; -+ return EXT_BREAK; -+ } -+ return EXT_CONTINUE; -+} -+ -+static int -+ext3_ext_collect_stats_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int exist) -+{ -+ struct ext3_extent_tree_stats *buf = -+ (struct ext3_extent_tree_stats *) tree->private; -+ int depth; -+ -+ if (!exist) -+ return EXT_CONTINUE; -+ -+ depth = EXT_DEPTH(tree); -+ buf->extents_num++; -+ if (path[depth].p_ext == EXT_FIRST_EXTENT(path[depth].p_hdr)) -+ buf->leaf_num++; -+ return EXT_CONTINUE; -+} -+ -+int ext3_ext_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, -+ unsigned long arg) -+{ -+ int err = 0; -+ -+ if (!(EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)) -+ return -EINVAL; -+ -+ if (cmd == EXT3_IOC_GET_EXTENTS) { -+ struct ext3_extent_buf buf; -+ struct ext3_extents_tree tree; -+ -+ if (copy_from_user(&buf, (void *) arg, sizeof(buf))) -+ return -EFAULT; -+ -+ ext3_init_tree_desc(&tree, inode); -+ buf.cur = buf.buffer; -+ buf.err = 0; -+ tree.private = &buf; -+ down_write(&EXT3_I(inode)->truncate_sem); -+ err = ext3_ext_walk_space(&tree, buf.start, EXT_MAX_BLOCK, -+ ext3_ext_store_extent_cb); -+ up_write(&EXT3_I(inode)->truncate_sem); -+ if (err == 0) -+ err = buf.err; -+ } else if (cmd == EXT3_IOC_GET_TREE_STATS) { -+ struct ext3_extent_tree_stats buf; -+ struct ext3_extents_tree tree; -+ -+ ext3_init_tree_desc(&tree, inode); -+ down_write(&EXT3_I(inode)->truncate_sem); -+ buf.depth = EXT_DEPTH(&tree); -+ buf.extents_num = 0; -+ buf.leaf_num = 0; -+ tree.private = &buf; -+ err = ext3_ext_walk_space(&tree, 0, EXT_MAX_BLOCK, -+ ext3_ext_collect_stats_cb); -+ up_write(&EXT3_I(inode)->truncate_sem); -+ if (!err) -+ err = copy_to_user((void *) arg, &buf, sizeof(buf)); -+ } else if (cmd == EXT3_IOC_GET_TREE_DEPTH) { -+ struct ext3_extents_tree tree; -+ ext3_init_tree_desc(&tree, inode); -+ down_write(&EXT3_I(inode)->truncate_sem); -+ err = EXT_DEPTH(&tree); -+ up_write(&EXT3_I(inode)->truncate_sem); -+ } -+ -+ return err; -+} -+ -+EXPORT_SYMBOL(ext3_init_tree_desc); -+EXPORT_SYMBOL(ext3_mark_inode_dirty); -+EXPORT_SYMBOL(ext3_ext_invalidate_cache); -+EXPORT_SYMBOL(ext3_ext_insert_extent); -+EXPORT_SYMBOL(ext3_ext_walk_space); -+EXPORT_SYMBOL(ext3_ext_find_goal); -+EXPORT_SYMBOL(ext3_ext_calc_credits_for_insert); -+ -Index: linux-2.4.20-rh-20.9/fs/ext3/ialloc.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/fs/ext3/ialloc.c 2004-11-02 21:01:47.000000000 +0300 -+++ linux-2.4.20-rh-20.9/fs/ext3/ialloc.c 2004-11-02 21:03:00.000000000 +0300 -@@ -593,10 +593,22 @@ - iloc.bh = NULL; - goto fail; - } -- err = ext3_mark_iloc_dirty(handle, inode, &iloc); -- if (err) goto fail; - -+ if (test_opt(sb, EXTENTS)) { -+ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; -+ memset(&inode->u.ext3_i.i_cached_extent, 0, sizeof(__u32) * 4); -+ ext3_extents_initialize_blockmap(handle, inode); -+ if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS)) { -+ err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -+ if (err) goto fail; -+ EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS); -+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "call ext3_journal_dirty_metadata"); -+ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -+ } -+ } - -+ err = ext3_mark_iloc_dirty(handle, inode, &iloc); -+ if (err) goto fail; - - unlock_super (sb); - if(DQUOT_ALLOC_INODE(inode)) { -Index: linux-2.4.20-rh-20.9/fs/ext3/inode.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/fs/ext3/inode.c 2004-11-02 21:01:55.000000000 +0300 -+++ linux-2.4.20-rh-20.9/fs/ext3/inode.c 2004-11-02 21:03:00.000000000 +0300 -@@ -852,6 +852,16 @@ - goto reread; - } - -+static inline int -+ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block, -+ struct buffer_head *bh, int create, int extend_disksize) -+{ -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) -+ return ext3_ext_get_block(handle, inode, block, bh, create); -+ return ext3_get_block_handle(handle, inode, block, bh, create, -+ extend_disksize); -+} -+ - /* - * The BKL is not held on entry here. - */ -@@ -865,7 +875,7 @@ - handle = ext3_journal_current_handle(); - J_ASSERT(handle != 0); - } -- ret = ext3_get_block_handle(handle, inode, iblock, -+ ret = ext3_get_block_wrap(handle, inode, iblock, - bh_result, create, 1); - return ret; - } -@@ -892,7 +902,7 @@ - } - } - if (ret == 0) -- ret = ext3_get_block_handle(handle, inode, iblock, -+ ret = ext3_get_block_wrap(handle, inode, iblock, - bh_result, create, 0); - if (ret == 0) - bh_result->b_size = (1 << inode->i_blkbits); -@@ -914,7 +924,7 @@ - dummy.b_state = 0; - dummy.b_blocknr = -1000; - buffer_trace_init(&dummy.b_history); -- *errp = ext3_get_block_handle(handle, inode, block, &dummy, create, 1); -+ *errp = ext3_get_block_wrap(handle, inode, block, &dummy, create, 1); - if (!*errp && buffer_mapped(&dummy)) { - struct buffer_head *bh; - bh = sb_getblk(inode->i_sb, dummy.b_blocknr); -@@ -1502,7 +1512,7 @@ - * This required during truncate. We need to physically zero the tail end - * of that block so it doesn't yield old data if the file is later grown. - */ --static int ext3_block_truncate_page(handle_t *handle, -+int ext3_block_truncate_page(handle_t *handle, - struct address_space *mapping, loff_t from) - { - unsigned long index = from >> PAGE_CACHE_SHIFT; -@@ -1990,6 +2000,9 @@ - - ext3_discard_prealloc(inode); - -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) -+ return ext3_ext_truncate(inode); -+ - handle = start_transaction(inode); - if (IS_ERR(handle)) - return; /* AKPM: return what? */ -@@ -2426,6 +2439,7 @@ - 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); -+ memset(&inode->u.ext3_i.i_cached_extent, 0, sizeof(__u32) * 4); - - if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) - inode->u.ext3_i.i_extra_isize = -@@ -2758,6 +2772,9 @@ - int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3; - int ret; - -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) -+ return ext3_ext_writepage_trans_blocks(inode, bpp); -+ - if (ext3_should_journal_data(inode)) - ret = 3 * (bpp + indirects) + 2; - else -@@ -3082,7 +3099,7 @@ - - /* alloc blocks one by one */ - for (i = 0; i < nblocks; i++) { -- ret = ext3_get_block_handle(handle, inode, blocks[i], -+ ret = ext3_get_block_wrap(handle, inode, blocks[i], - &bh_tmp, 1, 1); - if (ret) - break; -@@ -3158,7 +3175,7 @@ - if (blocks[i] != 0) - continue; - -- rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1, 1); -+ rc = ext3_get_block_wrap(handle, inode, iblock, &bh, 1, 1); - if (rc) { - printk(KERN_INFO "ext3_map_inode_page: error %d " - "allocating block %ld\n", rc, iblock); -Index: linux-2.4.20-rh-20.9/fs/ext3/Makefile -=================================================================== ---- linux-2.4.20-rh-20.9.orig/fs/ext3/Makefile 2004-11-02 21:01:49.000000000 +0300 -+++ linux-2.4.20-rh-20.9/fs/ext3/Makefile 2004-11-02 21:01:58.000000000 +0300 -@@ -13,7 +13,9 @@ - - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ - ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \ -- xattr_trusted.o -+ xattr_trusted.o extents.o -+export-objs += extents.o -+ - obj-m := $(O_TARGET) - - export-objs += xattr.o -Index: linux-2.4.20-rh-20.9/fs/ext3/super.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/fs/ext3/super.c 2004-11-02 21:01:47.000000000 +0300 -+++ linux-2.4.20-rh-20.9/fs/ext3/super.c 2004-11-02 21:01:58.000000000 +0300 -@@ -623,6 +623,7 @@ - int i; - - J_ASSERT(sbi->s_delete_inodes == 0); -+ ext3_ext_release(sb); - ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { -@@ -798,6 +799,10 @@ - } - else if (!strcmp (this_char, "pdirops")) - set_opt (sbi->s_mount_opt, PDIROPS); -+ else if (!strcmp (this_char, "extents")) -+ set_opt (*mount_options, EXTENTS); -+ else if (!strcmp (this_char, "extdebug")) -+ set_opt (*mount_options, EXTDEBUG); - else if (!strcmp (this_char, "grpid") || - !strcmp (this_char, "bsdgroups")) - set_opt (*mount_options, GRPID); -@@ -1499,6 +1504,8 @@ - printk (KERN_INFO "EXT3-fs: mounted filesystem with parallel dirops\n"); - sb->s_flags |= S_PDIROPS; - } -+ -+ ext3_ext_init(sb); - - return sb; - -Index: linux-2.4.20-rh-20.9/fs/ext3/ioctl.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/fs/ext3/ioctl.c 2004-11-02 21:01:31.000000000 +0300 -+++ linux-2.4.20-rh-20.9/fs/ext3/ioctl.c 2004-11-02 21:01:58.000000000 +0300 -@@ -189,6 +189,10 @@ - return ret; - } - #endif -+ case EXT3_IOC_GET_EXTENTS: -+ case EXT3_IOC_GET_TREE_STATS: -+ case EXT3_IOC_GET_TREE_DEPTH: -+ return ext3_ext_ioctl(inode, filp, cmd, arg); - default: - return -ENOTTY; - } -Index: linux-2.4.20-rh-20.9/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.20-rh-20.9.orig/include/linux/ext3_fs.h 2004-11-02 21:01:47.000000000 +0300 -+++ linux-2.4.20-rh-20.9/include/linux/ext3_fs.h 2004-11-02 21:01:58.000000000 +0300 -@@ -184,6 +184,7 @@ - #define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */ - #define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ - #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ -+#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ - - #define EXT3_FL_USER_VISIBLE 0x00005FFF /* User visible flags */ - #define EXT3_FL_USER_MODIFIABLE 0x000000FF /* User modifiable flags */ -@@ -208,6 +209,9 @@ - #ifdef CONFIG_JBD_DEBUG - #define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) - #endif -+#define EXT3_IOC_GET_EXTENTS _IOR('f', 5, long) -+#define EXT3_IOC_GET_TREE_DEPTH _IOR('f', 6, long) -+#define EXT3_IOC_GET_TREE_STATS _IOR('f', 7, long) - - /* - * Structure of an inode on the disk -@@ -328,6 +332,8 @@ - #define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ - #define EXT3_MOUNT_IOPEN 0x40000 /* Allow access via iopen */ - #define EXT3_MOUNT_IOPEN_NOPRIV 0x80000 /* Make iopen world-readable */ -+#define EXT3_MOUNT_EXTENTS 0x100000/* Extents support */ -+#define EXT3_MOUNT_EXTDEBUG 0x200000/* Extents debug */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -504,10 +510,12 @@ - #define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002 - #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ - #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ -+#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ - - #define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR - #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ -- EXT3_FEATURE_INCOMPAT_RECOVER) -+ EXT3_FEATURE_INCOMPAT_RECOVER| \ -+ EXT3_FEATURE_INCOMPAT_EXTENTS) - #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT3_FEATURE_RO_COMPAT_BTREE_DIR) -@@ -689,6 +697,7 @@ - extern unsigned long ext3_count_free (struct buffer_head *, unsigned); - - /* inode.c */ -+extern int ext3_block_truncate_page(handle_t *, struct address_space *, loff_t); - 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 *); -@@ -770,6 +779,16 @@ - extern struct inode_operations ext3_symlink_inode_operations; - extern struct inode_operations ext3_fast_symlink_inode_operations; - -+/* extents.c */ -+extern int ext3_ext_writepage_trans_blocks(struct inode *, int); -+extern int ext3_ext_get_block(handle_t *, struct inode *, long, -+ struct buffer_head *, int); -+extern void ext3_ext_truncate(struct inode *); -+extern void ext3_ext_init(struct super_block *); -+extern void ext3_ext_release(struct super_block *); -+extern void ext3_extents_initialize_blockmap(handle_t *, struct inode *); -+extern int ext3_ext_ioctl(struct inode *inode, struct file *filp, -+ unsigned int cmd, unsigned long arg); - - #endif /* __KERNEL__ */ - -Index: linux-2.4.20-rh-20.9/include/linux/ext3_extents.h -=================================================================== ---- linux-2.4.20-rh-20.9.orig/include/linux/ext3_extents.h 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.20-rh-20.9/include/linux/ext3_extents.h 2004-11-02 21:03:00.000000000 +0300 -@@ -0,0 +1,251 @@ -+/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com -+ * Written by Alex Tomas -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program 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 Licens -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- -+ */ -+ -+#ifndef _LINUX_EXT3_EXTENTS -+#define _LINUX_EXT3_EXTENTS -+ -+/* -+ * with AGRESSIVE_TEST defined capacity of index/leaf blocks -+ * become very little, so index split, in-depth growing and -+ * other hard changes happens much more often -+ * this is for debug purposes only -+ */ -+#define AGRESSIVE_TEST_ -+ -+/* -+ * if CHECK_BINSEARCH defined, then results of binary search -+ * will be checked by linear search -+ */ -+#define CHECK_BINSEARCH_ -+ -+/* -+ * if EXT_DEBUG is defined you can use 'extdebug' mount option -+ * to get lots of info what's going on -+ */ -+#define EXT_DEBUG_ -+#ifdef EXT_DEBUG -+#define ext_debug(tree,fmt,a...) \ -+do { \ -+ if (test_opt((tree)->inode->i_sb, EXTDEBUG)) \ -+ printk(fmt, ##a); \ -+} while (0); -+#else -+#define ext_debug(tree,fmt,a...) -+#endif -+ -+/* -+ * if EXT_STATS is defined then stats numbers are collected -+ * these number will be displayed at umount time -+ */ -+#define EXT_STATS_ -+ -+ -+#define EXT3_ALLOC_NEEDED 3 /* block bitmap + group desc. + sb */ -+ -+/* -+ * ext3_inode has i_block array (total 60 bytes) -+ * first 4 bytes are used to store: -+ * - tree depth (0 mean there is no tree yet. all extents in the inode) -+ * - number of alive extents in the inode -+ */ -+ -+/* -+ * this is extent on-disk structure -+ * it's used at the bottom of the tree -+ */ -+struct ext3_extent { -+ __u32 ee_block; /* first logical block extent covers */ -+ __u16 ee_len; /* number of blocks covered by extent */ -+ __u16 ee_start_hi; /* high 16 bits of physical block */ -+ __u32 ee_start; /* low 32 bigs of physical block */ -+}; -+ -+/* -+ * this is index on-disk structure -+ * it's used at all the levels, but the bottom -+ */ -+struct ext3_extent_idx { -+ __u32 ei_block; /* index covers logical blocks from 'block' */ -+ __u32 ei_leaf; /* pointer to the physical block of the next * -+ * level. leaf or next index could bet here */ -+ __u16 ei_leaf_hi; /* high 16 bits of physical block */ -+ __u16 ei_unused; -+}; -+ -+/* -+ * each block (leaves and indexes), even inode-stored has header -+ */ -+struct ext3_extent_header { -+ __u16 eh_magic; /* probably will support different formats */ -+ __u16 eh_entries; /* number of valid entries */ -+ __u16 eh_max; /* capacity of store in entries */ -+ __u16 eh_depth; /* has tree real underlaying blocks? */ -+ __u32 eh_generation; /* generation of the tree */ -+}; -+ -+#define EXT3_EXT_MAGIC 0xf30a -+ -+/* -+ * array of ext3_ext_path contains path to some extent -+ * creation/lookup routines use it for traversal/splitting/etc -+ * truncate uses it to simulate recursive walking -+ */ -+struct ext3_ext_path { -+ __u32 p_block; -+ __u16 p_depth; -+ struct ext3_extent *p_ext; -+ struct ext3_extent_idx *p_idx; -+ struct ext3_extent_header *p_hdr; -+ struct buffer_head *p_bh; -+}; -+ -+/* -+ * structure for external API -+ */ -+ -+/* -+ * storage for cached extent -+ */ -+struct ext3_ext_cache { -+ __u32 ec_start; -+ __u32 ec_block; -+ __u32 ec_len; -+ __u32 ec_type; -+}; -+ -+#define EXT3_EXT_CACHE_NO 0 -+#define EXT3_EXT_CACHE_GAP 1 -+#define EXT3_EXT_CACHE_EXTENT 2 -+ -+/* -+ * ext3_extents_tree is used to pass initial information -+ * to top-level extents API -+ */ -+struct ext3_extents_helpers; -+struct ext3_extents_tree { -+ struct inode *inode; /* inode which tree belongs to */ -+ void *root; /* ptr to data top of tree resides at */ -+ void *buffer; /* will be passed as arg to ^^ routines */ -+ int buffer_len; -+ void *private; -+ struct ext3_ext_cache *cex;/* last found extent */ -+ struct ext3_extents_helpers *ops; -+}; -+ -+struct ext3_extents_helpers { -+ int (*get_write_access)(handle_t *h, void *buffer); -+ int (*mark_buffer_dirty)(handle_t *h, void *buffer); -+ int (*mergable)(struct ext3_extent *ex1, struct ext3_extent *ex2); -+ int (*remove_extent_credits)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); -+ int (*remove_extent)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); -+ int (*new_block)(handle_t *, struct ext3_extents_tree *, -+ struct ext3_ext_path *, struct ext3_extent *, -+ int *); -+}; -+ -+/* -+ * to be called by ext3_ext_walk_space() -+ * negative retcode - error -+ * positive retcode - signal for ext3_ext_walk_space(), see below -+ * callback must return valid extent (passed or newly created) -+ */ -+typedef int (*ext_prepare_callback)(struct ext3_extents_tree *, -+ struct ext3_ext_path *, -+ struct ext3_extent *, int); -+ -+#define EXT_CONTINUE 0 -+#define EXT_BREAK 1 -+#define EXT_REPEAT 2 -+ -+ -+#define EXT_MAX_BLOCK 0xffffffff -+#define EXT_CACHE_MARK 0xffff -+ -+ -+#define EXT_FIRST_EXTENT(__hdr__) \ -+ ((struct ext3_extent *) (((char *) (__hdr__)) + \ -+ sizeof(struct ext3_extent_header))) -+#define EXT_FIRST_INDEX(__hdr__) \ -+ ((struct ext3_extent_idx *) (((char *) (__hdr__)) + \ -+ sizeof(struct ext3_extent_header))) -+#define EXT_HAS_FREE_INDEX(__path__) \ -+ ((__path__)->p_hdr->eh_entries < (__path__)->p_hdr->eh_max) -+#define EXT_LAST_EXTENT(__hdr__) \ -+ (EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_entries - 1) -+#define EXT_LAST_INDEX(__hdr__) \ -+ (EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_entries - 1) -+#define EXT_MAX_EXTENT(__hdr__) \ -+ (EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_max - 1) -+#define EXT_MAX_INDEX(__hdr__) \ -+ (EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_max - 1) -+ -+#define EXT_ROOT_HDR(tree) \ -+ ((struct ext3_extent_header *) (tree)->root) -+#define EXT_BLOCK_HDR(bh) \ -+ ((struct ext3_extent_header *) (bh)->b_data) -+#define EXT_DEPTH(_t_) \ -+ (((struct ext3_extent_header *)((_t_)->root))->eh_depth) -+#define EXT_GENERATION(_t_) \ -+ (((struct ext3_extent_header *)((_t_)->root))->eh_generation) -+ -+ -+#define EXT_ASSERT(__x__) if (!(__x__)) BUG(); -+ -+ -+/* -+ * this structure is used to gather extents from the tree via ioctl -+ */ -+struct ext3_extent_buf { -+ unsigned long start; -+ int buflen; -+ void *buffer; -+ void *cur; -+ int err; -+}; -+ -+/* -+ * this structure is used to collect stats info about the tree -+ */ -+struct ext3_extent_tree_stats { -+ int depth; -+ int extents_num; -+ int leaf_num; -+}; -+ -+void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); -+extern int ext3_extent_tree_init(handle_t *, struct ext3_extents_tree *); -+extern int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *, struct ext3_ext_path *); -+extern int ext3_ext_insert_extent(handle_t *, struct ext3_extents_tree *, struct ext3_ext_path *, struct ext3_extent *); -+extern int ext3_ext_walk_space(struct ext3_extents_tree *, unsigned long, unsigned long, ext_prepare_callback); -+extern int ext3_ext_remove_space(struct ext3_extents_tree *, unsigned long, unsigned long); -+extern struct ext3_ext_path * ext3_ext_find_extent(struct ext3_extents_tree *, int, struct ext3_ext_path *); -+ -+static inline void -+ext3_ext_invalidate_cache(struct ext3_extents_tree *tree) -+{ -+ if (tree->cex) -+ tree->cex->ec_type = EXT3_EXT_CACHE_NO; -+} -+ -+ -+#endif /* _LINUX_EXT3_EXTENTS */ -+ -Index: linux-2.4.20-rh-20.9/include/linux/ext3_fs_i.h -=================================================================== ---- linux-2.4.20-rh-20.9.orig/include/linux/ext3_fs_i.h 2004-11-02 21:01:47.000000000 +0300 -+++ linux-2.4.20-rh-20.9/include/linux/ext3_fs_i.h 2004-11-02 21:06:02.000000000 +0300 -@@ -82,6 +82,8 @@ - struct dynlock i_htree_lock; - struct semaphore i_append_sem; - struct semaphore i_rename_sem; -+ -+ __u32 i_cached_extent[4]; - }; - - #endif /* _LINUX_EXT3_FS_I */ diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.21-chaos.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.21-chaos.patch index 4b6ec48..c392ac9 100644 --- a/lustre/kernel_patches/patches/ext3-extents-2.4.21-chaos.patch +++ b/lustre/kernel_patches/patches/ext3-extents-2.4.21-chaos.patch @@ -1,10 +1,10 @@ -Index: linux-2.4.21-20.EL/fs/ext3/extents.c +Index: linux-2.4.21-rhel/fs/ext3/extents.c =================================================================== ---- linux-2.4.21-20.EL.orig/fs/ext3/extents.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.21-20.EL/fs/ext3/extents.c 2004-11-03 00:35:30.644364336 +0300 -@@ -0,0 +1,2278 @@ +--- linux-2.4.21-rhel.orig/fs/ext3/extents.c 2005-03-02 22:42:20.659360368 +0300 ++++ linux-2.4.21-rhel/fs/ext3/extents.c 2005-03-04 02:34:52.000000000 +0300 +@@ -0,0 +1,2312 @@ +/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com ++ * Copyright(c) 2003, 2004, 2005, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify @@ -39,16 +39,37 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +#include +#include +#include ++#include +#include +#include +#include +#include +#include +#include -+#include +#include +#include + ++ ++static inline int ext3_ext_check_header(struct ext3_extent_header *eh) ++{ ++ if (eh->eh_magic != EXT3_EXT_MAGIC) { ++ printk(KERN_ERR "EXT3-fs: invalid magic = 0x%x\n", ++ (unsigned)eh->eh_magic); ++ return -EIO; ++ } ++ if (eh->eh_max == 0) { ++ printk(KERN_ERR "EXT3-fs: invalid eh_max = %u\n", ++ (unsigned)eh->eh_max); ++ return -EIO; ++ } ++ if (eh->eh_entries > eh->eh_max) { ++ printk(KERN_ERR "EXT3-fs: invalid eh_entries = %u\n", ++ (unsigned)eh->eh_entries); ++ return -EIO; ++ } ++ return 0; ++} ++ +static handle_t *ext3_ext_journal_restart(handle_t *handle, int needed) +{ + int err; @@ -86,8 +107,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + * - ENOMEM + */ +static int ext3_ext_get_access(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path) +{ + int err; + @@ -108,7 +129,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + * - EIO + */ +static int ext3_ext_dirty(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int err; + if (path->p_bh) { @@ -123,8 +144,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + +static int inline +ext3_ext_new_block(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, struct ext3_extent *ex, -+ int *err) ++ struct ext3_ext_path *path, struct ext3_extent *ex, ++ int *err) +{ + int goal, depth, newblock; + struct inode *inode; @@ -143,7 +164,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + unsigned long colour; + + bg_start = (ei->i_block_group * -+ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + ++ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + + le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); + colour = (current->pid % 16) * + (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); @@ -166,8 +187,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 6; +#endif @@ -179,8 +200,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 5; +#endif @@ -191,8 +212,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 3; +#endif @@ -203,9 +224,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 4; +#endif @@ -213,7 +233,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +} + +static void ext3_ext_show_path(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int k, l = path->p_depth; @@ -222,12 +242,12 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + for (k = 0; k <= l; k++, path++) { + if (path->p_idx) { + ext_debug(tree, " %d->%d", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + } else if (path->p_ext) { + ext_debug(tree, " %d:%d:%d", -+ path->p_ext->ee_block, -+ path->p_ext->ee_len, -+ path->p_ext->ee_start); ++ path->p_ext->ee_block, ++ path->p_ext->ee_len, ++ path->p_ext->ee_start); + } else + ext_debug(tree, " []"); + } @@ -236,7 +256,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +} + +static void ext3_ext_show_leaf(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int depth = EXT_DEPTH(tree); @@ -252,7 +272,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + + for (i = 0; i < eh->eh_entries; i++, ex++) { + ext_debug(tree, "%d:%d:%d ", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + } + ext_debug(tree, "\n"); +#endif @@ -263,11 +283,12 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + int depth = path->p_depth; + int i; + -+ for (i = 0; i <= depth; i++, path++) ++ for (i = 0; i <= depth; i++, path++) { + if (path->p_bh) { + brelse(path->p_bh); + path->p_bh = NULL; + } ++ } +} + +/* @@ -275,7 +296,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch_idx(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent_idx *ix; @@ -301,7 +322,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + + ix += l; + path->p_idx = ix; -+ ext_debug(tree, " -> %d->%d ", path->p_idx->ei_block, path->p_idx->ei_leaf); ++ ext_debug(tree," -> %d->%d ",path->p_idx->ei_block,path->p_idx->ei_leaf); + + while (l++ < r) { + if (block < ix->ei_block) @@ -309,7 +330,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + path->p_idx = ix++; + } + ext_debug(tree, " -> %d->%d\n", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + +#ifdef CHECK_BINSEARCH + { @@ -319,9 +340,9 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + for (k = 0; k < eh->eh_entries; k++, ix++) { + if (k != 0 && ix->ei_block <= ix[-1].ei_block) { + printk("k=%d, ix=0x%p, first=0x%p\n", k, -+ ix, EXT_FIRST_INDEX(eh)); ++ ix, EXT_FIRST_INDEX(eh)); + printk("%u <= %u\n", -+ ix->ei_block,ix[-1].ei_block); ++ ix->ei_block,ix[-1].ei_block); + } + EXT_ASSERT(k == 0 || ix->ei_block > ix[-1].ei_block); + if (block < ix->ei_block) @@ -331,7 +352,6 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + EXT_ASSERT(chix == path->p_idx); + } +#endif -+ +} + +/* @@ -339,7 +359,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent *ex; @@ -373,7 +393,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + ex += l; + path->p_ext = ex; + ext_debug(tree, " -> %d:%d:%d ", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + + while (l++ < r) { + if (block < ex->ee_block) @@ -381,7 +401,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + path->p_ext = ex++; + } + ext_debug(tree, " -> %d:%d:%d\n", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + +#ifdef CHECK_BINSEARCH + { @@ -397,7 +417,6 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + EXT_ASSERT(chex == path->p_ext); + } +#endif -+ +} + +int ext3_extent_tree_init(handle_t *handle, struct ext3_extents_tree *tree) @@ -418,7 +437,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + +struct ext3_ext_path * +ext3_ext_find_extent(struct ext3_extents_tree *tree, int block, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + struct buffer_head *bh; @@ -430,15 +449,17 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + + eh = EXT_ROOT_HDR(tree); + EXT_ASSERT(eh); ++ if (ext3_ext_check_header(eh)) ++ goto err; ++ + i = depth = EXT_DEPTH(tree); + EXT_ASSERT(eh->eh_max); + EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ EXT_ASSERT(i == 0 || eh->eh_entries > 0); + + /* account possible depth increase */ + if (!path) { + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2), -+ GFP_NOFS); ++ GFP_NOFS); + if (!path) + return ERR_PTR(-ENOMEM); + } @@ -448,29 +469,34 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + /* walk through the tree */ + while (i) { + ext_debug(tree, "depth %d: num %d, max %d\n", -+ ppos, eh->eh_entries, eh->eh_max); ++ ppos, eh->eh_entries, eh->eh_max); + ext3_ext_binsearch_idx(tree, path + ppos, block); + path[ppos].p_block = path[ppos].p_idx->ei_leaf; + path[ppos].p_depth = i; + path[ppos].p_ext = NULL; + + bh = sb_bread(tree->inode->i_sb, path[ppos].p_block); -+ if (!bh) { -+ ext3_ext_drop_refs(path); -+ kfree(path); -+ return ERR_PTR(-EIO); -+ } ++ if (!bh) ++ goto err; ++ + eh = EXT_BLOCK_HDR(bh); + ppos++; + EXT_ASSERT(ppos <= depth); + path[ppos].p_bh = bh; + path[ppos].p_hdr = eh; + i--; ++ ++ if (ext3_ext_check_header(eh)) ++ goto err; + } + + path[ppos].p_depth = i; + path[ppos].p_hdr = eh; + path[ppos].p_ext = NULL; ++ path[ppos].p_idx = NULL; ++ ++ if (ext3_ext_check_header(eh)) ++ goto err; + + /* find extent */ + ext3_ext_binsearch(tree, path + ppos, block); @@ -478,6 +504,12 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + ext3_ext_show_path(tree, path); + + return path; ++ ++err: ++ printk(KERN_ERR "EXT3-fs: header is corrupted!\n"); ++ ext3_ext_drop_refs(path); ++ kfree(path); ++ return ERR_PTR(-EIO); +} + +/* @@ -485,9 +517,9 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + * it check where to insert: before curp or after curp + */ +static int ext3_ext_insert_index(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *curp, -+ int logical, int ptr) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *curp, ++ int logical, int ptr) +{ + struct ext3_extent_idx *ix; + int len, err; @@ -503,9 +535,9 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d after: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ (curp->p_idx + 1), (curp->p_idx + 2)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ (curp->p_idx + 1), (curp->p_idx + 2)); + memmove(curp->p_idx + 2, curp->p_idx + 1, len); + } + ix = curp->p_idx + 1; @@ -514,9 +546,9 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + len = len * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d before: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ curp->p_idx, (curp->p_idx + 1)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ curp->p_idx, (curp->p_idx + 1)); + memmove(curp->p_idx + 1, curp->p_idx, len); + ix = curp->p_idx; + } @@ -544,8 +576,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + * - initialize subtree + */ +static int ext3_ext_split(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext, int at) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext, int at) +{ + struct buffer_head *bh = NULL; + int depth = EXT_DEPTH(tree); @@ -566,13 +598,13 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) { + border = path[depth].p_ext[1].ee_block; + ext_debug(tree, "leaf will be splitted." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } else { + border = newext->ee_block; + ext_debug(tree, "leaf will be added." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } + + /* @@ -630,12 +662,11 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + while (path[depth].p_ext <= + EXT_MAX_EXTENT(path[depth].p_hdr)) { + ext_debug(tree, "move %d:%d:%d in new leaf %lu\n", -+ path[depth].p_ext->ee_block, -+ path[depth].p_ext->ee_start, -+ path[depth].p_ext->ee_len, -+ newblock); -+ memmove(ex++, path[depth].p_ext++, -+ sizeof(struct ext3_extent)); ++ path[depth].p_ext->ee_block, ++ path[depth].p_ext->ee_start, ++ path[depth].p_ext->ee_len, ++ newblock); ++ memmove(ex++, path[depth].p_ext++, sizeof(struct ext3_extent)); + neh->eh_entries++; + m++; + } @@ -688,21 +719,21 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + fidx->ei_leaf = oldblock; + + ext_debug(tree, "int.index at %d (block %lu): %lu -> %lu\n", -+ i, newblock, border, oldblock); ++ i, newblock, border, oldblock); + /* copy indexes */ + m = 0; + path[i].p_idx++; + + ext_debug(tree, "cur 0x%p, last 0x%p\n", path[i].p_idx, -+ EXT_MAX_INDEX(path[i].p_hdr)); ++ EXT_MAX_INDEX(path[i].p_hdr)); + EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) == -+ EXT_LAST_INDEX(path[i].p_hdr)); ++ EXT_LAST_INDEX(path[i].p_hdr)); + while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { + ext_debug(tree, "%d: move %d:%d in new index %lu\n", -+ i, path[i].p_idx->ei_block, -+ path[i].p_idx->ei_leaf, newblock); ++ i, path[i].p_idx->ei_block, ++ path[i].p_idx->ei_leaf, newblock); + memmove(++fidx, path[i].p_idx++, -+ sizeof(struct ext3_extent_idx)); ++ sizeof(struct ext3_extent_idx)); + neh->eh_entries++; + EXT_ASSERT(neh->eh_entries <= neh->eh_max); + m++; @@ -732,7 +763,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + /* insert new index */ + if (!err) + err = ext3_ext_insert_index(handle, tree, path + at, -+ border, newblock); ++ border, newblock); + +cleanup: + if (bh) { @@ -762,9 +793,9 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + * just created block + */ +static int ext3_ext_grow_indepth(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp = path; + struct ext3_extent_header *neh; @@ -823,7 +854,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + neh = EXT_ROOT_HDR(tree); + fidx = EXT_FIRST_INDEX(neh); + ext_debug(tree, "new root: num %d(%d), lblock %d, ptr %d\n", -+ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); ++ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); + + neh->eh_depth = path->p_depth + 1; + err = ext3_ext_dirty(handle, tree, curp); @@ -838,9 +869,9 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + * then it requests in-depth growing + */ +static int ext3_ext_create_new_leaf(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp; + int depth, i, err = 0; @@ -916,12 +947,12 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + if (depth == path->p_depth) { + /* leaf */ + if (path[depth].p_ext != -+ EXT_LAST_EXTENT(path[depth].p_hdr)) ++ EXT_LAST_EXTENT(path[depth].p_hdr)) + return path[depth].p_ext[1].ee_block; + } else { + /* index */ + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + } + depth--; @@ -934,7 +965,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + * returns first allocated block from next leaf or EXT_MAX_BLOCK + */ +static unsigned ext3_ext_next_leaf_block(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth; + @@ -950,7 +981,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + + while (depth >= 0) { + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + depth--; + } @@ -964,7 +995,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + * TODO: do we need to correct tree in all cases? + */ +int ext3_ext_correct_indexes(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + int depth = EXT_DEPTH(tree); @@ -1014,8 +1045,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + +static int inline +ext3_can_extents_be_merged(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex1, ++ struct ext3_extent *ex2) +{ + if (ex1->ee_block + ex1->ee_len != ex2->ee_block) + return 0; @@ -1037,8 +1068,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + * creating new leaf in no-space case + */ +int ext3_ext_insert_extent(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_extent_header * eh; + struct ext3_extent *ex, *fex; @@ -1047,7 +1078,6 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + int depth, len, err, next; + + EXT_ASSERT(newext->ee_len > 0); -+ EXT_ASSERT(newext->ee_len < EXT_CACHE_MARK); + depth = EXT_DEPTH(tree); + ex = path[depth].p_ext; + EXT_ASSERT(path[depth].p_hdr); @@ -1055,8 +1085,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + /* try to insert block into found extent and return */ + if (ex && ext3_can_extents_be_merged(tree, ex, newext)) { + ext_debug(tree, "append %d block to %d:%d (from %d)\n", -+ newext->ee_len, ex->ee_block, ex->ee_len, -+ ex->ee_start); ++ newext->ee_len, ex->ee_block, ex->ee_len, ++ ex->ee_start); + if ((err = ext3_ext_get_access(handle, tree, path + depth))) + return err; + ex->ee_len += newext->ee_len; @@ -1084,12 +1114,12 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + eh = npath[depth].p_hdr; + if (eh->eh_entries < eh->eh_max) { + ext_debug(tree, "next leaf isnt full(%d)\n", -+ eh->eh_entries); ++ eh->eh_entries); + path = npath; + goto repeat; + } + ext_debug(tree, "next leaf hasno free space(%d,%d)\n", -+ eh->eh_entries, eh->eh_max); ++ eh->eh_entries, eh->eh_max); + } + + /* @@ -1111,8 +1141,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + if (!nearex) { + /* there is no extent in this leaf, create first one */ + ext_debug(tree, "first extent in the leaf: %d:%d:%d\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len); ++ newext->ee_block, newext->ee_start, ++ newext->ee_len); + path[depth].p_ext = EXT_FIRST_EXTENT(eh); + } else if (newext->ee_block > nearex->ee_block) { + EXT_ASSERT(newext->ee_block != nearex->ee_block); @@ -1121,10 +1151,10 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d after: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, ++ newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 2, nearex + 1, len); + } + path[depth].p_ext = nearex + 1; @@ -1133,9 +1163,9 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d before: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 1, nearex, len); + path[depth].p_ext = nearex; + } @@ -1156,8 +1186,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + /* merge with next extent! */ + nearex->ee_len += nearex[1].ee_len; + if (nearex + 1 < EXT_LAST_EXTENT(eh)) { -+ len = (EXT_LAST_EXTENT(eh) - nearex - 1) -+ * sizeof(struct ext3_extent); ++ len = (EXT_LAST_EXTENT(eh) - nearex - 1) * ++ sizeof(struct ext3_extent); + memmove(nearex + 1, nearex + 2, len); + } + eh->eh_entries--; @@ -1187,7 +1217,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + unsigned long num, ext_prepare_callback func) +{ + struct ext3_ext_path *path = NULL; -+ struct ext3_extent *ex, cbex; ++ struct ext3_ext_cache cbex; ++ struct ext3_extent *ex; + unsigned long next, start = 0, end = 0; + unsigned long last = block + num; + int depth, exists, err = 0; @@ -1246,14 +1277,20 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + EXT_ASSERT(end > start); + + if (!exists) { -+ cbex.ee_block = start; -+ cbex.ee_len = end - start; -+ cbex.ee_start = 0; -+ } else -+ cbex = *ex; ++ cbex.ec_block = start; ++ cbex.ec_len = end - start; ++ cbex.ec_start = 0; ++ cbex.ec_type = EXT3_EXT_CACHE_GAP; ++ } else { ++ cbex.ec_block = ex->ee_block; ++ cbex.ec_len = ex->ee_len; ++ cbex.ec_start = ex->ee_start; ++ cbex.ec_type = EXT3_EXT_CACHE_EXTENT; ++ } + ++ EXT_ASSERT(cbex.ec_len > 0); + EXT_ASSERT(path[depth].p_hdr); -+ err = func(tree, path, &cbex, exists); ++ err = func(tree, path, &cbex); + ext3_ext_drop_refs(path); + + if (err < 0) @@ -1271,7 +1308,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + path = NULL; + } + -+ block = cbex.ee_block + cbex.ee_len; ++ block = cbex.ec_block + cbex.ec_len; + } + + if (path) { @@ -1284,7 +1321,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + +static inline void +ext3_ext_put_in_cache(struct ext3_extents_tree *tree, __u32 block, -+ __u32 len, __u32 start, int type) ++ __u32 len, __u32 start, int type) +{ + EXT_ASSERT(len > 0); + if (tree->cex) { @@ -1301,8 +1338,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + */ +static inline void +ext3_ext_put_gap_in_cache(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ unsigned long block) ++ struct ext3_ext_path *path, ++ unsigned long block) +{ + int depth = EXT_DEPTH(tree); + unsigned long lblock, len; @@ -1321,16 +1358,16 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + lblock = block; + len = ex->ee_block - block; + ext_debug(tree, "cache gap(before): %lu [%lu:%lu]", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len); + } else if (block >= ex->ee_block + ex->ee_len) { + lblock = ex->ee_block + ex->ee_len; + len = ext3_ext_next_allocated_block(path); + ext_debug(tree, "cache gap(after): [%lu:%lu] %lu", -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) block); ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) block); + EXT_ASSERT(len > lblock); + len = len - lblock; + } else { @@ -1344,7 +1381,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + +static inline int +ext3_ext_in_cache(struct ext3_extents_tree *tree, unsigned long block, -+ struct ext3_extent *ex) ++ struct ext3_extent *ex) +{ + struct ext3_ext_cache *cex = tree->cex; + @@ -1357,16 +1394,16 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + return EXT3_EXT_CACHE_NO; + + EXT_ASSERT(cex->ec_type == EXT3_EXT_CACHE_GAP || -+ cex->ec_type == EXT3_EXT_CACHE_EXTENT); ++ cex->ec_type == EXT3_EXT_CACHE_EXTENT); + if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) { + ex->ee_block = cex->ec_block; + ex->ee_start = cex->ec_start; + ex->ee_len = cex->ec_len; + ext_debug(tree, "%lu cached by %lu:%lu:%lu\n", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) ex->ee_start); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) ex->ee_start); + return cex->ec_type; + } + @@ -1380,7 +1417,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + * last index in the block only + */ +int ext3_ext_rm_idx(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct buffer_head *bh; + int err; @@ -1394,7 +1431,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + if ((err = ext3_ext_dirty(handle, tree, path))) + return err; + ext_debug(tree, "index is empty, remove it, free block %d\n", -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + bh = sb_get_hash_table(tree->inode->i_sb, path->p_idx->ei_leaf); + ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf); + ext3_free_blocks(handle, tree->inode, path->p_idx->ei_leaf, 1); @@ -1402,7 +1439,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +} + +int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth = EXT_DEPTH(tree); + int needed; @@ -1439,8 +1476,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + +static int +ext3_ext_split_for_rm(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, tex; + struct ext3_ext_path *npath; @@ -1474,7 +1511,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + /* FIXME: some callback to free underlying resource + * and correct ee_start? */ + ext_debug(tree, "split extent: head %u:%u, tail %u:%u\n", -+ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); ++ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); + + npath = ext3_ext_find_extent(tree, ex->ee_block, NULL); + if (IS_ERR(npath)) @@ -1488,13 +1525,12 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + kfree(npath); + + return err; -+ +} + +static int +ext3_ext_rm_leaf(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, *fu = NULL, *lu, *le; + int err = 0, correct_index = 0; @@ -1527,8 +1563,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + } + + lu = ex; -+ while (ex >= EXT_FIRST_EXTENT(eh) && -+ ex->ee_block + ex->ee_len > start) { ++ while (ex >= EXT_FIRST_EXTENT(eh) && ex->ee_block + ex->ee_len > start) { + ext_debug(tree, "remove ext %u:%u\n", ex->ee_block, ex->ee_len); + path[depth].p_ext = ex; + @@ -1555,7 +1590,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + block = ex->ee_block; + num = 0; + EXT_ASSERT(a == ex->ee_block && -+ b == ex->ee_block + ex->ee_len - 1); ++ b == ex->ee_block + ex->ee_len - 1); + } + + if (ex == EXT_FIRST_EXTENT(eh)) @@ -1597,7 +1632,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + goto out; + + ext_debug(tree, "new extent: %u:%u:%u\n", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + ex--; + } + @@ -1661,7 +1696,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +} + +int ext3_ext_remove_space(struct ext3_extents_tree *tree, -+ unsigned long start, unsigned long end) ++ unsigned long start, unsigned long end) +{ + struct inode *inode = tree->inode; + struct super_block *sb = inode->i_sb; @@ -1685,8 +1720,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + */ + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL); + if (IS_ERR(path)) { -+ ext3_error(sb, "ext3_ext_remove_space", -+ "Can't allocate path array"); ++ ext3_error(sb, __FUNCTION__, "Can't allocate path array"); + ext3_journal_stop(handle, inode); + return -ENOMEM; + } @@ -1718,19 +1752,19 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + ext3_ext_last_covered(path[i].p_hdr, end); + path[i].p_block = path[i].p_hdr->eh_entries + 1; + ext_debug(tree, "init index ptr: hdr 0x%p, num %d\n", -+ path[i].p_hdr, path[i].p_hdr->eh_entries); ++ path[i].p_hdr, path[i].p_hdr->eh_entries); + } else { + /* we've already was here, see at next index */ + path[i].p_idx--; + } + + ext_debug(tree, "level %d - index, first 0x%p, cur 0x%p\n", -+ i, EXT_FIRST_INDEX(path[i].p_hdr), -+ path[i].p_idx); ++ i, EXT_FIRST_INDEX(path[i].p_hdr), ++ path[i].p_idx); + if (ext3_ext_more_to_rm(path + i)) { + /* go to the next level */ + ext_debug(tree, "move to level %d (block %d)\n", -+ i + 1, path[i].p_idx->ei_leaf); ++ i + 1, path[i].p_idx->ei_leaf); + memset(path + i + 1, 0, sizeof(*path)); + path[i+1].p_bh = sb_bread(sb, path[i].p_idx->ei_leaf); + if (!path[i+1].p_bh) { @@ -1823,7 +1857,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +} + +static int ext3_ext_mergable(struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex2) +{ + /* FIXME: support for large fs */ + if (ex1->ee_start + ex1->ee_len == ex2->ee_start) @@ -1833,8 +1867,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + +static int +ext3_remove_blocks_credits(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed; + @@ -1849,8 +1883,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + +static int +ext3_remove_blocks(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed = ext3_remove_blocks_credits(tree, ex, from, to); + handle_t *handle = ext3_journal_start(tree->inode, needed); @@ -1865,7 +1899,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + num = ex->ee_block + ex->ee_len - from; + start = ex->ee_start + ex->ee_len - num; + ext_debug(tree, "free last %lu blocks starting %lu\n", -+ num, start); ++ num, start); + for (i = 0; i < num; i++) { + bh = sb_get_hash_table(tree->inode->i_sb, start + i); + ext3_forget(handle, 0, tree->inode, bh, start + i); @@ -1873,17 +1907,17 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + ext3_free_blocks(handle, tree->inode, start, num); + } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { + printk("strange request: removal %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } else { + printk("strange request: removal(2) %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } + ext3_journal_stop(handle, tree->inode); + return 0; +} + +int ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path, -+ unsigned long block) ++ unsigned long block) +{ + struct ext3_inode_info *ei = EXT3_I(inode); + unsigned long bg_start; @@ -1913,8 +1947,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +} + +static int ext3_new_block_cb(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int *err) ++ struct ext3_ext_path *path, ++ struct ext3_extent *ex, int *err) +{ + struct inode *inode = tree->inode; + int newblock, goal; @@ -1951,7 +1985,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +}; + +void ext3_init_tree_desc(struct ext3_extents_tree *tree, -+ struct inode *inode) ++ struct inode *inode) +{ + tree->inode = inode; + tree->root = (void *) EXT3_I(inode)->i_data; @@ -1962,7 +1996,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +} + +int ext3_ext_get_block(handle_t *handle, struct inode *inode, -+ long iblock, struct buffer_head *bh_result, int create) ++ long iblock, struct buffer_head *bh_result, int create) +{ + struct ext3_ext_path *path = NULL; + struct ext3_extent newex; @@ -1973,7 +2007,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + clear_bit(BH_New, &bh_result->b_state); + ext3_init_tree_desc(&tree, inode); + ext_debug(&tree, "block %d requested for inode %u\n", -+ (int) iblock, (unsigned) inode->i_ino); ++ (int) iblock, (unsigned) inode->i_ino); + down_write(&EXT3_I(inode)->truncate_sem); + + /* check in cache */ @@ -2016,11 +2050,11 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + if (iblock >= ex->ee_block && iblock < ex->ee_block + ex->ee_len) { + newblock = iblock - ex->ee_block + ex->ee_start; + ext_debug(&tree, "%d fit into %d:%d -> %d\n", -+ (int) iblock, ex->ee_block, ex->ee_len, -+ newblock); ++ (int) iblock, ex->ee_block, ex->ee_len, ++ newblock); + ext3_ext_put_in_cache(&tree, ex->ee_block, -+ ex->ee_len, ex->ee_start, -+ EXT3_EXT_CACHE_EXTENT); ++ ex->ee_len, ex->ee_start, ++ EXT3_EXT_CACHE_EXTENT); + goto out; + } + } @@ -2041,7 +2075,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + if (!newblock) + goto out2; + ext_debug(&tree, "allocate new block: goal %d, found %d\n", -+ goal, newblock); ++ goal, newblock); + + /* try to insert new extent into found leaf and return */ + newex.ee_block = iblock; @@ -2059,7 +2093,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + set_bit(BH_New, &bh_result->b_state); + + ext3_ext_put_in_cache(&tree, newex.ee_block, newex.ee_len, -+ newex.ee_start, EXT3_EXT_CACHE_EXTENT); ++ newex.ee_start, EXT3_EXT_CACHE_EXTENT); +out: + ext3_ext_show_leaf(&tree, path); + set_bit(BH_Mapped, &bh_result->b_state); @@ -2096,7 +2130,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + + if (page) + ext3_block_truncate_page(handle, mapping, inode->i_size, page, -+ inode->i_sb->s_blocksize); ++ inode->i_sb->s_blocksize); + + down_write(&EXT3_I(inode)->truncate_sem); + ext3_ext_invalidate_cache(&tree); @@ -2113,8 +2147,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + EXT3_I(inode)->i_disksize = inode->i_size; + ext3_mark_inode_dirty(handle, inode); + -+ last_block = (inode->i_size + sb->s_blocksize - 1) -+ >> EXT3_BLOCK_SIZE_BITS(sb); ++ last_block = (inode->i_size + sb->s_blocksize - 1) >> ++ EXT3_BLOCK_SIZE_BITS(sb); + err = ext3_ext_remove_space(&tree, last_block, EXT_MAX_BLOCK); + + /* In a multi-transaction truncate, we only make the final @@ -2181,13 +2215,14 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + +static int +ext3_ext_store_extent_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newex, int exist) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *newex) +{ + struct ext3_extent_buf *buf = (struct ext3_extent_buf *) tree->private; + -+ if (!exist) ++ if (newex->ec_type != EXT3_EXT_CACHE_EXTENT) + return EXT_CONTINUE; ++ + if (buf->err < 0) + return EXT_BREAK; + if (buf->cur - buf->buffer + sizeof(*newex) > buf->buflen) @@ -2205,14 +2240,14 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + +static int +ext3_ext_collect_stats_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int exist) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *ex) +{ + struct ext3_extent_tree_stats *buf = + (struct ext3_extent_tree_stats *) tree->private; + int depth; + -+ if (!exist) ++ if (ex->ec_type != EXT3_EXT_CACHE_EXTENT) + return EXT_CONTINUE; + + depth = EXT_DEPTH(tree); @@ -2243,7 +2278,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + tree.private = &buf; + down_write(&EXT3_I(inode)->truncate_sem); + err = ext3_ext_walk_space(&tree, buf.start, EXT_MAX_BLOCK, -+ ext3_ext_store_extent_cb); ++ ext3_ext_store_extent_cb); + up_write(&EXT3_I(inode)->truncate_sem); + if (err == 0) + err = buf.err; @@ -2258,7 +2293,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c + buf.leaf_num = 0; + tree.private = &buf; + err = ext3_ext_walk_space(&tree, 0, EXT_MAX_BLOCK, -+ ext3_ext_collect_stats_cb); ++ ext3_ext_collect_stats_cb); + up_write(&EXT3_I(inode)->truncate_sem); + if (!err) + err = copy_to_user((void *) arg, &buf, sizeof(buf)); @@ -2280,22 +2315,18 @@ Index: linux-2.4.21-20.EL/fs/ext3/extents.c +EXPORT_SYMBOL(ext3_ext_walk_space); +EXPORT_SYMBOL(ext3_ext_find_goal); +EXPORT_SYMBOL(ext3_ext_calc_credits_for_insert); -+ -Index: linux-2.4.21-20.EL/fs/ext3/ialloc.c +Index: linux-2.4.21-rhel/fs/ext3/ialloc.c =================================================================== ---- linux-2.4.21-20.EL.orig/fs/ext3/ialloc.c 2004-11-02 20:43:27.000000000 +0300 -+++ linux-2.4.21-20.EL/fs/ext3/ialloc.c 2004-11-02 20:53:34.000000000 +0300 -@@ -596,9 +596,22 @@ +--- linux-2.4.21-rhel.orig/fs/ext3/ialloc.c 2005-03-04 00:44:34.000000000 +0300 ++++ linux-2.4.21-rhel/fs/ext3/ialloc.c 2005-03-04 00:44:35.000000000 +0300 +@@ -596,6 +596,19 @@ iloc.bh = NULL; goto fail; } -- err = ext3_mark_iloc_dirty(handle, inode, &iloc); -- if (err) goto fail; - -+ if (test_opt(sb, EXTENTS)) { -+ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; -+ memset(&inode->u.ext3_i.i_cached_extent, 0, sizeof(__u32) * 4); -+ ext3_extents_initialize_blockmap(handle, inode); ++ if (test_opt(sb, EXTENTS) && S_ISREG(inode->i_mode)) { ++ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; ++ memset(&EXT3_I(inode)->i_cached_extent, 0, sizeof(__u32) * 4); ++ ext3_extents_initialize_blockmap(handle, inode); + if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS)) { + err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); + if (err) goto fail; @@ -2303,29 +2334,27 @@ Index: linux-2.4.21-20.EL/fs/ext3/ialloc.c + BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "call ext3_journal_dirty_metadata"); + err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); + } -+ } -+ -+ err = ext3_mark_iloc_dirty(handle, inode, &iloc); -+ if (err) goto fail; - - - #ifdef CONFIG_EXT3_FS_XATTR -Index: linux-2.4.21-20.EL/fs/ext3/inode.c ++ } ++ + err = ext3_mark_iloc_dirty(handle, inode, &iloc); + if (err) goto fail; + +Index: linux-2.4.21-rhel/fs/ext3/inode.c =================================================================== ---- linux-2.4.21-20.EL.orig/fs/ext3/inode.c 2004-11-02 20:43:31.000000000 +0300 -+++ linux-2.4.21-20.EL/fs/ext3/inode.c 2004-11-02 20:53:34.000000000 +0300 +--- linux-2.4.21-rhel.orig/fs/ext3/inode.c 2005-03-04 00:44:34.000000000 +0300 ++++ linux-2.4.21-rhel/fs/ext3/inode.c 2005-03-04 00:44:35.000000000 +0300 @@ -859,6 +859,16 @@ goto reread; } +static inline int +ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block, -+ struct buffer_head *bh, int create, int extend_disksize) ++ struct buffer_head *bh, int create, int extend_disksize) +{ + if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) + return ext3_ext_get_block(handle, inode, block, bh, create); + return ext3_get_block_handle(handle, inode, block, bh, create, -+ extend_disksize); ++ extend_disksize); +} + /* @@ -2363,8 +2392,8 @@ Index: linux-2.4.21-20.EL/fs/ext3/inode.c if (IS_ERR(page)) return; + -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) -+ return ext3_ext_truncate(inode, page); ++ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) ++ return ext3_ext_truncate(inode, page); handle = start_transaction(inode); if (IS_ERR(handle)) @@ -2372,7 +2401,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/inode.c for (block = 0; block < EXT3_N_BLOCKS; block++) ei->i_data[block] = iloc.raw_inode->i_block[block]; INIT_LIST_HEAD(&ei->i_orphan); -+ memset(&inode->u.ext3_i.i_cached_extent, 0, sizeof(__u32) * 4); ++ memset(&EXT3_I(inode)->i_cached_extent, 0, sizeof(__u32) * 4); if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) EXT3_I(inode)->i_extra_isize = @@ -2404,10 +2433,10 @@ Index: linux-2.4.21-20.EL/fs/ext3/inode.c if (rc) { printk(KERN_INFO "ext3_map_inode_page: error %d " "allocating block %ld\n", rc, iblock); -Index: linux-2.4.21-20.EL/fs/ext3/Makefile +Index: linux-2.4.21-rhel/fs/ext3/Makefile =================================================================== ---- linux-2.4.21-20.EL.orig/fs/ext3/Makefile 2004-11-02 20:43:19.000000000 +0300 -+++ linux-2.4.21-20.EL/fs/ext3/Makefile 2004-11-02 20:53:34.000000000 +0300 +--- linux-2.4.21-rhel.orig/fs/ext3/Makefile 2005-03-04 00:44:33.000000000 +0300 ++++ linux-2.4.21-rhel/fs/ext3/Makefile 2005-03-04 00:44:35.000000000 +0300 @@ -9,10 +9,11 @@ O_TARGET := ext3.o @@ -2422,11 +2451,11 @@ Index: linux-2.4.21-20.EL/fs/ext3/Makefile obj-m := $(O_TARGET) export-objs += xattr.o -Index: linux-2.4.21-20.EL/fs/ext3/super.c +Index: linux-2.4.21-rhel/fs/ext3/super.c =================================================================== ---- linux-2.4.21-20.EL.orig/fs/ext3/super.c 2004-11-02 20:43:27.000000000 +0300 -+++ linux-2.4.21-20.EL/fs/ext3/super.c 2004-11-02 20:53:34.000000000 +0300 -@@ -648,6 +648,7 @@ +--- linux-2.4.21-rhel.orig/fs/ext3/super.c 2005-03-04 00:44:34.000000000 +0300 ++++ linux-2.4.21-rhel/fs/ext3/super.c 2005-03-04 00:44:35.000000000 +0300 +@@ -556,6 +556,7 @@ #ifdef EXT3_DELETE_THREAD J_ASSERT(sbi->s_delete_inodes == 0); #endif @@ -2434,7 +2463,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/super.c ext3_xattr_put_super(sb); journal_destroy(sbi->s_journal); if (!(sb->s_flags & MS_RDONLY)) { -@@ -851,6 +852,10 @@ +@@ -755,6 +756,10 @@ return 0; } } @@ -2445,7 +2474,7 @@ Index: linux-2.4.21-20.EL/fs/ext3/super.c else if (!strcmp (this_char, "grpid") || !strcmp (this_char, "bsdgroups")) set_opt (*mount_options, GRPID); -@@ -1546,6 +1551,8 @@ +@@ -1450,6 +1455,8 @@ test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered": "writeback"); @@ -2454,10 +2483,10 @@ Index: linux-2.4.21-20.EL/fs/ext3/super.c return sb; failed_mount3: -Index: linux-2.4.21-20.EL/fs/ext3/ioctl.c +Index: linux-2.4.21-rhel/fs/ext3/ioctl.c =================================================================== ---- linux-2.4.21-20.EL.orig/fs/ext3/ioctl.c 2004-11-02 20:43:14.000000000 +0300 -+++ linux-2.4.21-20.EL/fs/ext3/ioctl.c 2004-11-02 20:53:34.000000000 +0300 +--- linux-2.4.21-rhel.orig/fs/ext3/ioctl.c 2005-03-04 00:44:32.000000000 +0300 ++++ linux-2.4.21-rhel/fs/ext3/ioctl.c 2005-03-04 00:44:35.000000000 +0300 @@ -173,6 +173,10 @@ return ret; } @@ -2469,25 +2498,28 @@ Index: linux-2.4.21-20.EL/fs/ext3/ioctl.c default: return -ENOTTY; } -Index: linux-2.4.21-20.EL/include/linux/ext3_fs.h +Index: linux-2.4.21-rhel/include/linux/ext3_fs.h =================================================================== ---- linux-2.4.21-20.EL.orig/include/linux/ext3_fs.h 2004-11-02 20:43:27.000000000 +0300 -+++ linux-2.4.21-20.EL/include/linux/ext3_fs.h 2004-11-02 20:53:34.000000000 +0300 -@@ -188,6 +188,7 @@ +--- linux-2.4.21-rhel.orig/include/linux/ext3_fs.h 2005-03-04 00:44:34.000000000 +0300 ++++ linux-2.4.21-rhel/include/linux/ext3_fs.h 2005-03-04 00:44:35.000000000 +0300 +@@ -188,8 +188,9 @@ #define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */ #define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ +#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ - #define EXT3_FL_USER_VISIBLE 0x00005FFF /* User visible flags */ +-#define EXT3_FL_USER_VISIBLE 0x00005FFF /* User visible flags */ ++#define EXT3_FL_USER_VISIBLE 0x00085FFF /* User visible flags */ #define EXT3_FL_USER_MODIFIABLE 0x000000FF /* User modifiable flags */ + + /* @@ -212,6 +213,9 @@ #ifdef CONFIG_JBD_DEBUG #define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) #endif -+#define EXT3_IOC_GET_EXTENTS _IOR('f', 5, long) -+#define EXT3_IOC_GET_TREE_DEPTH _IOR('f', 6, long) -+#define EXT3_IOC_GET_TREE_STATS _IOR('f', 7, long) ++#define EXT3_IOC_GET_EXTENTS _IOR('f', 5, long) ++#define EXT3_IOC_GET_TREE_DEPTH _IOR('f', 6, long) ++#define EXT3_IOC_GET_TREE_STATS _IOR('f', 7, long) /* * Structure of an inode on the disk @@ -2518,7 +2550,7 @@ Index: linux-2.4.21-20.EL/include/linux/ext3_fs.h extern unsigned long ext3_count_free (struct buffer_head *, unsigned); /* inode.c */ -+int ext3_block_truncate_page(handle_t *, struct address_space *, loff_t, ++extern int ext3_block_truncate_page(handle_t *, struct address_space *, loff_t, + struct page *, unsigned); 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 *); @@ -2530,7 +2562,7 @@ Index: linux-2.4.21-20.EL/include/linux/ext3_fs.h +/* extents.c */ +extern int ext3_ext_writepage_trans_blocks(struct inode *, int); +extern int ext3_ext_get_block(handle_t *, struct inode *, long, -+ struct buffer_head *, int); ++ struct buffer_head *, int); +extern void ext3_ext_truncate(struct inode *, struct page *); +extern void ext3_ext_init(struct super_block *); +extern void ext3_ext_release(struct super_block *); @@ -2540,11 +2572,11 @@ Index: linux-2.4.21-20.EL/include/linux/ext3_fs.h #endif /* __KERNEL__ */ -Index: linux-2.4.21-20.EL/include/linux/ext3_extents.h +Index: linux-2.4.21-rhel/include/linux/ext3_extents.h =================================================================== ---- linux-2.4.21-20.EL.orig/include/linux/ext3_extents.h 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.21-20.EL/include/linux/ext3_extents.h 2004-11-02 20:53:34.000000000 +0300 -@@ -0,0 +1,251 @@ +--- linux-2.4.21-rhel.orig/include/linux/ext3_extents.h 2005-03-02 22:42:20.659360368 +0300 ++++ linux-2.4.21-rhel/include/linux/ext3_extents.h 2005-03-04 02:34:52.000000000 +0300 +@@ -0,0 +1,263 @@ +/* + * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas @@ -2586,7 +2618,7 @@ Index: linux-2.4.21-20.EL/include/linux/ext3_extents.h + */ +#define EXT_DEBUG_ +#ifdef EXT_DEBUG -+#define ext_debug(tree,fmt,a...) \ ++#define ext_debug(tree,fmt,a...) \ +do { \ + if (test_opt((tree)->inode->i_sb, EXTDEBUG)) \ + printk(fmt, ##a); \ @@ -2699,14 +2731,14 @@ Index: linux-2.4.21-20.EL/include/linux/ext3_extents.h + int (*mark_buffer_dirty)(handle_t *h, void *buffer); + int (*mergable)(struct ext3_extent *ex1, struct ext3_extent *ex2); + int (*remove_extent_credits)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*remove_extent)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*new_block)(handle_t *, struct ext3_extents_tree *, -+ struct ext3_ext_path *, struct ext3_extent *, -+ int *); ++ struct ext3_ext_path *, struct ext3_extent *, ++ int *); +}; + +/* @@ -2716,8 +2748,8 @@ Index: linux-2.4.21-20.EL/include/linux/ext3_extents.h + * callback must return valid extent (passed or newly created) + */ +typedef int (*ext_prepare_callback)(struct ext3_extents_tree *, -+ struct ext3_ext_path *, -+ struct ext3_extent *, int); ++ struct ext3_ext_path *, ++ struct ext3_ext_cache *); + +#define EXT_CONTINUE 0 +#define EXT_BREAK 1 @@ -2725,7 +2757,6 @@ Index: linux-2.4.21-20.EL/include/linux/ext3_extents.h + + +#define EXT_MAX_BLOCK 0xffffffff -+#define EXT_CACHE_MARK 0xffff + + +#define EXT_FIRST_EXTENT(__hdr__) \ @@ -2757,6 +2788,20 @@ Index: linux-2.4.21-20.EL/include/linux/ext3_extents.h + +#define EXT_ASSERT(__x__) if (!(__x__)) BUG(); + ++#define EXT_CHECK_PATH(tree,path) \ ++{ \ ++ int depth = EXT_DEPTH(tree); \ ++ BUG_ON((unsigned long) (path) < __PAGE_OFFSET); \ ++ BUG_ON((unsigned long) (path)[depth].p_idx < \ ++ __PAGE_OFFSET && (path)[depth].p_idx != NULL); \ ++ BUG_ON((unsigned long) (path)[depth].p_ext < \ ++ __PAGE_OFFSET && (path)[depth].p_ext != NULL); \ ++ BUG_ON((unsigned long) (path)[depth].p_hdr < __PAGE_OFFSET); \ ++ BUG_ON((unsigned long) (path)[depth].p_bh < __PAGE_OFFSET \ ++ && depth != 0); \ ++ BUG_ON((path)[0].p_depth != depth); \ ++} ++ + +/* + * this structure is used to gather extents from the tree via ioctl @@ -2778,7 +2823,7 @@ Index: linux-2.4.21-20.EL/include/linux/ext3_extents.h + int leaf_num; +}; + -+void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); ++extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); +extern int ext3_extent_tree_init(handle_t *, struct ext3_extents_tree *); +extern int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *, struct ext3_ext_path *); +extern int ext3_ext_insert_extent(handle_t *, struct ext3_extents_tree *, struct ext3_ext_path *, struct ext3_extent *); @@ -2795,17 +2840,16 @@ Index: linux-2.4.21-20.EL/include/linux/ext3_extents.h + + +#endif /* _LINUX_EXT3_EXTENTS */ -+ -Index: linux-2.4.21-20.EL/include/linux/ext3_fs_i.h +Index: linux-2.4.21-rhel/include/linux/ext3_fs_i.h =================================================================== ---- linux-2.4.21-20.EL.orig/include/linux/ext3_fs_i.h 2004-11-02 20:43:27.000000000 +0300 -+++ linux-2.4.21-20.EL/include/linux/ext3_fs_i.h 2004-11-02 20:58:19.000000000 +0300 +--- linux-2.4.21-rhel.orig/include/linux/ext3_fs_i.h 2005-03-04 00:44:34.000000000 +0300 ++++ linux-2.4.21-rhel/include/linux/ext3_fs_i.h 2005-03-04 01:56:36.000000000 +0300 @@ -90,6 +90,8 @@ * by other means, so we have truncate_sem. */ struct rw_semaphore truncate_sem; + -+ __u32 i_cached_extent[4]; ++ __u32 i_cached_extent[4]; }; #endif /* _LINUX_EXT3_FS_I */ diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.21-suse2.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.21-suse2.patch index 2e467d6..7cfd7ee 100644 --- a/lustre/kernel_patches/patches/ext3-extents-2.4.21-suse2.patch +++ b/lustre/kernel_patches/patches/ext3-extents-2.4.21-suse2.patch @@ -2,9 +2,9 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c =================================================================== --- linux-2.4.21-suse2.orig/fs/ext3/extents.c 2003-01-30 13:24:37.000000000 +0300 +++ linux-2.4.21-suse2/fs/ext3/extents.c 2004-11-03 00:34:45.404241880 +0300 -@@ -0,0 +1,2269 @@ +@@ -0,0 +1,2303 @@ +/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com ++ * Copyright(c) 2003, 2004, 2005, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify @@ -49,6 +49,27 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +#include +#include + ++ ++static inline int ext3_ext_check_header(struct ext3_extent_header *eh) ++{ ++ if (eh->eh_magic != EXT3_EXT_MAGIC) { ++ printk(KERN_ERR "EXT3-fs: invalid magic = 0x%x\n", ++ (unsigned)eh->eh_magic); ++ return -EIO; ++ } ++ if (eh->eh_max == 0) { ++ printk(KERN_ERR "EXT3-fs: invalid eh_max = %u\n", ++ (unsigned)eh->eh_max); ++ return -EIO; ++ } ++ if (eh->eh_entries > eh->eh_max) { ++ printk(KERN_ERR "EXT3-fs: invalid eh_entries = %u\n", ++ (unsigned)eh->eh_entries); ++ return -EIO; ++ } ++ return 0; ++} ++ +static handle_t *ext3_ext_journal_restart(handle_t *handle, int needed) +{ + int err; @@ -86,8 +107,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + * - ENOMEM + */ +static int ext3_ext_get_access(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path) +{ + int err; + @@ -108,7 +129,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + * - EIO + */ +static int ext3_ext_dirty(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int err; + if (path->p_bh) { @@ -123,8 +144,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + +static int inline +ext3_ext_new_block(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, struct ext3_extent *ex, -+ int *err) ++ struct ext3_ext_path *path, struct ext3_extent *ex, ++ int *err) +{ + int goal, depth, newblock; + struct inode *inode; @@ -143,7 +164,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + unsigned long colour; + + bg_start = (ei->i_block_group * -+ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + ++ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + + le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); + colour = (current->pid % 16) * + (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); @@ -166,8 +187,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 6; +#endif @@ -179,8 +200,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 5; +#endif @@ -191,8 +212,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 3; +#endif @@ -203,9 +224,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 4; +#endif @@ -213,7 +233,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +} + +static void ext3_ext_show_path(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int k, l = path->p_depth; @@ -222,12 +242,12 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + for (k = 0; k <= l; k++, path++) { + if (path->p_idx) { + ext_debug(tree, " %d->%d", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + } else if (path->p_ext) { + ext_debug(tree, " %d:%d:%d", -+ path->p_ext->ee_block, -+ path->p_ext->ee_len, -+ path->p_ext->ee_start); ++ path->p_ext->ee_block, ++ path->p_ext->ee_len, ++ path->p_ext->ee_start); + } else + ext_debug(tree, " []"); + } @@ -236,7 +256,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +} + +static void ext3_ext_show_leaf(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int depth = EXT_DEPTH(tree); @@ -252,7 +272,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + + for (i = 0; i < eh->eh_entries; i++, ex++) { + ext_debug(tree, "%d:%d:%d ", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + } + ext_debug(tree, "\n"); +#endif @@ -263,11 +283,12 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + int depth = path->p_depth; + int i; + -+ for (i = 0; i <= depth; i++, path++) ++ for (i = 0; i <= depth; i++, path++) { + if (path->p_bh) { + brelse(path->p_bh); + path->p_bh = NULL; + } ++ } +} + +/* @@ -275,7 +296,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch_idx(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent_idx *ix; @@ -301,7 +322,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + + ix += l; + path->p_idx = ix; -+ ext_debug(tree, " -> %d->%d ", path->p_idx->ei_block, path->p_idx->ei_leaf); ++ ext_debug(tree," -> %d->%d ",path->p_idx->ei_block,path->p_idx->ei_leaf); + + while (l++ < r) { + if (block < ix->ei_block) @@ -309,7 +330,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + path->p_idx = ix++; + } + ext_debug(tree, " -> %d->%d\n", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + +#ifdef CHECK_BINSEARCH + { @@ -319,9 +340,9 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + for (k = 0; k < eh->eh_entries; k++, ix++) { + if (k != 0 && ix->ei_block <= ix[-1].ei_block) { + printk("k=%d, ix=0x%p, first=0x%p\n", k, -+ ix, EXT_FIRST_INDEX(eh)); ++ ix, EXT_FIRST_INDEX(eh)); + printk("%u <= %u\n", -+ ix->ei_block,ix[-1].ei_block); ++ ix->ei_block,ix[-1].ei_block); + } + EXT_ASSERT(k == 0 || ix->ei_block > ix[-1].ei_block); + if (block < ix->ei_block) @@ -331,7 +352,6 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + EXT_ASSERT(chix == path->p_idx); + } +#endif -+ +} + +/* @@ -339,7 +359,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent *ex; @@ -373,7 +393,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + ex += l; + path->p_ext = ex; + ext_debug(tree, " -> %d:%d:%d ", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + + while (l++ < r) { + if (block < ex->ee_block) @@ -381,7 +401,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + path->p_ext = ex++; + } + ext_debug(tree, " -> %d:%d:%d\n", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + +#ifdef CHECK_BINSEARCH + { @@ -397,7 +417,6 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + EXT_ASSERT(chex == path->p_ext); + } +#endif -+ +} + +int ext3_extent_tree_init(handle_t *handle, struct ext3_extents_tree *tree) @@ -418,7 +437,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + +struct ext3_ext_path * +ext3_ext_find_extent(struct ext3_extents_tree *tree, int block, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + struct buffer_head *bh; @@ -430,15 +449,17 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + + eh = EXT_ROOT_HDR(tree); + EXT_ASSERT(eh); ++ if (ext3_ext_check_header(eh)) ++ goto err; ++ + i = depth = EXT_DEPTH(tree); + EXT_ASSERT(eh->eh_max); + EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ EXT_ASSERT(i == 0 || eh->eh_entries > 0); + + /* account possible depth increase */ + if (!path) { + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2), -+ GFP_NOFS); ++ GFP_NOFS); + if (!path) + return ERR_PTR(-ENOMEM); + } @@ -448,29 +469,34 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + /* walk through the tree */ + while (i) { + ext_debug(tree, "depth %d: num %d, max %d\n", -+ ppos, eh->eh_entries, eh->eh_max); ++ ppos, eh->eh_entries, eh->eh_max); + ext3_ext_binsearch_idx(tree, path + ppos, block); + path[ppos].p_block = path[ppos].p_idx->ei_leaf; + path[ppos].p_depth = i; + path[ppos].p_ext = NULL; + + bh = sb_bread(tree->inode->i_sb, path[ppos].p_block); -+ if (!bh) { -+ ext3_ext_drop_refs(path); -+ kfree(path); -+ return ERR_PTR(-EIO); -+ } ++ if (!bh) ++ goto err; ++ + eh = EXT_BLOCK_HDR(bh); + ppos++; + EXT_ASSERT(ppos <= depth); + path[ppos].p_bh = bh; + path[ppos].p_hdr = eh; + i--; ++ ++ if (ext3_ext_check_header(eh)) ++ goto err; + } + + path[ppos].p_depth = i; + path[ppos].p_hdr = eh; + path[ppos].p_ext = NULL; ++ path[ppos].p_idx = NULL; ++ ++ if (ext3_ext_check_header(eh)) ++ goto err; + + /* find extent */ + ext3_ext_binsearch(tree, path + ppos, block); @@ -478,6 +504,12 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + ext3_ext_show_path(tree, path); + + return path; ++ ++err: ++ printk(KERN_ERR "EXT3-fs: header is corrupted!\n"); ++ ext3_ext_drop_refs(path); ++ kfree(path); ++ return ERR_PTR(-EIO); +} + +/* @@ -485,9 +517,9 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + * it check where to insert: before curp or after curp + */ +static int ext3_ext_insert_index(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *curp, -+ int logical, int ptr) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *curp, ++ int logical, int ptr) +{ + struct ext3_extent_idx *ix; + int len, err; @@ -503,9 +535,9 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d after: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ (curp->p_idx + 1), (curp->p_idx + 2)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ (curp->p_idx + 1), (curp->p_idx + 2)); + memmove(curp->p_idx + 2, curp->p_idx + 1, len); + } + ix = curp->p_idx + 1; @@ -514,9 +546,9 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + len = len * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d before: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ curp->p_idx, (curp->p_idx + 1)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ curp->p_idx, (curp->p_idx + 1)); + memmove(curp->p_idx + 1, curp->p_idx, len); + ix = curp->p_idx; + } @@ -544,8 +576,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + * - initialize subtree + */ +static int ext3_ext_split(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext, int at) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext, int at) +{ + struct buffer_head *bh = NULL; + int depth = EXT_DEPTH(tree); @@ -566,13 +598,13 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) { + border = path[depth].p_ext[1].ee_block; + ext_debug(tree, "leaf will be splitted." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } else { + border = newext->ee_block; + ext_debug(tree, "leaf will be added." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } + + /* @@ -630,12 +662,11 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + while (path[depth].p_ext <= + EXT_MAX_EXTENT(path[depth].p_hdr)) { + ext_debug(tree, "move %d:%d:%d in new leaf %lu\n", -+ path[depth].p_ext->ee_block, -+ path[depth].p_ext->ee_start, -+ path[depth].p_ext->ee_len, -+ newblock); -+ memmove(ex++, path[depth].p_ext++, -+ sizeof(struct ext3_extent)); ++ path[depth].p_ext->ee_block, ++ path[depth].p_ext->ee_start, ++ path[depth].p_ext->ee_len, ++ newblock); ++ memmove(ex++, path[depth].p_ext++, sizeof(struct ext3_extent)); + neh->eh_entries++; + m++; + } @@ -688,21 +719,21 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + fidx->ei_leaf = oldblock; + + ext_debug(tree, "int.index at %d (block %lu): %lu -> %lu\n", -+ i, newblock, border, oldblock); ++ i, newblock, border, oldblock); + /* copy indexes */ + m = 0; + path[i].p_idx++; + + ext_debug(tree, "cur 0x%p, last 0x%p\n", path[i].p_idx, -+ EXT_MAX_INDEX(path[i].p_hdr)); ++ EXT_MAX_INDEX(path[i].p_hdr)); + EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) == -+ EXT_LAST_INDEX(path[i].p_hdr)); ++ EXT_LAST_INDEX(path[i].p_hdr)); + while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { + ext_debug(tree, "%d: move %d:%d in new index %lu\n", -+ i, path[i].p_idx->ei_block, -+ path[i].p_idx->ei_leaf, newblock); ++ i, path[i].p_idx->ei_block, ++ path[i].p_idx->ei_leaf, newblock); + memmove(++fidx, path[i].p_idx++, -+ sizeof(struct ext3_extent_idx)); ++ sizeof(struct ext3_extent_idx)); + neh->eh_entries++; + EXT_ASSERT(neh->eh_entries <= neh->eh_max); + m++; @@ -732,7 +763,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + /* insert new index */ + if (!err) + err = ext3_ext_insert_index(handle, tree, path + at, -+ border, newblock); ++ border, newblock); + +cleanup: + if (bh) { @@ -762,9 +793,9 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + * just created block + */ +static int ext3_ext_grow_indepth(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp = path; + struct ext3_extent_header *neh; @@ -823,7 +854,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + neh = EXT_ROOT_HDR(tree); + fidx = EXT_FIRST_INDEX(neh); + ext_debug(tree, "new root: num %d(%d), lblock %d, ptr %d\n", -+ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); ++ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); + + neh->eh_depth = path->p_depth + 1; + err = ext3_ext_dirty(handle, tree, curp); @@ -838,9 +869,9 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + * then it requests in-depth growing + */ +static int ext3_ext_create_new_leaf(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp; + int depth, i, err = 0; @@ -916,12 +947,12 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + if (depth == path->p_depth) { + /* leaf */ + if (path[depth].p_ext != -+ EXT_LAST_EXTENT(path[depth].p_hdr)) ++ EXT_LAST_EXTENT(path[depth].p_hdr)) + return path[depth].p_ext[1].ee_block; + } else { + /* index */ + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + } + depth--; @@ -934,7 +965,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + * returns first allocated block from next leaf or EXT_MAX_BLOCK + */ +static unsigned ext3_ext_next_leaf_block(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth; + @@ -950,7 +981,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + + while (depth >= 0) { + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + depth--; + } @@ -964,7 +995,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + * TODO: do we need to correct tree in all cases? + */ +int ext3_ext_correct_indexes(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + int depth = EXT_DEPTH(tree); @@ -1014,8 +1045,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + +static int inline +ext3_can_extents_be_merged(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex1, ++ struct ext3_extent *ex2) +{ + if (ex1->ee_block + ex1->ee_len != ex2->ee_block) + return 0; @@ -1037,8 +1068,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + * creating new leaf in no-space case + */ +int ext3_ext_insert_extent(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_extent_header * eh; + struct ext3_extent *ex, *fex; @@ -1047,7 +1078,6 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + int depth, len, err, next; + + EXT_ASSERT(newext->ee_len > 0); -+ EXT_ASSERT(newext->ee_len < EXT_CACHE_MARK); + depth = EXT_DEPTH(tree); + ex = path[depth].p_ext; + EXT_ASSERT(path[depth].p_hdr); @@ -1055,8 +1085,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + /* try to insert block into found extent and return */ + if (ex && ext3_can_extents_be_merged(tree, ex, newext)) { + ext_debug(tree, "append %d block to %d:%d (from %d)\n", -+ newext->ee_len, ex->ee_block, ex->ee_len, -+ ex->ee_start); ++ newext->ee_len, ex->ee_block, ex->ee_len, ++ ex->ee_start); + if ((err = ext3_ext_get_access(handle, tree, path + depth))) + return err; + ex->ee_len += newext->ee_len; @@ -1084,12 +1114,12 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + eh = npath[depth].p_hdr; + if (eh->eh_entries < eh->eh_max) { + ext_debug(tree, "next leaf isnt full(%d)\n", -+ eh->eh_entries); ++ eh->eh_entries); + path = npath; + goto repeat; + } + ext_debug(tree, "next leaf hasno free space(%d,%d)\n", -+ eh->eh_entries, eh->eh_max); ++ eh->eh_entries, eh->eh_max); + } + + /* @@ -1111,8 +1141,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + if (!nearex) { + /* there is no extent in this leaf, create first one */ + ext_debug(tree, "first extent in the leaf: %d:%d:%d\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len); ++ newext->ee_block, newext->ee_start, ++ newext->ee_len); + path[depth].p_ext = EXT_FIRST_EXTENT(eh); + } else if (newext->ee_block > nearex->ee_block) { + EXT_ASSERT(newext->ee_block != nearex->ee_block); @@ -1121,10 +1151,10 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d after: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, ++ newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 2, nearex + 1, len); + } + path[depth].p_ext = nearex + 1; @@ -1133,9 +1163,9 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d before: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 1, nearex, len); + path[depth].p_ext = nearex; + } @@ -1156,8 +1186,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + /* merge with next extent! */ + nearex->ee_len += nearex[1].ee_len; + if (nearex + 1 < EXT_LAST_EXTENT(eh)) { -+ len = (EXT_LAST_EXTENT(eh) - nearex - 1) -+ * sizeof(struct ext3_extent); ++ len = (EXT_LAST_EXTENT(eh) - nearex - 1) * ++ sizeof(struct ext3_extent); + memmove(nearex + 1, nearex + 2, len); + } + eh->eh_entries--; @@ -1187,7 +1217,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + unsigned long num, ext_prepare_callback func) +{ + struct ext3_ext_path *path = NULL; -+ struct ext3_extent *ex, cbex; ++ struct ext3_ext_cache cbex; ++ struct ext3_extent *ex; + unsigned long next, start = 0, end = 0; + unsigned long last = block + num; + int depth, exists, err = 0; @@ -1246,14 +1277,20 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + EXT_ASSERT(end > start); + + if (!exists) { -+ cbex.ee_block = start; -+ cbex.ee_len = end - start; -+ cbex.ee_start = 0; -+ } else -+ cbex = *ex; ++ cbex.ec_block = start; ++ cbex.ec_len = end - start; ++ cbex.ec_start = 0; ++ cbex.ec_type = EXT3_EXT_CACHE_GAP; ++ } else { ++ cbex.ec_block = ex->ee_block; ++ cbex.ec_len = ex->ee_len; ++ cbex.ec_start = ex->ee_start; ++ cbex.ec_type = EXT3_EXT_CACHE_EXTENT; ++ } + ++ EXT_ASSERT(cbex.ec_len > 0); + EXT_ASSERT(path[depth].p_hdr); -+ err = func(tree, path, &cbex, exists); ++ err = func(tree, path, &cbex); + ext3_ext_drop_refs(path); + + if (err < 0) @@ -1271,7 +1308,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + path = NULL; + } + -+ block = cbex.ee_block + cbex.ee_len; ++ block = cbex.ec_block + cbex.ec_len; + } + + if (path) { @@ -1284,7 +1321,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + +static inline void +ext3_ext_put_in_cache(struct ext3_extents_tree *tree, __u32 block, -+ __u32 len, __u32 start, int type) ++ __u32 len, __u32 start, int type) +{ + EXT_ASSERT(len > 0); + if (tree->cex) { @@ -1301,8 +1338,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + */ +static inline void +ext3_ext_put_gap_in_cache(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ unsigned long block) ++ struct ext3_ext_path *path, ++ unsigned long block) +{ + int depth = EXT_DEPTH(tree); + unsigned long lblock, len; @@ -1321,16 +1358,16 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + lblock = block; + len = ex->ee_block - block; + ext_debug(tree, "cache gap(before): %lu [%lu:%lu]", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len); + } else if (block >= ex->ee_block + ex->ee_len) { + lblock = ex->ee_block + ex->ee_len; + len = ext3_ext_next_allocated_block(path); + ext_debug(tree, "cache gap(after): [%lu:%lu] %lu", -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) block); ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) block); + EXT_ASSERT(len > lblock); + len = len - lblock; + } else { @@ -1344,7 +1381,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + +static inline int +ext3_ext_in_cache(struct ext3_extents_tree *tree, unsigned long block, -+ struct ext3_extent *ex) ++ struct ext3_extent *ex) +{ + struct ext3_ext_cache *cex = tree->cex; + @@ -1357,16 +1394,16 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + return EXT3_EXT_CACHE_NO; + + EXT_ASSERT(cex->ec_type == EXT3_EXT_CACHE_GAP || -+ cex->ec_type == EXT3_EXT_CACHE_EXTENT); ++ cex->ec_type == EXT3_EXT_CACHE_EXTENT); + if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) { + ex->ee_block = cex->ec_block; + ex->ee_start = cex->ec_start; + ex->ee_len = cex->ec_len; + ext_debug(tree, "%lu cached by %lu:%lu:%lu\n", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) ex->ee_start); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) ex->ee_start); + return cex->ec_type; + } + @@ -1380,7 +1417,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + * last index in the block only + */ +int ext3_ext_rm_idx(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct buffer_head *bh; + int err; @@ -1394,7 +1431,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + if ((err = ext3_ext_dirty(handle, tree, path))) + return err; + ext_debug(tree, "index is empty, remove it, free block %d\n", -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + bh = sb_get_hash_table(tree->inode->i_sb, path->p_idx->ei_leaf); + ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf); + ext3_free_blocks(handle, tree->inode, path->p_idx->ei_leaf, 1); @@ -1402,7 +1439,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +} + +int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth = EXT_DEPTH(tree); + int needed; @@ -1439,8 +1476,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + +static int +ext3_ext_split_for_rm(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, tex; + struct ext3_ext_path *npath; @@ -1474,7 +1511,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + /* FIXME: some callback to free underlying resource + * and correct ee_start? */ + ext_debug(tree, "split extent: head %u:%u, tail %u:%u\n", -+ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); ++ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); + + npath = ext3_ext_find_extent(tree, ex->ee_block, NULL); + if (IS_ERR(npath)) @@ -1488,13 +1525,12 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + kfree(npath); + + return err; -+ +} + +static int +ext3_ext_rm_leaf(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, *fu = NULL, *lu, *le; + int err = 0, correct_index = 0; @@ -1527,8 +1563,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + } + + lu = ex; -+ while (ex >= EXT_FIRST_EXTENT(eh) && -+ ex->ee_block + ex->ee_len > start) { ++ while (ex >= EXT_FIRST_EXTENT(eh) && ex->ee_block + ex->ee_len > start) { + ext_debug(tree, "remove ext %u:%u\n", ex->ee_block, ex->ee_len); + path[depth].p_ext = ex; + @@ -1555,7 +1590,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + block = ex->ee_block; + num = 0; + EXT_ASSERT(a == ex->ee_block && -+ b == ex->ee_block + ex->ee_len - 1); ++ b == ex->ee_block + ex->ee_len - 1); + } + + if (ex == EXT_FIRST_EXTENT(eh)) @@ -1597,7 +1632,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + goto out; + + ext_debug(tree, "new extent: %u:%u:%u\n", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + ex--; + } + @@ -1661,7 +1696,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +} + +int ext3_ext_remove_space(struct ext3_extents_tree *tree, -+ unsigned long start, unsigned long end) ++ unsigned long start, unsigned long end) +{ + struct inode *inode = tree->inode; + struct super_block *sb = inode->i_sb; @@ -1685,8 +1720,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + */ + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL); + if (IS_ERR(path)) { -+ ext3_error(sb, "ext3_ext_remove_space", -+ "Can't allocate path array"); ++ ext3_error(sb, __FUNCTION__, "Can't allocate path array"); + ext3_journal_stop(handle, inode); + return -ENOMEM; + } @@ -1718,19 +1752,19 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + ext3_ext_last_covered(path[i].p_hdr, end); + path[i].p_block = path[i].p_hdr->eh_entries + 1; + ext_debug(tree, "init index ptr: hdr 0x%p, num %d\n", -+ path[i].p_hdr, path[i].p_hdr->eh_entries); ++ path[i].p_hdr, path[i].p_hdr->eh_entries); + } else { + /* we've already was here, see at next index */ + path[i].p_idx--; + } + + ext_debug(tree, "level %d - index, first 0x%p, cur 0x%p\n", -+ i, EXT_FIRST_INDEX(path[i].p_hdr), -+ path[i].p_idx); ++ i, EXT_FIRST_INDEX(path[i].p_hdr), ++ path[i].p_idx); + if (ext3_ext_more_to_rm(path + i)) { + /* go to the next level */ + ext_debug(tree, "move to level %d (block %d)\n", -+ i + 1, path[i].p_idx->ei_leaf); ++ i + 1, path[i].p_idx->ei_leaf); + memset(path + i + 1, 0, sizeof(*path)); + path[i+1].p_bh = sb_bread(sb, path[i].p_idx->ei_leaf); + if (!path[i+1].p_bh) { @@ -1823,7 +1857,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +} + +static int ext3_ext_mergable(struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex2) +{ + /* FIXME: support for large fs */ + if (ex1->ee_start + ex1->ee_len == ex2->ee_start) @@ -1833,8 +1867,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + +static int +ext3_remove_blocks_credits(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed; + @@ -1849,8 +1883,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + +static int +ext3_remove_blocks(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed = ext3_remove_blocks_credits(tree, ex, from, to); + handle_t *handle = ext3_journal_start(tree->inode, needed); @@ -1865,7 +1899,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + num = ex->ee_block + ex->ee_len - from; + start = ex->ee_start + ex->ee_len - num; + ext_debug(tree, "free last %lu blocks starting %lu\n", -+ num, start); ++ num, start); + for (i = 0; i < num; i++) { + bh = sb_get_hash_table(tree->inode->i_sb, start + i); + ext3_forget(handle, 0, tree->inode, bh, start + i); @@ -1873,17 +1907,17 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + ext3_free_blocks(handle, tree->inode, start, num); + } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { + printk("strange request: removal %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } else { + printk("strange request: removal(2) %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } + ext3_journal_stop(handle, tree->inode); + return 0; +} + +int ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path, -+ unsigned long block) ++ unsigned long block) +{ + struct ext3_inode_info *ei = EXT3_I(inode); + unsigned long bg_start; @@ -1913,8 +1947,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +} + +static int ext3_new_block_cb(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int *err) ++ struct ext3_ext_path *path, ++ struct ext3_extent *ex, int *err) +{ + struct inode *inode = tree->inode; + int newblock, goal; @@ -1951,7 +1985,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +}; + +void ext3_init_tree_desc(struct ext3_extents_tree *tree, -+ struct inode *inode) ++ struct inode *inode) +{ + tree->inode = inode; + tree->root = (void *) EXT3_I(inode)->i_data; @@ -1962,7 +1996,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +} + +int ext3_ext_get_block(handle_t *handle, struct inode *inode, -+ long iblock, struct buffer_head *bh_result, int create) ++ long iblock, struct buffer_head *bh_result, int create) +{ + struct ext3_ext_path *path = NULL; + struct ext3_extent newex; @@ -1973,7 +2007,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + clear_bit(BH_New, &bh_result->b_state); + ext3_init_tree_desc(&tree, inode); + ext_debug(&tree, "block %d requested for inode %u\n", -+ (int) iblock, (unsigned) inode->i_ino); ++ (int) iblock, (unsigned) inode->i_ino); + down_write(&EXT3_I(inode)->truncate_sem); + + /* check in cache */ @@ -2016,11 +2050,11 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + if (iblock >= ex->ee_block && iblock < ex->ee_block + ex->ee_len) { + newblock = iblock - ex->ee_block + ex->ee_start; + ext_debug(&tree, "%d fit into %d:%d -> %d\n", -+ (int) iblock, ex->ee_block, ex->ee_len, -+ newblock); ++ (int) iblock, ex->ee_block, ex->ee_len, ++ newblock); + ext3_ext_put_in_cache(&tree, ex->ee_block, -+ ex->ee_len, ex->ee_start, -+ EXT3_EXT_CACHE_EXTENT); ++ ex->ee_len, ex->ee_start, ++ EXT3_EXT_CACHE_EXTENT); + goto out; + } + } @@ -2041,7 +2075,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + if (!newblock) + goto out2; + ext_debug(&tree, "allocate new block: goal %d, found %d\n", -+ goal, newblock); ++ goal, newblock); + + /* try to insert new extent into found leaf and return */ + newex.ee_block = iblock; @@ -2059,7 +2093,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + set_bit(BH_New, &bh_result->b_state); + + ext3_ext_put_in_cache(&tree, newex.ee_block, newex.ee_len, -+ newex.ee_start, EXT3_EXT_CACHE_EXTENT); ++ newex.ee_start, EXT3_EXT_CACHE_EXTENT); +out: + ext3_ext_show_leaf(&tree, path); + set_bit(BH_Mapped, &bh_result->b_state); @@ -2111,8 +2145,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + EXT3_I(inode)->i_disksize = inode->i_size; + ext3_mark_inode_dirty(handle, inode); + -+ last_block = (inode->i_size + sb->s_blocksize - 1) -+ >> EXT3_BLOCK_SIZE_BITS(sb); ++ last_block = (inode->i_size + sb->s_blocksize - 1) >> ++ EXT3_BLOCK_SIZE_BITS(sb); + err = ext3_ext_remove_space(&tree, last_block, EXT_MAX_BLOCK); + + /* In a multi-transaction truncate, we only make the final @@ -2172,13 +2206,14 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + +static int +ext3_ext_store_extent_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newex, int exist) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *newex) +{ + struct ext3_extent_buf *buf = (struct ext3_extent_buf *) tree->private; + -+ if (!exist) ++ if (newex->ec_type != EXT3_EXT_CACHE_EXTENT) + return EXT_CONTINUE; ++ + if (buf->err < 0) + return EXT_BREAK; + if (buf->cur - buf->buffer + sizeof(*newex) > buf->buflen) @@ -2196,14 +2231,14 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + +static int +ext3_ext_collect_stats_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int exist) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *ex) +{ + struct ext3_extent_tree_stats *buf = + (struct ext3_extent_tree_stats *) tree->private; + int depth; + -+ if (!exist) ++ if (ex->ec_type != EXT3_EXT_CACHE_EXTENT) + return EXT_CONTINUE; + + depth = EXT_DEPTH(tree); @@ -2234,7 +2269,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + tree.private = &buf; + down_write(&EXT3_I(inode)->truncate_sem); + err = ext3_ext_walk_space(&tree, buf.start, EXT_MAX_BLOCK, -+ ext3_ext_store_extent_cb); ++ ext3_ext_store_extent_cb); + up_write(&EXT3_I(inode)->truncate_sem); + if (err == 0) + err = buf.err; @@ -2249,7 +2284,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c + buf.leaf_num = 0; + tree.private = &buf; + err = ext3_ext_walk_space(&tree, 0, EXT_MAX_BLOCK, -+ ext3_ext_collect_stats_cb); ++ ext3_ext_collect_stats_cb); + up_write(&EXT3_I(inode)->truncate_sem); + if (!err) + err = copy_to_user((void *) arg, &buf, sizeof(buf)); @@ -2271,23 +2306,18 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c +EXPORT_SYMBOL(ext3_ext_walk_space); +EXPORT_SYMBOL(ext3_ext_find_goal); +EXPORT_SYMBOL(ext3_ext_calc_credits_for_insert); -+ Index: linux-2.4.21-suse2/fs/ext3/ialloc.c =================================================================== --- linux-2.4.21-suse2.orig/fs/ext3/ialloc.c 2004-11-02 20:31:37.000000000 +0300 +++ linux-2.4.21-suse2/fs/ext3/ialloc.c 2004-11-02 20:34:00.000000000 +0300 -@@ -592,10 +592,22 @@ +@@ -592,6 +592,19 @@ iloc.bh = NULL; goto fail; } -- err = ext3_mark_iloc_dirty(handle, inode, &iloc); -- if (err) goto fail; -- - -+ if (test_opt(sb, EXTENTS)) { -+ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; -+ memset(&inode->u.ext3_i.i_cached_extent, 0, sizeof(__u32) * 4); -+ ext3_extents_initialize_blockmap(handle, inode); ++ if (test_opt(sb, EXTENTS) && S_ISREG(inode->i_mode)) { ++ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; ++ memset(&EXT3_I(inode)->i_cached_extent, 0, sizeof(__u32) * 4); ++ ext3_extents_initialize_blockmap(handle, inode); + if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS)) { + err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); + if (err) goto fail; @@ -2295,13 +2325,11 @@ Index: linux-2.4.21-suse2/fs/ext3/ialloc.c + BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "call ext3_journal_dirty_metadata"); + err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); + } -+ } -+ -+ err = ext3_mark_iloc_dirty(handle, inode, &iloc); -+ if (err) goto fail; - - #ifdef CONFIG_EXT3_FS_XATTR - init_rwsem(&inode->u.ext3_i.xattr_sem); ++ } ++ + err = ext3_mark_iloc_dirty(handle, inode, &iloc); + if (err) goto fail; + Index: linux-2.4.21-suse2/fs/ext3/inode.c =================================================================== --- linux-2.4.21-suse2.orig/fs/ext3/inode.c 2004-11-02 20:31:38.000000000 +0300 @@ -2312,12 +2340,12 @@ Index: linux-2.4.21-suse2/fs/ext3/inode.c +static inline int +ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block, -+ struct buffer_head *bh, int create, int extend_disksize) ++ struct buffer_head *bh, int create, int extend_disksize) +{ + if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) + return ext3_ext_get_block(handle, inode, block, bh, create); + return ext3_get_block_handle(handle, inode, block, bh, create, -+ extend_disksize); ++ extend_disksize); +} + /* @@ -2373,7 +2401,7 @@ Index: linux-2.4.21-suse2/fs/ext3/inode.c 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); -+ memset(&inode->u.ext3_i.i_cached_extent, 0, sizeof(__u32) * 4); ++ memset(&EXT3_I(inode)->i_cached_extent, 0, sizeof(__u32) * 4); brelse (iloc.bh); @@ -2472,21 +2500,24 @@ Index: linux-2.4.21-suse2/include/linux/ext3_fs.h =================================================================== --- linux-2.4.21-suse2.orig/include/linux/ext3_fs.h 2004-11-02 20:31:37.000000000 +0300 +++ linux-2.4.21-suse2/include/linux/ext3_fs.h 2004-11-02 20:31:39.000000000 +0300 -@@ -184,6 +184,7 @@ +@@ -184,8 +184,9 @@ #define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */ #define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ +#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ - #define EXT3_FL_USER_VISIBLE 0x00005FFF /* User visible flags */ +-#define EXT3_FL_USER_VISIBLE 0x00005FFF /* User visible flags */ ++#define EXT3_FL_USER_VISIBLE 0x00085FFF /* User visible flags */ #define EXT3_FL_USER_MODIFIABLE 0x000000FF /* User modifiable flags */ + + /* @@ -208,6 +209,9 @@ #ifdef CONFIG_JBD_DEBUG #define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) #endif -+#define EXT3_IOC_GET_EXTENTS _IOR('f', 5, long) -+#define EXT3_IOC_GET_TREE_DEPTH _IOR('f', 6, long) -+#define EXT3_IOC_GET_TREE_STATS _IOR('f', 7, long) ++#define EXT3_IOC_GET_EXTENTS _IOR('f', 5, long) ++#define EXT3_IOC_GET_TREE_DEPTH _IOR('f', 6, long) ++#define EXT3_IOC_GET_TREE_STATS _IOR('f', 7, long) /* * Structure of an inode on the disk @@ -2528,7 +2559,7 @@ Index: linux-2.4.21-suse2/include/linux/ext3_fs.h +/* extents.c */ +extern int ext3_ext_writepage_trans_blocks(struct inode *, int); +extern int ext3_ext_get_block(handle_t *, struct inode *, long, -+ struct buffer_head *, int); ++ struct buffer_head *, int); +extern void ext3_ext_truncate(struct inode *); +extern void ext3_ext_init(struct super_block *); +extern void ext3_ext_release(struct super_block *); @@ -2542,7 +2573,7 @@ Index: linux-2.4.21-suse2/include/linux/ext3_extents.h =================================================================== --- linux-2.4.21-suse2.orig/include/linux/ext3_extents.h 2003-01-30 13:24:37.000000000 +0300 +++ linux-2.4.21-suse2/include/linux/ext3_extents.h 2004-11-02 20:34:00.000000000 +0300 -@@ -0,0 +1,251 @@ +@@ -0,0 +1,264 @@ +/* + * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas @@ -2584,7 +2615,7 @@ Index: linux-2.4.21-suse2/include/linux/ext3_extents.h + */ +#define EXT_DEBUG_ +#ifdef EXT_DEBUG -+#define ext_debug(tree,fmt,a...) \ ++#define ext_debug(tree,fmt,a...) \ +do { \ + if (test_opt((tree)->inode->i_sb, EXTDEBUG)) \ + printk(fmt, ##a); \ @@ -2697,14 +2728,14 @@ Index: linux-2.4.21-suse2/include/linux/ext3_extents.h + int (*mark_buffer_dirty)(handle_t *h, void *buffer); + int (*mergable)(struct ext3_extent *ex1, struct ext3_extent *ex2); + int (*remove_extent_credits)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*remove_extent)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*new_block)(handle_t *, struct ext3_extents_tree *, -+ struct ext3_ext_path *, struct ext3_extent *, -+ int *); ++ struct ext3_ext_path *, struct ext3_extent *, ++ int *); +}; + +/* @@ -2714,8 +2745,8 @@ Index: linux-2.4.21-suse2/include/linux/ext3_extents.h + * callback must return valid extent (passed or newly created) + */ +typedef int (*ext_prepare_callback)(struct ext3_extents_tree *, -+ struct ext3_ext_path *, -+ struct ext3_extent *, int); ++ struct ext3_ext_path *, ++ struct ext3_ext_cache *); + +#define EXT_CONTINUE 0 +#define EXT_BREAK 1 @@ -2723,7 +2754,6 @@ Index: linux-2.4.21-suse2/include/linux/ext3_extents.h + + +#define EXT_MAX_BLOCK 0xffffffff -+#define EXT_CACHE_MARK 0xffff + + +#define EXT_FIRST_EXTENT(__hdr__) \ @@ -2755,6 +2785,20 @@ Index: linux-2.4.21-suse2/include/linux/ext3_extents.h + +#define EXT_ASSERT(__x__) if (!(__x__)) BUG(); + ++#define EXT_CHECK_PATH(tree,path) \ ++{ \ ++ int depth = EXT_DEPTH(tree); \ ++ BUG_ON((unsigned long) (path) < __PAGE_OFFSET); \ ++ BUG_ON((unsigned long) (path)[depth].p_idx < \ ++ __PAGE_OFFSET && (path)[depth].p_idx != NULL); \ ++ BUG_ON((unsigned long) (path)[depth].p_ext < \ ++ __PAGE_OFFSET && (path)[depth].p_ext != NULL); \ ++ BUG_ON((unsigned long) (path)[depth].p_hdr < __PAGE_OFFSET); \ ++ BUG_ON((unsigned long) (path)[depth].p_bh < __PAGE_OFFSET \ ++ && depth != 0); \ ++ BUG_ON((path)[0].p_depth != depth); \ ++} ++ + +/* + * this structure is used to gather extents from the tree via ioctl @@ -2776,7 +2820,7 @@ Index: linux-2.4.21-suse2/include/linux/ext3_extents.h + int leaf_num; +}; + -+void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); ++extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); +extern int ext3_extent_tree_init(handle_t *, struct ext3_extents_tree *); +extern int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *, struct ext3_ext_path *); +extern int ext3_ext_insert_extent(handle_t *, struct ext3_extents_tree *, struct ext3_ext_path *, struct ext3_extent *); @@ -2803,7 +2847,7 @@ Index: linux-2.4.21-suse2/include/linux/ext3_fs_i.h */ struct rw_semaphore truncate_sem; + -+ __u32 i_cached_extent[4]; ++ __u32 i_cached_extent[4]; }; #endif /* _LINUX_EXT3_FS_I */ diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.24.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.24.patch index 7480bde..1ad7c36 100644 --- a/lustre/kernel_patches/patches/ext3-extents-2.4.24.patch +++ b/lustre/kernel_patches/patches/ext3-extents-2.4.24.patch @@ -2,9 +2,9 @@ Index: linux-2.4.24/fs/ext3/extents.c =================================================================== --- linux-2.4.24.orig/fs/ext3/extents.c 2003-01-30 13:24:37.000000000 +0300 +++ linux-2.4.24/fs/ext3/extents.c 2004-11-03 00:36:44.894076664 +0300 -@@ -0,0 +1,2269 @@ +@@ -0,0 +1,2302 @@ +/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com ++ * Copyright(c) 2003, 2004, 2005, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify @@ -49,6 +49,27 @@ Index: linux-2.4.24/fs/ext3/extents.c +#include +#include + ++ ++static inline int ext3_ext_check_header(struct ext3_extent_header *eh) ++{ ++ if (eh->eh_magic != EXT3_EXT_MAGIC) { ++ printk(KERN_ERR "EXT3-fs: invalid magic = 0x%x\n", ++ (unsigned)eh->eh_magic); ++ return -EIO; ++ } ++ if (eh->eh_max == 0) { ++ printk(KERN_ERR "EXT3-fs: invalid eh_max = %u\n", ++ (unsigned)eh->eh_max); ++ return -EIO; ++ } ++ if (eh->eh_entries > eh->eh_max) { ++ printk(KERN_ERR "EXT3-fs: invalid eh_entries = %u\n", ++ (unsigned)eh->eh_entries); ++ return -EIO; ++ } ++ return 0; ++} ++ +static handle_t *ext3_ext_journal_restart(handle_t *handle, int needed) +{ + int err; @@ -86,8 +107,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + * - ENOMEM + */ +static int ext3_ext_get_access(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path) +{ + int err; + @@ -108,7 +129,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + * - EIO + */ +static int ext3_ext_dirty(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int err; + if (path->p_bh) { @@ -123,8 +144,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + +static int inline +ext3_ext_new_block(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, struct ext3_extent *ex, -+ int *err) ++ struct ext3_ext_path *path, struct ext3_extent *ex, ++ int *err) +{ + int goal, depth, newblock; + struct inode *inode; @@ -143,7 +164,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + unsigned long colour; + + bg_start = (ei->i_block_group * -+ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + ++ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + + le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); + colour = (current->pid % 16) * + (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); @@ -166,8 +187,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 6; +#endif @@ -179,8 +200,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 5; +#endif @@ -191,8 +212,8 @@ Index: linux-2.4.24/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 3; +#endif @@ -203,9 +224,8 @@ Index: linux-2.4.24/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 4; +#endif @@ -213,7 +233,7 @@ Index: linux-2.4.24/fs/ext3/extents.c +} + +static void ext3_ext_show_path(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int k, l = path->p_depth; @@ -222,12 +242,12 @@ Index: linux-2.4.24/fs/ext3/extents.c + for (k = 0; k <= l; k++, path++) { + if (path->p_idx) { + ext_debug(tree, " %d->%d", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + } else if (path->p_ext) { + ext_debug(tree, " %d:%d:%d", -+ path->p_ext->ee_block, -+ path->p_ext->ee_len, -+ path->p_ext->ee_start); ++ path->p_ext->ee_block, ++ path->p_ext->ee_len, ++ path->p_ext->ee_start); + } else + ext_debug(tree, " []"); + } @@ -236,7 +256,7 @@ Index: linux-2.4.24/fs/ext3/extents.c +} + +static void ext3_ext_show_leaf(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int depth = EXT_DEPTH(tree); @@ -252,7 +272,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + + for (i = 0; i < eh->eh_entries; i++, ex++) { + ext_debug(tree, "%d:%d:%d ", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + } + ext_debug(tree, "\n"); +#endif @@ -263,11 +283,12 @@ Index: linux-2.4.24/fs/ext3/extents.c + int depth = path->p_depth; + int i; + -+ for (i = 0; i <= depth; i++, path++) ++ for (i = 0; i <= depth; i++, path++) { + if (path->p_bh) { + brelse(path->p_bh); + path->p_bh = NULL; + } ++ } +} + +/* @@ -275,7 +296,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch_idx(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent_idx *ix; @@ -301,7 +322,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + + ix += l; + path->p_idx = ix; -+ ext_debug(tree, " -> %d->%d ", path->p_idx->ei_block, path->p_idx->ei_leaf); ++ ext_debug(tree," -> %d->%d ",path->p_idx->ei_block,path->p_idx->ei_leaf); + + while (l++ < r) { + if (block < ix->ei_block) @@ -309,7 +330,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + path->p_idx = ix++; + } + ext_debug(tree, " -> %d->%d\n", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + +#ifdef CHECK_BINSEARCH + { @@ -319,9 +340,9 @@ Index: linux-2.4.24/fs/ext3/extents.c + for (k = 0; k < eh->eh_entries; k++, ix++) { + if (k != 0 && ix->ei_block <= ix[-1].ei_block) { + printk("k=%d, ix=0x%p, first=0x%p\n", k, -+ ix, EXT_FIRST_INDEX(eh)); ++ ix, EXT_FIRST_INDEX(eh)); + printk("%u <= %u\n", -+ ix->ei_block,ix[-1].ei_block); ++ ix->ei_block,ix[-1].ei_block); + } + EXT_ASSERT(k == 0 || ix->ei_block > ix[-1].ei_block); + if (block < ix->ei_block) @@ -331,7 +352,6 @@ Index: linux-2.4.24/fs/ext3/extents.c + EXT_ASSERT(chix == path->p_idx); + } +#endif -+ +} + +/* @@ -339,7 +359,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent *ex; @@ -373,7 +393,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + ex += l; + path->p_ext = ex; + ext_debug(tree, " -> %d:%d:%d ", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + + while (l++ < r) { + if (block < ex->ee_block) @@ -381,7 +401,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + path->p_ext = ex++; + } + ext_debug(tree, " -> %d:%d:%d\n", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + +#ifdef CHECK_BINSEARCH + { @@ -397,7 +417,6 @@ Index: linux-2.4.24/fs/ext3/extents.c + EXT_ASSERT(chex == path->p_ext); + } +#endif -+ +} + +int ext3_extent_tree_init(handle_t *handle, struct ext3_extents_tree *tree) @@ -418,7 +437,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + +struct ext3_ext_path * +ext3_ext_find_extent(struct ext3_extents_tree *tree, int block, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + struct buffer_head *bh; @@ -430,15 +449,17 @@ Index: linux-2.4.24/fs/ext3/extents.c + + eh = EXT_ROOT_HDR(tree); + EXT_ASSERT(eh); ++ if (ext3_ext_check_header(eh)) ++ goto err; ++ + i = depth = EXT_DEPTH(tree); + EXT_ASSERT(eh->eh_max); + EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ EXT_ASSERT(i == 0 || eh->eh_entries > 0); + + /* account possible depth increase */ + if (!path) { + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2), -+ GFP_NOFS); ++ GFP_NOFS); + if (!path) + return ERR_PTR(-ENOMEM); + } @@ -448,29 +469,33 @@ Index: linux-2.4.24/fs/ext3/extents.c + /* walk through the tree */ + while (i) { + ext_debug(tree, "depth %d: num %d, max %d\n", -+ ppos, eh->eh_entries, eh->eh_max); ++ ppos, eh->eh_entries, eh->eh_max); + ext3_ext_binsearch_idx(tree, path + ppos, block); + path[ppos].p_block = path[ppos].p_idx->ei_leaf; + path[ppos].p_depth = i; + path[ppos].p_ext = NULL; + + bh = sb_bread(tree->inode->i_sb, path[ppos].p_block); -+ if (!bh) { -+ ext3_ext_drop_refs(path); -+ kfree(path); -+ return ERR_PTR(-EIO); -+ } ++ if (!bh) ++ goto err; + eh = EXT_BLOCK_HDR(bh); + ppos++; + EXT_ASSERT(ppos <= depth); + path[ppos].p_bh = bh; + path[ppos].p_hdr = eh; + i--; ++ ++ if (ext3_ext_check_header(eh)) ++ goto err; + } + + path[ppos].p_depth = i; + path[ppos].p_hdr = eh; + path[ppos].p_ext = NULL; ++ path[ppos].p_idx = NULL; ++ ++ if (ext3_ext_check_header(eh)) ++ goto err; + + /* find extent */ + ext3_ext_binsearch(tree, path + ppos, block); @@ -478,6 +503,12 @@ Index: linux-2.4.24/fs/ext3/extents.c + ext3_ext_show_path(tree, path); + + return path; ++ ++err: ++ printk(KERN_ERR "EXT3-fs: header is corrupted!\n"); ++ ext3_ext_drop_refs(path); ++ kfree(path); ++ return ERR_PTR(-EIO); +} + +/* @@ -485,9 +516,9 @@ Index: linux-2.4.24/fs/ext3/extents.c + * it check where to insert: before curp or after curp + */ +static int ext3_ext_insert_index(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *curp, -+ int logical, int ptr) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *curp, ++ int logical, int ptr) +{ + struct ext3_extent_idx *ix; + int len, err; @@ -503,9 +534,9 @@ Index: linux-2.4.24/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d after: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ (curp->p_idx + 1), (curp->p_idx + 2)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ (curp->p_idx + 1), (curp->p_idx + 2)); + memmove(curp->p_idx + 2, curp->p_idx + 1, len); + } + ix = curp->p_idx + 1; @@ -514,9 +545,9 @@ Index: linux-2.4.24/fs/ext3/extents.c + len = len * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d before: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ curp->p_idx, (curp->p_idx + 1)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ curp->p_idx, (curp->p_idx + 1)); + memmove(curp->p_idx + 1, curp->p_idx, len); + ix = curp->p_idx; + } @@ -544,8 +575,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + * - initialize subtree + */ +static int ext3_ext_split(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext, int at) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext, int at) +{ + struct buffer_head *bh = NULL; + int depth = EXT_DEPTH(tree); @@ -566,13 +597,13 @@ Index: linux-2.4.24/fs/ext3/extents.c + if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) { + border = path[depth].p_ext[1].ee_block; + ext_debug(tree, "leaf will be splitted." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } else { + border = newext->ee_block; + ext_debug(tree, "leaf will be added." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } + + /* @@ -630,12 +661,11 @@ Index: linux-2.4.24/fs/ext3/extents.c + while (path[depth].p_ext <= + EXT_MAX_EXTENT(path[depth].p_hdr)) { + ext_debug(tree, "move %d:%d:%d in new leaf %lu\n", -+ path[depth].p_ext->ee_block, -+ path[depth].p_ext->ee_start, -+ path[depth].p_ext->ee_len, -+ newblock); -+ memmove(ex++, path[depth].p_ext++, -+ sizeof(struct ext3_extent)); ++ path[depth].p_ext->ee_block, ++ path[depth].p_ext->ee_start, ++ path[depth].p_ext->ee_len, ++ newblock); ++ memmove(ex++, path[depth].p_ext++, sizeof(struct ext3_extent)); + neh->eh_entries++; + m++; + } @@ -688,21 +718,21 @@ Index: linux-2.4.24/fs/ext3/extents.c + fidx->ei_leaf = oldblock; + + ext_debug(tree, "int.index at %d (block %lu): %lu -> %lu\n", -+ i, newblock, border, oldblock); ++ i, newblock, border, oldblock); + /* copy indexes */ + m = 0; + path[i].p_idx++; + + ext_debug(tree, "cur 0x%p, last 0x%p\n", path[i].p_idx, -+ EXT_MAX_INDEX(path[i].p_hdr)); ++ EXT_MAX_INDEX(path[i].p_hdr)); + EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) == -+ EXT_LAST_INDEX(path[i].p_hdr)); ++ EXT_LAST_INDEX(path[i].p_hdr)); + while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { + ext_debug(tree, "%d: move %d:%d in new index %lu\n", -+ i, path[i].p_idx->ei_block, -+ path[i].p_idx->ei_leaf, newblock); ++ i, path[i].p_idx->ei_block, ++ path[i].p_idx->ei_leaf, newblock); + memmove(++fidx, path[i].p_idx++, -+ sizeof(struct ext3_extent_idx)); ++ sizeof(struct ext3_extent_idx)); + neh->eh_entries++; + EXT_ASSERT(neh->eh_entries <= neh->eh_max); + m++; @@ -732,7 +762,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + /* insert new index */ + if (!err) + err = ext3_ext_insert_index(handle, tree, path + at, -+ border, newblock); ++ border, newblock); + +cleanup: + if (bh) { @@ -762,9 +792,9 @@ Index: linux-2.4.24/fs/ext3/extents.c + * just created block + */ +static int ext3_ext_grow_indepth(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp = path; + struct ext3_extent_header *neh; @@ -823,7 +853,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + neh = EXT_ROOT_HDR(tree); + fidx = EXT_FIRST_INDEX(neh); + ext_debug(tree, "new root: num %d(%d), lblock %d, ptr %d\n", -+ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); ++ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); + + neh->eh_depth = path->p_depth + 1; + err = ext3_ext_dirty(handle, tree, curp); @@ -838,9 +868,9 @@ Index: linux-2.4.24/fs/ext3/extents.c + * then it requests in-depth growing + */ +static int ext3_ext_create_new_leaf(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp; + int depth, i, err = 0; @@ -916,12 +946,12 @@ Index: linux-2.4.24/fs/ext3/extents.c + if (depth == path->p_depth) { + /* leaf */ + if (path[depth].p_ext != -+ EXT_LAST_EXTENT(path[depth].p_hdr)) ++ EXT_LAST_EXTENT(path[depth].p_hdr)) + return path[depth].p_ext[1].ee_block; + } else { + /* index */ + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + } + depth--; @@ -934,7 +964,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + * returns first allocated block from next leaf or EXT_MAX_BLOCK + */ +static unsigned ext3_ext_next_leaf_block(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth; + @@ -950,7 +980,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + + while (depth >= 0) { + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + depth--; + } @@ -964,7 +994,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + * TODO: do we need to correct tree in all cases? + */ +int ext3_ext_correct_indexes(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + int depth = EXT_DEPTH(tree); @@ -1014,8 +1044,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + +static int inline +ext3_can_extents_be_merged(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex1, ++ struct ext3_extent *ex2) +{ + if (ex1->ee_block + ex1->ee_len != ex2->ee_block) + return 0; @@ -1037,8 +1067,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + * creating new leaf in no-space case + */ +int ext3_ext_insert_extent(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_extent_header * eh; + struct ext3_extent *ex, *fex; @@ -1047,7 +1077,6 @@ Index: linux-2.4.24/fs/ext3/extents.c + int depth, len, err, next; + + EXT_ASSERT(newext->ee_len > 0); -+ EXT_ASSERT(newext->ee_len < EXT_CACHE_MARK); + depth = EXT_DEPTH(tree); + ex = path[depth].p_ext; + EXT_ASSERT(path[depth].p_hdr); @@ -1055,8 +1084,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + /* try to insert block into found extent and return */ + if (ex && ext3_can_extents_be_merged(tree, ex, newext)) { + ext_debug(tree, "append %d block to %d:%d (from %d)\n", -+ newext->ee_len, ex->ee_block, ex->ee_len, -+ ex->ee_start); ++ newext->ee_len, ex->ee_block, ex->ee_len, ++ ex->ee_start); + if ((err = ext3_ext_get_access(handle, tree, path + depth))) + return err; + ex->ee_len += newext->ee_len; @@ -1084,12 +1113,12 @@ Index: linux-2.4.24/fs/ext3/extents.c + eh = npath[depth].p_hdr; + if (eh->eh_entries < eh->eh_max) { + ext_debug(tree, "next leaf isnt full(%d)\n", -+ eh->eh_entries); ++ eh->eh_entries); + path = npath; + goto repeat; + } + ext_debug(tree, "next leaf hasno free space(%d,%d)\n", -+ eh->eh_entries, eh->eh_max); ++ eh->eh_entries, eh->eh_max); + } + + /* @@ -1111,8 +1140,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + if (!nearex) { + /* there is no extent in this leaf, create first one */ + ext_debug(tree, "first extent in the leaf: %d:%d:%d\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len); ++ newext->ee_block, newext->ee_start, ++ newext->ee_len); + path[depth].p_ext = EXT_FIRST_EXTENT(eh); + } else if (newext->ee_block > nearex->ee_block) { + EXT_ASSERT(newext->ee_block != nearex->ee_block); @@ -1121,10 +1150,10 @@ Index: linux-2.4.24/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d after: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, ++ newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 2, nearex + 1, len); + } + path[depth].p_ext = nearex + 1; @@ -1133,9 +1162,9 @@ Index: linux-2.4.24/fs/ext3/extents.c + len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d before: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 1, nearex, len); + path[depth].p_ext = nearex; + } @@ -1156,8 +1185,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + /* merge with next extent! */ + nearex->ee_len += nearex[1].ee_len; + if (nearex + 1 < EXT_LAST_EXTENT(eh)) { -+ len = (EXT_LAST_EXTENT(eh) - nearex - 1) -+ * sizeof(struct ext3_extent); ++ len = (EXT_LAST_EXTENT(eh) - nearex - 1) * ++ sizeof(struct ext3_extent); + memmove(nearex + 1, nearex + 2, len); + } + eh->eh_entries--; @@ -1187,7 +1216,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + unsigned long num, ext_prepare_callback func) +{ + struct ext3_ext_path *path = NULL; -+ struct ext3_extent *ex, cbex; ++ struct ext3_ext_cache cbex; ++ struct ext3_extent *ex; + unsigned long next, start = 0, end = 0; + unsigned long last = block + num; + int depth, exists, err = 0; @@ -1246,14 +1276,20 @@ Index: linux-2.4.24/fs/ext3/extents.c + EXT_ASSERT(end > start); + + if (!exists) { -+ cbex.ee_block = start; -+ cbex.ee_len = end - start; -+ cbex.ee_start = 0; -+ } else -+ cbex = *ex; ++ cbex.ec_block = start; ++ cbex.ec_len = end - start; ++ cbex.ec_start = 0; ++ cbex.ec_type = EXT3_EXT_CACHE_GAP; ++ } else { ++ cbex.ec_block = ex->ee_block; ++ cbex.ec_len = ex->ee_len; ++ cbex.ec_start = ex->ee_start; ++ cbex.ec_type = EXT3_EXT_CACHE_EXTENT; ++ } + ++ EXT_ASSERT(cbex.ec_len > 0); + EXT_ASSERT(path[depth].p_hdr); -+ err = func(tree, path, &cbex, exists); ++ err = func(tree, path, &cbex); + ext3_ext_drop_refs(path); + + if (err < 0) @@ -1271,7 +1307,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + path = NULL; + } + -+ block = cbex.ee_block + cbex.ee_len; ++ block = cbex.ec_block + cbex.ec_len; + } + + if (path) { @@ -1284,7 +1320,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + +static inline void +ext3_ext_put_in_cache(struct ext3_extents_tree *tree, __u32 block, -+ __u32 len, __u32 start, int type) ++ __u32 len, __u32 start, int type) +{ + EXT_ASSERT(len > 0); + if (tree->cex) { @@ -1301,8 +1337,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + */ +static inline void +ext3_ext_put_gap_in_cache(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ unsigned long block) ++ struct ext3_ext_path *path, ++ unsigned long block) +{ + int depth = EXT_DEPTH(tree); + unsigned long lblock, len; @@ -1321,16 +1357,16 @@ Index: linux-2.4.24/fs/ext3/extents.c + lblock = block; + len = ex->ee_block - block; + ext_debug(tree, "cache gap(before): %lu [%lu:%lu]", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len); + } else if (block >= ex->ee_block + ex->ee_len) { + lblock = ex->ee_block + ex->ee_len; + len = ext3_ext_next_allocated_block(path); + ext_debug(tree, "cache gap(after): [%lu:%lu] %lu", -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) block); ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) block); + EXT_ASSERT(len > lblock); + len = len - lblock; + } else { @@ -1344,7 +1380,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + +static inline int +ext3_ext_in_cache(struct ext3_extents_tree *tree, unsigned long block, -+ struct ext3_extent *ex) ++ struct ext3_extent *ex) +{ + struct ext3_ext_cache *cex = tree->cex; + @@ -1357,16 +1393,16 @@ Index: linux-2.4.24/fs/ext3/extents.c + return EXT3_EXT_CACHE_NO; + + EXT_ASSERT(cex->ec_type == EXT3_EXT_CACHE_GAP || -+ cex->ec_type == EXT3_EXT_CACHE_EXTENT); ++ cex->ec_type == EXT3_EXT_CACHE_EXTENT); + if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) { + ex->ee_block = cex->ec_block; + ex->ee_start = cex->ec_start; + ex->ee_len = cex->ec_len; + ext_debug(tree, "%lu cached by %lu:%lu:%lu\n", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) ex->ee_start); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) ex->ee_start); + return cex->ec_type; + } + @@ -1380,7 +1416,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + * last index in the block only + */ +int ext3_ext_rm_idx(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct buffer_head *bh; + int err; @@ -1394,7 +1430,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + if ((err = ext3_ext_dirty(handle, tree, path))) + return err; + ext_debug(tree, "index is empty, remove it, free block %d\n", -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + bh = sb_get_hash_table(tree->inode->i_sb, path->p_idx->ei_leaf); + ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf); + ext3_free_blocks(handle, tree->inode, path->p_idx->ei_leaf, 1); @@ -1402,7 +1438,7 @@ Index: linux-2.4.24/fs/ext3/extents.c +} + +int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth = EXT_DEPTH(tree); + int needed; @@ -1439,8 +1475,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + +static int +ext3_ext_split_for_rm(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, tex; + struct ext3_ext_path *npath; @@ -1474,7 +1510,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + /* FIXME: some callback to free underlying resource + * and correct ee_start? */ + ext_debug(tree, "split extent: head %u:%u, tail %u:%u\n", -+ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); ++ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); + + npath = ext3_ext_find_extent(tree, ex->ee_block, NULL); + if (IS_ERR(npath)) @@ -1488,13 +1524,12 @@ Index: linux-2.4.24/fs/ext3/extents.c + kfree(npath); + + return err; -+ +} + +static int +ext3_ext_rm_leaf(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, *fu = NULL, *lu, *le; + int err = 0, correct_index = 0; @@ -1527,8 +1562,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + } + + lu = ex; -+ while (ex >= EXT_FIRST_EXTENT(eh) && -+ ex->ee_block + ex->ee_len > start) { ++ while (ex >= EXT_FIRST_EXTENT(eh) && ex->ee_block + ex->ee_len > start) { + ext_debug(tree, "remove ext %u:%u\n", ex->ee_block, ex->ee_len); + path[depth].p_ext = ex; + @@ -1555,7 +1589,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + block = ex->ee_block; + num = 0; + EXT_ASSERT(a == ex->ee_block && -+ b == ex->ee_block + ex->ee_len - 1); ++ b == ex->ee_block + ex->ee_len - 1); + } + + if (ex == EXT_FIRST_EXTENT(eh)) @@ -1597,7 +1631,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + goto out; + + ext_debug(tree, "new extent: %u:%u:%u\n", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + ex--; + } + @@ -1661,7 +1695,7 @@ Index: linux-2.4.24/fs/ext3/extents.c +} + +int ext3_ext_remove_space(struct ext3_extents_tree *tree, -+ unsigned long start, unsigned long end) ++ unsigned long start, unsigned long end) +{ + struct inode *inode = tree->inode; + struct super_block *sb = inode->i_sb; @@ -1685,8 +1719,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + */ + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL); + if (IS_ERR(path)) { -+ ext3_error(sb, "ext3_ext_remove_space", -+ "Can't allocate path array"); ++ ext3_error(sb, __FUNCTION__, "Can't allocate path array"); + ext3_journal_stop(handle, inode); + return -ENOMEM; + } @@ -1718,19 +1751,19 @@ Index: linux-2.4.24/fs/ext3/extents.c + ext3_ext_last_covered(path[i].p_hdr, end); + path[i].p_block = path[i].p_hdr->eh_entries + 1; + ext_debug(tree, "init index ptr: hdr 0x%p, num %d\n", -+ path[i].p_hdr, path[i].p_hdr->eh_entries); ++ path[i].p_hdr, path[i].p_hdr->eh_entries); + } else { + /* we've already was here, see at next index */ + path[i].p_idx--; + } + + ext_debug(tree, "level %d - index, first 0x%p, cur 0x%p\n", -+ i, EXT_FIRST_INDEX(path[i].p_hdr), -+ path[i].p_idx); ++ i, EXT_FIRST_INDEX(path[i].p_hdr), ++ path[i].p_idx); + if (ext3_ext_more_to_rm(path + i)) { + /* go to the next level */ + ext_debug(tree, "move to level %d (block %d)\n", -+ i + 1, path[i].p_idx->ei_leaf); ++ i + 1, path[i].p_idx->ei_leaf); + memset(path + i + 1, 0, sizeof(*path)); + path[i+1].p_bh = sb_bread(sb, path[i].p_idx->ei_leaf); + if (!path[i+1].p_bh) { @@ -1823,7 +1856,7 @@ Index: linux-2.4.24/fs/ext3/extents.c +} + +static int ext3_ext_mergable(struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex2) +{ + /* FIXME: support for large fs */ + if (ex1->ee_start + ex1->ee_len == ex2->ee_start) @@ -1833,8 +1866,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + +static int +ext3_remove_blocks_credits(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed; + @@ -1849,8 +1882,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + +static int +ext3_remove_blocks(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed = ext3_remove_blocks_credits(tree, ex, from, to); + handle_t *handle = ext3_journal_start(tree->inode, needed); @@ -1865,7 +1898,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + num = ex->ee_block + ex->ee_len - from; + start = ex->ee_start + ex->ee_len - num; + ext_debug(tree, "free last %lu blocks starting %lu\n", -+ num, start); ++ num, start); + for (i = 0; i < num; i++) { + bh = sb_get_hash_table(tree->inode->i_sb, start + i); + ext3_forget(handle, 0, tree->inode, bh, start + i); @@ -1873,17 +1906,17 @@ Index: linux-2.4.24/fs/ext3/extents.c + ext3_free_blocks(handle, tree->inode, start, num); + } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { + printk("strange request: removal %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } else { + printk("strange request: removal(2) %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } + ext3_journal_stop(handle, tree->inode); + return 0; +} + +int ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path, -+ unsigned long block) ++ unsigned long block) +{ + struct ext3_inode_info *ei = EXT3_I(inode); + unsigned long bg_start; @@ -1913,8 +1946,8 @@ Index: linux-2.4.24/fs/ext3/extents.c +} + +static int ext3_new_block_cb(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int *err) ++ struct ext3_ext_path *path, ++ struct ext3_extent *ex, int *err) +{ + struct inode *inode = tree->inode; + int newblock, goal; @@ -1951,7 +1984,7 @@ Index: linux-2.4.24/fs/ext3/extents.c +}; + +void ext3_init_tree_desc(struct ext3_extents_tree *tree, -+ struct inode *inode) ++ struct inode *inode) +{ + tree->inode = inode; + tree->root = (void *) EXT3_I(inode)->i_data; @@ -1962,7 +1995,7 @@ Index: linux-2.4.24/fs/ext3/extents.c +} + +int ext3_ext_get_block(handle_t *handle, struct inode *inode, -+ long iblock, struct buffer_head *bh_result, int create) ++ long iblock, struct buffer_head *bh_result, int create) +{ + struct ext3_ext_path *path = NULL; + struct ext3_extent newex; @@ -1973,7 +2006,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + clear_bit(BH_New, &bh_result->b_state); + ext3_init_tree_desc(&tree, inode); + ext_debug(&tree, "block %d requested for inode %u\n", -+ (int) iblock, (unsigned) inode->i_ino); ++ (int) iblock, (unsigned) inode->i_ino); + down_write(&EXT3_I(inode)->truncate_sem); + + /* check in cache */ @@ -2016,11 +2049,11 @@ Index: linux-2.4.24/fs/ext3/extents.c + if (iblock >= ex->ee_block && iblock < ex->ee_block + ex->ee_len) { + newblock = iblock - ex->ee_block + ex->ee_start; + ext_debug(&tree, "%d fit into %d:%d -> %d\n", -+ (int) iblock, ex->ee_block, ex->ee_len, -+ newblock); ++ (int) iblock, ex->ee_block, ex->ee_len, ++ newblock); + ext3_ext_put_in_cache(&tree, ex->ee_block, -+ ex->ee_len, ex->ee_start, -+ EXT3_EXT_CACHE_EXTENT); ++ ex->ee_len, ex->ee_start, ++ EXT3_EXT_CACHE_EXTENT); + goto out; + } + } @@ -2041,7 +2074,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + if (!newblock) + goto out2; + ext_debug(&tree, "allocate new block: goal %d, found %d\n", -+ goal, newblock); ++ goal, newblock); + + /* try to insert new extent into found leaf and return */ + newex.ee_block = iblock; @@ -2059,7 +2092,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + set_bit(BH_New, &bh_result->b_state); + + ext3_ext_put_in_cache(&tree, newex.ee_block, newex.ee_len, -+ newex.ee_start, EXT3_EXT_CACHE_EXTENT); ++ newex.ee_start, EXT3_EXT_CACHE_EXTENT); +out: + ext3_ext_show_leaf(&tree, path); + set_bit(BH_Mapped, &bh_result->b_state); @@ -2111,8 +2144,8 @@ Index: linux-2.4.24/fs/ext3/extents.c + EXT3_I(inode)->i_disksize = inode->i_size; + ext3_mark_inode_dirty(handle, inode); + -+ last_block = (inode->i_size + sb->s_blocksize - 1) -+ >> EXT3_BLOCK_SIZE_BITS(sb); ++ last_block = (inode->i_size + sb->s_blocksize - 1) >> ++ EXT3_BLOCK_SIZE_BITS(sb); + err = ext3_ext_remove_space(&tree, last_block, EXT_MAX_BLOCK); + + /* In a multi-transaction truncate, we only make the final @@ -2172,13 +2205,14 @@ Index: linux-2.4.24/fs/ext3/extents.c + +static int +ext3_ext_store_extent_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newex, int exist) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *newex) +{ + struct ext3_extent_buf *buf = (struct ext3_extent_buf *) tree->private; + -+ if (!exist) ++ if (newex->ec_type != EXT3_EXT_CACHE_EXTENT) + return EXT_CONTINUE; ++ + if (buf->err < 0) + return EXT_BREAK; + if (buf->cur - buf->buffer + sizeof(*newex) > buf->buflen) @@ -2196,14 +2230,14 @@ Index: linux-2.4.24/fs/ext3/extents.c + +static int +ext3_ext_collect_stats_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int exist) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *ex) +{ + struct ext3_extent_tree_stats *buf = + (struct ext3_extent_tree_stats *) tree->private; + int depth; + -+ if (!exist) ++ if (ex->ec_type != EXT3_EXT_CACHE_EXTENT) + return EXT_CONTINUE; + + depth = EXT_DEPTH(tree); @@ -2234,7 +2268,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + tree.private = &buf; + down_write(&EXT3_I(inode)->truncate_sem); + err = ext3_ext_walk_space(&tree, buf.start, EXT_MAX_BLOCK, -+ ext3_ext_store_extent_cb); ++ ext3_ext_store_extent_cb); + up_write(&EXT3_I(inode)->truncate_sem); + if (err == 0) + err = buf.err; @@ -2249,7 +2283,7 @@ Index: linux-2.4.24/fs/ext3/extents.c + buf.leaf_num = 0; + tree.private = &buf; + err = ext3_ext_walk_space(&tree, 0, EXT_MAX_BLOCK, -+ ext3_ext_collect_stats_cb); ++ ext3_ext_collect_stats_cb); + up_write(&EXT3_I(inode)->truncate_sem); + if (!err) + err = copy_to_user((void *) arg, &buf, sizeof(buf)); @@ -2271,22 +2305,18 @@ Index: linux-2.4.24/fs/ext3/extents.c +EXPORT_SYMBOL(ext3_ext_walk_space); +EXPORT_SYMBOL(ext3_ext_find_goal); +EXPORT_SYMBOL(ext3_ext_calc_credits_for_insert); -+ Index: linux-2.4.24/fs/ext3/ialloc.c =================================================================== --- linux-2.4.24.orig/fs/ext3/ialloc.c 2004-11-02 20:28:32.000000000 +0300 +++ linux-2.4.24/fs/ext3/ialloc.c 2004-11-02 20:32:17.000000000 +0300 -@@ -592,10 +592,22 @@ +@@ -592,6 +592,19 @@ iloc.bh = NULL; goto fail; } -- err = ext3_mark_iloc_dirty(handle, inode, &iloc); -- if (err) goto fail; - -+ if (test_opt(sb, EXTENTS)) { -+ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; -+ memset(&inode->u.ext3_i.i_cached_extent, 0, sizeof(__u32) * 4); -+ ext3_extents_initialize_blockmap(handle, inode); ++ if (test_opt(sb, EXTENTS) && S_ISREG(inode->i_mode)) { ++ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; ++ memset(&EXT3_I(inode)->i_cached_extent, 0, sizeof(__u32) * 4); ++ ext3_extents_initialize_blockmap(handle, inode); + if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS)) { + err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); + if (err) goto fail; @@ -2294,13 +2324,11 @@ Index: linux-2.4.24/fs/ext3/ialloc.c + BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "call ext3_journal_dirty_metadata"); + err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); + } -+ } ++ } ++ + err = ext3_mark_iloc_dirty(handle, inode, &iloc); + if (err) goto fail; -+ err = ext3_mark_iloc_dirty(handle, inode, &iloc); -+ if (err) goto fail; - - unlock_super (sb); - if(DQUOT_ALLOC_INODE(inode)) { Index: linux-2.4.24/fs/ext3/inode.c =================================================================== --- linux-2.4.24.orig/fs/ext3/inode.c 2004-11-02 20:28:33.000000000 +0300 @@ -2311,7 +2339,7 @@ Index: linux-2.4.24/fs/ext3/inode.c +static inline int +ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block, -+ struct buffer_head *bh, int create) ++ struct buffer_head *bh, int create) +{ + if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) + return ext3_ext_get_block(handle, inode, block, bh, create); @@ -2362,7 +2390,7 @@ Index: linux-2.4.24/fs/ext3/inode.c 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); -+ memset(&inode->u.ext3_i.i_cached_extent, 0, sizeof(__u32) * 4); ++ memset(&EXT3_I(inode)->i_cached_extent, 0, sizeof(__u32) * 4); if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) inode->u.ext3_i.i_extra_isize = @@ -2460,21 +2488,24 @@ Index: linux-2.4.24/include/linux/ext3_fs.h =================================================================== --- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-11-02 20:28:32.000000000 +0300 +++ linux-2.4.24/include/linux/ext3_fs.h 2004-11-02 20:32:17.000000000 +0300 -@@ -184,6 +184,7 @@ +@@ -184,8 +184,9 @@ #define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */ #define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ +#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ - #define EXT3_FL_USER_VISIBLE 0x00005FFF /* User visible flags */ +-#define EXT3_FL_USER_VISIBLE 0x00005FFF /* User visible flags */ ++#define EXT3_FL_USER_VISIBLE 0x00085FFF /* User visible flags */ #define EXT3_FL_USER_MODIFIABLE 0x000000FF /* User modifiable flags */ + + /* @@ -208,6 +209,9 @@ #ifdef CONFIG_JBD_DEBUG #define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) #endif -+#define EXT3_IOC_GET_EXTENTS _IOR('f', 5, long) -+#define EXT3_IOC_GET_TREE_DEPTH _IOR('f', 6, long) -+#define EXT3_IOC_GET_TREE_STATS _IOR('f', 7, long) ++#define EXT3_IOC_GET_EXTENTS _IOR('f', 5, long) ++#define EXT3_IOC_GET_TREE_DEPTH _IOR('f', 6, long) ++#define EXT3_IOC_GET_TREE_STATS _IOR('f', 7, long) /* * Structure of an inode on the disk @@ -2516,7 +2547,7 @@ Index: linux-2.4.24/include/linux/ext3_fs.h +/* extents.c */ +extern int ext3_ext_writepage_trans_blocks(struct inode *, int); +extern int ext3_ext_get_block(handle_t *, struct inode *, long, -+ struct buffer_head *, int); ++ struct buffer_head *, int); +extern void ext3_ext_truncate(struct inode *); +extern void ext3_ext_init(struct super_block *); +extern void ext3_ext_release(struct super_block *); @@ -2530,7 +2561,7 @@ Index: linux-2.4.24/include/linux/ext3_extents.h =================================================================== --- linux-2.4.24.orig/include/linux/ext3_extents.h 2003-01-30 13:24:37.000000000 +0300 +++ linux-2.4.24/include/linux/ext3_extents.h 2004-11-02 20:32:17.000000000 +0300 -@@ -0,0 +1,251 @@ +@@ -0,0 +1,263 @@ +/* + * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas @@ -2572,7 +2603,7 @@ Index: linux-2.4.24/include/linux/ext3_extents.h + */ +#define EXT_DEBUG_ +#ifdef EXT_DEBUG -+#define ext_debug(tree,fmt,a...) \ ++#define ext_debug(tree,fmt,a...) \ +do { \ + if (test_opt((tree)->inode->i_sb, EXTDEBUG)) \ + printk(fmt, ##a); \ @@ -2685,14 +2716,14 @@ Index: linux-2.4.24/include/linux/ext3_extents.h + int (*mark_buffer_dirty)(handle_t *h, void *buffer); + int (*mergable)(struct ext3_extent *ex1, struct ext3_extent *ex2); + int (*remove_extent_credits)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*remove_extent)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*new_block)(handle_t *, struct ext3_extents_tree *, -+ struct ext3_ext_path *, struct ext3_extent *, -+ int *); ++ struct ext3_ext_path *, struct ext3_extent *, ++ int *); +}; + +/* @@ -2702,8 +2733,8 @@ Index: linux-2.4.24/include/linux/ext3_extents.h + * callback must return valid extent (passed or newly created) + */ +typedef int (*ext_prepare_callback)(struct ext3_extents_tree *, -+ struct ext3_ext_path *, -+ struct ext3_extent *, int); ++ struct ext3_ext_path *, ++ struct ext3_ext_cache *); + +#define EXT_CONTINUE 0 +#define EXT_BREAK 1 @@ -2711,7 +2742,6 @@ Index: linux-2.4.24/include/linux/ext3_extents.h + + +#define EXT_MAX_BLOCK 0xffffffff -+#define EXT_CACHE_MARK 0xffff + + +#define EXT_FIRST_EXTENT(__hdr__) \ @@ -2743,6 +2773,20 @@ Index: linux-2.4.24/include/linux/ext3_extents.h + +#define EXT_ASSERT(__x__) if (!(__x__)) BUG(); + ++#define EXT_CHECK_PATH(tree,path) \ ++{ \ ++ int depth = EXT_DEPTH(tree); \ ++ BUG_ON((unsigned long) (path) < __PAGE_OFFSET); \ ++ BUG_ON((unsigned long) (path)[depth].p_idx < \ ++ __PAGE_OFFSET && (path)[depth].p_idx != NULL); \ ++ BUG_ON((unsigned long) (path)[depth].p_ext < \ ++ __PAGE_OFFSET && (path)[depth].p_ext != NULL); \ ++ BUG_ON((unsigned long) (path)[depth].p_hdr < __PAGE_OFFSET); \ ++ BUG_ON((unsigned long) (path)[depth].p_bh < __PAGE_OFFSET \ ++ && depth != 0); \ ++ BUG_ON((path)[0].p_depth != depth); \ ++} ++ + +/* + * this structure is used to gather extents from the tree via ioctl @@ -2764,7 +2808,7 @@ Index: linux-2.4.24/include/linux/ext3_extents.h + int leaf_num; +}; + -+void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); ++extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); +extern int ext3_extent_tree_init(handle_t *, struct ext3_extents_tree *); +extern int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *, struct ext3_ext_path *); +extern int ext3_ext_insert_extent(handle_t *, struct ext3_extents_tree *, struct ext3_ext_path *, struct ext3_extent *); @@ -2781,7 +2825,6 @@ Index: linux-2.4.24/include/linux/ext3_extents.h + + +#endif /* _LINUX_EXT3_EXTENTS */ -+ Index: linux-2.4.24/include/linux/ext3_fs_i.h =================================================================== --- linux-2.4.24.orig/include/linux/ext3_fs_i.h 2004-11-02 20:28:32.000000000 +0300 @@ -2791,7 +2834,7 @@ Index: linux-2.4.24/include/linux/ext3_fs_i.h */ struct rw_semaphore truncate_sem; + -+ __u32 i_cached_extent[4]; ++ __u32 i_cached_extent[4]; }; #endif /* _LINUX_EXT3_FS_I */ diff --git a/lustre/kernel_patches/patches/ext3-extents-2.6.5.patch b/lustre/kernel_patches/patches/ext3-extents-2.6.5.patch index 671fbc0..053c0fb 100644 --- a/lustre/kernel_patches/patches/ext3-extents-2.6.5.patch +++ b/lustre/kernel_patches/patches/ext3-extents-2.6.5.patch @@ -3,9 +3,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c =================================================================== --- linux-2.6.5-sles9.orig/fs/ext3/extents.c 2005-02-17 22:07:57.023609040 +0300 +++ linux-2.6.5-sles9/fs/ext3/extents.c 2005-02-23 01:02:37.396435640 +0300 -@@ -0,0 +1,2356 @@ +@@ -0,0 +1,2349 @@ +/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com ++ * Copyright(c) 2003, 2004, 2005, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify @@ -54,17 +54,17 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +{ + if (eh->eh_magic != EXT3_EXT_MAGIC) { + printk(KERN_ERR "EXT3-fs: invalid magic = 0x%x\n", -+ (unsigned) eh->eh_magic); ++ (unsigned)eh->eh_magic); + return -EIO; + } + if (eh->eh_max == 0) { + printk(KERN_ERR "EXT3-fs: invalid eh_max = %u\n", -+ (unsigned) eh->eh_max); ++ (unsigned)eh->eh_max); + return -EIO; + } + if (eh->eh_entries > eh->eh_max) { + printk(KERN_ERR "EXT3-fs: invalid eh_entries = %u\n", -+ (unsigned) eh->eh_entries); ++ (unsigned)eh->eh_entries); + return -EIO; + } + return 0; @@ -107,8 +107,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * - ENOMEM + */ +static int ext3_ext_get_access(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path) +{ + int err; + @@ -129,7 +129,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * - EIO + */ +static int ext3_ext_dirty(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int err; + if (path->p_bh) { @@ -144,8 +144,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int inline +ext3_ext_new_block(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, struct ext3_extent *ex, -+ int *err) ++ struct ext3_ext_path *path, struct ext3_extent *ex, ++ int *err) +{ + int goal, depth, newblock; + struct inode *inode; @@ -164,7 +164,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + unsigned long colour; + + bg_start = (ei->i_block_group * -+ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + ++ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + + le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); + colour = (current->pid % 16) * + (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); @@ -187,8 +187,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 6; +#endif @@ -200,8 +200,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 5; +#endif @@ -212,8 +212,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 3; +#endif @@ -224,9 +224,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 4; +#endif @@ -234,7 +233,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +static void ext3_ext_show_path(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int k, l = path->p_depth; @@ -243,12 +242,12 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + for (k = 0; k <= l; k++, path++) { + if (path->p_idx) { + ext_debug(tree, " %d->%d", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + } else if (path->p_ext) { + ext_debug(tree, " %d:%d:%d", -+ path->p_ext->ee_block, -+ path->p_ext->ee_len, -+ path->p_ext->ee_start); ++ path->p_ext->ee_block, ++ path->p_ext->ee_len, ++ path->p_ext->ee_start); + } else + ext_debug(tree, " []"); + } @@ -257,7 +256,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +static void ext3_ext_show_leaf(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int depth = EXT_DEPTH(tree); @@ -273,7 +272,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + + for (i = 0; i < eh->eh_entries; i++, ex++) { + ext_debug(tree, "%d:%d:%d ", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + } + ext_debug(tree, "\n"); +#endif @@ -284,11 +283,12 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + int depth = path->p_depth; + int i; + -+ for (i = 0; i <= depth; i++, path++) ++ for (i = 0; i <= depth; i++, path++) { + if (path->p_bh) { + brelse(path->p_bh); + path->p_bh = NULL; + } ++ } +} + +/* @@ -296,7 +296,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch_idx(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent_idx *ix; @@ -322,7 +322,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + + ix += l; + path->p_idx = ix; -+ ext_debug(tree, " -> %d->%d ", path->p_idx->ei_block, path->p_idx->ei_leaf); ++ ext_debug(tree," -> %d->%d ",path->p_idx->ei_block,path->p_idx->ei_leaf); + + while (l++ < r) { + if (block < ix->ei_block) @@ -330,7 +330,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + path->p_idx = ix++; + } + ext_debug(tree, " -> %d->%d\n", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + +#ifdef CHECK_BINSEARCH + { @@ -340,9 +340,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + for (k = 0; k < eh->eh_entries; k++, ix++) { + if (k != 0 && ix->ei_block <= ix[-1].ei_block) { + printk("k=%d, ix=0x%p, first=0x%p\n", k, -+ ix, EXT_FIRST_INDEX(eh)); ++ ix, EXT_FIRST_INDEX(eh)); + printk("%u <= %u\n", -+ ix->ei_block,ix[-1].ei_block); ++ ix->ei_block,ix[-1].ei_block); + } + EXT_ASSERT(k == 0 || ix->ei_block > ix[-1].ei_block); + if (block < ix->ei_block) @@ -352,7 +352,6 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + EXT_ASSERT(chix == path->p_idx); + } +#endif -+ +} + +/* @@ -360,7 +359,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent *ex; @@ -394,7 +393,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + ex += l; + path->p_ext = ex; + ext_debug(tree, " -> %d:%d:%d ", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + + while (l++ < r) { + if (block < ex->ee_block) @@ -402,7 +401,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + path->p_ext = ex++; + } + ext_debug(tree, " -> %d:%d:%d\n", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + +#ifdef CHECK_BINSEARCH + { @@ -418,7 +417,6 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + EXT_ASSERT(chex == path->p_ext); + } +#endif -+ +} + +int ext3_extent_tree_init(handle_t *handle, struct ext3_extents_tree *tree) @@ -439,7 +437,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +struct ext3_ext_path * +ext3_ext_find_extent(struct ext3_extents_tree *tree, int block, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + struct buffer_head *bh; @@ -461,7 +459,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* account possible depth increase */ + if (!path) { + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2), -+ GFP_NOFS); ++ GFP_NOFS); + if (!path) + return ERR_PTR(-ENOMEM); + } @@ -471,7 +469,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* walk through the tree */ + while (i) { + ext_debug(tree, "depth %d: num %d, max %d\n", -+ ppos, eh->eh_entries, eh->eh_max); ++ ppos, eh->eh_entries, eh->eh_max); + ext3_ext_binsearch_idx(tree, path + ppos, block); + path[ppos].p_block = path[ppos].p_idx->ei_leaf; + path[ppos].p_depth = i; @@ -519,9 +517,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * it check where to insert: before curp or after curp + */ +static int ext3_ext_insert_index(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *curp, -+ int logical, int ptr) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *curp, ++ int logical, int ptr) +{ + struct ext3_extent_idx *ix; + int len, err; @@ -537,9 +535,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d after: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ (curp->p_idx + 1), (curp->p_idx + 2)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ (curp->p_idx + 1), (curp->p_idx + 2)); + memmove(curp->p_idx + 2, curp->p_idx + 1, len); + } + ix = curp->p_idx + 1; @@ -548,9 +546,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + len = len * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d before: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ curp->p_idx, (curp->p_idx + 1)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ curp->p_idx, (curp->p_idx + 1)); + memmove(curp->p_idx + 1, curp->p_idx, len); + ix = curp->p_idx; + } @@ -578,8 +576,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * - initialize subtree + */ +static int ext3_ext_split(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext, int at) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext, int at) +{ + struct buffer_head *bh = NULL; + int depth = EXT_DEPTH(tree); @@ -600,13 +598,13 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) { + border = path[depth].p_ext[1].ee_block; + ext_debug(tree, "leaf will be splitted." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } else { + border = newext->ee_block; + ext_debug(tree, "leaf will be added." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } + + /* @@ -664,12 +662,11 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + while (path[depth].p_ext <= + EXT_MAX_EXTENT(path[depth].p_hdr)) { + ext_debug(tree, "move %d:%d:%d in new leaf %lu\n", -+ path[depth].p_ext->ee_block, -+ path[depth].p_ext->ee_start, -+ path[depth].p_ext->ee_len, -+ newblock); -+ memmove(ex++, path[depth].p_ext++, -+ sizeof(struct ext3_extent)); ++ path[depth].p_ext->ee_block, ++ path[depth].p_ext->ee_start, ++ path[depth].p_ext->ee_len, ++ newblock); ++ memmove(ex++, path[depth].p_ext++, sizeof(struct ext3_extent)); + neh->eh_entries++; + m++; + } @@ -722,21 +719,21 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + fidx->ei_leaf = oldblock; + + ext_debug(tree, "int.index at %d (block %lu): %lu -> %lu\n", -+ i, newblock, border, oldblock); ++ i, newblock, border, oldblock); + /* copy indexes */ + m = 0; + path[i].p_idx++; + + ext_debug(tree, "cur 0x%p, last 0x%p\n", path[i].p_idx, -+ EXT_MAX_INDEX(path[i].p_hdr)); ++ EXT_MAX_INDEX(path[i].p_hdr)); + EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) == -+ EXT_LAST_INDEX(path[i].p_hdr)); ++ EXT_LAST_INDEX(path[i].p_hdr)); + while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { + ext_debug(tree, "%d: move %d:%d in new index %lu\n", -+ i, path[i].p_idx->ei_block, -+ path[i].p_idx->ei_leaf, newblock); ++ i, path[i].p_idx->ei_block, ++ path[i].p_idx->ei_leaf, newblock); + memmove(++fidx, path[i].p_idx++, -+ sizeof(struct ext3_extent_idx)); ++ sizeof(struct ext3_extent_idx)); + neh->eh_entries++; + EXT_ASSERT(neh->eh_entries <= neh->eh_max); + m++; @@ -766,7 +763,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* insert new index */ + if (!err) + err = ext3_ext_insert_index(handle, tree, path + at, -+ border, newblock); ++ border, newblock); + +cleanup: + if (bh) { @@ -796,9 +793,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * just created block + */ +static int ext3_ext_grow_indepth(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp = path; + struct ext3_extent_header *neh; @@ -830,7 +827,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* set size of new block */ + neh = EXT_BLOCK_HDR(bh); + /* old root could have indexes or leaves -+ * so calculate e_max right way */ ++ * so calculate eh_max right way */ + if (EXT_DEPTH(tree)) + neh->eh_max = ext3_ext_space_block_idx(tree); + else @@ -857,7 +854,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + neh = EXT_ROOT_HDR(tree); + fidx = EXT_FIRST_INDEX(neh); + ext_debug(tree, "new root: num %d(%d), lblock %d, ptr %d\n", -+ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); ++ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); + + neh->eh_depth = path->p_depth + 1; + err = ext3_ext_dirty(handle, tree, curp); @@ -872,9 +869,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * then it requests in-depth growing + */ +static int ext3_ext_create_new_leaf(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp; + int depth, i, err = 0; @@ -950,12 +947,12 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if (depth == path->p_depth) { + /* leaf */ + if (path[depth].p_ext != -+ EXT_LAST_EXTENT(path[depth].p_hdr)) ++ EXT_LAST_EXTENT(path[depth].p_hdr)) + return path[depth].p_ext[1].ee_block; + } else { + /* index */ + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + } + depth--; @@ -968,7 +965,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * returns first allocated block from next leaf or EXT_MAX_BLOCK + */ +static unsigned ext3_ext_next_leaf_block(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth; + @@ -984,7 +981,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + + while (depth >= 0) { + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + depth--; + } @@ -998,7 +995,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * TODO: do we need to correct tree in all cases? + */ +int ext3_ext_correct_indexes(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + int depth = EXT_DEPTH(tree); @@ -1048,8 +1045,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int inline +ext3_can_extents_be_merged(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex1, ++ struct ext3_extent *ex2) +{ + if (ex1->ee_block + ex1->ee_len != ex2->ee_block) + return 0; @@ -1071,8 +1068,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * creating new leaf in no-space case + */ +int ext3_ext_insert_extent(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_extent_header * eh; + struct ext3_extent *ex, *fex; @@ -1088,8 +1085,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* try to insert block into found extent and return */ + if (ex && ext3_can_extents_be_merged(tree, ex, newext)) { + ext_debug(tree, "append %d block to %d:%d (from %d)\n", -+ newext->ee_len, ex->ee_block, ex->ee_len, -+ ex->ee_start); ++ newext->ee_len, ex->ee_block, ex->ee_len, ++ ex->ee_start); + if ((err = ext3_ext_get_access(handle, tree, path + depth))) + return err; + ex->ee_len += newext->ee_len; @@ -1117,12 +1114,12 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + eh = npath[depth].p_hdr; + if (eh->eh_entries < eh->eh_max) { + ext_debug(tree, "next leaf isnt full(%d)\n", -+ eh->eh_entries); ++ eh->eh_entries); + path = npath; + goto repeat; + } + ext_debug(tree, "next leaf hasno free space(%d,%d)\n", -+ eh->eh_entries, eh->eh_max); ++ eh->eh_entries, eh->eh_max); + } + + /* @@ -1144,8 +1141,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if (!nearex) { + /* there is no extent in this leaf, create first one */ + ext_debug(tree, "first extent in the leaf: %d:%d:%d\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len); ++ newext->ee_block, newext->ee_start, ++ newext->ee_len); + path[depth].p_ext = EXT_FIRST_EXTENT(eh); + } else if (newext->ee_block > nearex->ee_block) { + EXT_ASSERT(newext->ee_block != nearex->ee_block); @@ -1154,10 +1151,10 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d after: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, ++ newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 2, nearex + 1, len); + } + path[depth].p_ext = nearex + 1; @@ -1166,9 +1163,9 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d before: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 1, nearex, len); + path[depth].p_ext = nearex; + } @@ -1189,8 +1186,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* merge with next extent! */ + nearex->ee_len += nearex[1].ee_len; + if (nearex + 1 < EXT_LAST_EXTENT(eh)) { -+ len = (EXT_LAST_EXTENT(eh) - nearex - 1) -+ * sizeof(struct ext3_extent); ++ len = (EXT_LAST_EXTENT(eh) - nearex - 1) * ++ sizeof(struct ext3_extent); + memmove(nearex + 1, nearex + 2, len); + } + eh->eh_entries--; @@ -1324,7 +1321,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static inline void +ext3_ext_put_in_cache(struct ext3_extents_tree *tree, __u32 block, -+ __u32 len, __u32 start, int type) ++ __u32 len, __u32 start, int type) +{ + EXT_ASSERT(len > 0); + if (tree->cex) { @@ -1341,8 +1338,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + */ +static inline void +ext3_ext_put_gap_in_cache(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ unsigned long block) ++ struct ext3_ext_path *path, ++ unsigned long block) +{ + int depth = EXT_DEPTH(tree); + unsigned long lblock, len; @@ -1361,16 +1358,16 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + lblock = block; + len = ex->ee_block - block; + ext_debug(tree, "cache gap(before): %lu [%lu:%lu]", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len); + } else if (block >= ex->ee_block + ex->ee_len) { + lblock = ex->ee_block + ex->ee_len; + len = ext3_ext_next_allocated_block(path); + ext_debug(tree, "cache gap(after): [%lu:%lu] %lu", -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) block); ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) block); + EXT_ASSERT(len > lblock); + len = len - lblock; + } else { @@ -1384,7 +1381,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static inline int +ext3_ext_in_cache(struct ext3_extents_tree *tree, unsigned long block, -+ struct ext3_extent *ex) ++ struct ext3_extent *ex) +{ + struct ext3_ext_cache *cex = tree->cex; + @@ -1397,16 +1394,16 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + return EXT3_EXT_CACHE_NO; + + EXT_ASSERT(cex->ec_type == EXT3_EXT_CACHE_GAP || -+ cex->ec_type == EXT3_EXT_CACHE_EXTENT); ++ cex->ec_type == EXT3_EXT_CACHE_EXTENT); + if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) { + ex->ee_block = cex->ec_block; + ex->ee_start = cex->ec_start; + ex->ee_len = cex->ec_len; + ext_debug(tree, "%lu cached by %lu:%lu:%lu\n", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) ex->ee_start); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) ex->ee_start); + return cex->ec_type; + } + @@ -1420,7 +1417,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + * last index in the block only + */ +int ext3_ext_rm_idx(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct buffer_head *bh; + int err; @@ -1434,7 +1431,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if ((err = ext3_ext_dirty(handle, tree, path))) + return err; + ext_debug(tree, "index is empty, remove it, free block %d\n", -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + bh = sb_find_get_block(tree->inode->i_sb, path->p_idx->ei_leaf); + ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf); + ext3_free_blocks(handle, tree->inode, path->p_idx->ei_leaf, 1); @@ -1442,7 +1439,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth = EXT_DEPTH(tree); + int needed; @@ -1479,8 +1476,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int +ext3_ext_split_for_rm(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, tex; + struct ext3_ext_path *npath; @@ -1514,7 +1511,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + /* FIXME: some callback to free underlying resource + * and correct ee_start? */ + ext_debug(tree, "split extent: head %u:%u, tail %u:%u\n", -+ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); ++ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); + + npath = ext3_ext_find_extent(tree, ex->ee_block, NULL); + if (IS_ERR(npath)) @@ -1528,13 +1525,12 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + kfree(npath); + + return err; -+ +} + +static int +ext3_ext_rm_leaf(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, *fu = NULL, *lu, *le; + int err = 0, correct_index = 0; @@ -1567,8 +1563,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + } + + lu = ex; -+ while (ex >= EXT_FIRST_EXTENT(eh) && -+ ex->ee_block + ex->ee_len > start) { ++ while (ex >= EXT_FIRST_EXTENT(eh) && ex->ee_block + ex->ee_len > start) { + ext_debug(tree, "remove ext %u:%u\n", ex->ee_block, ex->ee_len); + path[depth].p_ext = ex; + @@ -1595,7 +1590,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + block = ex->ee_block; + num = 0; + EXT_ASSERT(a == ex->ee_block && -+ b == ex->ee_block + ex->ee_len - 1); ++ b == ex->ee_block + ex->ee_len - 1); + } + + if (ex == EXT_FIRST_EXTENT(eh)) @@ -1637,7 +1632,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + goto out; + + ext_debug(tree, "new extent: %u:%u:%u\n", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + ex--; + } + @@ -1701,7 +1696,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +int ext3_ext_remove_space(struct ext3_extents_tree *tree, -+ unsigned long start, unsigned long end) ++ unsigned long start, unsigned long end) +{ + struct inode *inode = tree->inode; + struct super_block *sb = inode->i_sb; @@ -1725,8 +1720,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + */ + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL); + if (IS_ERR(path)) { -+ ext3_error(sb, "ext3_ext_remove_space", -+ "Can't allocate path array"); ++ ext3_error(sb, __FUNCTION__, "Can't allocate path array"); + ext3_journal_stop(handle); + return -ENOMEM; + } @@ -1758,19 +1752,19 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + ext3_ext_last_covered(path[i].p_hdr, end); + path[i].p_block = path[i].p_hdr->eh_entries + 1; + ext_debug(tree, "init index ptr: hdr 0x%p, num %d\n", -+ path[i].p_hdr, path[i].p_hdr->eh_entries); ++ path[i].p_hdr, path[i].p_hdr->eh_entries); + } else { + /* we've already was here, see at next index */ + path[i].p_idx--; + } + + ext_debug(tree, "level %d - index, first 0x%p, cur 0x%p\n", -+ i, EXT_FIRST_INDEX(path[i].p_hdr), -+ path[i].p_idx); ++ i, EXT_FIRST_INDEX(path[i].p_hdr), ++ path[i].p_idx); + if (ext3_ext_more_to_rm(path + i)) { + /* go to the next level */ + ext_debug(tree, "move to level %d (block %d)\n", -+ i + 1, path[i].p_idx->ei_leaf); ++ i + 1, path[i].p_idx->ei_leaf); + memset(path + i + 1, 0, sizeof(*path)); + path[i+1].p_bh = sb_bread(sb, path[i].p_idx->ei_leaf); + if (!path[i+1].p_bh) { @@ -1893,7 +1887,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +static int ext3_ext_mergable(struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex2) +{ + /* FIXME: support for large fs */ + if (ex1->ee_start + ex1->ee_len == ex2->ee_start) @@ -1903,8 +1897,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int +ext3_remove_blocks_credits(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed; + @@ -1919,8 +1913,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int +ext3_remove_blocks(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed = ext3_remove_blocks_credits(tree, ex, from, to); + handle_t *handle = ext3_journal_start(tree->inode, needed); @@ -1935,7 +1929,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + num = ex->ee_block + ex->ee_len - from; + start = ex->ee_start + ex->ee_len - num; + ext_debug(tree, "free last %lu blocks starting %lu\n", -+ num, start); ++ num, start); + for (i = 0; i < num; i++) { + bh = sb_find_get_block(tree->inode->i_sb, start + i); + ext3_forget(handle, 0, tree->inode, bh, start + i); @@ -1943,17 +1937,17 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + ext3_free_blocks(handle, tree->inode, start, num); + } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { + printk("strange request: removal %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } else { + printk("strange request: removal(2) %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } + ext3_journal_stop(handle); + return 0; +} + +static int ext3_ext_find_goal(struct inode *inode, -+ struct ext3_ext_path *path, unsigned long block) ++ struct ext3_ext_path *path, unsigned long block) +{ + struct ext3_inode_info *ei = EXT3_I(inode); + unsigned long bg_start; @@ -1983,8 +1977,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +static int ext3_new_block_cb(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int *err) ++ struct ext3_ext_path *path, ++ struct ext3_extent *ex, int *err) +{ + struct inode *inode = tree->inode; + int newblock, goal; @@ -2021,7 +2015,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +}; + +void ext3_init_tree_desc(struct ext3_extents_tree *tree, -+ struct inode *inode) ++ struct inode *inode) +{ + tree->inode = inode; + tree->root = (void *) EXT3_I(inode)->i_data; @@ -2032,8 +2026,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +int ext3_ext_get_block(handle_t *handle, struct inode *inode, -+ long iblock, struct buffer_head *bh_result, -+ int create, int extend_disksize) ++ long iblock, struct buffer_head *bh_result, ++ int create, int extend_disksize) +{ + struct ext3_ext_path *path = NULL; + struct ext3_extent newex; @@ -2044,7 +2038,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + __clear_bit(BH_New, &bh_result->b_state); + ext3_init_tree_desc(&tree, inode); + ext_debug(&tree, "block %d requested for inode %u\n", -+ (int) iblock, (unsigned) inode->i_ino); ++ (int) iblock, (unsigned) inode->i_ino); + down(&EXT3_I(inode)->truncate_sem); + + /* check in cache */ @@ -2087,11 +2081,11 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if (iblock >= ex->ee_block && iblock < ex->ee_block + ex->ee_len) { + newblock = iblock - ex->ee_block + ex->ee_start; + ext_debug(&tree, "%d fit into %d:%d -> %d\n", -+ (int) iblock, ex->ee_block, ex->ee_len, -+ newblock); ++ (int) iblock, ex->ee_block, ex->ee_len, ++ newblock); + ext3_ext_put_in_cache(&tree, ex->ee_block, -+ ex->ee_len, ex->ee_start, -+ EXT3_EXT_CACHE_EXTENT); ++ ex->ee_len, ex->ee_start, ++ EXT3_EXT_CACHE_EXTENT); + goto out; + } + } @@ -2112,7 +2106,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + if (!newblock) + goto out2; + ext_debug(&tree, "allocate new block: goal %d, found %d\n", -+ goal, newblock); ++ goal, newblock); + + /* try to insert new extent into found leaf and return */ + newex.ee_block = iblock; @@ -2130,7 +2124,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + __set_bit(BH_New, &bh_result->b_state); + + ext3_ext_put_in_cache(&tree, newex.ee_block, newex.ee_len, -+ newex.ee_start, EXT3_EXT_CACHE_EXTENT); ++ newex.ee_start, EXT3_EXT_CACHE_EXTENT); +out: + ext3_ext_show_leaf(&tree, path); + __set_bit(BH_Mapped, &bh_result->b_state); @@ -2190,8 +2184,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + EXT3_I(inode)->i_disksize = inode->i_size; + ext3_mark_inode_dirty(handle, inode); + -+ last_block = (inode->i_size + sb->s_blocksize - 1) -+ >> EXT3_BLOCK_SIZE_BITS(sb); ++ last_block = (inode->i_size + sb->s_blocksize - 1) >> ++ EXT3_BLOCK_SIZE_BITS(sb); + err = ext3_ext_remove_space(&tree, last_block, EXT_MAX_BLOCK); + + /* In a multi-transaction truncate, we only make the final @@ -2259,8 +2253,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int +ext3_ext_store_extent_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_ext_cache *newex) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *newex) +{ + struct ext3_extent_buf *buf = (struct ext3_extent_buf *) tree->private; + @@ -2284,8 +2278,8 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + +static int +ext3_ext_collect_stats_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_ext_cache *ex) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *ex) +{ + struct ext3_extent_tree_stats *buf = + (struct ext3_extent_tree_stats *) tree->private; @@ -2302,7 +2296,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +} + +int ext3_ext_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, -+ unsigned long arg) ++ unsigned long arg) +{ + int err = 0; + @@ -2322,7 +2316,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + tree.private = &buf; + down(&EXT3_I(inode)->truncate_sem); + err = ext3_ext_walk_space(&tree, buf.start, EXT_MAX_BLOCK, -+ ext3_ext_store_extent_cb); ++ ext3_ext_store_extent_cb); + up(&EXT3_I(inode)->truncate_sem); + if (err == 0) + err = buf.err; @@ -2337,7 +2331,7 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c + buf.leaf_num = 0; + tree.private = &buf; + err = ext3_ext_walk_space(&tree, 0, EXT_MAX_BLOCK, -+ ext3_ext_collect_stats_cb); ++ ext3_ext_collect_stats_cb); + up(&EXT3_I(inode)->truncate_sem); + if (!err) + err = copy_to_user((void *) arg, &buf, sizeof(buf)); @@ -2359,19 +2353,26 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c +EXPORT_SYMBOL(ext3_ext_walk_space); +EXPORT_SYMBOL(ext3_ext_find_goal); +EXPORT_SYMBOL(ext3_ext_calc_credits_for_insert); -+ Index: linux-2.6.5-sles9/fs/ext3/ialloc.c =================================================================== --- linux-2.6.5-sles9.orig/fs/ext3/ialloc.c 2005-02-23 01:01:52.366281264 +0300 +++ linux-2.6.5-sles9/fs/ext3/ialloc.c 2005-02-23 01:02:37.398435336 +0300 -@@ -647,6 +647,10 @@ +@@ -647,6 +647,18 @@ DQUOT_FREE_INODE(inode); goto fail2; } -+ if (test_opt(sb, EXTENTS)) { -+ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; -+ ext3_extents_initialize_blockmap(handle, inode); -+ } ++ if (test_opt(sb, EXTENTS) && S_ISREG(inode->i_mode)) { ++ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; ++ ext3_extents_initialize_blockmap(handle, inode); ++ if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS)) { ++ err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); ++ if (err) goto fail; ++ EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS); ++ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "call ext3_journal_dirty_metadata"); ++ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); ++ } ++ } ++ err = ext3_mark_inode_dirty(handle, inode); if (err) { ext3_std_error(sb, err); @@ -2385,13 +2386,13 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c +static inline int +ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block, -+ struct buffer_head *bh, int create, int extend_disksize) ++ struct buffer_head *bh, int create, int extend_disksize) +{ + if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) + return ext3_ext_get_block(handle, inode, block, bh, create, -+ extend_disksize); ++ extend_disksize); + return ext3_get_block_handle(handle, inode, block, bh, create, -+ extend_disksize); ++ extend_disksize); +} + static int ext3_get_block(struct inode *inode, sector_t iblock, @@ -2404,7 +2405,7 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c - ret = ext3_get_block_handle(handle, inode, iblock, - bh_result, create, 1); + ret = ext3_get_block_wrap(handle, inode, iblock, -+ bh_result, create, 1); ++ bh_result, create, 1); return ret; } @@ -2415,7 +2416,7 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c - ret = ext3_get_block_handle(handle, inode, iblock, - bh_result, create, 0); + ret = ext3_get_block_wrap(handle, inode, iblock, -+ bh_result, create, 0); ++ bh_result, create, 0); if (ret == 0) bh_result->b_size = (1 << inode->i_blkbits); return ret; @@ -2451,9 +2452,9 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3; int ret; -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) -+ return ext3_ext_writepage_trans_blocks(inode, bpp); -+ ++ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) ++ return ext3_ext_writepage_trans_blocks(inode, bpp); ++ if (ext3_should_journal_data(inode)) ret = 3 * (bpp + indirects) + 2; else @@ -2478,7 +2479,7 @@ Index: linux-2.6.5-sles9/fs/ext3/super.c struct ext3_super_block *es = sbi->s_es; int i; -+ ext3_ext_release(sb); ++ ext3_ext_release(sb); ext3_xattr_put_super(sb); journal_destroy(sbi->s_journal); if (!(sb->s_flags & MS_RDONLY)) { @@ -2526,8 +2527,8 @@ Index: linux-2.6.5-sles9/fs/ext3/super.c percpu_counter_mod(&sbi->s_dirs_counter, ext3_count_dirs(sb)); -+ ext3_ext_init(sb); -+ ++ ext3_ext_init(sb); ++ return 0; failed_mount3: @@ -2550,14 +2551,17 @@ Index: linux-2.6.5-sles9/include/linux/ext3_fs.h =================================================================== --- linux-2.6.5-sles9.orig/include/linux/ext3_fs.h 2005-02-23 01:02:35.823674736 +0300 +++ linux-2.6.5-sles9/include/linux/ext3_fs.h 2005-02-23 01:02:37.414432904 +0300 -@@ -186,6 +186,7 @@ +@@ -186,8 +186,9 @@ + #define EXT3_NOTAIL_FL 0x00008000 /* don't merge file tail */ #define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ #define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ - #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ +#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ + #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ - #define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ +-#define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ ++#define EXT3_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */ #define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ + @@ -211,6 +212,9 @@ #endif #define EXT3_IOC_GETRSVSZ _IOR('f', 5, long) @@ -2577,6 +2581,21 @@ Index: linux-2.6.5-sles9/include/linux/ext3_fs.h /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef clear_opt +@@ -503,11 +509,13 @@ + #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ + #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ + #define EXT3_FEATURE_INCOMPAT_META_BG 0x0010 ++#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ + + #define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR + #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ + EXT3_FEATURE_INCOMPAT_RECOVER| \ +- EXT3_FEATURE_INCOMPAT_META_BG) ++ EXT3_FEATURE_INCOMPAT_META_BG| \ ++ EXT3_FEATURE_INCOMPAT_EXTENTS) + #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ + EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ + EXT3_FEATURE_RO_COMPAT_BTREE_DIR) @@ -729,6 +735,7 @@ @@ -2592,7 +2611,7 @@ Index: linux-2.6.5-sles9/include/linux/ext3_fs.h +/* extents.c */ +extern int ext3_ext_writepage_trans_blocks(struct inode *, int); +extern int ext3_ext_get_block(handle_t *, struct inode *, long, -+ struct buffer_head *, int, int); ++ struct buffer_head *, int, int); +extern void ext3_ext_truncate(struct inode *, struct page *); +extern void ext3_ext_init(struct super_block *); +extern void ext3_ext_release(struct super_block *); @@ -2606,7 +2625,7 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h =================================================================== --- linux-2.6.5-sles9.orig/include/linux/ext3_extents.h 2005-02-17 22:07:57.023609040 +0300 +++ linux-2.6.5-sles9/include/linux/ext3_extents.h 2005-02-23 01:02:37.416432600 +0300 -@@ -0,0 +1,265 @@ +@@ -0,0 +1,264 @@ +/* + * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas @@ -2648,7 +2667,7 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + */ +#define EXT_DEBUG_ +#ifdef EXT_DEBUG -+#define ext_debug(tree,fmt,a...) \ ++#define ext_debug(tree,fmt,a...) \ +do { \ + if (test_opt((tree)->inode->i_sb, EXTDEBUG)) \ + printk(fmt, ##a); \ @@ -2761,14 +2780,14 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + int (*mark_buffer_dirty)(handle_t *h, void *buffer); + int (*mergable)(struct ext3_extent *ex1, struct ext3_extent *ex2); + int (*remove_extent_credits)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*remove_extent)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*new_block)(handle_t *, struct ext3_extents_tree *, -+ struct ext3_ext_path *, struct ext3_extent *, -+ int *); ++ struct ext3_ext_path *, struct ext3_extent *, ++ int *); +}; + +/* @@ -2778,8 +2797,8 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + * callback must return valid extent (passed or newly created) + */ +typedef int (*ext_prepare_callback)(struct ext3_extents_tree *, -+ struct ext3_ext_path *, -+ struct ext3_ext_cache *); ++ struct ext3_ext_path *, ++ struct ext3_ext_cache *); + +#define EXT_CONTINUE 0 +#define EXT_BREAK 1 @@ -2831,7 +2850,7 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + && depth != 0); \ + BUG_ON((path)[0].p_depth != depth); \ +} -+ ++ + +/* + * this structure is used to gather extents from the tree via ioctl @@ -2853,13 +2872,13 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + int leaf_num; +}; + ++extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); +extern int ext3_extent_tree_init(handle_t *, struct ext3_extents_tree *); +extern int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *, struct ext3_ext_path *); +extern int ext3_ext_insert_extent(handle_t *, struct ext3_extents_tree *, struct ext3_ext_path *, struct ext3_extent *); +extern int ext3_ext_walk_space(struct ext3_extents_tree *, unsigned long, unsigned long, ext_prepare_callback); +extern int ext3_ext_remove_space(struct ext3_extents_tree *, unsigned long, unsigned long); +extern struct ext3_ext_path * ext3_ext_find_extent(struct ext3_extents_tree *, int, struct ext3_ext_path *); -+extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); +extern int ext3_ext_calc_blockmap_metadata(struct inode *, int); + +static inline void @@ -2871,7 +2890,6 @@ Index: linux-2.6.5-sles9/include/linux/ext3_extents.h + + +#endif /* _LINUX_EXT3_EXTENTS */ -+ Index: linux-2.6.5-sles9/include/linux/ext3_fs_i.h =================================================================== --- linux-2.6.5-sles9.orig/include/linux/ext3_fs_i.h 2005-02-23 01:01:52.425272296 +0300 diff --git a/lustre/kernel_patches/patches/ext3-extents-2.6.9-rhel4.patch b/lustre/kernel_patches/patches/ext3-extents-2.6.9-rhel4.patch index 78c5d81..02745cc 100644 --- a/lustre/kernel_patches/patches/ext3-extents-2.6.9-rhel4.patch +++ b/lustre/kernel_patches/patches/ext3-extents-2.6.9-rhel4.patch @@ -2,9 +2,9 @@ Index: linux-stage/fs/ext3/extents.c =================================================================== --- linux-stage.orig/fs/ext3/extents.c 2005-02-25 15:33:48.890198160 +0200 +++ linux-stage/fs/ext3/extents.c 2005-02-25 15:33:48.917194056 +0200 -@@ -0,0 +1,2313 @@ +@@ -0,0 +1,2347 @@ +/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com ++ * Copyright(c) 2003, 2004, 2005, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify @@ -48,6 +48,27 @@ Index: linux-stage/fs/ext3/extents.c +#include +#include + ++ ++static inline int ext3_ext_check_header(struct ext3_extent_header *eh) ++{ ++ if (eh->eh_magic != EXT3_EXT_MAGIC) { ++ printk(KERN_ERR "EXT3-fs: invalid magic = 0x%x\n", ++ (unsigned)eh->eh_magic); ++ return -EIO; ++ } ++ if (eh->eh_max == 0) { ++ printk(KERN_ERR "EXT3-fs: invalid eh_max = %u\n", ++ (unsigned)eh->eh_max); ++ return -EIO; ++ } ++ if (eh->eh_entries > eh->eh_max) { ++ printk(KERN_ERR "EXT3-fs: invalid eh_entries = %u\n", ++ (unsigned)eh->eh_entries); ++ return -EIO; ++ } ++ return 0; ++} ++ +static handle_t *ext3_ext_journal_restart(handle_t *handle, int needed) +{ + int err; @@ -85,8 +106,8 @@ Index: linux-stage/fs/ext3/extents.c + * - ENOMEM + */ +static int ext3_ext_get_access(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path) +{ + int err; + @@ -107,7 +128,7 @@ Index: linux-stage/fs/ext3/extents.c + * - EIO + */ +static int ext3_ext_dirty(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int err; + if (path->p_bh) { @@ -122,8 +143,8 @@ Index: linux-stage/fs/ext3/extents.c + +static int inline +ext3_ext_new_block(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, struct ext3_extent *ex, -+ int *err) ++ struct ext3_ext_path *path, struct ext3_extent *ex, ++ int *err) +{ + int goal, depth, newblock; + struct inode *inode; @@ -142,7 +163,7 @@ Index: linux-stage/fs/ext3/extents.c + unsigned long colour; + + bg_start = (ei->i_block_group * -+ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + ++ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + + le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); + colour = (current->pid % 16) * + (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); @@ -165,8 +186,8 @@ Index: linux-stage/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 6; +#endif @@ -178,8 +199,8 @@ Index: linux-stage/fs/ext3/extents.c + int size; + + size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 5; +#endif @@ -190,8 +211,8 @@ Index: linux-stage/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent); +#ifdef AGRESSIVE_TEST + size = 3; +#endif @@ -202,9 +223,8 @@ Index: linux-stage/fs/ext3/extents.c +{ + int size; + -+ size = (tree->buffer_len - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); ++ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) / ++ sizeof(struct ext3_extent_idx); +#ifdef AGRESSIVE_TEST + size = 4; +#endif @@ -212,7 +232,7 @@ Index: linux-stage/fs/ext3/extents.c +} + +static void ext3_ext_show_path(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int k, l = path->p_depth; @@ -221,12 +241,12 @@ Index: linux-stage/fs/ext3/extents.c + for (k = 0; k <= l; k++, path++) { + if (path->p_idx) { + ext_debug(tree, " %d->%d", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + } else if (path->p_ext) { + ext_debug(tree, " %d:%d:%d", -+ path->p_ext->ee_block, -+ path->p_ext->ee_len, -+ path->p_ext->ee_start); ++ path->p_ext->ee_block, ++ path->p_ext->ee_len, ++ path->p_ext->ee_start); + } else + ext_debug(tree, " []"); + } @@ -235,7 +255,7 @@ Index: linux-stage/fs/ext3/extents.c +} + +static void ext3_ext_show_leaf(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ +#ifdef EXT_DEBUG + int depth = EXT_DEPTH(tree); @@ -251,7 +271,7 @@ Index: linux-stage/fs/ext3/extents.c + + for (i = 0; i < eh->eh_entries; i++, ex++) { + ext_debug(tree, "%d:%d:%d ", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + } + ext_debug(tree, "\n"); +#endif @@ -262,11 +282,12 @@ Index: linux-stage/fs/ext3/extents.c + int depth = path->p_depth; + int i; + -+ for (i = 0; i <= depth; i++, path++) ++ for (i = 0; i <= depth; i++, path++) { + if (path->p_bh) { + brelse(path->p_bh); + path->p_bh = NULL; + } ++ } +} + +/* @@ -274,7 +295,7 @@ Index: linux-stage/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch_idx(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent_idx *ix; @@ -300,7 +321,7 @@ Index: linux-stage/fs/ext3/extents.c + + ix += l; + path->p_idx = ix; -+ ext_debug(tree, " -> %d->%d ", path->p_idx->ei_block, path->p_idx->ei_leaf); ++ ext_debug(tree," -> %d->%d ",path->p_idx->ei_block,path->p_idx->ei_leaf); + + while (l++ < r) { + if (block < ix->ei_block) @@ -308,7 +329,7 @@ Index: linux-stage/fs/ext3/extents.c + path->p_idx = ix++; + } + ext_debug(tree, " -> %d->%d\n", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + +#ifdef CHECK_BINSEARCH + { @@ -318,9 +339,9 @@ Index: linux-stage/fs/ext3/extents.c + for (k = 0; k < eh->eh_entries; k++, ix++) { + if (k != 0 && ix->ei_block <= ix[-1].ei_block) { + printk("k=%d, ix=0x%p, first=0x%p\n", k, -+ ix, EXT_FIRST_INDEX(eh)); ++ ix, EXT_FIRST_INDEX(eh)); + printk("%u <= %u\n", -+ ix->ei_block,ix[-1].ei_block); ++ ix->ei_block,ix[-1].ei_block); + } + EXT_ASSERT(k == 0 || ix->ei_block > ix[-1].ei_block); + if (block < ix->ei_block) @@ -330,7 +351,6 @@ Index: linux-stage/fs/ext3/extents.c + EXT_ASSERT(chix == path->p_idx); + } +#endif -+ +} + +/* @@ -338,7 +358,7 @@ Index: linux-stage/fs/ext3/extents.c + */ +static inline void +ext3_ext_binsearch(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) ++ struct ext3_ext_path *path, int block) +{ + struct ext3_extent_header *eh = path->p_hdr; + struct ext3_extent *ex; @@ -372,7 +392,7 @@ Index: linux-stage/fs/ext3/extents.c + ex += l; + path->p_ext = ex; + ext_debug(tree, " -> %d:%d:%d ", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + + while (l++ < r) { + if (block < ex->ee_block) @@ -380,7 +400,7 @@ Index: linux-stage/fs/ext3/extents.c + path->p_ext = ex++; + } + ext_debug(tree, " -> %d:%d:%d\n", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); ++ path->p_ext->ee_start, path->p_ext->ee_len); + +#ifdef CHECK_BINSEARCH + { @@ -396,7 +416,6 @@ Index: linux-stage/fs/ext3/extents.c + EXT_ASSERT(chex == path->p_ext); + } +#endif -+ +} + +int ext3_extent_tree_init(handle_t *handle, struct ext3_extents_tree *tree) @@ -417,7 +436,7 @@ Index: linux-stage/fs/ext3/extents.c + +struct ext3_ext_path * +ext3_ext_find_extent(struct ext3_extents_tree *tree, int block, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + struct buffer_head *bh; @@ -429,15 +448,17 @@ Index: linux-stage/fs/ext3/extents.c + + eh = EXT_ROOT_HDR(tree); + EXT_ASSERT(eh); ++ if (ext3_ext_check_header(eh)) ++ goto err; ++ + i = depth = EXT_DEPTH(tree); + EXT_ASSERT(eh->eh_max); + EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ EXT_ASSERT(i == 0 || eh->eh_entries > 0); + + /* account possible depth increase */ + if (!path) { + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2), -+ GFP_NOFS); ++ GFP_NOFS); + if (!path) + return ERR_PTR(-ENOMEM); + } @@ -447,29 +468,34 @@ Index: linux-stage/fs/ext3/extents.c + /* walk through the tree */ + while (i) { + ext_debug(tree, "depth %d: num %d, max %d\n", -+ ppos, eh->eh_entries, eh->eh_max); ++ ppos, eh->eh_entries, eh->eh_max); + ext3_ext_binsearch_idx(tree, path + ppos, block); + path[ppos].p_block = path[ppos].p_idx->ei_leaf; + path[ppos].p_depth = i; + path[ppos].p_ext = NULL; + + bh = sb_bread(tree->inode->i_sb, path[ppos].p_block); -+ if (!bh) { -+ ext3_ext_drop_refs(path); -+ kfree(path); -+ return ERR_PTR(-EIO); -+ } ++ if (!bh) ++ goto err; ++ + eh = EXT_BLOCK_HDR(bh); + ppos++; + EXT_ASSERT(ppos <= depth); + path[ppos].p_bh = bh; + path[ppos].p_hdr = eh; + i--; ++ ++ if (ext3_ext_check_header(eh)) ++ goto err; + } + + path[ppos].p_depth = i; + path[ppos].p_hdr = eh; + path[ppos].p_ext = NULL; ++ path[ppos].p_idx = NULL; ++ ++ if (ext3_ext_check_header(eh)) ++ goto err; + + /* find extent */ + ext3_ext_binsearch(tree, path + ppos, block); @@ -477,6 +503,12 @@ Index: linux-stage/fs/ext3/extents.c + ext3_ext_show_path(tree, path); + + return path; ++ ++err: ++ printk(KERN_ERR "EXT3-fs: header is corrupted!\n"); ++ ext3_ext_drop_refs(path); ++ kfree(path); ++ return ERR_PTR(-EIO); +} + +/* @@ -484,9 +516,9 @@ Index: linux-stage/fs/ext3/extents.c + * it check where to insert: before curp or after curp + */ +static int ext3_ext_insert_index(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *curp, -+ int logical, int ptr) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *curp, ++ int logical, int ptr) +{ + struct ext3_extent_idx *ix; + int len, err; @@ -502,9 +534,9 @@ Index: linux-stage/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d after: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ (curp->p_idx + 1), (curp->p_idx + 2)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ (curp->p_idx + 1), (curp->p_idx + 2)); + memmove(curp->p_idx + 2, curp->p_idx + 1, len); + } + ix = curp->p_idx + 1; @@ -513,9 +545,9 @@ Index: linux-stage/fs/ext3/extents.c + len = len * sizeof(struct ext3_extent_idx); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert new index %d before: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ curp->p_idx, (curp->p_idx + 1)); ++ "move %d from 0x%p to 0x%p\n", ++ logical, ptr, len, ++ curp->p_idx, (curp->p_idx + 1)); + memmove(curp->p_idx + 1, curp->p_idx, len); + ix = curp->p_idx; + } @@ -543,8 +575,8 @@ Index: linux-stage/fs/ext3/extents.c + * - initialize subtree + */ +static int ext3_ext_split(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext, int at) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext, int at) +{ + struct buffer_head *bh = NULL; + int depth = EXT_DEPTH(tree); @@ -565,13 +597,13 @@ Index: linux-stage/fs/ext3/extents.c + if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) { + border = path[depth].p_ext[1].ee_block; + ext_debug(tree, "leaf will be splitted." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } else { + border = newext->ee_block; + ext_debug(tree, "leaf will be added." -+ " next leaf starts at %d\n", -+ (int)border); ++ " next leaf starts at %d\n", ++ (int)border); + } + + /* @@ -629,12 +661,11 @@ Index: linux-stage/fs/ext3/extents.c + while (path[depth].p_ext <= + EXT_MAX_EXTENT(path[depth].p_hdr)) { + ext_debug(tree, "move %d:%d:%d in new leaf %lu\n", -+ path[depth].p_ext->ee_block, -+ path[depth].p_ext->ee_start, -+ path[depth].p_ext->ee_len, -+ newblock); -+ memmove(ex++, path[depth].p_ext++, -+ sizeof(struct ext3_extent)); ++ path[depth].p_ext->ee_block, ++ path[depth].p_ext->ee_start, ++ path[depth].p_ext->ee_len, ++ newblock); ++ memmove(ex++, path[depth].p_ext++, sizeof(struct ext3_extent)); + neh->eh_entries++; + m++; + } @@ -687,21 +718,21 @@ Index: linux-stage/fs/ext3/extents.c + fidx->ei_leaf = oldblock; + + ext_debug(tree, "int.index at %d (block %lu): %lu -> %lu\n", -+ i, newblock, border, oldblock); ++ i, newblock, border, oldblock); + /* copy indexes */ + m = 0; + path[i].p_idx++; + + ext_debug(tree, "cur 0x%p, last 0x%p\n", path[i].p_idx, -+ EXT_MAX_INDEX(path[i].p_hdr)); ++ EXT_MAX_INDEX(path[i].p_hdr)); + EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) == -+ EXT_LAST_INDEX(path[i].p_hdr)); ++ EXT_LAST_INDEX(path[i].p_hdr)); + while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { + ext_debug(tree, "%d: move %d:%d in new index %lu\n", -+ i, path[i].p_idx->ei_block, -+ path[i].p_idx->ei_leaf, newblock); ++ i, path[i].p_idx->ei_block, ++ path[i].p_idx->ei_leaf, newblock); + memmove(++fidx, path[i].p_idx++, -+ sizeof(struct ext3_extent_idx)); ++ sizeof(struct ext3_extent_idx)); + neh->eh_entries++; + EXT_ASSERT(neh->eh_entries <= neh->eh_max); + m++; @@ -731,7 +762,7 @@ Index: linux-stage/fs/ext3/extents.c + /* insert new index */ + if (!err) + err = ext3_ext_insert_index(handle, tree, path + at, -+ border, newblock); ++ border, newblock); + +cleanup: + if (bh) { @@ -761,9 +792,9 @@ Index: linux-stage/fs/ext3/extents.c + * just created block + */ +static int ext3_ext_grow_indepth(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp = path; + struct ext3_extent_header *neh; @@ -795,7 +826,7 @@ Index: linux-stage/fs/ext3/extents.c + /* set size of new block */ + neh = EXT_BLOCK_HDR(bh); + /* old root could have indexes or leaves -+ * so calculate e_max right way */ ++ * so calculate eh_max right way */ + if (EXT_DEPTH(tree)) + neh->eh_max = ext3_ext_space_block_idx(tree); + else @@ -822,7 +853,7 @@ Index: linux-stage/fs/ext3/extents.c + neh = EXT_ROOT_HDR(tree); + fidx = EXT_FIRST_INDEX(neh); + ext_debug(tree, "new root: num %d(%d), lblock %d, ptr %d\n", -+ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); ++ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); + + neh->eh_depth = path->p_depth + 1; + err = ext3_ext_dirty(handle, tree, curp); @@ -837,9 +868,9 @@ Index: linux-stage/fs/ext3/extents.c + * then it requests in-depth growing + */ +static int ext3_ext_create_new_leaf(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_extents_tree *tree, ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_ext_path *curp; + int depth, i, err = 0; @@ -915,12 +946,12 @@ Index: linux-stage/fs/ext3/extents.c + if (depth == path->p_depth) { + /* leaf */ + if (path[depth].p_ext != -+ EXT_LAST_EXTENT(path[depth].p_hdr)) ++ EXT_LAST_EXTENT(path[depth].p_hdr)) + return path[depth].p_ext[1].ee_block; + } else { + /* index */ + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + } + depth--; @@ -933,7 +964,7 @@ Index: linux-stage/fs/ext3/extents.c + * returns first allocated block from next leaf or EXT_MAX_BLOCK + */ +static unsigned ext3_ext_next_leaf_block(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth; + @@ -949,7 +980,7 @@ Index: linux-stage/fs/ext3/extents.c + + while (depth >= 0) { + if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) ++ EXT_LAST_INDEX(path[depth].p_hdr)) + return path[depth].p_idx[1].ei_block; + depth--; + } @@ -963,7 +994,7 @@ Index: linux-stage/fs/ext3/extents.c + * TODO: do we need to correct tree in all cases? + */ +int ext3_ext_correct_indexes(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct ext3_extent_header *eh; + int depth = EXT_DEPTH(tree); @@ -1013,8 +1044,8 @@ Index: linux-stage/fs/ext3/extents.c + +static int inline +ext3_can_extents_be_merged(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex1, ++ struct ext3_extent *ex2) +{ + if (ex1->ee_block + ex1->ee_len != ex2->ee_block) + return 0; @@ -1036,8 +1067,8 @@ Index: linux-stage/fs/ext3/extents.c + * creating new leaf in no-space case + */ +int ext3_ext_insert_extent(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) ++ struct ext3_ext_path *path, ++ struct ext3_extent *newext) +{ + struct ext3_extent_header * eh; + struct ext3_extent *ex, *fex; @@ -1046,7 +1077,6 @@ Index: linux-stage/fs/ext3/extents.c + int depth, len, err, next; + + EXT_ASSERT(newext->ee_len > 0); -+ EXT_ASSERT(newext->ee_len < EXT_CACHE_MARK); + depth = EXT_DEPTH(tree); + ex = path[depth].p_ext; + EXT_ASSERT(path[depth].p_hdr); @@ -1054,8 +1084,8 @@ Index: linux-stage/fs/ext3/extents.c + /* try to insert block into found extent and return */ + if (ex && ext3_can_extents_be_merged(tree, ex, newext)) { + ext_debug(tree, "append %d block to %d:%d (from %d)\n", -+ newext->ee_len, ex->ee_block, ex->ee_len, -+ ex->ee_start); ++ newext->ee_len, ex->ee_block, ex->ee_len, ++ ex->ee_start); + if ((err = ext3_ext_get_access(handle, tree, path + depth))) + return err; + ex->ee_len += newext->ee_len; @@ -1083,12 +1113,12 @@ Index: linux-stage/fs/ext3/extents.c + eh = npath[depth].p_hdr; + if (eh->eh_entries < eh->eh_max) { + ext_debug(tree, "next leaf isnt full(%d)\n", -+ eh->eh_entries); ++ eh->eh_entries); + path = npath; + goto repeat; + } + ext_debug(tree, "next leaf hasno free space(%d,%d)\n", -+ eh->eh_entries, eh->eh_max); ++ eh->eh_entries, eh->eh_max); + } + + /* @@ -1110,8 +1140,8 @@ Index: linux-stage/fs/ext3/extents.c + if (!nearex) { + /* there is no extent in this leaf, create first one */ + ext_debug(tree, "first extent in the leaf: %d:%d:%d\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len); ++ newext->ee_block, newext->ee_start, ++ newext->ee_len); + path[depth].p_ext = EXT_FIRST_EXTENT(eh); + } else if (newext->ee_block > nearex->ee_block) { + EXT_ASSERT(newext->ee_block != nearex->ee_block); @@ -1120,10 +1150,10 @@ Index: linux-stage/fs/ext3/extents.c + len = (len - 1) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d after: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, ++ newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 2, nearex + 1, len); + } + path[depth].p_ext = nearex + 1; @@ -1132,9 +1162,9 @@ Index: linux-stage/fs/ext3/extents.c + len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent); + len = len < 0 ? 0 : len; + ext_debug(tree, "insert %d:%d:%d before: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); ++ "move %d from 0x%p to 0x%p\n", ++ newext->ee_block, newext->ee_start, newext->ee_len, ++ nearex, len, nearex + 1, nearex + 2); + memmove(nearex + 1, nearex, len); + path[depth].p_ext = nearex; + } @@ -1155,8 +1185,8 @@ Index: linux-stage/fs/ext3/extents.c + /* merge with next extent! */ + nearex->ee_len += nearex[1].ee_len; + if (nearex + 1 < EXT_LAST_EXTENT(eh)) { -+ len = (EXT_LAST_EXTENT(eh) - nearex - 1) -+ * sizeof(struct ext3_extent); ++ len = (EXT_LAST_EXTENT(eh) - nearex - 1) * ++ sizeof(struct ext3_extent); + memmove(nearex + 1, nearex + 2, len); + } + eh->eh_entries--; @@ -1186,7 +1216,8 @@ Index: linux-stage/fs/ext3/extents.c + unsigned long num, ext_prepare_callback func) +{ + struct ext3_ext_path *path = NULL; -+ struct ext3_extent *ex, cbex; ++ struct ext3_ext_cache cbex; ++ struct ext3_extent *ex; + unsigned long next, start = 0, end = 0; + unsigned long last = block + num; + int depth, exists, err = 0; @@ -1245,14 +1276,20 @@ Index: linux-stage/fs/ext3/extents.c + EXT_ASSERT(end > start); + + if (!exists) { -+ cbex.ee_block = start; -+ cbex.ee_len = end - start; -+ cbex.ee_start = 0; -+ } else -+ cbex = *ex; ++ cbex.ec_block = start; ++ cbex.ec_len = end - start; ++ cbex.ec_start = 0; ++ cbex.ec_type = EXT3_EXT_CACHE_GAP; ++ } else { ++ cbex.ec_block = ex->ee_block; ++ cbex.ec_len = ex->ee_len; ++ cbex.ec_start = ex->ee_start; ++ cbex.ec_type = EXT3_EXT_CACHE_EXTENT; ++ } + ++ EXT_ASSERT(cbex.ec_len > 0); + EXT_ASSERT(path[depth].p_hdr); -+ err = func(tree, path, &cbex, exists); ++ err = func(tree, path, &cbex); + ext3_ext_drop_refs(path); + + if (err < 0) @@ -1270,7 +1307,7 @@ Index: linux-stage/fs/ext3/extents.c + path = NULL; + } + -+ block = cbex.ee_block + cbex.ee_len; ++ block = cbex.ec_block + cbex.ec_len; + } + + if (path) { @@ -1283,7 +1320,7 @@ Index: linux-stage/fs/ext3/extents.c + +static inline void +ext3_ext_put_in_cache(struct ext3_extents_tree *tree, __u32 block, -+ __u32 len, __u32 start, int type) ++ __u32 len, __u32 start, int type) +{ + EXT_ASSERT(len > 0); + if (tree->cex) { @@ -1300,8 +1337,8 @@ Index: linux-stage/fs/ext3/extents.c + */ +static inline void +ext3_ext_put_gap_in_cache(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ unsigned long block) ++ struct ext3_ext_path *path, ++ unsigned long block) +{ + int depth = EXT_DEPTH(tree); + unsigned long lblock, len; @@ -1320,16 +1357,16 @@ Index: linux-stage/fs/ext3/extents.c + lblock = block; + len = ex->ee_block - block; + ext_debug(tree, "cache gap(before): %lu [%lu:%lu]", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len); + } else if (block >= ex->ee_block + ex->ee_len) { + lblock = ex->ee_block + ex->ee_len; + len = ext3_ext_next_allocated_block(path); + ext_debug(tree, "cache gap(after): [%lu:%lu] %lu", -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) block); ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) block); + EXT_ASSERT(len > lblock); + len = len - lblock; + } else { @@ -1343,7 +1380,7 @@ Index: linux-stage/fs/ext3/extents.c + +static inline int +ext3_ext_in_cache(struct ext3_extents_tree *tree, unsigned long block, -+ struct ext3_extent *ex) ++ struct ext3_extent *ex) +{ + struct ext3_ext_cache *cex = tree->cex; + @@ -1356,16 +1393,16 @@ Index: linux-stage/fs/ext3/extents.c + return EXT3_EXT_CACHE_NO; + + EXT_ASSERT(cex->ec_type == EXT3_EXT_CACHE_GAP || -+ cex->ec_type == EXT3_EXT_CACHE_EXTENT); ++ cex->ec_type == EXT3_EXT_CACHE_EXTENT); + if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) { + ex->ee_block = cex->ec_block; + ex->ee_start = cex->ec_start; + ex->ee_len = cex->ec_len; + ext_debug(tree, "%lu cached by %lu:%lu:%lu\n", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) ex->ee_start); ++ (unsigned long) block, ++ (unsigned long) ex->ee_block, ++ (unsigned long) ex->ee_len, ++ (unsigned long) ex->ee_start); + return cex->ec_type; + } + @@ -1379,7 +1416,7 @@ Index: linux-stage/fs/ext3/extents.c + * last index in the block only + */ +int ext3_ext_rm_idx(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + struct buffer_head *bh; + int err; @@ -1393,7 +1430,7 @@ Index: linux-stage/fs/ext3/extents.c + if ((err = ext3_ext_dirty(handle, tree, path))) + return err; + ext_debug(tree, "index is empty, remove it, free block %d\n", -+ path->p_idx->ei_leaf); ++ path->p_idx->ei_leaf); + bh = sb_find_get_block(tree->inode->i_sb, path->p_idx->ei_leaf); + ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf); + ext3_free_blocks(handle, tree->inode, path->p_idx->ei_leaf, 1); @@ -1401,7 +1438,7 @@ Index: linux-stage/fs/ext3/extents.c +} + +int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) ++ struct ext3_ext_path *path) +{ + int depth = EXT_DEPTH(tree); + int needed; @@ -1438,8 +1475,8 @@ Index: linux-stage/fs/ext3/extents.c + +static int +ext3_ext_split_for_rm(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, tex; + struct ext3_ext_path *npath; @@ -1473,7 +1510,7 @@ Index: linux-stage/fs/ext3/extents.c + /* FIXME: some callback to free underlying resource + * and correct ee_start? */ + ext_debug(tree, "split extent: head %u:%u, tail %u:%u\n", -+ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); ++ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); + + npath = ext3_ext_find_extent(tree, ex->ee_block, NULL); + if (IS_ERR(npath)) @@ -1487,13 +1524,12 @@ Index: linux-stage/fs/ext3/extents.c + kfree(npath); + + return err; -+ +} + +static int +ext3_ext_rm_leaf(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) ++ struct ext3_ext_path *path, unsigned long start, ++ unsigned long end) +{ + struct ext3_extent *ex, *fu = NULL, *lu, *le; + int err = 0, correct_index = 0; @@ -1526,8 +1562,7 @@ Index: linux-stage/fs/ext3/extents.c + } + + lu = ex; -+ while (ex >= EXT_FIRST_EXTENT(eh) && -+ ex->ee_block + ex->ee_len > start) { ++ while (ex >= EXT_FIRST_EXTENT(eh) && ex->ee_block + ex->ee_len > start) { + ext_debug(tree, "remove ext %u:%u\n", ex->ee_block, ex->ee_len); + path[depth].p_ext = ex; + @@ -1554,7 +1589,7 @@ Index: linux-stage/fs/ext3/extents.c + block = ex->ee_block; + num = 0; + EXT_ASSERT(a == ex->ee_block && -+ b == ex->ee_block + ex->ee_len - 1); ++ b == ex->ee_block + ex->ee_len - 1); + } + + if (ex == EXT_FIRST_EXTENT(eh)) @@ -1596,7 +1631,7 @@ Index: linux-stage/fs/ext3/extents.c + goto out; + + ext_debug(tree, "new extent: %u:%u:%u\n", -+ ex->ee_block, ex->ee_len, ex->ee_start); ++ ex->ee_block, ex->ee_len, ex->ee_start); + ex--; + } + @@ -1660,7 +1695,7 @@ Index: linux-stage/fs/ext3/extents.c +} + +int ext3_ext_remove_space(struct ext3_extents_tree *tree, -+ unsigned long start, unsigned long end) ++ unsigned long start, unsigned long end) +{ + struct inode *inode = tree->inode; + struct super_block *sb = inode->i_sb; @@ -1684,8 +1719,7 @@ Index: linux-stage/fs/ext3/extents.c + */ + path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL); + if (IS_ERR(path)) { -+ ext3_error(sb, "ext3_ext_remove_space", -+ "Can't allocate path array"); ++ ext3_error(sb, __FUNCTION__, "Can't allocate path array"); + ext3_journal_stop(handle); + return -ENOMEM; + } @@ -1717,19 +1751,19 @@ Index: linux-stage/fs/ext3/extents.c + ext3_ext_last_covered(path[i].p_hdr, end); + path[i].p_block = path[i].p_hdr->eh_entries + 1; + ext_debug(tree, "init index ptr: hdr 0x%p, num %d\n", -+ path[i].p_hdr, path[i].p_hdr->eh_entries); ++ path[i].p_hdr, path[i].p_hdr->eh_entries); + } else { + /* we've already was here, see at next index */ + path[i].p_idx--; + } + + ext_debug(tree, "level %d - index, first 0x%p, cur 0x%p\n", -+ i, EXT_FIRST_INDEX(path[i].p_hdr), -+ path[i].p_idx); ++ i, EXT_FIRST_INDEX(path[i].p_hdr), ++ path[i].p_idx); + if (ext3_ext_more_to_rm(path + i)) { + /* go to the next level */ + ext_debug(tree, "move to level %d (block %d)\n", -+ i + 1, path[i].p_idx->ei_leaf); ++ i + 1, path[i].p_idx->ei_leaf); + memset(path + i + 1, 0, sizeof(*path)); + path[i+1].p_bh = sb_bread(sb, path[i].p_idx->ei_leaf); + if (!path[i+1].p_bh) { @@ -1852,7 +1886,7 @@ Index: linux-stage/fs/ext3/extents.c +} + +static int ext3_ext_mergable(struct ext3_extent *ex1, -+ struct ext3_extent *ex2) ++ struct ext3_extent *ex2) +{ + /* FIXME: support for large fs */ + if (ex1->ee_start + ex1->ee_len == ex2->ee_start) @@ -1862,8 +1896,8 @@ Index: linux-stage/fs/ext3/extents.c + +static int +ext3_remove_blocks_credits(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed; + @@ -1878,8 +1912,8 @@ Index: linux-stage/fs/ext3/extents.c + +static int +ext3_remove_blocks(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) ++ struct ext3_extent *ex, ++ unsigned long from, unsigned long to) +{ + int needed = ext3_remove_blocks_credits(tree, ex, from, to); + handle_t *handle = ext3_journal_start(tree->inode, needed); @@ -1894,7 +1928,7 @@ Index: linux-stage/fs/ext3/extents.c + num = ex->ee_block + ex->ee_len - from; + start = ex->ee_start + ex->ee_len - num; + ext_debug(tree, "free last %lu blocks starting %lu\n", -+ num, start); ++ num, start); + for (i = 0; i < num; i++) { + bh = sb_find_get_block(tree->inode->i_sb, start + i); + ext3_forget(handle, 0, tree->inode, bh, start + i); @@ -1902,17 +1936,17 @@ Index: linux-stage/fs/ext3/extents.c + ext3_free_blocks(handle, tree->inode, start, num); + } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { + printk("strange request: removal %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } else { + printk("strange request: removal(2) %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); ++ from, to, ex->ee_block, ex->ee_len); + } + ext3_journal_stop(handle); + return 0; +} + +static int ext3_ext_find_goal(struct inode *inode, -+ struct ext3_ext_path *path, unsigned long block) ++ struct ext3_ext_path *path, unsigned long block) +{ + struct ext3_inode_info *ei = EXT3_I(inode); + unsigned long bg_start; @@ -1942,8 +1976,8 @@ Index: linux-stage/fs/ext3/extents.c +} + +static int ext3_new_block_cb(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int *err) ++ struct ext3_ext_path *path, ++ struct ext3_extent *ex, int *err) +{ + struct inode *inode = tree->inode; + int newblock, goal; @@ -1980,7 +2014,7 @@ Index: linux-stage/fs/ext3/extents.c +}; + +void ext3_init_tree_desc(struct ext3_extents_tree *tree, -+ struct inode *inode) ++ struct inode *inode) +{ + tree->inode = inode; + tree->root = (void *) EXT3_I(inode)->i_data; @@ -1991,8 +2025,8 @@ Index: linux-stage/fs/ext3/extents.c +} + +int ext3_ext_get_block(handle_t *handle, struct inode *inode, -+ long iblock, struct buffer_head *bh_result, -+ int create, int extend_disksize) ++ long iblock, struct buffer_head *bh_result, ++ int create, int extend_disksize) +{ + struct ext3_ext_path *path = NULL; + struct ext3_extent newex; @@ -2003,7 +2037,7 @@ Index: linux-stage/fs/ext3/extents.c + clear_buffer_new(bh_result); + ext3_init_tree_desc(&tree, inode); + ext_debug(&tree, "block %d requested for inode %u\n", -+ (int) iblock, (unsigned) inode->i_ino); ++ (int) iblock, (unsigned) inode->i_ino); + down(&EXT3_I(inode)->truncate_sem); + + /* check in cache */ @@ -2046,11 +2080,11 @@ Index: linux-stage/fs/ext3/extents.c + if (iblock >= ex->ee_block && iblock < ex->ee_block + ex->ee_len) { + newblock = iblock - ex->ee_block + ex->ee_start; + ext_debug(&tree, "%d fit into %d:%d -> %d\n", -+ (int) iblock, ex->ee_block, ex->ee_len, -+ newblock); ++ (int) iblock, ex->ee_block, ex->ee_len, ++ newblock); + ext3_ext_put_in_cache(&tree, ex->ee_block, -+ ex->ee_len, ex->ee_start, -+ EXT3_EXT_CACHE_EXTENT); ++ ex->ee_len, ex->ee_start, ++ EXT3_EXT_CACHE_EXTENT); + goto out; + } + } @@ -2071,7 +2105,7 @@ Index: linux-stage/fs/ext3/extents.c + if (!newblock) + goto out2; + ext_debug(&tree, "allocate new block: goal %d, found %d\n", -+ goal, newblock); ++ goal, newblock); + + /* try to insert new extent into found leaf and return */ + newex.ee_block = iblock; @@ -2089,7 +2123,7 @@ Index: linux-stage/fs/ext3/extents.c + set_buffer_new(bh_result); + + ext3_ext_put_in_cache(&tree, newex.ee_block, newex.ee_len, -+ newex.ee_start, EXT3_EXT_CACHE_EXTENT); ++ newex.ee_start, EXT3_EXT_CACHE_EXTENT); +out: + ext3_ext_show_leaf(&tree, path); + map_bh(bh_result, inode->i_sb, newblock); @@ -2147,8 +2181,8 @@ Index: linux-stage/fs/ext3/extents.c + EXT3_I(inode)->i_disksize = inode->i_size; + ext3_mark_inode_dirty(handle, inode); + -+ last_block = (inode->i_size + sb->s_blocksize - 1) -+ >> EXT3_BLOCK_SIZE_BITS(sb); ++ last_block = (inode->i_size + sb->s_blocksize - 1) >> ++ EXT3_BLOCK_SIZE_BITS(sb); + err = ext3_ext_remove_space(&tree, last_block, EXT_MAX_BLOCK); + + /* In a multi-transaction truncate, we only make the final @@ -2216,13 +2250,14 @@ Index: linux-stage/fs/ext3/extents.c + +static int +ext3_ext_store_extent_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newex, int exist) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *newex) +{ + struct ext3_extent_buf *buf = (struct ext3_extent_buf *) tree->private; + -+ if (!exist) ++ if (newex->ec_type != EXT3_EXT_CACHE_EXTENT) + return EXT_CONTINUE; ++ + if (buf->err < 0) + return EXT_BREAK; + if (buf->cur - buf->buffer + sizeof(*newex) > buf->buflen) @@ -2240,14 +2275,14 @@ Index: linux-stage/fs/ext3/extents.c + +static int +ext3_ext_collect_stats_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int exist) ++ struct ext3_ext_path *path, ++ struct ext3_ext_cache *ex) +{ + struct ext3_extent_tree_stats *buf = + (struct ext3_extent_tree_stats *) tree->private; + int depth; + -+ if (!exist) ++ if (ex->ec_type != EXT3_EXT_CACHE_EXTENT) + return EXT_CONTINUE; + + depth = EXT_DEPTH(tree); @@ -2278,7 +2313,7 @@ Index: linux-stage/fs/ext3/extents.c + tree.private = &buf; + down(&EXT3_I(inode)->truncate_sem); + err = ext3_ext_walk_space(&tree, buf.start, EXT_MAX_BLOCK, -+ ext3_ext_store_extent_cb); ++ ext3_ext_store_extent_cb); + up(&EXT3_I(inode)->truncate_sem); + if (err == 0) + err = buf.err; @@ -2293,7 +2328,7 @@ Index: linux-stage/fs/ext3/extents.c + buf.leaf_num = 0; + tree.private = &buf; + err = ext3_ext_walk_space(&tree, 0, EXT_MAX_BLOCK, -+ ext3_ext_collect_stats_cb); ++ ext3_ext_collect_stats_cb); + up(&EXT3_I(inode)->truncate_sem); + if (!err) + err = copy_to_user((void *) arg, &buf, sizeof(buf)); @@ -2315,19 +2350,26 @@ Index: linux-stage/fs/ext3/extents.c +EXPORT_SYMBOL(ext3_ext_walk_space); +EXPORT_SYMBOL(ext3_ext_find_goal); +EXPORT_SYMBOL(ext3_ext_calc_credits_for_insert); -+ Index: linux-stage/fs/ext3/ialloc.c =================================================================== --- linux-stage.orig/fs/ext3/ialloc.c 2005-02-25 14:50:50.304202816 +0200 +++ linux-stage/fs/ext3/ialloc.c 2005-02-25 15:33:48.920193600 +0200 -@@ -646,6 +646,10 @@ +@@ -646,6 +646,18 @@ DQUOT_FREE_INODE(inode); goto fail2; } -+ if (test_opt(sb, EXTENTS)) { -+ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; -+ ext3_extents_initialize_blockmap(handle, inode); -+ } ++ if (test_opt(sb, EXTENTS) && S_ISREG(inode->i_mode)) { ++ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; ++ ext3_extents_initialize_blockmap(handle, inode); ++ if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS)) { ++ err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); ++ if (err) goto fail; ++ EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS); ++ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "call ext3_journal_dirty_metadata"); ++ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); ++ } ++ } ++ err = ext3_mark_inode_dirty(handle, inode); if (err) { ext3_std_error(sb, err); @@ -2341,13 +2383,13 @@ Index: linux-stage/fs/ext3/inode.c +static inline int +ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block, -+ struct buffer_head *bh, int create, int extend_disksize) ++ struct buffer_head *bh, int create, int extend_disksize) +{ + if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) + return ext3_ext_get_block(handle, inode, block, bh, create, -+ extend_disksize); ++ extend_disksize); + return ext3_get_block_handle(handle, inode, block, bh, create, -+ extend_disksize); ++ extend_disksize); +} + static int ext3_get_block(struct inode *inode, sector_t iblock, @@ -2360,7 +2402,7 @@ Index: linux-stage/fs/ext3/inode.c - ret = ext3_get_block_handle(handle, inode, iblock, - bh_result, create, 1); + ret = ext3_get_block_wrap(handle, inode, iblock, -+ bh_result, create, 1); ++ bh_result, create, 1); return ret; } @@ -2405,9 +2447,9 @@ Index: linux-stage/fs/ext3/inode.c int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3; int ret; -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) -+ return ext3_ext_writepage_trans_blocks(inode, bpp); -+ ++ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) ++ return ext3_ext_writepage_trans_blocks(inode, bpp); ++ if (ext3_should_journal_data(inode)) ret = 3 * (bpp + indirects) + 2; else @@ -2432,18 +2474,16 @@ Index: linux-stage/fs/ext3/super.c struct ext3_super_block *es = sbi->s_es; int i; -+ ext3_ext_release(sb); ++ ext3_ext_release(sb); ext3_xattr_put_super(sb); journal_destroy(sbi->s_journal); if (!(sb->s_flags & MS_RDONLY)) { -@@ -457,6 +458,10 @@ +@@ -457,6 +458,8 @@ #endif ei->i_rsv_window.rsv_end = EXT3_RESERVE_WINDOW_NOT_ALLOCATED; ei->vfs_inode.i_version = 1; -+ ei->i_cached_extent[0] = 0; -+ ei->i_cached_extent[1] = 0; -+ ei->i_cached_extent[2] = 0; -+ ei->i_cached_extent[3] = 0; ++ ++ memset(&ei->i_cached_extent, 0, sizeof(ei->i_cached_extent)); return &ei->vfs_inode; } @@ -2482,8 +2522,8 @@ Index: linux-stage/fs/ext3/super.c percpu_counter_mod(&sbi->s_dirs_counter, ext3_count_dirs(sb)); -+ ext3_ext_init(sb); -+ ++ ext3_ext_init(sb); ++ return 0; failed_mount3: @@ -2506,14 +2546,17 @@ Index: linux-stage/include/linux/ext3_fs.h =================================================================== --- linux-stage.orig/include/linux/ext3_fs.h 2005-02-25 14:53:56.424908168 +0200 +++ linux-stage/include/linux/ext3_fs.h 2005-02-25 15:39:12.841950008 +0200 -@@ -186,6 +186,7 @@ +@@ -186,8 +186,9 @@ #define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ #define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ +#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ - #define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ +-#define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ ++#define EXT3_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */ #define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ + + /* @@ -237,6 +238,9 @@ #endif #define EXT3_IOC_GETRSVSZ _IOR('f', 5, long) @@ -2524,16 +2567,30 @@ Index: linux-stage/include/linux/ext3_fs.h /* * Structure of an inode on the disk -@@ -359,6 +363,9 @@ +@@ -359,6 +363,8 @@ #define EXT3_MOUNT_RESERVATION 0x20000 /* Preallocation */ #define EXT3_MOUNT_IOPEN 0x40000 /* Allow access via iopen */ #define EXT3_MOUNT_IOPEN_NOPRIV 0x80000 /* Make iopen world-readable */ +#define EXT3_MOUNT_EXTENTS 0x100000/* Extents support */ +#define EXT3_MOUNT_EXTDEBUG 0x200000/* Extents debug */ -+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H +@@ -503,11 +509,13 @@ + #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ + #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ + #define EXT3_FEATURE_INCOMPAT_META_BG 0x0010 ++#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ + + #define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR + #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ + EXT3_FEATURE_INCOMPAT_RECOVER| \ +- EXT3_FEATURE_INCOMPAT_META_BG) ++ EXT3_FEATURE_INCOMPAT_META_BG| \ ++ EXT3_FEATURE_INCOMPAT_EXTENTS) + #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ + EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ + EXT3_FEATURE_RO_COMPAT_BTREE_DIR) @@ -756,6 +763,7 @@ @@ -2549,7 +2606,7 @@ Index: linux-stage/include/linux/ext3_fs.h +/* extents.c */ +extern int ext3_ext_writepage_trans_blocks(struct inode *, int); +extern int ext3_ext_get_block(handle_t *, struct inode *, long, -+ struct buffer_head *, int, int); ++ struct buffer_head *, int, int); +extern void ext3_ext_truncate(struct inode *, struct page *); +extern void ext3_ext_init(struct super_block *); +extern void ext3_ext_release(struct super_block *); @@ -2563,7 +2620,7 @@ Index: linux-stage/include/linux/ext3_extents.h =================================================================== --- linux-stage.orig/include/linux/ext3_extents.h 2005-02-25 15:33:48.891198008 +0200 +++ linux-stage/include/linux/ext3_extents.h 2005-02-25 15:33:48.944189952 +0200 -@@ -0,0 +1,252 @@ +@@ -0,0 +1,264 @@ +/* + * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas @@ -2605,7 +2662,7 @@ Index: linux-stage/include/linux/ext3_extents.h + */ +#define EXT_DEBUG_ +#ifdef EXT_DEBUG -+#define ext_debug(tree,fmt,a...) \ ++#define ext_debug(tree,fmt,a...) \ +do { \ + if (test_opt((tree)->inode->i_sb, EXTDEBUG)) \ + printk(fmt, ##a); \ @@ -2718,14 +2775,14 @@ Index: linux-stage/include/linux/ext3_extents.h + int (*mark_buffer_dirty)(handle_t *h, void *buffer); + int (*mergable)(struct ext3_extent *ex1, struct ext3_extent *ex2); + int (*remove_extent_credits)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*remove_extent)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); ++ struct ext3_extent *, unsigned long, ++ unsigned long); + int (*new_block)(handle_t *, struct ext3_extents_tree *, -+ struct ext3_ext_path *, struct ext3_extent *, -+ int *); ++ struct ext3_ext_path *, struct ext3_extent *, ++ int *); +}; + +/* @@ -2735,8 +2792,8 @@ Index: linux-stage/include/linux/ext3_extents.h + * callback must return valid extent (passed or newly created) + */ +typedef int (*ext_prepare_callback)(struct ext3_extents_tree *, -+ struct ext3_ext_path *, -+ struct ext3_extent *, int); ++ struct ext3_ext_path *, ++ struct ext3_ext_cache *); + +#define EXT_CONTINUE 0 +#define EXT_BREAK 1 @@ -2744,7 +2801,6 @@ Index: linux-stage/include/linux/ext3_extents.h + + +#define EXT_MAX_BLOCK 0xffffffff -+#define EXT_CACHE_MARK 0xffff + + +#define EXT_FIRST_EXTENT(__hdr__) \ @@ -2776,6 +2832,20 @@ Index: linux-stage/include/linux/ext3_extents.h + +#define EXT_ASSERT(__x__) if (!(__x__)) BUG(); + ++#define EXT_CHECK_PATH(tree,path) \ ++{ \ ++ int depth = EXT_DEPTH(tree); \ ++ BUG_ON((unsigned long) (path) < __PAGE_OFFSET); \ ++ BUG_ON((unsigned long) (path)[depth].p_idx < \ ++ __PAGE_OFFSET && (path)[depth].p_idx != NULL); \ ++ BUG_ON((unsigned long) (path)[depth].p_ext < \ ++ __PAGE_OFFSET && (path)[depth].p_ext != NULL); \ ++ BUG_ON((unsigned long) (path)[depth].p_hdr < __PAGE_OFFSET); \ ++ BUG_ON((unsigned long) (path)[depth].p_bh < __PAGE_OFFSET \ ++ && depth != 0); \ ++ BUG_ON((path)[0].p_depth != depth); \ ++} ++ + +/* + * this structure is used to gather extents from the tree via ioctl @@ -2797,13 +2867,13 @@ Index: linux-stage/include/linux/ext3_extents.h + int leaf_num; +}; + ++extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); +extern int ext3_extent_tree_init(handle_t *, struct ext3_extents_tree *); +extern int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *, struct ext3_ext_path *); +extern int ext3_ext_insert_extent(handle_t *, struct ext3_extents_tree *, struct ext3_ext_path *, struct ext3_extent *); +extern int ext3_ext_walk_space(struct ext3_extents_tree *, unsigned long, unsigned long, ext_prepare_callback); +extern int ext3_ext_remove_space(struct ext3_extents_tree *, unsigned long, unsigned long); +extern struct ext3_ext_path * ext3_ext_find_extent(struct ext3_extents_tree *, int, struct ext3_ext_path *); -+extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); +extern int ext3_ext_calc_blockmap_metadata(struct inode *, int); + +static inline void @@ -2815,7 +2885,6 @@ Index: linux-stage/include/linux/ext3_extents.h + + +#endif /* _LINUX_EXT3_EXTENTS */ -+ Index: linux-stage/include/linux/ext3_fs_i.h =================================================================== --- linux-stage.orig/include/linux/ext3_fs_i.h 2005-02-25 14:50:50.320200384 +0200 @@ -2825,7 +2894,7 @@ Index: linux-stage/include/linux/ext3_fs_i.h struct semaphore truncate_sem; struct inode vfs_inode; + -+ __u32 i_cached_extent[4]; ++ __u32 i_cached_extent[4]; }; #endif /* _LINUX_EXT3_FS_I */ diff --git a/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.20-rh.patch b/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.20-rh.patch deleted file mode 100644 index 20eac0aa..0000000 --- a/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.20-rh.patch +++ /dev/null @@ -1,29 +0,0 @@ -Index: linux-2.4.20-30.9/fs/ext3/inode.c -=================================================================== ---- linux-2.4.20-30.9.orig/fs/ext3/inode.c 2004-05-18 13:55:49.000000000 -0700 -+++ linux-2.4.20-30.9/fs/ext3/inode.c 2004-05-18 13:59:46.000000000 -0700 -@@ -2217,6 +2217,10 @@ - - memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data)); - memset(oei->i_data, 0, sizeof(oei->i_data)); -+ if (EXT3_I(old_inode)->i_flags & EXT3_EXTENTS_FL) { -+ EXT3_I(new_inode)->i_flags |= EXT3_EXTENTS_FL; -+ ext3_extents_initialize_blockmap(handle, old_inode); -+ } - - nei->i_disksize = oei->i_disksize; - nei->i_state |= EXT3_STATE_DELETE; -@@ -2447,6 +2451,13 @@ - - brelse (iloc.bh); - -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) { -+ inode->u.ext3_i.i_cached_extent[0] = 0; -+ inode->u.ext3_i.i_cached_extent[1] = 0; -+ inode->u.ext3_i.i_cached_extent[2] = 0; -+ inode->u.ext3_i.i_cached_extent[3] = 0; -+ } -+ - if (S_ISREG(inode->i_mode)) { - inode->i_op = &ext3_file_inode_operations; - inode->i_fop = &ext3_file_operations; diff --git a/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.21-chaos.patch b/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.21-chaos.patch index d425fe6..e5a5616 100644 --- a/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.21-chaos.patch +++ b/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.21-chaos.patch @@ -6,10 +6,10 @@ Index: 57chaos/fs/ext3/inode.c memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data)); memset(oei->i_data, 0, sizeof(oei->i_data)); -+ if (EXT3_I(old_inode)->i_flags & EXT3_EXTENTS_FL) { -+ EXT3_I(new_inode)->i_flags |= EXT3_EXTENTS_FL; -+ ext3_extents_initialize_blockmap(handle, old_inode); -+ } ++ if (EXT3_I(old_inode)->i_flags & EXT3_EXTENTS_FL) { ++ EXT3_I(new_inode)->i_flags |= EXT3_EXTENTS_FL; ++ ext3_extents_initialize_blockmap(handle, old_inode); ++ } nei->i_disksize = oei->i_disksize; nei->i_state |= EXT3_STATE_DELETE; diff --git a/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.24.patch b/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.24.patch index 44432fc..43681a6 100644 --- a/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.24.patch +++ b/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.24.patch @@ -22,7 +22,7 @@ Index: linux-2.4.24/fs/ext3/inode.c memset(oei->i_data, 0, sizeof(oei->i_data)); + if (EXT3_I(old_inode)->i_flags & EXT3_EXTENTS_FL) { + EXT3_I(new_inode)->i_flags |= EXT3_EXTENTS_FL; -+ ext3_extents_initialize_blockmap(handle, old_inode); ++ ext3_extents_initialize_blockmap(handle, old_inode); + } nei->i_disksize = oei->i_disksize; diff --git a/lustre/kernel_patches/patches/ext3-htree-suse.patch b/lustre/kernel_patches/patches/ext3-htree-suse.patch deleted file mode 100644 index 3e5148e..0000000 --- a/lustre/kernel_patches/patches/ext3-htree-suse.patch +++ /dev/null @@ -1,2557 +0,0 @@ - fs/ext3/Makefile | 2 - fs/ext3/dir.c | 302 +++++++++ - fs/ext3/file.c | 3 - fs/ext3/hash.c | 215 ++++++ - fs/ext3/namei.c | 1420 ++++++++++++++++++++++++++++++++++++++++----- - 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, 1921 insertions(+), 161 deletions(-) - -Index: linux-2.4.21-suse/fs/ext3/dir.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/dir.c 2001-11-10 01:25:04.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/dir.c 2003-10-29 23:17:20.000000000 +0300 -@@ -21,12 +21,16 @@ - #include - #include - #include -+#include -+#include - - 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 @@ - 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 @@ - - 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 @@ - * 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,272 @@ - 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. -+ */ -+int 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); -+ if (!new_fn) -+ return -ENOMEM; -+ 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 0; -+ } -+ -+ 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); -+ return 0; -+} -+ -+ -+ -+/* -+ * 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 -Index: linux-2.4.21-suse/fs/ext3/file.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/file.c 2002-11-29 02:53:15.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/file.c 2003-10-29 23:17:20.000000000 +0300 -@@ -35,6 +35,9 @@ - { - 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; - } - -Index: linux-2.4.21-suse/fs/ext3/hash.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/hash.c 2003-10-29 23:17:20.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/hash.c 2003-10-29 23:17:20.000000000 +0300 -@@ -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 -+#include -+#include -+#include -+ -+#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; -+} -Index: linux-2.4.21-suse/fs/ext3/Makefile -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/Makefile 2003-10-29 22:39:14.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/Makefile 2003-10-29 23:17:20.000000000 +0300 -@@ -12,7 +12,7 @@ - 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 -Index: linux-2.4.21-suse/fs/ext3/namei.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/namei.c 2003-06-13 18:51:37.000000000 +0400 -+++ linux-2.4.21-suse/fs/ext3/namei.c 2003-10-29 23:25:23.000000000 +0300 -@@ -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 -@@ -38,6 +44,642 @@ - #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; -+ -+ /* Add '.' and '..' from the htree header */ -+ if (!start_hash && !start_minor_hash) { -+ de = (struct ext3_dir_entry_2 *) frames[0].bh->b_data; -+ if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0) -+ goto errout; -+ de = ext3_next_entry(de); -+ if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0) -+ goto errout; -+ count += 2; -+ } -+ -+ 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; -+ if ((err = ext3_htree_store_dirent(dir_file, -+ hinfo.hash, hinfo.minor_hash, de)) != 0) -+ goto errout; -+ 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 +736,7 @@ - return 0; - } - -+ - /* - * ext3_find_entry() - * -@@ -105,6 +748,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,12 +764,32 @@ - 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 +830,7 @@ - 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 +861,66 @@ - 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<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 +937,9 @@ - brelse (bh); - inode = iget(dir->i_sb, ino); - -- if (!inode) -+ if (!inode) { - return ERR_PTR(-EACCES); -+ } - } - d_add(dentry, inode); - return NULL; -@@ -237,6 +963,301 @@ - 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 = cpu_to_le16(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 = cpu_to_le16(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->dotdot; -+ de = (struct ext3_dir_entry_2 *)((char *)de + le16_to_cpu(de->rec_len)); -+ 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 +1268,198 @@ - * 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 -@@ -454,9 +1546,11 @@ - 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; -@@ -480,9 +1574,11 @@ - 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; -@@ -508,9 +1604,11 @@ - 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; -@@ -522,7 +1620,7 @@ - - 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) { -@@ -555,21 +1653,19 @@ - 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; - } - - /* -@@ -656,7 +1752,7 @@ - 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 -@@ -697,7 +1793,7 @@ - * 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", -@@ -794,8 +1890,9 @@ - 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); -@@ -833,7 +1930,7 @@ - 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: -@@ -851,8 +1948,9 @@ - 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; -@@ -879,7 +1977,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) -@@ -905,9 +2003,11 @@ - 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; -@@ -917,7 +2017,7 @@ - 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; - /* -@@ -926,8 +2026,12 @@ - * 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); -@@ -938,12 +2042,6 @@ - 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 +2054,15 @@ - 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; -@@ -994,9 +2095,11 @@ - - 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; -@@ -1069,14 +2172,37 @@ - /* - * ok, that's it - */ -- ext3_delete_entry(handle, old_dir, old_de, old_bh); -+ if (le32_to_cpu(old_de->inode) != old_inode->i_ino || -+ old_de->name_len != old_dentry->d_name.len || -+ strncmp(old_de->name, old_dentry->d_name.name, old_de->name_len) || -+ (retval = ext3_delete_entry(handle, old_dir, -+ old_de, old_bh)) == -ENOENT) { -+ /* old_de could have moved from under us during htree split, so -+ * make sure that we are deleting the right entry. We might -+ * also be pointing to a stale entry in the unused part of -+ * old_bh so just checking inum and the name isn't enough. */ -+ 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--; - 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); -@@ -1088,7 +2210,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); - } - } -Index: linux-2.4.21-suse/fs/ext3/super.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/super.c 2003-10-29 22:39:14.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/super.c 2003-10-29 23:17:20.000000000 +0300 -@@ -710,6 +710,7 @@ - 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 @@ - 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 @@ - return res; - } - -+ - struct super_block * ext3_read_super (struct super_block * sb, void * data, - int silent) - { -@@ -1069,6 +1072,9 @@ - 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 @@ - 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"); -Index: linux-2.4.21-suse/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.21-suse.orig/include/linux/ext3_fs.h 2003-06-14 02:28:25.000000000 +0400 -+++ linux-2.4.21-suse/include/linux/ext3_fs.h 2003-10-29 23:17:20.000000000 +0300 -@@ -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 -@@ -438,8 +443,11 @@ - /*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__ -@@ -576,9 +584,46 @@ - #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 -@@ -588,6 +633,27 @@ - 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 - */ -@@ -615,11 +681,20 @@ - - /* 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 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); -+ - /* 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 *); -@@ -652,6 +727,8 @@ - /* 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 *, ...) -Index: linux-2.4.21-suse/include/linux/ext3_fs_sb.h -=================================================================== ---- linux-2.4.21-suse.orig/include/linux/ext3_fs_sb.h 2003-06-14 02:26:52.000000000 +0400 -+++ linux-2.4.21-suse/include/linux/ext3_fs_sb.h 2003-10-29 23:17:20.000000000 +0300 -@@ -62,6 +62,8 @@ - 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; -Index: linux-2.4.21-suse/include/linux/ext3_jbd.h -=================================================================== ---- linux-2.4.21-suse.orig/include/linux/ext3_jbd.h 2003-06-14 02:28:25.000000000 +0400 -+++ linux-2.4.21-suse/include/linux/ext3_jbd.h 2003-10-29 23:17:20.000000000 +0300 -@@ -63,6 +63,8 @@ - - #define EXT3_RESERVE_TRANS_BLOCKS 12U - -+#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 -+ - int - ext3_mark_iloc_dirty(handle_t *handle, - struct inode *inode, -Index: linux-2.4.21-suse/include/linux/rbtree.h -=================================================================== ---- linux-2.4.21-suse.orig/include/linux/rbtree.h 2003-06-14 02:26:51.000000000 +0400 -+++ linux-2.4.21-suse/include/linux/rbtree.h 2003-10-29 23:17:20.000000000 +0300 -@@ -120,6 +120,8 @@ - - 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) - { -Index: linux-2.4.21-suse/lib/rbtree.c -=================================================================== ---- linux-2.4.21-suse.orig/lib/rbtree.c 2002-08-03 04:39:46.000000000 +0400 -+++ linux-2.4.21-suse/lib/rbtree.c 2003-10-29 23:17:20.000000000 +0300 -@@ -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 -@@ -294,3 +296,43 @@ - __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/ext3-init-generation-2.6-suse.patch b/lustre/kernel_patches/patches/ext3-init-generation-2.6-suse.patch deleted file mode 100644 index d15e397..0000000 --- a/lustre/kernel_patches/patches/ext3-init-generation-2.6-suse.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: linux-2.6.0/fs/ext3/super.c -=================================================================== ---- linux-2.6.0.orig/fs/ext3/super.c 2003-12-31 16:00:58.000000000 +0300 -+++ linux-2.6.0/fs/ext3/super.c 2004-01-03 11:25:32.000000000 +0300 -@@ -1068,6 +1068,7 @@ - sbi->s_mount_opt = 0; - sbi->s_resuid = EXT3_DEF_RESUID; - sbi->s_resgid = EXT3_DEF_RESGID; -+ sbi->s_next_generation = jiffies; - - blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE); - if (!blocksize) { diff --git a/lustre/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch b/lustre/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch index 82957f1..b9bcfac 100644 --- a/lustre/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch +++ b/lustre/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch @@ -1,10 +1,10 @@ -Index: linux-2.6.5-sles9/fs/ext3/mballoc.c +Index: linux-2.6.5-suse/fs/ext3/mballoc.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/mballoc.c 2005-02-17 22:07:57.023609040 +0300 -+++ linux-2.6.5-sles9/fs/ext3/mballoc.c 2005-02-23 01:56:19.101662000 +0300 -@@ -0,0 +1,1835 @@ +--- linux-2.6.5-suse.orig/fs/ext3/mballoc.c 2005-03-02 22:42:20.659360368 +0300 ++++ linux-2.6.5-suse/fs/ext3/mballoc.c 2005-03-11 16:13:13.000000000 +0300 +@@ -0,0 +1,1863 @@ +/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com ++ * Copyright(c) 2003, 2004, 2005, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify @@ -39,6 +39,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + +/* + * TODO: ++ * - bitmap/buddy read-ahead (proposed by Oleg Drokin aka green) + * - track min/max extents in each group for better group selection + * - is it worthwhile to use buddies directly if req is 2^N blocks? + * - mb_mark_used() may allocate chunk right after splitting buddy @@ -96,7 +97,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + __u32 mh_magic; +}; + -+#define EXT3_MB_MAGIC_V1 0xbaad16fc ++#define EXT3_MB_MAGIC_V1 0xbabd16fd + + +struct ext3_free_extent { @@ -109,7 +110,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + struct super_block *ac_sb; + + /* search goals */ -+struct ext3_free_extent ac_g_ex; ++ struct ext3_free_extent ac_g_ex; + + /* the best found extent */ + struct ext3_free_extent ac_b_ex; @@ -148,47 +149,50 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c +void ext3_mb_poll_new_transaction(struct super_block *, handle_t *); +void ext3_mb_free_committed_blocks(struct super_block *); + -+#define mb_correct_addr_and_bit(bit,addr) \ -+{ \ -+ if ((unsigned long)addr & 1) { \ -+ bit += 8; \ -+ addr--; \ -+ } \ -+ if ((unsigned long)addr & 2) { \ -+ bit += 16; \ -+ addr--; \ -+ addr--; \ -+ } \ ++#if BITS_PER_LONG == 64 ++#define mb_correct_addr_and_bit(bit,addr) \ ++{ \ ++ bit += ((unsigned long) addr & 7UL) << 3; \ ++ addr = (void *) ((unsigned long) addr & ~7UL); \ +} ++#elif BITS_PER_LONG == 32 ++#define mb_correct_addr_and_bit(bit,addr) \ ++{ \ ++ bit += ((unsigned long) addr & 3UL) << 3; \ ++ addr = (void *) ((unsigned long) addr & ~3UL); \ ++} ++#else ++#error "how many bits you are?!" ++#endif + +static inline int mb_test_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ return test_bit(bit, addr); ++ return ext2_test_bit(bit, addr); +} + +static inline void mb_set_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ __set_bit(bit, addr); ++ ext2_set_bit(bit, addr); +} + +static inline void mb_set_bit_atomic(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ set_bit(bit, addr); ++ ext2_set_bit_atomic(NULL, bit, addr); +} + +static inline void mb_clear_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ __clear_bit(bit, addr); ++ ext2_clear_bit(bit, addr); +} + +static inline void mb_clear_bit_atomic(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ clear_bit(bit, addr); ++ ext2_clear_bit_atomic(NULL, bit, addr); +} + +static inline void *mb_find_buddy(struct ext3_buddy *e3b, int order, int *max) @@ -199,8 +203,10 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + J_ASSERT(EXT3_MB_BITMAP(e3b) != EXT3_MB_BUDDY(e3b)); + J_ASSERT(max != NULL); + -+ if (order > e3b->bd_blkbits + 1) ++ if (order > e3b->bd_blkbits + 1) { ++ *max = 0; + return NULL; ++ } + + /* at order 0 we see each particular block */ + *max = 1 << (e3b->bd_blkbits + 3); @@ -234,12 +240,6 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + "can't get block for buddy bitmap\n"); + goto out; + } -+ if (!buffer_uptodate(e3b->bd_bh)) { -+ ll_rw_block(READ, 1, &e3b->bd_bh); -+ wait_on_buffer(e3b->bd_bh); -+ } -+ J_ASSERT(buffer_uptodate(e3b->bd_bh)); -+ + /* load buddy */ + e3b->bd_bh2 = sb_getblk(sb, sbi->s_buddy_blocks[group]->bb_buddy); + if (e3b->bd_bh2 == NULL) { @@ -247,10 +247,15 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + "can't get block for buddy bitmap\n"); + goto out; + } -+ if (!buffer_uptodate(e3b->bd_bh2)) { ++ ++ if (!buffer_uptodate(e3b->bd_bh)) ++ ll_rw_block(READ, 1, &e3b->bd_bh); ++ if (!buffer_uptodate(e3b->bd_bh2)) + ll_rw_block(READ, 1, &e3b->bd_bh2); -+ wait_on_buffer(e3b->bd_bh2); -+ } ++ ++ wait_on_buffer(e3b->bd_bh); ++ J_ASSERT(buffer_uptodate(e3b->bd_bh)); ++ wait_on_buffer(e3b->bd_bh2); + J_ASSERT(buffer_uptodate(e3b->bd_bh2)); + + e3b->bd_blkbits = sb->s_blocksize_bits; @@ -300,22 +305,22 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + count = 0; + for (i = 0; i < max; i++) { + -+ if (!mb_test_bit(i, buddy)) { ++ if (mb_test_bit(i, buddy)) { + /* only single bit in buddy2 may be 1 */ -+ if (mb_test_bit(i << 1, buddy2)) -+ J_ASSERT(!mb_test_bit((i<<1)+1, buddy2)); -+ else if (mb_test_bit((i << 1) + 1, buddy2)) -+ J_ASSERT(!mb_test_bit(i << 1, buddy2)); ++ if (!mb_test_bit(i << 1, buddy2)) ++ J_ASSERT(mb_test_bit((i<<1)+1, buddy2)); ++ else if (!mb_test_bit((i << 1) + 1, buddy2)) ++ J_ASSERT(mb_test_bit(i << 1, buddy2)); + continue; + } + + /* both bits in buddy2 must be 0 */ -+ J_ASSERT(!mb_test_bit(i << 1, buddy2)); -+ J_ASSERT(!mb_test_bit((i << 1) + 1, buddy2)); ++ J_ASSERT(mb_test_bit(i << 1, buddy2)); ++ J_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); + + for (j = 0; j < (1 << order); j++) { + k = (i * (1 << order)) + j; -+ J_ASSERT(mb_test_bit(k, EXT3_MB_BITMAP(e3b))); ++ J_ASSERT(!mb_test_bit(k, EXT3_MB_BITMAP(e3b))); + } + count++; + } @@ -325,14 +330,14 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + + buddy = mb_find_buddy(e3b, 0, &max); + for (i = 0; i < max; i++) { -+ if (mb_test_bit(i, buddy)) ++ if (!mb_test_bit(i, buddy)) + continue; + /* check used bits only */ + for (j = 0; j < e3b->bd_blkbits + 1; j++) { + buddy2 = mb_find_buddy(e3b, j, &max2); + k = i >> j; + J_ASSERT(k < max2); -+ J_ASSERT(!mb_test_bit(k, buddy2)); ++ J_ASSERT(mb_test_bit(k, buddy2)); + } + } +} @@ -363,7 +368,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + bb = EXT3_MB_BUDDY(e3b); + while (order <= e3b->bd_blkbits + 1) { + block = block >> 1; -+ if (mb_test_bit(block, bb)) { ++ if (!mb_test_bit(block, bb)) { + /* this block is part of buddy of order 'order' */ + return order; + } @@ -424,8 +429,8 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + block = first++; + order = 0; + -+ J_ASSERT(!mb_test_bit(block, EXT3_MB_BITMAP(e3b))); -+ mb_set_bit(block, EXT3_MB_BITMAP(e3b)); ++ J_ASSERT(mb_test_bit(block, EXT3_MB_BITMAP(e3b))); ++ mb_clear_bit(block, EXT3_MB_BITMAP(e3b)); + e3b->bd_bd->bb_counters[order]++; + + /* start of the buddy */ @@ -433,8 +438,8 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + + do { + block &= ~1UL; -+ if (!mb_test_bit(block, buddy) || -+ !mb_test_bit(block + 1, buddy)) ++ if (mb_test_bit(block, buddy) || ++ mb_test_bit(block + 1, buddy)) + break; + + /* both the buddies are free, try to coalesce them */ @@ -444,10 +449,10 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + break; + + if (order > 0) { -+ /* for special purposes, we don't clear ++ /* for special purposes, we don't set + * free bits in bitmap */ -+ mb_clear_bit(block, buddy); -+ mb_clear_bit(block + 1, buddy); ++ mb_set_bit(block, buddy); ++ mb_set_bit(block + 1, buddy); + } + e3b->bd_bd->bb_counters[order]--; + e3b->bd_bd->bb_counters[order]--; @@ -456,7 +461,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + order++; + e3b->bd_bd->bb_counters[order]++; + -+ mb_set_bit(block, buddy2); ++ mb_clear_bit(block, buddy2); + buddy = buddy2; + } while (1); + } @@ -466,7 +471,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c +} + +static int mb_find_extent(struct ext3_buddy *e3b, int order, int block, -+ int needed, struct ext3_free_extent *ex) ++ int needed, struct ext3_free_extent *ex) +{ + int next, max, ord; + void *buddy; @@ -476,7 +481,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + buddy = mb_find_buddy(e3b, order, &max); + J_ASSERT(buddy); + J_ASSERT(block < max); -+ if (!mb_test_bit(block, buddy)) { ++ if (mb_test_bit(block, buddy)) { + ex->fe_len = 0; + ex->fe_start = 0; + ex->fe_group = 0; @@ -499,7 +504,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + break; + + next = (block + 1) * (1 << order); -+ if (!mb_test_bit(next, EXT3_MB_BITMAP(e3b))) ++ if (mb_test_bit(next, EXT3_MB_BITMAP(e3b))) + break; + + ord = mb_find_order_for_block(e3b, next); @@ -533,7 +538,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + mlen = 1 << ord; + buddy = mb_find_buddy(e3b, ord, &max); + J_ASSERT((start >> ord) < max); -+ mb_clear_bit(start >> ord, buddy); ++ mb_set_bit(start >> ord, buddy); + e3b->bd_bd->bb_counters[ord]--; + start += mlen; + len -= mlen; @@ -544,20 +549,20 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + /* we have to split large buddy */ + J_ASSERT(ord > 0); + buddy = mb_find_buddy(e3b, ord, &max); -+ mb_clear_bit(start >> ord, buddy); ++ mb_set_bit(start >> ord, buddy); + e3b->bd_bd->bb_counters[ord]--; + + ord--; + cur = (start >> ord) & ~1U; + buddy = mb_find_buddy(e3b, ord, &max); -+ mb_set_bit(cur, buddy); -+ mb_set_bit(cur + 1, buddy); ++ mb_clear_bit(cur, buddy); ++ mb_clear_bit(cur + 1, buddy); + e3b->bd_bd->bb_counters[ord]++; + e3b->bd_bd->bb_counters[ord]++; + } + + /* now drop all the bits in bitmap */ -+ mb_clear_bits(EXT3_MB_BITMAP(e3b), ex->fe_start, len0); ++ mb_set_bits(EXT3_MB_BITMAP(e3b), ex->fe_start, len0); + + mb_check_buddy(e3b); + @@ -733,7 +738,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + i = e3b->bd_bd->bb_first_free; + + while (free && ac->ac_status != AC_STATUS_FOUND) { -+ i = find_next_bit(bitmap, sb->s_blocksize * 8, i); ++ i = ext2_find_next_zero_bit(bitmap, sb->s_blocksize * 8, i); + if (i >= sb->s_blocksize * 8) { + J_ASSERT(free == 0); + break; @@ -951,7 +956,6 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + /* + * We aren't lucky definitely + */ -+ J_ASSERT(ac.ac_b_ex.fe_len == 0); + DQUOT_FREE_BLOCK(inode, *len); + *errp = -ENOSPC; + block = 0; @@ -1020,8 +1024,8 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + ext3_error(sb, "ext3_new_block", + "Allocating block in system zone - " + "block = %u", block); -+#if AGGRESSIVE_CHECK -+ for (i = 0; i < ac.ac_b_len; i++) ++#ifdef AGGRESSIVE_CHECK ++ for (i = 0; i < ac.ac_b_ex.fe_len; i++) + J_ASSERT(!mb_test_bit(ac.ac_b_ex.fe_start + i, bitmap_bh->b_data)); +#endif + mb_set_bits(bitmap_bh->b_data, ac.ac_b_ex.fe_start, ac.ac_b_ex.fe_len); @@ -1141,7 +1145,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + + e3b->bd_bd->bb_first_free = grp->mgd_first_free; + e3b->bd_bd->bb_free = grp->mgd_free; -+ for (i = 0; i < e3b->bd_blkbits; i++) { ++ for (i = 0; i <= e3b->bd_blkbits + 1; i++) { + J_ASSERT(i < 16); + e3b->bd_bd->bb_counters[i] = grp->mgd_counters[i]; + } @@ -1155,7 +1159,6 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + printk(KERN_ERR "EXT3-fs: mbgroup %d corrupted (%d != %d)\n", + e3b->bd_group, e3b->bd_bd->bb_free, + le16_to_cpu(gdp->bg_free_blocks_count)); -+ BUG(); + return -ENODATA; + } + @@ -1166,20 +1169,19 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c +int ext3_mb_update_descr(struct ext3_buddy *e3b) +{ + struct ext3_mb_group_descr *grp; -+ struct ext3_group_desc *ogdp; ++ struct ext3_group_desc *gdp; + struct buffer_head *bh; + handle_t *handle; + int err, i; + + /* additional checks against old group descriptor */ -+ ogdp = ext3_get_group_desc(e3b->bd_sb, e3b->bd_group, NULL); -+ if (!ogdp) ++ gdp = ext3_get_group_desc(e3b->bd_sb, e3b->bd_group, NULL); ++ if (!gdp) + return -EIO; -+ if (e3b->bd_bd->bb_free != le16_to_cpu(ogdp->bg_free_blocks_count)) { ++ if (e3b->bd_bd->bb_free != le16_to_cpu(gdp->bg_free_blocks_count)) { + printk(KERN_ERR "EXT3-fs: mbgroup %d corrupted (%d != %d)\n", + e3b->bd_group, e3b->bd_bd->bb_free, -+ le16_to_cpu(ogdp->bg_free_blocks_count)); -+ BUG(); ++ le16_to_cpu(gdp->bg_free_blocks_count)); + return -ENODATA; + } + @@ -1187,7 +1189,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + if (err) + return err; + -+ handle = journal_start(EXT3_SB(e3b->bd_sb)->s_journal, 1); ++ handle = ext3_journal_start(EXT3_SB(e3b->bd_sb)->s_buddy, 1); + if (IS_ERR(handle)) { + err = PTR_ERR(handle); + handle = NULL; @@ -1199,7 +1201,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + goto out; + grp->mgd_first_free = e3b->bd_bd->bb_first_free; + grp->mgd_free = e3b->bd_bd->bb_free; -+ for (i = 0; i < e3b->bd_blkbits; i++) { ++ for (i = 0; i <= e3b->bd_blkbits + 1; i++) { + J_ASSERT(i < 16); + grp->mgd_counters[i] = e3b->bd_bd->bb_counters[i]; + } @@ -1219,16 +1221,24 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + struct super_block *sb = e3b->bd_sb; + struct buffer_head *bh; + int i, count = 0; -+ -+ memset(e3b->bd_bh->b_data, 0, sb->s_blocksize); -+ memset(e3b->bd_bh2->b_data, 0, sb->s_blocksize); ++ ++ mb_debug("generate buddy for group %d\n", e3b->bd_group); ++ memset(e3b->bd_bh->b_data, 0xff, sb->s_blocksize); ++ memset(e3b->bd_bh2->b_data, 0xff, sb->s_blocksize); + + bh = read_block_bitmap(sb, e3b->bd_group); + if (bh == NULL) + return -EIO; + + /* mb_free_blocks will set real free */ ++ e3b->bd_bd->bb_free = 0; + e3b->bd_bd->bb_first_free = 1 << 15; ++ /* ++ * if change bb_counters size, don't forget about ++ * ext3_mb_init_backend() -bzzz ++ */ ++ memset(e3b->bd_bd->bb_counters, 0, ++ sizeof(unsigned) * (sb->s_blocksize_bits + 2)); + + /* loop over the blocks, and create buddies for free ones */ + for (i = 0; i < sb->s_blocksize * 8; i++) { @@ -1291,7 +1301,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + } + db->d_inode->i_flags |= S_IMMUTABLE | S_NOATIME; + *created = 1; -+ printk("EXT3-fs: no buddy file, regenerate\n"); ++ mb_debug("no buddy file, regenerate\n"); + } + up(&root->i_sem); + sbi->s_buddy = igrab(db->d_inode); @@ -1304,8 +1314,10 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + len = sbi->s_groups_count * sb->s_blocksize * 2 + + buddy_offset * sb->s_blocksize; + if (len != i_size_read(sbi->s_buddy)) { -+ printk("EXT3-fs: wrong i_size (%u != %u), regenerate\n", -+ (unsigned) len, (unsigned) i_size_read(sbi->s_buddy)); ++ if (*created == 0) ++ printk("EXT3-fs: wrong i_size (%u != %u), regenerate\n", ++ (unsigned) len, ++ (unsigned) i_size_read(sbi->s_buddy)); + *created = 1; + } + @@ -1313,14 +1325,14 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + for (i = 0; i < buddy_offset; i++) { + handle = ext3_journal_start(sbi->s_buddy, MB_CREDITS); + if (IS_ERR(handle)) { -+ printk(KERN_ERR "EXT3-fs: can't start transaction\n"); ++ printk(KERN_ERR "EXT3-fs: cant start transaction\n"); + err = PTR_ERR(handle); + goto err_out; + } + + bh = ext3_bread(handle, sbi->s_buddy, i, 1, &err); + if (bh == NULL) { -+ printk(KERN_ERR "EXT3-fs: can't getblk grp: %d\n", err); ++ printk(KERN_ERR "EXT3-fs: cant getblk grp: %d\n", err); + goto err_out; + } + hdr = (struct ext3_mb_grp_header *) bh->b_data; @@ -1328,9 +1340,11 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + err = ext3_journal_get_write_access(handle, bh); + if (err) + goto err_out; ++ if (*created == 0) ++ printk(KERN_ERR ++ "EXT3-fs: invalid header 0x%x in %d," ++ "regenerate\n", hdr->mh_magic, i); + *created = 1; -+ printk("EXT3-fs: invalid header %#x in %d regenerate\n", -+ hdr->mh_magic, i); + hdr->mh_magic = EXT3_MB_MAGIC_V1; + err = ext3_journal_dirty_metadata(handle, bh); + if (err) @@ -1340,12 +1354,16 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + ext3_journal_stop(handle); + } + ++ /* ++ * if change bb_counters size, don't forget about ext3_mb_generate_buddy() ++ */ + len = sizeof(struct ext3_buddy_group_blocks); + len += sizeof(unsigned) * (sb->s_blocksize_bits + 2); + for (i = 0; i < sbi->s_groups_count; i++) { ++ + sbi->s_buddy_blocks[i] = kmalloc(len, GFP_KERNEL); + if (sbi->s_buddy_blocks[i] == NULL) { -+ printk(KERN_ERR "EXT3-fs: can't allocate buddy mem\n"); ++ printk(KERN_ERR "EXT3-fs: cant allocate mem for buddy\n"); + err = -ENOMEM; + goto out2; + } @@ -1353,7 +1371,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + + handle = ext3_journal_start(sbi->s_buddy, MB_CREDITS); + if (IS_ERR(handle)) { -+ printk(KERN_ERR "EXT3-fs: can't start transaction\n"); ++ printk(KERN_ERR "EXT3-fs: cant start transaction\n"); + err = PTR_ERR(handle); + goto out2; + } @@ -1362,8 +1380,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + block = buddy_offset + i * 2; + bh = ext3_getblk(handle, sbi->s_buddy, block, 1, &err); + if (bh == NULL) { -+ printk(KERN_ERR "EXT3-fs: can't getblk bitmap: %d\n", -+ err); ++ printk(KERN_ERR "EXT3-fs: cant getblk bitmap: %d\n", err); + goto out2; + } + sbi->s_buddy_blocks[i]->bb_bitmap = bh->b_blocknr; @@ -1373,7 +1390,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + block = buddy_offset + i * 2 + 1; + bh = ext3_getblk(handle, sbi->s_buddy, block, 1, &err); + if (bh == NULL) { -+ printk(KERN_ERR "EXT3-fs: can't getblk for buddy: %d\n",+ err); ++ printk(KERN_ERR "EXT3-fs: cant getblk for buddy: %d\n", err); + goto out2; + } + sbi->s_buddy_blocks[i]->bb_buddy = bh->b_blocknr; @@ -1736,6 +1753,19 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + if (err) + goto error_return; + ++#ifdef AGGRESSIVE_CHECK ++ { ++ int i; ++ for (i = 0; i < count; i++) ++ J_ASSERT(mb_test_bit(bit + i, bitmap_bh->b_data)); ++ } ++#endif ++ mb_clear_bits(bitmap_bh->b_data, bit, count); ++ ++ /* We dirtied the bitmap block */ ++ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); ++ err = ext3_journal_dirty_metadata(handle, bitmap_bh); ++ + if (metadata) { + /* blocks being freed are metadata. these blocks shouldn't + * be used until this transaction is committed */ @@ -1745,21 +1775,18 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + mb_free_blocks(&e3b, bit, count); + ext3_unlock_group(sb, block_group); + } ++ + spin_lock(sb_bgl_lock(sbi, block_group)); + gdp->bg_free_blocks_count = + cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) + count); + spin_unlock(sb_bgl_lock(sbi, block_group)); ++ percpu_counter_mod(&sbi->s_freeblocks_counter, count); + + ext3_mb_dirty_buddy(&e3b); + ext3_mb_release_desc(&e3b); + -+ mb_clear_bits(bitmap_bh->b_data, bit, count); + *freed = count; + -+ /* We dirtied the bitmap block */ -+ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); -+ err = ext3_journal_dirty_metadata(handle, bitmap_bh); -+ + /* And the group descriptor block */ + BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); + ret = ext3_journal_dirty_metadata(handle, gd_bh); @@ -1821,6 +1848,7 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + return ret; +} + ++ +extern void ext3_free_blocks_old(handle_t *, struct inode *, + unsigned long, unsigned long); +void ext3_free_blocks(handle_t *handle, struct inode * inode, @@ -1838,19 +1866,19 @@ Index: linux-2.6.5-sles9/fs/ext3/mballoc.c + return; +} + -Index: linux-2.6.5-sles9/fs/ext3/super.c +Index: linux-2.6.5-suse/fs/ext3/super.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/super.c 2005-02-23 01:47:15.291333736 +0300 -+++ linux-2.6.5-sles9/fs/ext3/super.c 2005-02-23 01:48:54.515249408 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/super.c 2005-02-26 18:40:25.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/super.c 2005-02-26 18:40:26.000000000 +0300 @@ -389,6 +389,7 @@ struct ext3_super_block *es = sbi->s_es; int i; + ext3_mb_release(sb); - ext3_ext_release(sb); + ext3_ext_release(sb); ext3_xattr_put_super(sb); journal_destroy(sbi->s_journal); -@@ -540,6 +541,7 @@ +@@ -543,6 +544,7 @@ Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, Opt_ignore, Opt_barrier, Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, @@ -1858,7 +1886,7 @@ Index: linux-2.6.5-sles9/fs/ext3/super.c Opt_err, Opt_extents, Opt_extdebug }; -@@ -587,6 +589,8 @@ +@@ -590,6 +592,8 @@ {Opt_iopen_nopriv, "iopen_nopriv"}, {Opt_extents, "extents"}, {Opt_extdebug, "extdebug"}, @@ -1867,7 +1895,7 @@ Index: linux-2.6.5-sles9/fs/ext3/super.c {Opt_err, NULL} }; -@@ -808,6 +812,16 @@ +@@ -811,6 +815,16 @@ case Opt_extdebug: set_opt (sbi->s_mount_opt, EXTDEBUG); break; @@ -1884,20 +1912,18 @@ Index: linux-2.6.5-sles9/fs/ext3/super.c default: printk (KERN_ERR "EXT3-fs: Unrecognized mount option \"%s\" " -@@ -1461,7 +1475,8 @@ +@@ -1464,6 +1478,7 @@ ext3_count_dirs(sb)); - ext3_ext_init(sb); -- + ext3_ext_init(sb); + ext3_mb_init(sb, needs_recovery); -+ + return 0; - failed_mount3: -Index: linux-2.6.5-sles9/fs/ext3/Makefile +Index: linux-2.6.5-suse/fs/ext3/Makefile =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/Makefile 2005-02-23 01:02:37.405434272 +0300 -+++ linux-2.6.5-sles9/fs/ext3/Makefile 2005-02-23 01:48:54.517249104 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/Makefile 2005-02-26 18:40:25.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/Makefile 2005-02-26 18:40:26.000000000 +0300 @@ -5,7 +5,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o @@ -1907,10 +1933,10 @@ Index: linux-2.6.5-sles9/fs/ext3/Makefile ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o -Index: linux-2.6.5-sles9/fs/ext3/balloc.c +Index: linux-2.6.5-suse/fs/ext3/balloc.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/balloc.c 2004-11-03 08:36:51.000000000 +0300 -+++ linux-2.6.5-sles9/fs/ext3/balloc.c 2005-02-23 01:48:54.520248648 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/balloc.c 2005-02-02 00:55:47.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/balloc.c 2005-02-26 18:40:26.000000000 +0300 @@ -78,7 +78,7 @@ * * Return buffer_head on success or NULL in case of failure. @@ -1938,10 +1964,10 @@ Index: linux-2.6.5-sles9/fs/ext3/balloc.c unsigned long goal, int *errp) { struct buffer_head *bitmap_bh = NULL; -Index: linux-2.6.5-sles9/fs/ext3/namei.c +Index: linux-2.6.5-suse/fs/ext3/namei.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/namei.c 2005-02-23 01:01:46.551165296 +0300 -+++ linux-2.6.5-sles9/fs/ext3/namei.c 2005-02-23 01:48:54.523248192 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/namei.c 2005-02-26 18:40:19.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/namei.c 2005-02-26 18:40:26.000000000 +0300 @@ -1640,7 +1640,7 @@ * If the create succeeds, we fill in the inode information * with d_instantiate(). @@ -1951,10 +1977,10 @@ Index: linux-2.6.5-sles9/fs/ext3/namei.c struct nameidata *nd) { handle_t *handle; -Index: linux-2.6.5-sles9/fs/ext3/inode.c +Index: linux-2.6.5-suse/fs/ext3/inode.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/inode.c 2005-02-23 01:02:37.404434424 +0300 -+++ linux-2.6.5-sles9/fs/ext3/inode.c 2005-02-23 01:48:54.529247280 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/inode.c 2005-02-26 18:40:25.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/inode.c 2005-02-26 18:40:26.000000000 +0300 @@ -572,7 +572,7 @@ ext3_journal_forget(handle, branch[i].bh); } @@ -1973,7 +1999,7 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c return err; } -@@ -1829,7 +1829,7 @@ +@@ -1830,7 +1830,7 @@ } } @@ -1982,7 +2008,7 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c } /** -@@ -2000,7 +2000,7 @@ +@@ -2001,7 +2001,7 @@ ext3_journal_test_restart(handle, inode); } @@ -1991,10 +2017,10 @@ Index: linux-2.6.5-sles9/fs/ext3/inode.c if (parent_bh) { /* -Index: linux-2.6.5-sles9/fs/ext3/extents.c +Index: linux-2.6.5-suse/fs/ext3/extents.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/extents.c 2005-02-23 01:02:37.396435640 +0300 -+++ linux-2.6.5-sles9/fs/ext3/extents.c 2005-02-23 01:48:54.533246672 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/extents.c 2005-02-26 18:40:25.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/extents.c 2005-02-26 18:40:26.000000000 +0300 @@ -774,7 +774,7 @@ for (i = 0; i < depth; i++) { if (!ablocks[i]) @@ -2036,10 +2062,10 @@ Index: linux-2.6.5-sles9/fs/ext3/extents.c } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { printk("strange request: removal %lu-%lu from %u:%u\n", from, to, ex->ee_block, ex->ee_len); -Index: linux-2.6.5-sles9/fs/ext3/xattr.c +Index: linux-2.6.5-suse/fs/ext3/xattr.c =================================================================== ---- linux-2.6.5-sles9.orig/fs/ext3/xattr.c 2005-02-23 01:01:52.387278072 +0300 -+++ linux-2.6.5-sles9/fs/ext3/xattr.c 2005-02-23 01:48:54.537246064 +0300 +--- linux-2.6.5-suse.orig/fs/ext3/xattr.c 2005-02-26 18:40:22.000000000 +0300 ++++ linux-2.6.5-suse/fs/ext3/xattr.c 2005-02-26 18:40:26.000000000 +0300 @@ -1366,7 +1366,7 @@ new_bh = sb_getblk(sb, block); if (!new_bh) { @@ -2067,10 +2093,10 @@ Index: linux-2.6.5-sles9/fs/ext3/xattr.c get_bh(bh); ext3_forget(handle, 1, inode, bh, EXT3_I(inode)->i_file_acl); } else { -Index: linux-2.6.5-sles9/include/linux/ext3_fs.h +Index: linux-2.6.5-suse/include/linux/ext3_fs.h =================================================================== ---- linux-2.6.5-sles9.orig/include/linux/ext3_fs.h 2005-02-23 01:02:37.414432904 +0300 -+++ linux-2.6.5-sles9/include/linux/ext3_fs.h 2005-02-23 01:48:54.539245760 +0300 +--- linux-2.6.5-suse.orig/include/linux/ext3_fs.h 2005-02-26 18:40:25.000000000 +0300 ++++ linux-2.6.5-suse/include/linux/ext3_fs.h 2005-02-26 18:40:26.000000000 +0300 @@ -57,6 +57,14 @@ #define ext3_debug(f, a...) do {} while (0) #endif @@ -2090,7 +2116,7 @@ Index: linux-2.6.5-sles9/include/linux/ext3_fs.h #define EXT3_MOUNT_IOPEN_NOPRIV 0x80000 /* Make iopen world-readable */ #define EXT3_MOUNT_EXTENTS 0x100000/* Extents support */ #define EXT3_MOUNT_EXTDEBUG 0x200000/* Extents debug */ -+#define EXT3_MOUNT_MBALLOC 0x100000/* Buddy allocation support */ ++#define EXT3_MOUNT_MBALLOC 0x400000/* Buddy allocation support */ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef clear_opt @@ -2141,10 +2167,10 @@ Index: linux-2.6.5-sles9/include/linux/ext3_fs.h #endif /* __KERNEL__ */ #define EXT3_IOC_CREATE_INUM _IOW('f', 5, long) -Index: linux-2.6.5-sles9/include/linux/ext3_fs_sb.h +Index: linux-2.6.5-suse/include/linux/ext3_fs_sb.h =================================================================== ---- linux-2.6.5-sles9.orig/include/linux/ext3_fs_sb.h 2005-02-23 01:01:48.242908112 +0300 -+++ linux-2.6.5-sles9/include/linux/ext3_fs_sb.h 2005-02-23 01:48:54.541245456 +0300 +--- linux-2.6.5-suse.orig/include/linux/ext3_fs_sb.h 2005-02-26 18:40:20.000000000 +0300 ++++ linux-2.6.5-suse/include/linux/ext3_fs_sb.h 2005-02-26 18:40:26.000000000 +0300 @@ -23,10 +23,30 @@ #define EXT_INCLUDE #include diff --git a/lustre/kernel_patches/patches/ext3-mballoc2-2.6.7.patch b/lustre/kernel_patches/patches/ext3-mballoc2-2.6.7.patch deleted file mode 100644 index 1c8b8d9..0000000 --- a/lustre/kernel_patches/patches/ext3-mballoc2-2.6.7.patch +++ /dev/null @@ -1,1750 +0,0 @@ -Index: linux-2.6.7/fs/ext3/mballoc.c -=================================================================== ---- linux-2.6.7.orig/fs/ext3/mballoc.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.6.7/fs/ext3/mballoc.c 2004-09-06 12:51:42.000000000 +0400 -@@ -0,0 +1,1428 @@ -+/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com -+ * Written by Alex Tomas -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program 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 Licens -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- -+ */ -+ -+ -+/* -+ * mballoc.c contains the multiblocks allocation routines -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * TODO: -+ * - do not scan from the beginning, try to remember first free block -+ * - mb_mark_used_* may allocate chunk right after splitting buddy -+ * - special flag to advice allocator to look for requested + N blocks -+ * this may improve interaction between extents and mballoc -+ */ -+ -+/* -+ * with AGRESSIVE_CHECK allocator runs consistency checks over -+ * structures. this checks slow things down a lot -+ */ -+#define AGGRESSIVE_CHECK__ -+ -+/* -+ */ -+#define MB_DEBUG__ -+#ifdef MB_DEBUG -+#define mb_debug(fmt,a...) printk(fmt, ##a) -+#else -+#define mb_debug(fmt,a...) -+#endif -+ -+/* -+ * where to save buddies structures beetween umount/mount (clean case only) -+ */ -+#define EXT3_BUDDY_FILE ".buddy" -+ -+/* -+ * max. number of chunks to be tracked in ext3_free_extent struct -+ */ -+#define MB_ARR_SIZE 32 -+ -+struct ext3_allocation_context { -+ struct super_block *ac_sb; -+ -+ /* search goals */ -+ int ac_g_group; -+ int ac_g_start; -+ int ac_g_len; -+ int ac_g_flags; -+ -+ /* the best found extent */ -+ int ac_b_group; -+ int ac_b_start; -+ int ac_b_len; -+ -+ /* number of iterations done. we have to track to limit searching */ -+ int ac_repeats; -+ int ac_groups_scanned; -+ int ac_status; -+}; -+ -+#define AC_STATUS_CONTINUE 1 -+#define AC_STATUS_FOUND 2 -+ -+ -+struct ext3_buddy { -+ void *bd_bitmap; -+ void *bd_buddy; -+ int bd_blkbits; -+ struct buffer_head *bd_bh; -+ struct buffer_head *bd_bh2; -+ struct ext3_buddy_group_blocks *bd_bd; -+ struct super_block *bd_sb; -+}; -+ -+struct ext3_free_extent { -+ int fe_start; -+ int fe_len; -+ unsigned char fe_orders[MB_ARR_SIZE]; -+ unsigned char fe_nums; -+ unsigned char fe_back; -+}; -+ -+#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1) -+ -+ -+int ext3_create (struct inode *, struct dentry *, int, struct nameidata *); -+struct buffer_head * read_block_bitmap(struct super_block *, unsigned int); -+void ext3_free_blocks_old(handle_t *, struct inode *, unsigned long, unsigned long); -+int ext3_new_block_old(handle_t *, struct inode *, unsigned long, u32 *, u32 *, int *); -+int ext3_mb_reserve_blocks(struct super_block *, int); -+void ext3_mb_release_blocks(struct super_block *, int); -+void ext3_mb_poll_new_transaction(struct super_block *, handle_t *); -+void ext3_mb_free_committed_blocks(struct super_block *); -+ -+#define mb_correct_addr_and_bit(bit,addr) \ -+{ \ -+ if ((unsigned) addr & 1) { \ -+ bit += 8; \ -+ addr--; \ -+ } \ -+ if ((unsigned) addr & 2) { \ -+ bit += 16; \ -+ addr--; \ -+ addr--; \ -+ } \ -+} -+ -+static inline int mb_test_bit(int bit, void *addr) -+{ -+ mb_correct_addr_and_bit(bit,addr); -+ return test_bit(bit, addr); -+} -+ -+static inline void mb_set_bit(int bit, void *addr) -+{ -+ mb_correct_addr_and_bit(bit,addr); -+ set_bit(bit, addr); -+} -+ -+static inline void mb_clear_bit(int bit, void *addr) -+{ -+ mb_correct_addr_and_bit(bit,addr); -+ clear_bit(bit, addr); -+} -+ -+static inline void *mb_find_buddy(struct ext3_buddy *e3b, int order, int *max) -+{ -+ int i = 1; -+ void *bb; -+ -+ J_ASSERT(e3b->bd_bitmap != e3b->bd_buddy); -+ J_ASSERT(max != NULL); -+ -+ if (order > e3b->bd_blkbits + 1) -+ return NULL; -+ -+ /* at order 0 we see each particular block */ -+ *max = 1 << (e3b->bd_blkbits + 3); -+ if (order == 0) -+ return e3b->bd_bitmap; -+ -+ bb = e3b->bd_buddy; -+ *max = *max >> 1; -+ while (i < order) { -+ bb += 1 << (e3b->bd_blkbits - i); -+ i++; -+ *max = *max >> 1; -+ } -+ return bb; -+} -+ -+static int ext3_mb_load_desc(struct super_block *sb, int group, -+ struct ext3_buddy *e3b) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ -+ J_ASSERT(sbi->s_buddy_blocks[group].bb_bitmap); -+ J_ASSERT(sbi->s_buddy_blocks[group].bb_buddy); -+ -+ /* load bitmap */ -+ e3b->bd_bh = sb_getblk(sb, sbi->s_buddy_blocks[group].bb_bitmap); -+ if (e3b->bd_bh == NULL) { -+ ext3_error(sb, "ext3_mb_load_desc", -+ "can't get block for buddy bitmap\n"); -+ goto out; -+ } -+ if (!buffer_uptodate(e3b->bd_bh)) { -+ ll_rw_block(READ, 1, &e3b->bd_bh); -+ wait_on_buffer(e3b->bd_bh); -+ } -+ J_ASSERT(buffer_uptodate(e3b->bd_bh)); -+ -+ /* load buddy */ -+ e3b->bd_bh2 = sb_getblk(sb, sbi->s_buddy_blocks[group].bb_buddy); -+ if (e3b->bd_bh2 == NULL) { -+ ext3_error(sb, "ext3_mb_load_desc", -+ "can't get block for buddy bitmap\n"); -+ goto out; -+ } -+ if (!buffer_uptodate(e3b->bd_bh2)) { -+ ll_rw_block(READ, 1, &e3b->bd_bh2); -+ wait_on_buffer(e3b->bd_bh2); -+ } -+ J_ASSERT(buffer_uptodate(e3b->bd_bh2)); -+ -+ e3b->bd_bitmap = e3b->bd_bh->b_data; -+ e3b->bd_buddy = e3b->bd_bh2->b_data; -+ e3b->bd_blkbits = sb->s_blocksize_bits; -+ e3b->bd_bd = sbi->s_buddy_blocks + group; -+ e3b->bd_sb = sb; -+ -+ return 0; -+out: -+ brelse(e3b->bd_bh); -+ brelse(e3b->bd_bh2); -+ e3b->bd_bh = NULL; -+ e3b->bd_bh2 = NULL; -+ return -EIO; -+} -+ -+static void ext3_mb_dirty_buddy(struct ext3_buddy *e3b) -+{ -+ mark_buffer_dirty(e3b->bd_bh); -+ mark_buffer_dirty(e3b->bd_bh2); -+} -+ -+static void ext3_mb_release_desc(struct ext3_buddy *e3b) -+{ -+ brelse(e3b->bd_bh); -+ brelse(e3b->bd_bh2); -+} -+ -+#ifdef AGGRESSIVE_CHECK -+static void mb_check_buddy(struct ext3_buddy *e3b) -+{ -+ int order = e3b->bd_blkbits + 1; -+ int max, max2, i, j, k, count; -+ void *buddy, *buddy2; -+ -+ if (!test_opt(e3b->bd_sb, MBALLOC)) -+ return; -+ -+ while (order > 1) { -+ buddy = mb_find_buddy(e3b, order, &max); -+ J_ASSERT(buddy); -+ buddy2 = mb_find_buddy(e3b, order - 1, &max2); -+ J_ASSERT(buddy2); -+ J_ASSERT(buddy != buddy2); -+ J_ASSERT(max * 2 == max2); -+ -+ count = 0; -+ for (i = 0; i < max; i++) { -+ -+ if (!mb_test_bit(i, buddy)) { -+ /* only single bit in buddy2 may be 1 */ -+ if (mb_test_bit(i << 1, buddy2)) -+ J_ASSERT(!mb_test_bit((i<<1)+1, buddy2)); -+ else if (mb_test_bit((i << 1) + 1, buddy2)) -+ J_ASSERT(!mb_test_bit(i << 1, buddy2)); -+ continue; -+ } -+ -+ /* both bits in buddy2 must be 0 */ -+ J_ASSERT(!mb_test_bit(i << 1, buddy2)); -+ J_ASSERT(!mb_test_bit((i << 1) + 1, buddy2)); -+ -+ for (j = 0; j < (1 << order); j++) { -+ k = (i * (1 << order)) + j; -+ J_ASSERT(mb_test_bit(k, e3b->bd_bitmap)); -+ } -+ count++; -+ } -+ J_ASSERT(e3b->bd_bd->bb_counters[order] == count); -+ order--; -+ } -+ -+ buddy = mb_find_buddy(e3b, 0, &max); -+ for (i = 0; i < max; i++) { -+ if (mb_test_bit(i, buddy)) -+ continue; -+ /* check used bits only */ -+ for (j = 0; j < e3b->bd_blkbits + 1; j++) { -+ buddy2 = mb_find_buddy(e3b, j, &max2); -+ k = i >> j; -+ J_ASSERT(k < max2); -+ J_ASSERT(!mb_test_bit(k, buddy2)); -+ } -+ } -+} -+#else -+#define mb_check_buddy(e3b) -+#endif -+ -+static inline void -+ext3_lock_group(struct super_block *sb, int group) -+{ -+ spin_lock(&EXT3_SB(sb)->s_buddy_blocks[group].bb_lock); -+} -+ -+static inline void -+ext3_unlock_group(struct super_block *sb, int group) -+{ -+ spin_unlock(&EXT3_SB(sb)->s_buddy_blocks[group].bb_lock); -+} -+ -+static int mb_find_order_for_block(struct ext3_buddy *e3b, int block) -+{ -+ int order = 1; -+ void *bb; -+ -+ J_ASSERT(e3b->bd_bitmap != e3b->bd_buddy); -+ J_ASSERT(block < (1 << (e3b->bd_blkbits + 3))); -+ -+ bb = e3b->bd_buddy; -+ while (order <= e3b->bd_blkbits + 1) { -+ block = block >> 1; -+ if (mb_test_bit(block, bb)) { -+ /* this block is part of buddy of order 'order' */ -+ return order; -+ } -+ bb += 1 << (e3b->bd_blkbits - order); -+ order++; -+ } -+ return 0; -+} -+ -+static inline void mb_clear_bits(void *bm, int cur, int len) -+{ -+ __u32 *addr; -+ -+ len = cur + len; -+ while (cur < len) { -+ if ((cur & 31) == 0 && (len - cur) >= 32) { -+ /* fast path: clear whole word at once */ -+ addr = bm + (cur >> 3); -+ *addr = 0; -+ cur += 32; -+ continue; -+ } -+ mb_clear_bit(cur, bm); -+ cur++; -+ } -+} -+ -+static inline void mb_set_bits(void *bm, int cur, int len) -+{ -+ __u32 *addr; -+ -+ len = cur + len; -+ while (cur < len) { -+ if ((cur & 31) == 0 && (len - cur) >= 32) { -+ /* fast path: clear whole word at once */ -+ addr = bm + (cur >> 3); -+ *addr = 0xffffffff; -+ cur += 32; -+ continue; -+ } -+ mb_set_bit(cur, bm); -+ cur++; -+ } -+} -+ -+static int mb_free_blocks(struct ext3_buddy *e3b, int first, int count) -+{ -+ int block, max, order; -+ void *buddy, *buddy2; -+ -+ mb_check_buddy(e3b); -+ while (count-- > 0) { -+ block = first++; -+ order = 0; -+ -+ J_ASSERT(!mb_test_bit(block, e3b->bd_bitmap)); -+ mb_set_bit(block, e3b->bd_bitmap); -+ e3b->bd_bd->bb_counters[order]++; -+ -+ /* start of the buddy */ -+ buddy = mb_find_buddy(e3b, order, &max); -+ -+ do { -+ block &= ~1UL; -+ if (!mb_test_bit(block, buddy) || -+ !mb_test_bit(block + 1, buddy)) -+ break; -+ -+ /* both the buddies are free, try to coalesce them */ -+ buddy2 = mb_find_buddy(e3b, order + 1, &max); -+ -+ if (!buddy2) -+ break; -+ -+ if (order > 0) { -+ /* for special purposes, we don't clear -+ * free bits in bitmap */ -+ mb_clear_bit(block, buddy); -+ mb_clear_bit(block + 1, buddy); -+ } -+ e3b->bd_bd->bb_counters[order]--; -+ e3b->bd_bd->bb_counters[order]--; -+ -+ block = block >> 1; -+ order++; -+ e3b->bd_bd->bb_counters[order]++; -+ -+ mb_set_bit(block, buddy2); -+ buddy = buddy2; -+ } while (1); -+ } -+ mb_check_buddy(e3b); -+ -+ return 0; -+} -+ -+/* -+ * returns 1 if out extent is enough to fill needed space -+ */ -+int mb_make_backward_extent(struct ext3_free_extent *in, -+ struct ext3_free_extent *out, int needed) -+{ -+ int i; -+ -+ J_ASSERT(in); -+ J_ASSERT(out); -+ J_ASSERT(in->fe_nums < MB_ARR_SIZE); -+ -+ out->fe_len = 0; -+ out->fe_start = in->fe_start + in->fe_len; -+ out->fe_nums = 0; -+ -+ /* for single-chunk extent we need not back order -+ * also, if an extent doesn't fill needed space -+ * then it makes no sense to try back order becase -+ * if we select this extent then it'll be use as is */ -+ if (in->fe_nums < 2 || in->fe_len < needed) -+ return 0; -+ -+ i = in->fe_nums - 1; -+ while (i >= 0 && out->fe_len < needed) { -+ out->fe_len += (1 << in->fe_orders[i]); -+ out->fe_start -= (1 << in->fe_orders[i]); -+ i--; -+ } -+ /* FIXME: in some situation fe_orders may be too small to hold -+ * all the buddies */ -+ J_ASSERT(out->fe_len >= needed); -+ -+ for (i++; i < in->fe_nums; i++) -+ out->fe_orders[out->fe_nums++] = in->fe_orders[i]; -+ J_ASSERT(out->fe_nums < MB_ARR_SIZE); -+ out->fe_back = 1; -+ -+ return 1; -+} -+ -+int mb_find_extent(struct ext3_buddy *e3b, int order, int block, -+ int needed, struct ext3_free_extent *ex) -+{ -+ int space = needed; -+ int next, max, ord; -+ void *buddy; -+ -+ J_ASSERT(ex != NULL); -+ -+ ex->fe_nums = 0; -+ ex->fe_len = 0; -+ -+ buddy = mb_find_buddy(e3b, order, &max); -+ J_ASSERT(buddy); -+ J_ASSERT(block < max); -+ if (!mb_test_bit(block, buddy)) -+ goto nofree; -+ -+ if (order == 0) { -+ /* find actual order */ -+ order = mb_find_order_for_block(e3b, block); -+ block = block >> order; -+ } -+ -+ ex->fe_orders[ex->fe_nums++] = order; -+ ex->fe_len = 1 << order; -+ ex->fe_start = block << order; -+ ex->fe_back = 0; -+ -+ while ((space = space - (1 << order)) > 0) { -+ -+ buddy = mb_find_buddy(e3b, order, &max); -+ J_ASSERT(buddy); -+ -+ if (block + 1 >= max) -+ break; -+ -+ next = (block + 1) * (1 << order); -+ if (!mb_test_bit(next, e3b->bd_bitmap)) -+ break; -+ -+ ord = mb_find_order_for_block(e3b, next); -+ -+ if ((1 << ord) >= needed) { -+ /* we dont want to coalesce with self-enough buddies */ -+ break; -+ } -+ order = ord; -+ block = next >> order; -+ ex->fe_len += 1 << order; -+ -+ if (ex->fe_nums < MB_ARR_SIZE) -+ ex->fe_orders[ex->fe_nums++] = order; -+ } -+ -+nofree: -+ J_ASSERT(ex->fe_start + ex->fe_len <= (1 << (e3b->bd_blkbits + 3))); -+ return ex->fe_len; -+} -+ -+static int mb_mark_used_backward(struct ext3_buddy *e3b, -+ struct ext3_free_extent *ex, int len) -+{ -+ int start = ex->fe_start, len0 = len; -+ int ord, mlen, max, cur; -+ void *buddy; -+ -+ start = ex->fe_start + ex->fe_len - 1; -+ while (len) { -+ ord = mb_find_order_for_block(e3b, start); -+ if (((start >> ord) << ord) == (start - (1 << ord) + 1) && -+ len >= (1 << ord)) { -+ /* the whole chunk may be allocated at once! */ -+ mlen = 1 << ord; -+ buddy = mb_find_buddy(e3b, ord, &max); -+ J_ASSERT((start >> ord) < max); -+ mb_clear_bit(start >> ord, buddy); -+ e3b->bd_bd->bb_counters[ord]--; -+ start -= mlen; -+ len -= mlen; -+ J_ASSERT(len >= 0); -+ J_ASSERT(start >= 0); -+ continue; -+ } -+ -+ /* we have to split large buddy */ -+ J_ASSERT(ord > 0); -+ buddy = mb_find_buddy(e3b, ord, &max); -+ mb_clear_bit(start >> ord, buddy); -+ e3b->bd_bd->bb_counters[ord]--; -+ -+ ord--; -+ cur = (start >> ord) & ~1U; -+ buddy = mb_find_buddy(e3b, ord, &max); -+ mb_set_bit(cur, buddy); -+ mb_set_bit(cur + 1, buddy); -+ e3b->bd_bd->bb_counters[ord]++; -+ e3b->bd_bd->bb_counters[ord]++; -+ } -+ -+ /* now drop all the bits in bitmap */ -+ mb_clear_bits(e3b->bd_bitmap, ex->fe_start + ex->fe_len - len0, len0); -+ -+ mb_check_buddy(e3b); -+ -+ return 0; -+} -+ -+static int mb_mark_used_forward(struct ext3_buddy *e3b, -+ struct ext3_free_extent *ex, int len) -+{ -+ int start = ex->fe_start, len0 = len; -+ int ord, mlen, max, cur; -+ void *buddy; -+ -+ while (len) { -+ ord = mb_find_order_for_block(e3b, start); -+ -+ if (((start >> ord) << ord) == start && len >= (1 << ord)) { -+ /* the whole chunk may be allocated at once! */ -+ mlen = 1 << ord; -+ buddy = mb_find_buddy(e3b, ord, &max); -+ J_ASSERT((start >> ord) < max); -+ mb_clear_bit(start >> ord, buddy); -+ e3b->bd_bd->bb_counters[ord]--; -+ start += mlen; -+ len -= mlen; -+ J_ASSERT(len >= 0); -+ continue; -+ } -+ -+ /* we have to split large buddy */ -+ J_ASSERT(ord > 0); -+ buddy = mb_find_buddy(e3b, ord, &max); -+ mb_clear_bit(start >> ord, buddy); -+ e3b->bd_bd->bb_counters[ord]--; -+ -+ ord--; -+ cur = (start >> ord) & ~1U; -+ buddy = mb_find_buddy(e3b, ord, &max); -+ mb_set_bit(cur, buddy); -+ mb_set_bit(cur + 1, buddy); -+ e3b->bd_bd->bb_counters[ord]++; -+ e3b->bd_bd->bb_counters[ord]++; -+ } -+ -+ /* now drop all the bits in bitmap */ -+ mb_clear_bits(e3b->bd_bitmap, ex->fe_start, len0); -+ -+ mb_check_buddy(e3b); -+ -+ return 0; -+} -+ -+int inline mb_mark_used(struct ext3_buddy *e3b, -+ struct ext3_free_extent *ex, int len) -+{ -+ int err; -+ -+ J_ASSERT(ex); -+ if (ex->fe_back == 0) -+ err = mb_mark_used_forward(e3b, ex, len); -+ else -+ err = mb_mark_used_backward(e3b, ex, len); -+ return err; -+} -+ -+int ext3_mb_new_in_group(struct ext3_allocation_context *ac, -+ struct ext3_buddy *e3b, int group) -+{ -+ struct super_block *sb = ac->ac_sb; -+ int err, gorder, max, i; -+ struct ext3_free_extent curex; -+ -+ /* let's know order of allocation */ -+ gorder = 0; -+ while (ac->ac_g_len > (1 << gorder)) -+ gorder++; -+ -+ if ((ac->ac_g_flags & 1) && ac->ac_g_group == group) { -+ /* someone asks for space at this specified block -+ * probably he wants to merge it into existing extent */ -+ if (mb_test_bit(ac->ac_g_start, e3b->bd_bitmap)) { -+ /* good. at least one block is free */ -+ max = mb_find_extent(e3b, 0, ac->ac_g_start, -+ ac->ac_g_len, &curex); -+ max = min(curex.fe_len, ac->ac_g_len); -+ mb_mark_used(e3b, &curex, max); -+ -+ ac->ac_b_group = group; -+ ac->ac_b_start = curex.fe_start; -+ ac->ac_b_len = max; -+ ac->ac_status = AC_STATUS_FOUND; -+ err = 0; -+ goto out; -+ } -+ /* don't try to find goal anymore */ -+ ac->ac_g_flags &= ~1; -+ } -+ -+ i = 0; -+ while (1) { -+ i = find_next_bit(e3b->bd_bitmap, sb->s_blocksize * 8, i); -+ if (i >= sb->s_blocksize * 8) -+ break; -+ -+ max = mb_find_extent(e3b, 0, i, ac->ac_g_len, &curex); -+ if (max >= ac->ac_g_len) { -+ max = min(curex.fe_len, ac->ac_g_len); -+ mb_mark_used(e3b, &curex, max); -+ -+ ac->ac_b_group = group; -+ ac->ac_b_start = curex.fe_start; -+ ac->ac_b_len = max; -+ ac->ac_status = AC_STATUS_FOUND; -+ break; -+ } -+ i += max; -+ } -+ -+ return 0; -+ -+out: -+ return err; -+} -+ -+int mb_good_group(struct ext3_allocation_context *ac, int group, int cr) -+{ -+ struct ext3_group_desc *gdp; -+ int free_blocks; -+ -+ gdp = ext3_get_group_desc(ac->ac_sb, group, NULL); -+ if (!gdp) -+ return 0; -+ free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); -+ if (free_blocks == 0) -+ return 0; -+ -+ /* someone wants this block very much */ -+ if ((ac->ac_g_flags & 1) && ac->ac_g_group == group) -+ return 1; -+ -+ /* FIXME: I'd like to take fragmentation into account here */ -+ if (cr == 0) { -+ if (free_blocks >= ac->ac_g_len >> 1) -+ return 1; -+ } else if (cr == 1) { -+ if (free_blocks >= ac->ac_g_len >> 2) -+ return 1; -+ } else if (cr == 2) { -+ return 1; -+ } else { -+ BUG(); -+ } -+ return 0; -+} -+ -+int ext3_mb_new_blocks(handle_t *handle, struct inode *inode, -+ unsigned long goal, int *len, int flags, int *errp) -+{ -+ struct buffer_head *bitmap_bh = NULL; -+ struct ext3_allocation_context ac; -+ int i, group, block, cr, err = 0; -+ struct ext3_group_desc *gdp; -+ struct ext3_super_block *es; -+ struct buffer_head *gdp_bh; -+ struct ext3_sb_info *sbi; -+ struct super_block *sb; -+ struct ext3_buddy e3b; -+ -+ J_ASSERT(len != NULL); -+ J_ASSERT(*len > 0); -+ -+ sb = inode->i_sb; -+ if (!sb) { -+ printk("ext3_mb_new_nblocks: nonexistent device"); -+ return 0; -+ } -+ -+ if (!test_opt(sb, MBALLOC)) { -+ static int ext3_mballoc_warning = 0; -+ if (ext3_mballoc_warning == 0) { -+ printk(KERN_ERR "EXT3-fs: multiblock request with " -+ "mballoc disabled!\n"); -+ ext3_mballoc_warning++; -+ } -+ *len = 1; -+ err = ext3_new_block_old(handle, inode, goal, NULL,NULL, errp); -+ return err; -+ } -+ -+ ext3_mb_poll_new_transaction(sb, handle); -+ -+ sbi = EXT3_SB(sb); -+ es = EXT3_SB(sb)->s_es; -+ -+ if (!(flags & 2)) { -+ /* someone asks for non-reserved blocks */ -+ BUG_ON(*len > 1); -+ err = ext3_mb_reserve_blocks(sb, 1); -+ if (err) { -+ *errp = err; -+ return 0; -+ } -+ } -+ -+ /* -+ * Check quota for allocation of this blocks. -+ */ -+ while (*len && DQUOT_ALLOC_BLOCK(inode, *len)) -+ *len -= 1; -+ if (*len == 0) { -+ *errp = -EDQUOT; -+ block = 0; -+ goto out; -+ } -+ -+ /* start searching from the goal */ -+ if (goal < le32_to_cpu(es->s_first_data_block) || -+ goal >= le32_to_cpu(es->s_blocks_count)) -+ goal = le32_to_cpu(es->s_first_data_block); -+ group = (goal - le32_to_cpu(es->s_first_data_block)) / -+ EXT3_BLOCKS_PER_GROUP(sb); -+ block = ((goal - le32_to_cpu(es->s_first_data_block)) % -+ EXT3_BLOCKS_PER_GROUP(sb)); -+ -+ /* set up allocation goals */ -+ ac.ac_b_group = ac.ac_b_start = ac.ac_b_len = 0; -+ ac.ac_status = 0; -+ ac.ac_groups_scanned = 0; -+ ac.ac_sb = inode->i_sb; -+ ac.ac_g_group = group; -+ ac.ac_g_start = block; -+ ac.ac_g_len = *len; -+ ac.ac_g_flags = flags; -+ -+ /* loop over the groups */ -+ for (cr = 0; cr < 3 && ac.ac_status != AC_STATUS_FOUND; cr++) { -+ for (i = 0; i < EXT3_SB(sb)->s_groups_count; group++, i++) { -+ if (group == EXT3_SB(sb)->s_groups_count) -+ group = 0; -+ -+ /* check is group good for our criteries */ -+ if (!mb_good_group(&ac, group, cr)) -+ continue; -+ -+ err = ext3_mb_load_desc(ac.ac_sb, group, &e3b); -+ if (err) -+ goto out_err; -+ -+ ext3_lock_group(sb, group); -+ if (!mb_good_group(&ac, group, cr)) { -+ /* someone did allocation from this group */ -+ ext3_unlock_group(sb, group); -+ ext3_mb_release_desc(&e3b); -+ continue; -+ } -+ -+ err = ext3_mb_new_in_group(&ac, &e3b, group); -+ ext3_unlock_group(sb, group); -+ if (ac.ac_status == AC_STATUS_FOUND) -+ ext3_mb_dirty_buddy(&e3b); -+ ext3_mb_release_desc(&e3b); -+ if (err) -+ goto out_err; -+ if (ac.ac_status == AC_STATUS_FOUND) -+ break; -+ } -+ } -+ -+ if (ac.ac_status != AC_STATUS_FOUND) { -+ /* unfortunately, we can't satisfy this request */ -+ J_ASSERT(ac.ac_b_len == 0); -+ DQUOT_FREE_BLOCK(inode, *len); -+ *errp = -ENOSPC; -+ block = 0; -+ goto out; -+ } -+ -+ /* good news - free block(s) have been found. now it's time -+ * to mark block(s) in good old journaled bitmap */ -+ block = ac.ac_b_group * EXT3_BLOCKS_PER_GROUP(sb) -+ + ac.ac_b_start + le32_to_cpu(es->s_first_data_block); -+ -+ /* we made a desicion, now mark found blocks in good old -+ * bitmap to be journaled */ -+ -+ ext3_debug("using block group %d(%d)\n", -+ ac.ac_b_group.group, gdp->bg_free_blocks_count); -+ -+ bitmap_bh = read_block_bitmap(sb, ac.ac_b_group); -+ if (!bitmap_bh) { -+ *errp = -EIO; -+ goto out_err; -+ } -+ -+ err = ext3_journal_get_write_access(handle, bitmap_bh); -+ if (err) { -+ *errp = err; -+ goto out_err; -+ } -+ -+ gdp = ext3_get_group_desc(sb, ac.ac_b_group, &gdp_bh); -+ if (!gdp) { -+ *errp = -EIO; -+ goto out_err; -+ } -+ -+ err = ext3_journal_get_write_access(handle, gdp_bh); -+ if (err) -+ goto out_err; -+ -+ block = ac.ac_b_start + ac.ac_b_group * EXT3_BLOCKS_PER_GROUP(sb) -+ + le32_to_cpu(es->s_first_data_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, "ext3_new_block", -+ "Allocating block in system zone - " -+ "block = %u", block); -+#if 0 -+ for (i = 0; i < ac.ac_b_len; i++) -+ J_ASSERT(!mb_test_bit(ac.ac_b_start + i, bitmap_bh->b_data)); -+#endif -+ mb_set_bits(bitmap_bh->b_data, ac.ac_b_start, ac.ac_b_len); -+ -+ ext3_lock_group(sb, ac.ac_b_group); -+ gdp->bg_free_blocks_count = -+ cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) - -+ ac.ac_b_len); -+ ext3_unlock_group(sb, ac.ac_b_group); -+ percpu_counter_mod(&sbi->s_freeblocks_counter, -ac.ac_b_len); -+ -+ err = ext3_journal_dirty_metadata(handle, bitmap_bh); -+ if (err) -+ goto out_err; -+ err = ext3_journal_dirty_metadata(handle, gdp_bh); -+ if (err) -+ goto out_err; -+ -+ sb->s_dirt = 1; -+ *errp = 0; -+ brelse(bitmap_bh); -+ -+ /* drop non-allocated, but dquote'd blocks */ -+ J_ASSERT(*len >= ac.ac_b_len); -+ DQUOT_FREE_BLOCK(inode, *len - ac.ac_b_len); -+ -+ *len = ac.ac_b_len; -+ J_ASSERT(block != 0); -+ goto out; -+ -+out_err: -+ /* if we've already allocated something, roll it back */ -+ if (ac.ac_status == AC_STATUS_FOUND) { -+ /* FIXME: free blocks here */ -+ } -+ -+ DQUOT_FREE_BLOCK(inode, *len); -+ brelse(bitmap_bh); -+ *errp = err; -+ block = 0; -+out: -+ if (!(flags & 2)) { -+ /* block wasn't reserved before and we reserved it -+ * at the beginning of allocation. it doesn't matter -+ * whether we allocated anything or we failed: time -+ * to release reservation. NOTE: because I expect -+ * any multiblock request from delayed allocation -+ * path only, here is single block always */ -+ ext3_mb_release_blocks(sb, 1); -+ } -+ return block; -+} -+ -+int ext3_mb_generate_buddy(struct super_block *sb, int group) -+{ -+ struct buffer_head *bh; -+ int i, err, count = 0; -+ struct ext3_buddy e3b; -+ -+ err = ext3_mb_load_desc(sb, group, &e3b); -+ if (err) -+ goto out; -+ memset(e3b.bd_bh->b_data, 0, sb->s_blocksize); -+ memset(e3b.bd_bh2->b_data, 0, sb->s_blocksize); -+ -+ bh = read_block_bitmap(sb, group); -+ if (bh == NULL) { -+ err = -EIO; -+ goto out2; -+ } -+ -+ /* loop over the blocks, nad create buddies for free ones */ -+ for (i = 0; i < sb->s_blocksize * 8; i++) { -+ if (!mb_test_bit(i, (void *) bh->b_data)) { -+ mb_free_blocks(&e3b, i, 1); -+ count++; -+ } -+ } -+ brelse(bh); -+ mb_check_buddy(&e3b); -+ ext3_mb_dirty_buddy(&e3b); -+ -+out2: -+ ext3_mb_release_desc(&e3b); -+out: -+ return err; -+} -+ -+EXPORT_SYMBOL(ext3_mb_new_blocks); -+ -+#define MB_CREDITS \ -+ (EXT3_DATA_TRANS_BLOCKS + 3 + EXT3_INDEX_EXTRA_TRANS_BLOCKS + \ -+ 2 * EXT3_QUOTA_INIT_BLOCKS) -+ -+int ext3_mb_init_backend(struct super_block *sb) -+{ -+ struct inode *root = sb->s_root->d_inode; -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ struct dentry *db; -+ tid_t target; -+ int err, i; -+ -+ sbi->s_buddy_blocks = kmalloc(sizeof(struct ext3_buddy_group_blocks) * -+ sbi->s_groups_count, GFP_KERNEL); -+ if (sbi->s_buddy_blocks == NULL) { -+ printk("can't allocate mem for buddy maps\n"); -+ return -ENOMEM; -+ } -+ memset(sbi->s_buddy_blocks, 0, -+ sizeof(struct ext3_buddy_group_blocks) * sbi->s_groups_count); -+ sbi->s_buddy = NULL; -+ -+ down(&root->i_sem); -+ db = lookup_one_len(EXT3_BUDDY_FILE, sb->s_root, -+ strlen(EXT3_BUDDY_FILE)); -+ if (IS_ERR(db)) { -+ err = PTR_ERR(db); -+ printk("can't lookup buddy file: %d\n", err); -+ goto out; -+ } -+ -+ if (db->d_inode != NULL) { -+ sbi->s_buddy = igrab(db->d_inode); -+ goto map; -+ } -+ -+ err = ext3_create(root, db, S_IFREG, NULL); -+ if (err) { -+ printk("error while creation buddy file: %d\n", err); -+ } else { -+ sbi->s_buddy = igrab(db->d_inode); -+ } -+ -+map: -+ for (i = 0; i < sbi->s_groups_count; i++) { -+ struct buffer_head *bh = NULL; -+ handle_t *handle; -+ -+ handle = ext3_journal_start(sbi->s_buddy, MB_CREDITS); -+ if (IS_ERR(handle)) { -+ err = PTR_ERR(handle); -+ goto out2; -+ } -+ -+ /* allocate block for bitmap */ -+ bh = ext3_getblk(handle, sbi->s_buddy, i * 2, 1, &err); -+ if (bh == NULL) { -+ printk("can't get block for buddy bitmap: %d\n", err); -+ goto out2; -+ } -+ sbi->s_buddy_blocks[i].bb_bitmap = bh->b_blocknr; -+ brelse(bh); -+ -+ /* allocate block for buddy */ -+ bh = ext3_getblk(handle, sbi->s_buddy, i * 2 + 1, 1, &err); -+ if (bh == NULL) { -+ printk("can't get block for buddy: %d\n", err); -+ goto out2; -+ } -+ sbi->s_buddy_blocks[i].bb_buddy = bh->b_blocknr; -+ brelse(bh); -+ ext3_journal_stop(handle); -+ spin_lock_init(&sbi->s_buddy_blocks[i].bb_lock); -+ sbi->s_buddy_blocks[i].bb_md_cur = NULL; -+ sbi->s_buddy_blocks[i].bb_tid = 0; -+ } -+ -+ if (journal_start_commit(sbi->s_journal, &target)) -+ log_wait_commit(sbi->s_journal, target); -+ -+out2: -+ dput(db); -+out: -+ up(&root->i_sem); -+ return err; -+} -+ -+int ext3_mb_release(struct super_block *sb) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ -+ if (!test_opt(sb, MBALLOC)) -+ return 0; -+ -+ /* release freed, non-committed blocks */ -+ spin_lock(&sbi->s_md_lock); -+ list_splice_init(&sbi->s_closed_transaction, -+ &sbi->s_committed_transaction); -+ list_splice_init(&sbi->s_active_transaction, -+ &sbi->s_committed_transaction); -+ spin_unlock(&sbi->s_md_lock); -+ ext3_mb_free_committed_blocks(sb); -+ -+ if (sbi->s_buddy_blocks) -+ kfree(sbi->s_buddy_blocks); -+ if (sbi->s_buddy) -+ iput(sbi->s_buddy); -+ if (sbi->s_blocks_reserved) -+ printk("ext3-fs: %ld blocks being reserved at umount!\n", -+ sbi->s_blocks_reserved); -+ return 0; -+} -+ -+int ext3_mb_init(struct super_block *sb) -+{ -+ struct ext3_super_block *es; -+ int i; -+ -+ if (!test_opt(sb, MBALLOC)) -+ return 0; -+ -+ /* init file for buddy data */ -+ clear_opt(EXT3_SB(sb)->s_mount_opt, MBALLOC); -+ ext3_mb_init_backend(sb); -+ -+ es = EXT3_SB(sb)->s_es; -+ for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) -+ ext3_mb_generate_buddy(sb, i); -+ spin_lock_init(&EXT3_SB(sb)->s_reserve_lock); -+ spin_lock_init(&EXT3_SB(sb)->s_md_lock); -+ INIT_LIST_HEAD(&EXT3_SB(sb)->s_active_transaction); -+ INIT_LIST_HEAD(&EXT3_SB(sb)->s_closed_transaction); -+ INIT_LIST_HEAD(&EXT3_SB(sb)->s_committed_transaction); -+ set_opt(EXT3_SB(sb)->s_mount_opt, MBALLOC); -+ printk("EXT3-fs: mballoc enabled\n"); -+ return 0; -+} -+ -+void ext3_mb_free_committed_blocks(struct super_block *sb) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ int err, i, count = 0, count2 = 0; -+ struct ext3_free_metadata *md; -+ struct ext3_buddy e3b; -+ -+ if (list_empty(&sbi->s_committed_transaction)) -+ return; -+ -+ /* there is committed blocks to be freed yet */ -+ do { -+ /* get next array of blocks */ -+ md = NULL; -+ spin_lock(&sbi->s_md_lock); -+ if (!list_empty(&sbi->s_committed_transaction)) { -+ md = list_entry(sbi->s_committed_transaction.next, -+ struct ext3_free_metadata, list); -+ list_del(&md->list); -+ } -+ spin_unlock(&sbi->s_md_lock); -+ -+ if (md == NULL) -+ break; -+ -+ mb_debug("gonna free %u blocks in group %u (0x%p):", -+ md->num, md->group, md); -+ -+ err = ext3_mb_load_desc(sb, md->group, &e3b); -+ BUG_ON(err != 0); -+ -+ /* there are blocks to put in buddy to make them really free */ -+ count += md->num; -+ count2++; -+ ext3_lock_group(sb, md->group); -+ for (i = 0; i < md->num; i++) { -+ mb_debug(" %u", md->blocks[i]); -+ mb_free_blocks(&e3b, md->blocks[i], 1); -+ } -+ mb_debug("\n"); -+ ext3_unlock_group(sb, md->group); -+ -+ kfree(md); -+ ext3_mb_dirty_buddy(&e3b); -+ ext3_mb_release_desc(&e3b); -+ -+ } while (md); -+ mb_debug("freed %u blocks in %u structures\n", count, count2); -+} -+ -+void ext3_mb_poll_new_transaction(struct super_block *sb, handle_t *handle) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ -+ if (sbi->s_last_transaction == handle->h_transaction->t_tid) -+ return; -+ -+ /* new transaction! time to close last one and free blocks for -+ * committed transaction. we know that only transaction can be -+ * active, so previos transaction can be being logged and we -+ * know that transaction before previous is known to be alreade -+ * logged. this means that now we may free blocks freed in all -+ * transactions before previous one. hope I'm clear enough ... */ -+ -+ spin_lock(&sbi->s_md_lock); -+ if (sbi->s_last_transaction != handle->h_transaction->t_tid) { -+ mb_debug("new transaction %lu, old %lu\n", -+ (unsigned long) handle->h_transaction->t_tid, -+ (unsigned long) sbi->s_last_transaction); -+ list_splice_init(&sbi->s_closed_transaction, -+ &sbi->s_committed_transaction); -+ list_splice_init(&sbi->s_active_transaction, -+ &sbi->s_closed_transaction); -+ sbi->s_last_transaction = handle->h_transaction->t_tid; -+ } -+ spin_unlock(&sbi->s_md_lock); -+ -+ ext3_mb_free_committed_blocks(sb); -+} -+ -+int ext3_mb_free_metadata(handle_t *handle, struct ext3_buddy *e3b, -+ int group, int block, int count) -+{ -+ struct ext3_buddy_group_blocks *db = e3b->bd_bd; -+ struct super_block *sb = e3b->bd_sb; -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ struct ext3_free_metadata *md; -+ int i; -+ -+ ext3_lock_group(sb, group); -+ for (i = 0; i < count; i++) { -+ md = db->bb_md_cur; -+ if (md && db->bb_tid != handle->h_transaction->t_tid) { -+ db->bb_md_cur = NULL; -+ md = NULL; -+ } -+ -+ if (md == NULL) { -+ ext3_unlock_group(sb, group); -+ md = kmalloc(sizeof(*md), GFP_KERNEL); -+ if (md == NULL) -+ return -ENOMEM; -+ md->num = 0; -+ md->group = group; -+ -+ ext3_lock_group(sb, group); -+ if (db->bb_md_cur == NULL) { -+ spin_lock(&sbi->s_md_lock); -+ list_add(&md->list, &sbi->s_active_transaction); -+ spin_unlock(&sbi->s_md_lock); -+ db->bb_md_cur = md; -+ db->bb_tid = handle->h_transaction->t_tid; -+ mb_debug("new md 0x%p for group %u\n", -+ md, md->group); -+ } else { -+ kfree(md); -+ md = db->bb_md_cur; -+ } -+ } -+ -+ BUG_ON(md->num >= EXT3_BB_MAX_BLOCKS); -+ md->blocks[md->num] = block + i; -+ md->num++; -+ if (md->num == EXT3_BB_MAX_BLOCKS) { -+ /* no more space, put full container on a sb's list */ -+ db->bb_md_cur = NULL; -+ } -+ } -+ ext3_unlock_group(sb, group); -+ return 0; -+} -+ -+void ext3_mb_free_blocks(handle_t *handle, struct inode *inode, -+ unsigned long block, unsigned long count, int metadata) -+{ -+ struct buffer_head *bitmap_bh = NULL; -+ struct ext3_group_desc *gdp; -+ struct ext3_super_block *es; -+ unsigned long bit, overflow; -+ struct buffer_head *gd_bh; -+ unsigned long block_group; -+ struct ext3_sb_info *sbi; -+ struct super_block *sb; -+ struct ext3_buddy e3b; -+ int err = 0, ret; -+ -+ sb = inode->i_sb; -+ if (!sb) { -+ printk ("ext3_free_blocks: nonexistent device"); -+ return; -+ } -+ -+ ext3_mb_poll_new_transaction(sb, handle); -+ -+ sbi = EXT3_SB(sb); -+ 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)) { -+ ext3_error (sb, "ext3_free_blocks", -+ "Freeing blocks not in datazone - " -+ "block = %lu, count = %lu", block, count); -+ goto error_return; -+ } -+ -+ ext3_debug("freeing block %lu\n", block); -+ -+do_more: -+ overflow = 0; -+ block_group = (block - le32_to_cpu(es->s_first_data_block)) / -+ EXT3_BLOCKS_PER_GROUP(sb); -+ bit = (block - le32_to_cpu(es->s_first_data_block)) % -+ EXT3_BLOCKS_PER_GROUP(sb); -+ /* -+ * Check to see if we are freeing blocks across a group -+ * boundary. -+ */ -+ if (bit + count > EXT3_BLOCKS_PER_GROUP(sb)) { -+ overflow = bit + count - EXT3_BLOCKS_PER_GROUP(sb); -+ count -= overflow; -+ } -+ brelse(bitmap_bh); -+ bitmap_bh = read_block_bitmap(sb, block_group); -+ if (!bitmap_bh) -+ goto error_return; -+ gdp = ext3_get_group_desc (sb, block_group, &gd_bh); -+ 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), -+ EXT3_SB(sb)->s_itb_per_group) || -+ in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table), -+ EXT3_SB(sb)->s_itb_per_group)) -+ ext3_error (sb, "ext3_free_blocks", -+ "Freeing blocks in system zones - " -+ "Block = %lu, count = %lu", -+ block, count); -+ -+ BUFFER_TRACE(bitmap_bh, "getting write access"); -+ err = ext3_journal_get_write_access(handle, bitmap_bh); -+ if (err) -+ goto error_return; -+ -+ /* -+ * We are about to modify some metadata. Call the journal APIs -+ * to unshare ->b_data if a currently-committing transaction is -+ * using it -+ */ -+ BUFFER_TRACE(gd_bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, gd_bh); -+ if (err) -+ goto error_return; -+ -+ err = ext3_mb_load_desc(sb, block_group, &e3b); -+ if (err) -+ goto error_return; -+ -+ if (metadata) { -+ /* blocks being freed are metadata. these blocks shouldn't -+ * be used until this transaction is committed */ -+ ext3_mb_free_metadata(handle, &e3b, block_group, bit, count); -+ } else { -+ ext3_lock_group(sb, block_group); -+ mb_free_blocks(&e3b, bit, count); -+ gdp->bg_free_blocks_count = -+ cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) + count); -+ ext3_unlock_group(sb, block_group); -+ percpu_counter_mod(&sbi->s_freeblocks_counter, count); -+ } -+ -+ ext3_mb_dirty_buddy(&e3b); -+ ext3_mb_release_desc(&e3b); -+ -+ /* FIXME: undo logic will be implemented later and another way */ -+ mb_clear_bits(bitmap_bh->b_data, bit, count); -+ DQUOT_FREE_BLOCK(inode, count); -+ -+ /* We dirtied the bitmap block */ -+ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); -+ err = ext3_journal_dirty_metadata(handle, bitmap_bh); -+ -+ /* And the group descriptor block */ -+ BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); -+ ret = ext3_journal_dirty_metadata(handle, gd_bh); -+ if (!err) err = ret; -+ -+ if (overflow && !err) { -+ block += count; -+ count = overflow; -+ goto do_more; -+ } -+ sb->s_dirt = 1; -+error_return: -+ brelse(bitmap_bh); -+ ext3_std_error(sb, err); -+ return; -+} -+ -+int ext3_mb_reserve_blocks(struct super_block *sb, int blocks) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ int free, ret = -ENOSPC; -+ -+ BUG_ON(blocks < 0); -+ spin_lock(&sbi->s_reserve_lock); -+ free = percpu_counter_read_positive(&sbi->s_freeblocks_counter); -+ if (blocks <= free - sbi->s_blocks_reserved) { -+ sbi->s_blocks_reserved += blocks; -+ ret = 0; -+ } -+ spin_unlock(&sbi->s_reserve_lock); -+ return ret; -+} -+ -+void ext3_mb_release_blocks(struct super_block *sb, int blocks) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ -+ BUG_ON(blocks < 0); -+ spin_lock(&sbi->s_reserve_lock); -+ sbi->s_blocks_reserved -= blocks; -+ WARN_ON(sbi->s_blocks_reserved < 0); -+ if (sbi->s_blocks_reserved < 0) -+ sbi->s_blocks_reserved = 0; -+ spin_unlock(&sbi->s_reserve_lock); -+} -+ -+int ext3_new_block(handle_t *handle, struct inode *inode, -+ unsigned long goal, u32 *pc, u32 *pb, int *errp) -+{ -+ int ret, len; -+ -+ if (!test_opt(inode->i_sb, MBALLOC)) { -+ ret = ext3_new_block_old(handle, inode, goal, pc, pb, errp); -+ goto out; -+ } -+ len = 1; -+ ret = ext3_mb_new_blocks(handle, inode, goal, &len, 0, errp); -+out: -+ return ret; -+} -+ -+ -+void ext3_free_blocks(handle_t *handle, struct inode * inode, -+ unsigned long block, unsigned long count, int metadata) -+{ -+ if (!test_opt(inode->i_sb, MBALLOC)) -+ ext3_free_blocks_old(handle, inode, block, count); -+ else -+ ext3_mb_free_blocks(handle, inode, block, count, metadata); -+ return; -+} -+ -Index: linux-2.6.7/fs/ext3/super.c -=================================================================== ---- linux-2.6.7.orig/fs/ext3/super.c 2004-09-03 08:46:59.000000000 +0400 -+++ linux-2.6.7/fs/ext3/super.c 2004-09-03 08:46:59.000000000 +0400 -@@ -392,6 +392,7 @@ - struct ext3_super_block *es = sbi->s_es; - int i; - -+ ext3_mb_release(sb); - ext3_ext_release(sb); - ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); -@@ -594,7 +595,7 @@ - Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, - Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, - Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, -- Opt_ignore, Opt_err, Opt_extents, Opt_extdebug -+ Opt_ignore, Opt_err, Opt_extents, Opt_extdebug, Opt_mballoc, - }; - - static match_table_t tokens = { -@@ -644,6 +645,7 @@ - {Opt_iopen_nopriv, "iopen_nopriv"}, - {Opt_extents, "extents"}, - {Opt_extdebug, "extdebug"}, -+ {Opt_mballoc, "mballoc"}, - {Opt_err, NULL} - }; - -@@ -929,6 +931,9 @@ - case Opt_extdebug: - set_opt (sbi->s_mount_opt, EXTDEBUG); - break; -+ case Opt_mballoc: -+ set_opt (sbi->s_mount_opt, MBALLOC); -+ break; - default: - printk (KERN_ERR - "EXT3-fs: Unrecognized mount option \"%s\" " -@@ -1602,7 +1607,8 @@ - ext3_count_dirs(sb)); - - ext3_ext_init(sb); -- -+ ext3_mb_init(sb); -+ - return 0; - - failed_mount3: -Index: linux-2.6.7/fs/ext3/Makefile -=================================================================== ---- linux-2.6.7.orig/fs/ext3/Makefile 2004-09-03 08:46:59.000000000 +0400 -+++ linux-2.6.7/fs/ext3/Makefile 2004-09-03 08:46:59.000000000 +0400 -@@ -5,7 +5,7 @@ - obj-$(CONFIG_EXT3_FS) += ext3.o - - ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ -- ioctl.o namei.o super.o symlink.o hash.o extents.o -+ ioctl.o namei.o super.o symlink.o hash.o extents.o mballoc.o - - ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o - ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o -Index: linux-2.6.7/fs/ext3/balloc.c -=================================================================== ---- linux-2.6.7.orig/fs/ext3/balloc.c 2004-08-26 17:11:16.000000000 +0400 -+++ linux-2.6.7/fs/ext3/balloc.c 2004-09-03 08:46:59.000000000 +0400 -@@ -78,7 +78,7 @@ - * - * Return buffer_head on success or NULL in case of failure. - */ --static struct buffer_head * -+struct buffer_head * - read_block_bitmap(struct super_block *sb, unsigned int block_group) - { - struct ext3_group_desc * desc; -@@ -98,8 +98,8 @@ - } - - /* Free given blocks, update quota and i_blocks field */ --void ext3_free_blocks (handle_t *handle, struct inode * inode, -- unsigned long block, unsigned long count) -+void ext3_free_blocks_old (handle_t *handle, struct inode * inode, -+ unsigned long block, unsigned long count) - { - struct buffer_head *bitmap_bh = NULL; - struct buffer_head *gd_bh; -@@ -474,8 +474,8 @@ - * This function also updates quota and i_blocks field. - */ - int --ext3_new_block(handle_t *handle, struct inode *inode, unsigned long goal, -- u32 *prealloc_count, u32 *prealloc_block, int *errp) -+ext3_new_block_old(handle_t *handle, struct inode *inode, unsigned long goal, -+ u32 *prealloc_count, u32 *prealloc_block, int *errp) - { - struct buffer_head *bitmap_bh = NULL; /* bh */ - struct buffer_head *gdp_bh; /* bh2 */ -Index: linux-2.6.7/fs/ext3/namei.c -=================================================================== ---- linux-2.6.7.orig/fs/ext3/namei.c 2004-09-03 08:46:59.000000000 +0400 -+++ linux-2.6.7/fs/ext3/namei.c 2004-09-03 08:46:59.000000000 +0400 -@@ -1640,7 +1640,7 @@ - * If the create succeeds, we fill in the inode information - * with d_instantiate(). - */ --static int ext3_create (struct inode * dir, struct dentry * dentry, int mode, -+int ext3_create (struct inode * dir, struct dentry * dentry, int mode, - struct nameidata *nd) - { - handle_t *handle; -Index: linux-2.6.7/fs/ext3/inode.c -=================================================================== ---- linux-2.6.7.orig/fs/ext3/inode.c 2004-09-03 08:46:59.000000000 +0400 -+++ linux-2.6.7/fs/ext3/inode.c 2004-09-03 08:46:59.000000000 +0400 -@@ -254,7 +254,7 @@ - ei->i_prealloc_count = 0; - ei->i_prealloc_block = 0; - /* Writer: end */ -- ext3_free_blocks (inode, block, total); -+ ext3_free_blocks (inode, block, total, 1); - } - #endif - } -@@ -633,7 +633,7 @@ - ext3_journal_forget(handle, branch[i].bh); - } - for (i = 0; i < keys; i++) -- ext3_free_blocks(handle, inode, le32_to_cpu(branch[i].key), 1); -+ ext3_free_blocks(handle, inode, le32_to_cpu(branch[i].key), 1, 1); - return err; - } - -@@ -734,7 +734,7 @@ - if (err == -EAGAIN) - for (i = 0; i < num; i++) - ext3_free_blocks(handle, inode, -- le32_to_cpu(where[i].key), 1); -+ le32_to_cpu(where[i].key), 1, 1); - return err; - } - -@@ -1911,7 +1911,7 @@ - } - } - -- ext3_free_blocks(handle, inode, block_to_free, count); -+ ext3_free_blocks(handle, inode, block_to_free, count, 1); - } - - /** -@@ -2082,7 +2082,7 @@ - ext3_journal_test_restart(handle, inode); - } - -- ext3_free_blocks(handle, inode, nr, 1); -+ ext3_free_blocks(handle, inode, nr, 1, 1); - - if (parent_bh) { - /* -Index: linux-2.6.7/fs/ext3/extents.c -=================================================================== ---- linux-2.6.7.orig/fs/ext3/extents.c 2004-09-03 08:46:59.000000000 +0400 -+++ linux-2.6.7/fs/ext3/extents.c 2004-09-03 08:46:59.000000000 +0400 -@@ -740,7 +740,7 @@ - for (i = 0; i < depth; i++) { - if (!ablocks[i]) - continue; -- ext3_free_blocks(handle, tree->inode, ablocks[i], 1); -+ ext3_free_blocks(handle, tree->inode, ablocks[i], 1, 1); - } - } - kfree(ablocks); -@@ -1388,7 +1388,7 @@ - path->p_idx->ei_leaf); - bh = sb_find_get_block(tree->inode->i_sb, path->p_idx->ei_leaf); - ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf); -- ext3_free_blocks(handle, tree->inode, path->p_idx->ei_leaf, 1); -+ ext3_free_blocks(handle, tree->inode, path->p_idx->ei_leaf, 1, 1); - return err; - } - -@@ -1876,10 +1876,12 @@ - int needed = ext3_remove_blocks_credits(tree, ex, from, to); - handle_t *handle = ext3_journal_start(tree->inode, needed); - struct buffer_head *bh; -- int i; -+ int i, metadata = 0; - - if (IS_ERR(handle)) - return PTR_ERR(handle); -+ if (S_ISDIR(tree->inode->i_mode)) -+ metadata = 1; - if (from >= ex->ee_block && to == ex->ee_block + ex->ee_len - 1) { - /* tail removal */ - unsigned long num, start; -@@ -1891,7 +1893,7 @@ - bh = sb_find_get_block(tree->inode->i_sb, start + i); - ext3_forget(handle, 0, tree->inode, bh, start + i); - } -- ext3_free_blocks(handle, tree->inode, start, num); -+ ext3_free_blocks(handle, tree->inode, start, num, metadata); - } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { - printk("strange request: removal %lu-%lu from %u:%u\n", - from, to, ex->ee_block, ex->ee_len); -Index: linux-2.6.7/fs/ext3/xattr.c -=================================================================== ---- linux-2.6.7.orig/fs/ext3/xattr.c 2004-09-03 08:46:59.000000000 +0400 -+++ linux-2.6.7/fs/ext3/xattr.c 2004-09-03 08:46:59.000000000 +0400 -@@ -1366,7 +1366,7 @@ - new_bh = sb_getblk(sb, block); - if (!new_bh) { - getblk_failed: -- ext3_free_blocks(handle, inode, block, 1); -+ ext3_free_blocks(handle, inode, block, 1, 1); - error = -EIO; - goto cleanup; - } -@@ -1408,7 +1408,7 @@ - if (HDR(old_bh)->h_refcount == cpu_to_le32(1)) { - /* Free the old block. */ - ea_bdebug(old_bh, "freeing"); -- ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1); -+ ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1, 1); - - /* ext3_forget() calls bforget() for us, but we - let our caller release old_bh, so we need to -@@ -1497,7 +1497,7 @@ - lock_buffer(bh); - if (HDR(bh)->h_refcount == cpu_to_le32(1)) { - ext3_xattr_cache_remove(bh); -- ext3_free_blocks(handle, inode, EXT3_I(inode)->i_file_acl, 1); -+ ext3_free_blocks(handle, inode, EXT3_I(inode)->i_file_acl, 1, 1); - get_bh(bh); - ext3_forget(handle, 1, inode, bh, EXT3_I(inode)->i_file_acl); - } else { -Index: linux-2.6.7/include/linux/ext3_fs.h -=================================================================== ---- linux-2.6.7.orig/include/linux/ext3_fs.h 2004-09-03 08:46:59.000000000 +0400 -+++ linux-2.6.7/include/linux/ext3_fs.h 2004-09-03 08:47:35.000000000 +0400 -@@ -57,6 +57,8 @@ - #define ext3_debug(f, a...) do {} while (0) - #endif - -+#define EXT3_MULTIBLOCK_ALLOCATOR 1 -+ - /* - * Special inodes numbers - */ -@@ -335,6 +337,7 @@ - #define EXT3_MOUNT_IOPEN_NOPRIV 0x80000 /* Make iopen world-readable */ - #define EXT3_MOUNT_EXTENTS 0x100000/* Extents support */ - #define EXT3_MOUNT_EXTDEBUG 0x200000/* Extents debug */ -+#define EXT3_MOUNT_MBALLOC 0x400000/* Buddy allocation support */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef clear_opt -@@ -695,7 +698,7 @@ - extern int ext3_new_block (handle_t *, struct inode *, unsigned long, - __u32 *, __u32 *, int *); - extern void ext3_free_blocks (handle_t *, struct inode *, unsigned long, -- unsigned long); -+ unsigned long, int); - extern unsigned long ext3_count_free_blocks (struct super_block *); - extern void ext3_check_blocks_bitmap (struct super_block *); - extern struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, -Index: linux-2.6.7/include/linux/ext3_fs_sb.h -=================================================================== ---- linux-2.6.7.orig/include/linux/ext3_fs_sb.h 2004-09-03 08:46:59.000000000 +0400 -+++ linux-2.6.7/include/linux/ext3_fs_sb.h 2004-09-03 08:46:59.000000000 +0400 -@@ -23,9 +23,29 @@ - #define EXT_INCLUDE - #include - #include -+#include - #endif - #endif - -+#define EXT3_BB_MAX_BLOCKS 30 -+struct ext3_free_metadata { -+ unsigned short group; -+ unsigned short num; -+ unsigned short blocks[EXT3_BB_MAX_BLOCKS]; -+ struct list_head list; -+}; -+ -+#define EXT3_BB_MAX_ORDER 14 -+ -+struct ext3_buddy_group_blocks { -+ sector_t bb_bitmap; -+ sector_t bb_buddy; -+ spinlock_t bb_lock; -+ unsigned bb_counters[EXT3_BB_MAX_ORDER]; -+ struct ext3_free_metadata *bb_md_cur; -+ unsigned long bb_tid; -+}; -+ - /* - * third extended-fs super-block data in memory - */ -@@ -76,6 +96,17 @@ - char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ - int s_jquota_fmt; /* Format of quota to use */ - #endif -+ -+ /* for buddy allocator */ -+ struct ext3_buddy_group_blocks *s_buddy_blocks; -+ struct inode *s_buddy; -+ long s_blocks_reserved; -+ spinlock_t s_reserve_lock; -+ struct list_head s_active_transaction; -+ struct list_head s_closed_transaction; -+ struct list_head s_committed_transaction; -+ spinlock_t s_md_lock; -+ tid_t s_last_transaction; - }; - - #endif /* _LINUX_EXT3_FS_SB */ diff --git a/lustre/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch b/lustre/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch index fcceb30..dc6ffe3 100644 --- a/lustre/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch +++ b/lustre/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch @@ -2,7 +2,7 @@ Index: linux-stage/fs/ext3/mballoc.c =================================================================== --- linux-stage.orig/fs/ext3/mballoc.c 2005-02-25 17:28:41.836311072 +0200 +++ linux-stage/fs/ext3/mballoc.c 2005-02-25 17:28:41.859307576 +0200 -@@ -0,0 +1,1847 @@ +@@ -0,0 +1,1860 @@ +/* + * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas @@ -39,6 +39,7 @@ Index: linux-stage/fs/ext3/mballoc.c + +/* + * TODO: ++ * - bitmap/buddy read-ahead (proposed by Oleg Drokin aka green) + * - track min/max extents in each group for better group selection + * - is it worthwhile to use buddies directly if req is 2^N blocks? + * - mb_mark_used() may allocate chunk right after splitting buddy @@ -96,7 +97,7 @@ Index: linux-stage/fs/ext3/mballoc.c + __u32 mh_magic; +}; + -+#define EXT3_MB_MAGIC_V1 0xbaad16fc ++#define EXT3_MB_MAGIC_V1 0xbabd16fd + + +struct ext3_free_extent { @@ -148,47 +149,50 @@ Index: linux-stage/fs/ext3/mballoc.c +void ext3_mb_poll_new_transaction(struct super_block *, handle_t *); +void ext3_mb_free_committed_blocks(struct super_block *); + -+#define mb_correct_addr_and_bit(bit,addr) \ -+{ \ -+ if ((unsigned long)addr & 1) { \ -+ bit += 8; \ -+ addr--; \ -+ } \ -+ if ((unsigned long)addr & 2) { \ -+ bit += 16; \ -+ addr--; \ -+ addr--; \ -+ } \ ++#if BITS_PER_LONG == 64 ++#define mb_correct_addr_and_bit(bit,addr) \ ++{ \ ++ bit += ((unsigned long) addr & 7UL) << 3; \ ++ addr = (void *) ((unsigned long) addr & ~7UL); \ +} ++#elif BITS_PER_LONG == 32 ++#define mb_correct_addr_and_bit(bit,addr) \ ++{ \ ++ bit += ((unsigned long) addr & 3UL) << 3; \ ++ addr = (void *) ((unsigned long) addr & ~3UL); \ ++} ++#else ++#error "how many bits you are?!" ++#endif + +static inline int mb_test_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ return test_bit(bit, addr); ++ return ext2_test_bit(bit, addr); +} + +static inline void mb_set_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ __set_bit(bit, addr); ++ ext2_set_bit(bit, addr); +} + +static inline void mb_set_bit_atomic(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ set_bit(bit, addr); ++ ext2_set_bit_atomic(NULL, bit, addr); +} + +static inline void mb_clear_bit(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ __clear_bit(bit, addr); ++ ext2_clear_bit(bit, addr); +} + +static inline void mb_clear_bit_atomic(int bit, void *addr) +{ + mb_correct_addr_and_bit(bit,addr); -+ clear_bit(bit, addr); ++ ext2_clear_bit_atomic(NULL, bit, addr); +} + +static inline void *mb_find_buddy(struct ext3_buddy *e3b, int order, int *max) @@ -199,8 +203,10 @@ Index: linux-stage/fs/ext3/mballoc.c + J_ASSERT(EXT3_MB_BITMAP(e3b) != EXT3_MB_BUDDY(e3b)); + J_ASSERT(max != NULL); + -+ if (order > e3b->bd_blkbits + 1) ++ if (order > e3b->bd_blkbits + 1) { ++ *max = 0; + return NULL; ++ } + + /* at order 0 we see each particular block */ + *max = 1 << (e3b->bd_blkbits + 3); @@ -234,12 +240,6 @@ Index: linux-stage/fs/ext3/mballoc.c + "can't get block for buddy bitmap\n"); + goto out; + } -+ if (!buffer_uptodate(e3b->bd_bh)) { -+ ll_rw_block(READ, 1, &e3b->bd_bh); -+ wait_on_buffer(e3b->bd_bh); -+ } -+ J_ASSERT(buffer_uptodate(e3b->bd_bh)); -+ + /* load buddy */ + e3b->bd_bh2 = sb_getblk(sb, sbi->s_buddy_blocks[group]->bb_buddy); + if (e3b->bd_bh2 == NULL) { @@ -247,10 +247,15 @@ Index: linux-stage/fs/ext3/mballoc.c + "can't get block for buddy bitmap\n"); + goto out; + } -+ if (!buffer_uptodate(e3b->bd_bh2)) { ++ ++ if (!buffer_uptodate(e3b->bd_bh)) ++ ll_rw_block(READ, 1, &e3b->bd_bh); ++ if (!buffer_uptodate(e3b->bd_bh2)) + ll_rw_block(READ, 1, &e3b->bd_bh2); -+ wait_on_buffer(e3b->bd_bh2); -+ } ++ ++ wait_on_buffer(e3b->bd_bh); ++ J_ASSERT(buffer_uptodate(e3b->bd_bh)); ++ wait_on_buffer(e3b->bd_bh2); + J_ASSERT(buffer_uptodate(e3b->bd_bh2)); + + e3b->bd_blkbits = sb->s_blocksize_bits; @@ -300,22 +305,22 @@ Index: linux-stage/fs/ext3/mballoc.c + count = 0; + for (i = 0; i < max; i++) { + -+ if (!mb_test_bit(i, buddy)) { ++ if (mb_test_bit(i, buddy)) { + /* only single bit in buddy2 may be 1 */ -+ if (mb_test_bit(i << 1, buddy2)) -+ J_ASSERT(!mb_test_bit((i<<1)+1, buddy2)); -+ else if (mb_test_bit((i << 1) + 1, buddy2)) -+ J_ASSERT(!mb_test_bit(i << 1, buddy2)); ++ if (!mb_test_bit(i << 1, buddy2)) ++ J_ASSERT(mb_test_bit((i<<1)+1, buddy2)); ++ else if (!mb_test_bit((i << 1) + 1, buddy2)) ++ J_ASSERT(mb_test_bit(i << 1, buddy2)); + continue; + } + + /* both bits in buddy2 must be 0 */ -+ J_ASSERT(!mb_test_bit(i << 1, buddy2)); -+ J_ASSERT(!mb_test_bit((i << 1) + 1, buddy2)); ++ J_ASSERT(mb_test_bit(i << 1, buddy2)); ++ J_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); + + for (j = 0; j < (1 << order); j++) { + k = (i * (1 << order)) + j; -+ J_ASSERT(mb_test_bit(k, EXT3_MB_BITMAP(e3b))); ++ J_ASSERT(!mb_test_bit(k, EXT3_MB_BITMAP(e3b))); + } + count++; + } @@ -325,14 +330,14 @@ Index: linux-stage/fs/ext3/mballoc.c + + buddy = mb_find_buddy(e3b, 0, &max); + for (i = 0; i < max; i++) { -+ if (mb_test_bit(i, buddy)) ++ if (!mb_test_bit(i, buddy)) + continue; + /* check used bits only */ + for (j = 0; j < e3b->bd_blkbits + 1; j++) { + buddy2 = mb_find_buddy(e3b, j, &max2); + k = i >> j; + J_ASSERT(k < max2); -+ J_ASSERT(!mb_test_bit(k, buddy2)); ++ J_ASSERT(mb_test_bit(k, buddy2)); + } + } +} @@ -363,7 +368,7 @@ Index: linux-stage/fs/ext3/mballoc.c + bb = EXT3_MB_BUDDY(e3b); + while (order <= e3b->bd_blkbits + 1) { + block = block >> 1; -+ if (mb_test_bit(block, bb)) { ++ if (!mb_test_bit(block, bb)) { + /* this block is part of buddy of order 'order' */ + return order; + } @@ -424,8 +429,8 @@ Index: linux-stage/fs/ext3/mballoc.c + block = first++; + order = 0; + -+ J_ASSERT(!mb_test_bit(block, EXT3_MB_BITMAP(e3b))); -+ mb_set_bit(block, EXT3_MB_BITMAP(e3b)); ++ J_ASSERT(mb_test_bit(block, EXT3_MB_BITMAP(e3b))); ++ mb_clear_bit(block, EXT3_MB_BITMAP(e3b)); + e3b->bd_bd->bb_counters[order]++; + + /* start of the buddy */ @@ -433,8 +438,8 @@ Index: linux-stage/fs/ext3/mballoc.c + + do { + block &= ~1UL; -+ if (!mb_test_bit(block, buddy) || -+ !mb_test_bit(block + 1, buddy)) ++ if (mb_test_bit(block, buddy) || ++ mb_test_bit(block + 1, buddy)) + break; + + /* both the buddies are free, try to coalesce them */ @@ -444,10 +449,10 @@ Index: linux-stage/fs/ext3/mballoc.c + break; + + if (order > 0) { -+ /* for special purposes, we don't clear ++ /* for special purposes, we don't set + * free bits in bitmap */ -+ mb_clear_bit(block, buddy); -+ mb_clear_bit(block + 1, buddy); ++ mb_set_bit(block, buddy); ++ mb_set_bit(block + 1, buddy); + } + e3b->bd_bd->bb_counters[order]--; + e3b->bd_bd->bb_counters[order]--; @@ -456,7 +461,7 @@ Index: linux-stage/fs/ext3/mballoc.c + order++; + e3b->bd_bd->bb_counters[order]++; + -+ mb_set_bit(block, buddy2); ++ mb_clear_bit(block, buddy2); + buddy = buddy2; + } while (1); + } @@ -476,7 +481,7 @@ Index: linux-stage/fs/ext3/mballoc.c + buddy = mb_find_buddy(e3b, order, &max); + J_ASSERT(buddy); + J_ASSERT(block < max); -+ if (!mb_test_bit(block, buddy)) { ++ if (mb_test_bit(block, buddy)) { + ex->fe_len = 0; + ex->fe_start = 0; + ex->fe_group = 0; @@ -499,7 +504,7 @@ Index: linux-stage/fs/ext3/mballoc.c + break; + + next = (block + 1) * (1 << order); -+ if (!mb_test_bit(next, EXT3_MB_BITMAP(e3b))) ++ if (mb_test_bit(next, EXT3_MB_BITMAP(e3b))) + break; + + ord = mb_find_order_for_block(e3b, next); @@ -533,7 +538,7 @@ Index: linux-stage/fs/ext3/mballoc.c + mlen = 1 << ord; + buddy = mb_find_buddy(e3b, ord, &max); + J_ASSERT((start >> ord) < max); -+ mb_clear_bit(start >> ord, buddy); ++ mb_set_bit(start >> ord, buddy); + e3b->bd_bd->bb_counters[ord]--; + start += mlen; + len -= mlen; @@ -544,20 +549,20 @@ Index: linux-stage/fs/ext3/mballoc.c + /* we have to split large buddy */ + J_ASSERT(ord > 0); + buddy = mb_find_buddy(e3b, ord, &max); -+ mb_clear_bit(start >> ord, buddy); ++ mb_set_bit(start >> ord, buddy); + e3b->bd_bd->bb_counters[ord]--; + + ord--; + cur = (start >> ord) & ~1U; + buddy = mb_find_buddy(e3b, ord, &max); -+ mb_set_bit(cur, buddy); -+ mb_set_bit(cur + 1, buddy); ++ mb_clear_bit(cur, buddy); ++ mb_clear_bit(cur + 1, buddy); + e3b->bd_bd->bb_counters[ord]++; + e3b->bd_bd->bb_counters[ord]++; + } + + /* now drop all the bits in bitmap */ -+ mb_clear_bits(EXT3_MB_BITMAP(e3b), ex->fe_start, len0); ++ mb_set_bits(EXT3_MB_BITMAP(e3b), ex->fe_start, len0); + + mb_check_buddy(e3b); + @@ -733,7 +738,7 @@ Index: linux-stage/fs/ext3/mballoc.c + i = e3b->bd_bd->bb_first_free; + + while (free && ac->ac_status != AC_STATUS_FOUND) { -+ i = find_next_bit(bitmap, sb->s_blocksize * 8, i); ++ i = ext2_find_next_zero_bit(bitmap, sb->s_blocksize * 8, i); + if (i >= sb->s_blocksize * 8) { + J_ASSERT(free == 0); + break; @@ -951,7 +956,6 @@ Index: linux-stage/fs/ext3/mballoc.c + /* + * We aren't lucky definitely + */ -+ J_ASSERT(ac.ac_b_ex.fe_len == 0); + DQUOT_FREE_BLOCK(inode, *len); + *errp = -ENOSPC; + block = 0; @@ -1020,8 +1024,8 @@ Index: linux-stage/fs/ext3/mballoc.c + ext3_error(sb, "ext3_new_block", + "Allocating block in system zone - " + "block = %u", block); -+#if AGGRESSIVE_CHECK -+ for (i = 0; i < ac.ac_b_len; i++) ++#ifdef AGGRESSIVE_CHECK ++ for (i = 0; i < ac.ac_b_ex.fe_len; i++) + J_ASSERT(!mb_test_bit(ac.ac_b_ex.fe_start + i, bitmap_bh->b_data)); +#endif + mb_set_bits(bitmap_bh->b_data, ac.ac_b_ex.fe_start, ac.ac_b_ex.fe_len); @@ -1141,7 +1145,7 @@ Index: linux-stage/fs/ext3/mballoc.c + + e3b->bd_bd->bb_first_free = grp->mgd_first_free; + e3b->bd_bd->bb_free = grp->mgd_free; -+ for (i = 0; i < e3b->bd_blkbits; i++) { ++ for (i = 0; i <= e3b->bd_blkbits + 1; i++) { + J_ASSERT(i < 16); + e3b->bd_bd->bb_counters[i] = grp->mgd_counters[i]; + } @@ -1197,7 +1201,7 @@ Index: linux-stage/fs/ext3/mballoc.c + goto out; + grp->mgd_first_free = e3b->bd_bd->bb_first_free; + grp->mgd_free = e3b->bd_bd->bb_free; -+ for (i = 0; i < e3b->bd_blkbits; i++) { ++ for (i = 0; i <= e3b->bd_blkbits + 1; i++) { + J_ASSERT(i < 16); + grp->mgd_counters[i] = e3b->bd_bd->bb_counters[i]; + } @@ -1217,9 +1221,10 @@ Index: linux-stage/fs/ext3/mballoc.c + struct super_block *sb = e3b->bd_sb; + struct buffer_head *bh; + int i, count = 0; -+ -+ memset(e3b->bd_bh->b_data, 0, sb->s_blocksize); -+ memset(e3b->bd_bh2->b_data, 0, sb->s_blocksize); ++ ++ mb_debug("generate buddy for group %d\n", e3b->bd_group); ++ memset(e3b->bd_bh->b_data, 0xff, sb->s_blocksize); ++ memset(e3b->bd_bh2->b_data, 0xff, sb->s_blocksize); + + bh = read_block_bitmap(sb, e3b->bd_group); + if (bh == NULL) @@ -1748,6 +1753,19 @@ Index: linux-stage/fs/ext3/mballoc.c + if (err) + goto error_return; + ++#ifdef AGGRESSIVE_CHECK ++ { ++ int i; ++ for (i = 0; i < count; i++) ++ J_ASSERT(mb_test_bit(bit + i, bitmap_bh->b_data)); ++ } ++#endif ++ mb_clear_bits(bitmap_bh->b_data, bit, count); ++ ++ /* We dirtied the bitmap block */ ++ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); ++ err = ext3_journal_dirty_metadata(handle, bitmap_bh); ++ + if (metadata) { + /* blocks being freed are metadata. these blocks shouldn't + * be used until this transaction is committed */ @@ -1757,21 +1775,18 @@ Index: linux-stage/fs/ext3/mballoc.c + mb_free_blocks(&e3b, bit, count); + ext3_unlock_group(sb, block_group); + } ++ + spin_lock(sb_bgl_lock(sbi, block_group)); + gdp->bg_free_blocks_count = + cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) + count); + spin_unlock(sb_bgl_lock(sbi, block_group)); ++ percpu_counter_mod(&sbi->s_freeblocks_counter, count); + + ext3_mb_dirty_buddy(&e3b); + ext3_mb_release_desc(&e3b); + -+ mb_clear_bits(bitmap_bh->b_data, bit, count); + *freed = count; + -+ /* We dirtied the bitmap block */ -+ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); -+ err = ext3_journal_dirty_metadata(handle, bitmap_bh); -+ + /* And the group descriptor block */ + BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); + ret = ext3_journal_dirty_metadata(handle, gd_bh); @@ -1833,7 +1848,6 @@ Index: linux-stage/fs/ext3/mballoc.c + return ret; +} + -+ +void ext3_free_blocks(handle_t *handle, struct inode * inode, + unsigned long block, unsigned long count, int metadata) +{ @@ -1849,7 +1863,6 @@ Index: linux-stage/fs/ext3/mballoc.c + DQUOT_FREE_BLOCK(inode, freed); + return; +} -+ Index: linux-stage/fs/ext3/super.c =================================================================== --- linux-stage.orig/fs/ext3/super.c 2005-02-25 17:27:00.231757312 +0200 @@ -1859,7 +1872,7 @@ Index: linux-stage/fs/ext3/super.c int i; + ext3_mb_release(sb); - ext3_ext_release(sb); + ext3_ext_release(sb); ext3_xattr_put_super(sb); journal_destroy(sbi->s_journal); @@ -592,7 +593,7 @@ @@ -1897,16 +1910,14 @@ Index: linux-stage/fs/ext3/super.c default: printk (KERN_ERR "EXT3-fs: Unrecognized mount option \"%s\" " -@@ -1639,7 +1652,8 @@ +@@ -1639,6 +1652,7 @@ ext3_count_dirs(sb)); - ext3_ext_init(sb); -- + ext3_ext_init(sb); + ext3_mb_init(sb, needs_recovery); -+ + return 0; - failed_mount3: Index: linux-stage/fs/ext3/Makefile =================================================================== --- linux-stage.orig/fs/ext3/Makefile 2005-02-25 17:27:00.228757768 +0200 @@ -2122,8 +2133,8 @@ Index: linux-stage/include/linux/ext3_fs.h #define EXT3_MOUNT_EXTDEBUG 0x200000/* Extents debug */ +#define EXT3_MOUNT_MBALLOC 0x400000/* Buddy allocation support */ - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ + #ifndef _LINUX_EXT2_FS_H @@ -725,7 +734,7 @@ extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group); extern int ext3_new_block (handle_t *, struct inode *, unsigned long, int *); @@ -2184,7 +2195,7 @@ Index: linux-stage/include/linux/ext3_fs_sb.h #endif #include -+#define EXT3_BB_MAX_BLOCKS 30 ++#define EXT3_BB_MAX_BLOCKS 30 +struct ext3_free_metadata { + unsigned short group; + unsigned short num; @@ -2222,7 +2233,7 @@ Index: linux-stage/include/linux/ext3_fs_sb.h + spinlock_t s_md_lock; + tid_t s_last_transaction; + int s_mb_factor; -+ ++ + /* stats for buddy allocator */ + spinlock_t s_bal_lock; + unsigned long s_bal_reqs; /* number of reqs with len > 1 */ diff --git a/lustre/kernel_patches/patches/ext3-o_direct-1.2.4.20-rh.patch b/lustre/kernel_patches/patches/ext3-o_direct-1.2.4.20-rh.patch deleted file mode 100644 index 3aff4c5..0000000 --- a/lustre/kernel_patches/patches/ext3-o_direct-1.2.4.20-rh.patch +++ /dev/null @@ -1,197 +0,0 @@ - -Index: linux-2.4.20-rh/fs/ext3/inode.c -=================================================================== ---- linux-2.4.20-rh.orig/fs/ext3/inode.c 2003-09-04 18:01:41.000000000 +0800 -+++ linux-2.4.20-rh/fs/ext3/inode.c 2003-09-04 18:18:54.000000000 +0800 -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -743,9 +744,9 @@ - * The BKL may not be held on entry here. Be sure to take it early. - */ - --static int ext3_get_block_handle(handle_t *handle, struct inode *inode, -- long iblock, -- struct buffer_head *bh_result, int create) -+static int -+ext3_get_block_handle(handle_t *handle, struct inode *inode, long iblock, -+ struct buffer_head *bh_result, int create, int extend_disksize) - { - int err = -EIO; - int offsets[4]; -@@ -825,15 +826,18 @@ - if (err) - goto cleanup; - -- new_size = inode->i_size; -- /* -- * This is not racy against ext3_truncate's modification of i_disksize -- * because VM/VFS ensures that the file cannot be extended while -- * 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 (extend_disksize) { -+ /* -+ * This is not racy against ext3_truncate's modification of -+ * i_disksize because VM/VFS ensures that the file cannot be -+ * extended while truncate is in progress. It is racy between -+ * multiple parallel instances of get_block, but we have BKL. -+ */ -+ struct ext3_inode_info *ei = EXT3_I(inode); -+ new_size = inode->i_size; -+ if (new_size > ei->i_disksize) -+ ei->i_disksize = new_size; -+ } - - bh_result->b_state |= (1UL << BH_New); - goto got_it; -@@ -861,7 +865,38 @@ - handle = ext3_journal_current_handle(); - J_ASSERT(handle != 0); - } -- ret = ext3_get_block_handle(handle, inode, iblock, bh_result, create); -+ ret = ext3_get_block_handle(handle, inode, iblock, -+ bh_result, create, 1); -+ return ret; -+} -+ -+#define DIO_CREDITS (EXT3_RESERVE_TRANS_BLOCKS + 32) -+ -+static int -+ext3_direct_io_get_block(struct inode *inode, long iblock, -+ struct buffer_head *bh_result, int create) -+{ -+ handle_t *handle = journal_current_handle(); -+ int ret = 0; -+ -+ lock_kernel(); -+ if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) { -+ /* -+ * Getting low on buffer credits... -+ */ -+ if (!ext3_journal_extend(handle, DIO_CREDITS)) { -+ /* -+ * Couldn't extend the transaction. Start a new one -+ */ -+ ret = ext3_journal_restart(handle, DIO_CREDITS); -+ } -+ } -+ if (ret == 0) -+ ret = ext3_get_block_handle(handle, inode, iblock, -+ bh_result, create, 0); -+ if (ret == 0) -+ bh_result->b_size = (1 << inode->i_blkbits); -+ unlock_kernel(); - return ret; - } - -@@ -879,7 +914,7 @@ - dummy.b_state = 0; - dummy.b_blocknr = -1000; - buffer_trace_init(&dummy.b_history); -- *errp = ext3_get_block_handle(handle, inode, block, &dummy, create); -+ *errp = ext3_get_block_handle(handle, inode, block, &dummy, create, 1); - if (!*errp && buffer_mapped(&dummy)) { - struct buffer_head *bh; - bh = sb_getblk(inode->i_sb, dummy.b_blocknr); -@@ -1387,6 +1422,67 @@ - return journal_try_to_free_buffers(journal, page, wait); - } - -+static int -+ext3_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf, -+ unsigned long blocknr, int blocksize) -+{ -+ struct ext3_inode_info *ei = EXT3_I(inode); -+ handle_t *handle = NULL; -+ int ret; -+ int orphan = 0; -+ loff_t offset = (loff_t)blocknr << inode->i_blkbits; /* ugh */ -+ ssize_t count = iobuf->length; /* ditto */ -+ -+ if (rw == WRITE) { -+ loff_t final_size = offset + count; -+ -+ lock_kernel(); -+ handle = ext3_journal_start(inode, DIO_CREDITS); -+ unlock_kernel(); -+ if (IS_ERR(handle)) { -+ ret = PTR_ERR(handle); -+ goto out; -+ } -+ if (final_size > inode->i_size) { -+ lock_kernel(); -+ ret = ext3_orphan_add(handle, inode); -+ unlock_kernel(); -+ if (ret) -+ goto out_stop; -+ orphan = 1; -+ ei->i_disksize = inode->i_size; -+ } -+ } -+ -+ ret = generic_direct_IO(rw, inode, iobuf, blocknr, -+ blocksize, ext3_direct_io_get_block); -+ -+out_stop: -+ if (handle) { -+ int err; -+ -+ lock_kernel(); -+ if (orphan) -+ ext3_orphan_del(handle, inode); -+ if (orphan && ret > 0) { -+ loff_t end = offset + ret; -+ if (end > inode->i_size) { -+ ei->i_disksize = end; -+ inode->i_size = end; -+ err = ext3_mark_inode_dirty(handle, inode); -+ if (!ret) -+ ret = err; -+ } -+ } -+ err = ext3_journal_stop(handle, inode); -+ if (ret == 0) -+ ret = err; -+ unlock_kernel(); -+ } -+out: -+ return ret; -+ -+} - - struct address_space_operations ext3_aops = { - readpage: ext3_readpage, /* BKL not held. Don't need */ -@@ -1397,6 +1493,7 @@ - bmap: ext3_bmap, /* BKL held */ - flushpage: ext3_flushpage, /* BKL not held. Don't need */ - releasepage: ext3_releasepage, /* BKL not held. Don't need */ -+ direct_IO: ext3_direct_IO, /* BKL not held. Don't need */ - }; - - /* -@@ -2970,7 +3067,7 @@ - /* alloc blocks one by one */ - for (i = 0; i < nblocks; i++) { - ret = ext3_get_block_handle(handle, inode, blocks[i], -- &bh_tmp, 1); -+ &bh_tmp, 1, 1); - if (ret) - break; - -@@ -3030,7 +3127,7 @@ - if (blocks[i] != 0) - continue; - -- rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1); -+ rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1, 1); - if (rc) { - printk(KERN_INFO "ext3_map_inode_page: error %d " - "allocating block %ld\n", rc, iblock); diff --git a/lustre/kernel_patches/patches/ext3-orphan_lock-suse.patch b/lustre/kernel_patches/patches/ext3-orphan_lock-suse.patch deleted file mode 100644 index c3369e6..0000000 --- a/lustre/kernel_patches/patches/ext3-orphan_lock-suse.patch +++ /dev/null @@ -1,81 +0,0 @@ -Index: linux-2.4.21-suse/fs/ext3/namei.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/namei.c 2003-10-30 02:17:22.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/namei.c 2003-10-30 02:20:53.000000000 +0300 -@@ -1747,8 +1747,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; - -@@ -1796,7 +1796,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; - } -@@ -1808,20 +1808,19 @@ - int ext3_orphan_del(handle_t *handle, struct inode *inode) - { - struct list_head *prev; -- 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(&inode->u.ext3_i.i_orphan)) { -- unlock_super(inode->i_sb); -+ up(&sbi->s_orphan_lock); - return 0; - } - - ino_next = NEXT_ORPHAN(inode); - prev = inode->u.ext3_i.i_orphan.prev; -- sbi = EXT3_SB(inode->i_sb); - - jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino); - -@@ -1870,7 +1869,7 @@ - out_err: - ext3_std_error(inode->i_sb, err); - out: -- unlock_super(inode->i_sb); -+ up(&sbi->s_orphan_lock); - return err; - - out_brelse: -Index: linux-2.4.21-suse/fs/ext3/super.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/super.c 2003-10-30 02:17:22.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/super.c 2003-10-30 02:17:22.000000000 +0300 -@@ -1151,6 +1151,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; - -Index: linux-2.4.21-suse/include/linux/ext3_fs_sb.h -=================================================================== ---- linux-2.4.21-suse.orig/include/linux/ext3_fs_sb.h 2003-10-30 02:17:22.000000000 +0300 -+++ linux-2.4.21-suse/include/linux/ext3_fs_sb.h 2003-10-30 02:17:22.000000000 +0300 -@@ -69,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-pdirops-2.4.20-rh.patch b/lustre/kernel_patches/patches/ext3-pdirops-2.4.20-rh.patch deleted file mode 100644 index 2733e7d..0000000 --- a/lustre/kernel_patches/patches/ext3-pdirops-2.4.20-rh.patch +++ /dev/null @@ -1,1248 +0,0 @@ - fs/ext3/ialloc.c | 3 - fs/ext3/inode.c | 3 - fs/ext3/namei.c | 582 +++++++++++++++++++++++++++++++++++++--------- - fs/ext3/super.c | 14 + - include/linux/ext3_fs.h | 1 - include/linux/ext3_fs_i.h | 6 - 6 files changed, 500 insertions(+), 109 deletions(-) - -Index: linux-2.4.20/fs/ext3/namei.c -=================================================================== ---- linux-2.4.20.orig/fs/ext3/namei.c 2004-05-27 15:10:40.000000000 -0400 -+++ linux-2.4.20/fs/ext3/namei.c 2004-05-27 15:29:52.000000000 -0400 -@@ -51,6 +51,9 @@ - { - struct buffer_head *bh; - -+ /* with parallel dir operations all appends -+ * have to be serialized -bzzz */ -+ down(&EXT3_I(inode)->i_append_sem); - *block = inode->i_size >> inode->i_sb->s_blocksize_bits; - - if ((bh = ext3_bread(handle, inode, *block, 1, err))) { -@@ -58,6 +61,8 @@ - EXT3_I(inode)->i_disksize = inode->i_size; - ext3_journal_get_write_access(handle,bh); - } -+ up(&EXT3_I(inode)->i_append_sem); -+ - return bh; - } - -@@ -134,6 +139,8 @@ - struct buffer_head *bh; - struct dx_entry *entries; - struct dx_entry *at; -+ unsigned long leaf; -+ unsigned int curidx; - }; - - struct dx_map_entry -@@ -142,6 +149,30 @@ - u32 offs; - }; - -+/* FIXME: this should be reworked using bb_spin_lock -+ * introduced in -mm tree -+ */ -+#define BH_DXLock 25 -+ -+static inline void dx_lock_bh(struct buffer_head volatile *bh) -+{ -+#ifdef CONFIG_SMP -+ while (test_and_set_bit(BH_DXLock, &bh->b_state)) { -+ while (test_bit(BH_DXLock, &bh->b_state)) -+ cpu_relax(); -+ } -+#endif -+} -+ -+static inline void dx_unlock_bh(struct buffer_head *bh) -+{ -+#ifdef CONFIG_SMP -+ smp_mb__before_clear_bit(); -+ clear_bit(BH_DXLock, &bh->b_state); -+#endif -+} -+ -+ - #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); -@@ -153,7 +184,7 @@ - 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, -+static struct dx_frame *dx_probe(struct qstr *name, - struct inode *dir, - struct dx_hash_info *hinfo, - struct dx_frame *frame, -@@ -165,15 +196,18 @@ - 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 void dx_insert_block (struct inode *, struct dx_frame *, u32, u32, u32); - 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); -+ struct ext3_dir_entry_2 **res_dir, int *err, -+ int rwlock, void **lock); - static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, - struct inode *inode); -+static inline void *ext3_lock_htree(struct inode *, unsigned long, int); -+static inline void ext3_unlock_htree(struct inode *, void *); - - /* - * Future: use high four bits of block for coalesce-on-delete flags -@@ -306,6 +340,94 @@ - #endif /* DX_DEBUG */ - - /* -+ * dx_find_position -+ * -+ * search position of specified hash in index -+ * -+ */ -+ -+struct dx_entry * dx_find_position(struct dx_entry * entries, u32 hash) -+{ -+ struct dx_entry *p, *q, *m; -+ int count; -+ -+ count = dx_get_count(entries); -+ p = entries + 1; -+ q = entries + count - 1; -+ while (p <= q) -+ { -+ m = p + (q - p)/2; -+ if (dx_get_hash(m) > hash) -+ q = m - 1; -+ else -+ p = m + 1; -+ } -+ return p - 1; -+} -+ -+/* -+ * returns 1 if path is unchanged -+ */ -+int dx_check_path(struct dx_frame *frame, u32 hash) -+{ -+ struct dx_entry *p; -+ int ret = 1; -+ -+ dx_lock_bh(frame->bh); -+ p = dx_find_position(frame->entries, hash); -+ if (frame->leaf != dx_get_block(p)) -+ ret = 0; -+ dx_unlock_bh(frame->bh); -+ -+ return ret; -+} -+ -+/* -+ * 0 - changed -+ * 1 - hasn't changed -+ */ -+static int -+dx_check_full_path(struct dx_frame *frames, struct dx_hash_info *hinfo) -+{ -+ struct dx_entry *p; -+ struct dx_frame *frame = frames; -+ u32 leaf; -+ -+ /* check first level */ -+ dx_lock_bh(frame->bh); -+ p = dx_find_position(frame->entries, hinfo->hash); -+ leaf = dx_get_block(p); -+ dx_unlock_bh(frame->bh); -+ -+ if (leaf != frame->leaf) -+ return 0; -+ -+ /* is there 2nd level? */ -+ frame++; -+ if (frame->bh == NULL) -+ return 1; -+ -+ /* check second level */ -+ dx_lock_bh(frame->bh); -+ -+ /* probably 1st level got changed, check it */ -+ if (!dx_check_path(frames, hinfo->hash)) { -+ /* path changed */ -+ dx_unlock_bh(frame->bh); -+ return 0; -+ } -+ -+ p = dx_find_position(frame->entries, hinfo->hash); -+ leaf = dx_get_block(p); -+ dx_unlock_bh(frame->bh); -+ -+ if (leaf != frame->leaf) -+ return 0; -+ -+ return 1; -+} -+ -+/* - * Probe for a directory leaf block to search. - * - * dx_probe can return ERR_BAD_DX_DIR, which means there was a format -@@ -315,19 +437,20 @@ - * back to userspace. - */ - static struct dx_frame * --dx_probe(struct dentry *dentry, struct inode *dir, -+dx_probe(struct qstr *name, 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; -+ unsigned indirect; -+ struct dx_entry *at, *entries; - struct dx_root *root; - struct buffer_head *bh; - struct dx_frame *frame = frame_in; - u32 hash; -+ unsigned int curidx; - - frame->bh = NULL; -- if (dentry) -- dir = dentry->d_parent->d_inode; -+ frame[1].bh = NULL; -+ - if (!(bh = ext3_bread (NULL,dir, 0, 0, err))) - goto fail; - root = (struct dx_root *) bh->b_data; -@@ -343,8 +466,8 @@ - } - 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); -+ if (name) -+ ext3fs_dirhash(name->name, name->len, hinfo); - hash = hinfo->hash; - - if (root->info.unused_flags & 1) { -@@ -356,7 +479,19 @@ - goto fail; - } - -+repeat: -+ curidx = 0; -+ 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)); -+ dx_lock_bh(bh); -+ /* indirect must be initialized under bh lock because -+ * 2nd level creation procedure may change it and dx_probe() -+ * will suggest htree is still single-level -bzzz */ - if ((indirect = root->info.indirect_levels) > 1) { -+ dx_unlock_bh(bh); - ext3_warning(dir->i_sb, __FUNCTION__, - "Unimplemented inode hash depth: %#06x", - root->info.indirect_levels); -@@ -364,56 +499,46 @@ - *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))); -+ at = dx_find_position(entries, hinfo->hash); -+ 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))) -+ frame->curidx = curidx; -+ frame->leaf = dx_get_block(at); -+ if (!indirect--) { -+ dx_unlock_bh(bh); -+ return frame; -+ } -+ -+ /* step into next htree level */ -+ curidx = dx_get_block(at); -+ dx_unlock_bh(bh); -+ if (!(bh = ext3_bread (NULL,dir, frame->leaf, 0, err))) - goto fail2; -+ -+ dx_lock_bh(bh); -+ /* splitting may change root index block and move -+ * hash we're looking for into another index block -+ * so, we have to check this situation and repeat -+ * from begining if path got changed -bzzz */ -+ if (!dx_check_path(frame, hash)) { -+ dx_unlock_bh(bh); -+ bh = frame->bh; -+ indirect++; -+ goto repeat; -+ } -+ - at = entries = ((struct dx_node *) bh->b_data)->entries; - assert (dx_get_limit(entries) == dx_node_limit (dir)); - frame++; - } -+ dx_unlock_bh(bh); - fail2: - while (frame >= frame_in) { - brelse(frame->bh); -@@ -427,8 +552,7 @@ - { - if (frames[0].bh == NULL) - return; -- -- if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels) -+ if (frames[1].bh != NULL) - brelse(frames[1].bh); - brelse(frames[0].bh); - } -@@ -470,8 +594,10 @@ - * nodes need to be read. - */ - while (1) { -- if (++(p->at) < p->entries + dx_get_count(p->entries)) -+ if (++(p->at) < p->entries + dx_get_count(p->entries)) { -+ p->leaf = dx_get_block(p->at); - break; -+ } - if (p == frames) - return 0; - num_frames++; -@@ -497,13 +623,17 @@ - * block so no check is necessary - */ - while (num_frames--) { -- if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at), -- 0, err))) -+ u32 idx; -+ -+ idx = p->leaf = dx_get_block(p->at); -+ if (!(bh = ext3_bread(NULL, dir, idx, 0, err))) - return -1; /* Failure */ - p++; - brelse (p->bh); - p->bh = bh; - p->at = p->entries = ((struct dx_node *) bh->b_data)->entries; -+ p->curidx = idx; -+ p->leaf = dx_get_block(p->at); - } - return 1; - } -@@ -543,7 +673,7 @@ - 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); -+ frame = dx_probe(NULL, dir_file->f_dentry->d_inode, &hinfo, frames, &err); - if (!frame) - return err; - -@@ -625,7 +755,8 @@ - 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)); -+ de = (struct ext3_dir_entry_2 *)((char*)de + -+ le16_to_cpu(de->rec_len)); - } - return count; - } -@@ -658,7 +789,8 @@ - } while(more); - } - --static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block) -+static void dx_insert_block(struct inode *dir, struct dx_frame *frame, -+ u32 hash, u32 block, u32 idx) - { - struct dx_entry *entries = frame->entries; - struct dx_entry *old = frame->at, *new = old + 1; -@@ -670,6 +802,7 @@ - dx_set_hash(new, hash); - dx_set_block(new, block); - dx_set_count(entries, count + 1); -+ - } - #endif - -@@ -752,7 +885,8 @@ - - - static struct buffer_head * ext3_find_entry (struct dentry *dentry, -- struct ext3_dir_entry_2 ** res_dir) -+ struct ext3_dir_entry_2 ** res_dir, -+ int rwlock, void **lock) - { - struct super_block * sb; - struct buffer_head * bh_use[NAMEI_RA_SIZE]; -@@ -768,6 +902,7 @@ - int namelen; - const u8 *name; - unsigned blocksize; -+ int do_not_use_dx = 0; - - *res_dir = NULL; - sb = dir->i_sb; -@@ -776,9 +911,10 @@ - name = dentry->d_name.name; - if (namelen > EXT3_NAME_LEN) - return NULL; -+repeat: - #ifdef CONFIG_EXT3_INDEX - if (is_dx(dir)) { -- bh = ext3_dx_find_entry(dentry, res_dir, &err); -+ bh = ext3_dx_find_entry(dentry, res_dir, &err, rwlock, lock); - /* - * On success, or if the error was file not found, - * return. Otherwise, fall back to doing a search the -@@ -787,8 +923,14 @@ - if (bh || (err != ERR_BAD_DX_DIR)) - return bh; - dxtrace(printk("ext3_find_entry: dx failed, falling back\n")); -+ do_not_use_dx = 1; - } - #endif -+ *lock = ext3_lock_htree(dir, 0, rwlock); -+ if (is_dx(dir) && !do_not_use_dx) { -+ ext3_unlock_htree(dir, *lock); -+ goto repeat; -+ } - nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb); - start = EXT3_I(dir)->i_dir_start_lookup; - if (start >= nblocks) -@@ -860,12 +1002,17 @@ - /* Clean up the read-ahead blocks */ - for (; ra_ptr < ra_max; ra_ptr++) - brelse (bh_use[ra_ptr]); -+ if (!ret) { -+ ext3_unlock_htree(dir, *lock); -+ *lock = NULL; -+ } - 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 ext3_dir_entry_2 **res_dir, int *err, -+ int rwlock, void **lock) - { - struct super_block * sb; - struct dx_hash_info hinfo; -@@ -880,11 +1027,22 @@ - struct inode *dir = dentry->d_parent->d_inode; - - sb = dir->i_sb; -- if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err))) -+repeat: -+ if (!(frame = dx_probe (&dentry->d_name, dir, &hinfo, frames, err))) - return NULL; -+ -+ *lock = ext3_lock_htree(dir, frame->leaf, rwlock); -+ /* while locking leaf we just found may get splitted -+ * so, we need another leaf. check this */ -+ if (!dx_check_full_path(frames, &hinfo)) { -+ ext3_unlock_htree(dir, *lock); -+ dx_release(frames); -+ goto repeat; -+ } -+ - hash = hinfo.hash; - do { -- block = dx_get_block(frame->at); -+ block = frame->leaf; - if (!(bh = ext3_bread (NULL,dir, block, 0, err))) - goto errout; - de = (struct ext3_dir_entry_2 *) bh->b_data; -@@ -918,6 +1076,8 @@ - *err = -ENOENT; - errout: - dxtrace(printk("%s not found\n", name)); -+ ext3_unlock_htree(dir, *lock); -+ *lock = NULL; - dx_release (frames); - return NULL; - } -@@ -928,6 +1088,7 @@ - struct inode * inode; - struct ext3_dir_entry_2 * de; - struct buffer_head * bh; -+ void *lock = NULL; - - if (dentry->d_name.len > EXT3_NAME_LEN) - return ERR_PTR(-ENAMETOOLONG); -@@ -935,10 +1096,11 @@ - if (ext3_check_for_iopen(dir, dentry)) - return NULL; - -- bh = ext3_find_entry(dentry, &de); -+ bh = ext3_find_entry(dentry, &de, 0, &lock); - inode = NULL; - if (bh) { - unsigned long ino = le32_to_cpu(de->inode); -+ ext3_unlock_htree(dir, lock); - brelse (bh); - inode = iget(dir->i_sb, ino); - -@@ -975,7 +1137,8 @@ - unsigned rec_len = 0; - - while (count--) { -- struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs); -+ 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; -@@ -988,7 +1151,8 @@ - - 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; -+ struct ext3_dir_entry_2 *next, *to, *prev; -+ struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) base; - unsigned rec_len = 0; - - prev = to = de; -@@ -1010,7 +1174,8 @@ - - 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) -+ struct dx_hash_info *hinfo, void **target, -+ int *error) - { - unsigned blocksize = dir->i_sb->s_blocksize; - unsigned count, continued; -@@ -1057,23 +1222,30 @@ - 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)); -- -+ frame->leaf, 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)); -+ 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? */ -+ *target = NULL; - if (hinfo->hash >= hash2) - { - swap(*bh, bh2); - de = de2; -- } -- dx_insert_block (frame, hash2 + continued, newblock); -+ -+ /* entry will be stored into new block -+ * we have to lock it before add_dirent_to_buf */ -+ *target = ext3_lock_htree(dir, newblock, 1); -+ } -+ dx_lock_bh(frame->bh); -+ dx_insert_block (dir, frame, hash2 + continued, newblock, frame->curidx); -+ dx_unlock_bh(frame->bh); - err = ext3_journal_dirty_metadata (handle, bh2); - if (err) - goto journal_error; -@@ -1147,7 +1319,8 @@ - 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); -+ 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; -@@ -1205,7 +1378,8 @@ - unsigned blocksize; - struct dx_hash_info hinfo; - u32 block; -- -+ void *lock, *new_lock; -+ - blocksize = dir->i_sb->s_blocksize; - dxtrace(printk("Creating index\n")); - retval = ext3_journal_get_write_access(handle, bh); -@@ -1216,7 +1390,6 @@ - } - 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); -@@ -1224,6 +1397,8 @@ - } - data1 = bh2->b_data; - -+ lock = ext3_lock_htree(dir, block, 1); -+ - /* The 0th block becomes the root, move the dirents out */ - de = (struct ext3_dir_entry_2 *) &root->dotdot; - de = (struct ext3_dir_entry_2 *) ((char *)de + de->rec_len); -@@ -1253,13 +1428,25 @@ - frame->entries = entries; - frame->at = entries; - frame->bh = bh; -+ frame->curidx = 0; -+ frame->leaf = 0; -+ frame[1].bh = NULL; - bh = bh2; -- de = do_split(handle,dir, &bh, frame, &hinfo, &retval); -+ de = do_split(handle,dir, &bh, frame, &hinfo, &new_lock, &retval); - dx_release (frames); - if (!(de)) -- return retval; -+ goto cleanup; -+ -+ retval = add_dirent_to_buf(handle, dentry, inode, de, bh); -+cleanup: -+ if (new_lock) -+ ext3_unlock_htree(dir, new_lock); -+ /* we mark directory indexed in order to -+ * avoid races while htree being created -bzzz */ -+ EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; -+ ext3_unlock_htree(dir, lock); - -- return add_dirent_to_buf(handle, dentry, inode, de, bh); -+ return retval; - } - #endif - -@@ -1288,11 +1475,13 @@ - unsigned blocksize; - unsigned nlen, rlen; - u32 block, blocks; -+ void *lock; - - sb = dir->i_sb; - blocksize = sb->s_blocksize; - if (!dentry->d_name.len) - return -EINVAL; -+repeat: - #ifdef CONFIG_EXT3_INDEX - if (is_dx(dir)) { - retval = ext3_dx_add_entry(handle, dentry, inode); -@@ -1303,36 +1492,53 @@ - ext3_mark_inode_dirty(handle, dir); - } - #endif -+ lock = ext3_lock_htree(dir, 0, 1); -+ if (is_dx(dir)) { -+ /* we got lock for block 0 -+ * probably previous holder of the lock -+ * created htree -bzzz */ -+ ext3_unlock_htree(dir, lock); -+ goto repeat; -+ } -+ - 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) -+ if(!bh) { -+ ext3_unlock_htree(dir, lock); - return retval; -+ } - retval = add_dirent_to_buf(handle, dentry, inode, 0, bh); -- if (retval != -ENOSPC) -+ if (retval != -ENOSPC) { -+ ext3_unlock_htree(dir, lock); - 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); -+ EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) { -+ retval = make_indexed_dir(handle, dentry, inode, bh); -+ ext3_unlock_htree(dir, lock); -+ return retval; -+ } - #endif - brelse(bh); - } - bh = ext3_append(handle, dir, &block, &retval); -- if (!bh) -+ if (!bh) { -+ ext3_unlock_htree(dir, lock); - 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); -+ retval = add_dirent_to_buf(handle, dentry, inode, de, bh); -+ ext3_unlock_htree(dir, lock); -+ return retval; - } - - #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) - { -@@ -1344,15 +1550,28 @@ - struct super_block * sb = dir->i_sb; - struct ext3_dir_entry_2 *de; - int err; -- -- frame = dx_probe(dentry, 0, &hinfo, frames, &err); -+ int curidx; -+ void *idx_lock, *leaf_lock, *newleaf_lock; -+ -+repeat: -+ frame = dx_probe(&dentry->d_name, dir, &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))) -+ /* we're going to chage leaf, so lock it first */ -+ leaf_lock = ext3_lock_htree(dir, frame->leaf, 1); -+ -+ /* while locking leaf we just found may get splitted -+ * so we need to check this */ -+ if (!dx_check_full_path(frames, &hinfo)) { -+ ext3_unlock_htree(dir, leaf_lock); -+ dx_release(frames); -+ goto repeat; -+ } -+ if (!(bh = ext3_bread(handle,dir, frame->leaf, 0, &err))) { -+ printk("can't ext3_bread(%d) = %d\n", (int) frame->leaf, err); - goto cleanup; -+ } - - BUFFER_TRACE(bh, "get_write_access"); - err = ext3_journal_get_write_access(handle, bh); -@@ -1365,6 +1584,35 @@ - goto cleanup; - } - -+ /* our leaf has no enough space. hence, we have to -+ * split it. so lock index for this leaf first */ -+ curidx = frame->curidx; -+ idx_lock = ext3_lock_htree(dir, curidx, 1); -+ -+ /* now check did path get changed? */ -+ dx_release(frames); -+ -+ frame = dx_probe(&dentry->d_name, dentry->d_parent->d_inode, -+ &hinfo, frames, &err); -+ if (!frame) { -+ /* FIXME: error handling here */ -+ brelse(bh); -+ ext3_unlock_htree(dir, idx_lock); -+ return err; -+ } -+ -+ if (frame->curidx != curidx) { -+ /* path has been changed. we have to drop old lock -+ * and repeat */ -+ brelse(bh); -+ ext3_unlock_htree(dir, idx_lock); -+ ext3_unlock_htree(dir, leaf_lock); -+ dx_release(frames); -+ goto repeat; -+ } -+ entries = frame->entries; -+ at = frame->at; -+ - /* 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))); -@@ -1376,7 +1624,8 @@ - struct dx_entry *entries2; - struct dx_node *node2; - struct buffer_head *bh2; -- -+ void *nb_lock; -+ - if (levels && (dx_get_count(frames->entries) == - dx_get_limit(frames->entries))) { - ext3_warning(sb, __FUNCTION__, -@@ -1387,6 +1636,7 @@ - bh2 = ext3_append (handle, dir, &newblock, &err); - if (!(bh2)) - goto cleanup; -+ nb_lock = ext3_lock_htree(dir, newblock, 1); - node2 = (struct dx_node *)(bh2->b_data); - entries2 = node2->entries; - node2->fake.rec_len = cpu_to_le16(sb->s_blocksize); -@@ -1398,27 +1648,73 @@ - if (levels) { - unsigned icount1 = icount/2, icount2 = icount - icount1; - unsigned hash2 = dx_get_hash(entries + icount1); -+ void *ri_lock; -+ -+ /* we have to protect root htree index against -+ * another dx_add_entry() which would want to -+ * split it too -bzzz */ -+ ri_lock = ext3_lock_htree(dir, 0, 1); -+ -+ /* as root index block blocked we must repeat -+ * searching for current position of our 2nd index -bzzz */ -+ dx_lock_bh(frame->bh); -+ frames->at = dx_find_position(frames->entries, hinfo.hash); -+ dx_unlock_bh(frame->bh); -+ - dxtrace(printk("Split index %i/%i\n", icount1, icount2)); -- -- BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */ -+ -+ BUFFER_TRACE(frame->bh, "get_write_access"); - err = ext3_journal_get_write_access(handle, - frames[0].bh); - if (err) - goto journal_error; -- -+ -+ /* copy index into new one */ - 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) { -+ /* unlock index we won't use */ -+ ext3_unlock_htree(dir, idx_lock); -+ idx_lock = nb_lock; - frame->at = at = at - entries - icount1 + entries2; -- frame->entries = entries = entries2; -+ frame->entries = entries2; -+ frame->curidx = curidx = newblock; - swap(frame->bh, bh2); -+ } else { -+ /* we'll use old index,so new one may be freed */ -+ ext3_unlock_htree(dir, nb_lock); - } -- dx_insert_block (frames + 0, hash2, newblock); -+ -+ /* NOTE: very subtle piece of code -+ * competing dx_probe() may find 2nd level index in root -+ * index, then we insert new index here and set new count -+ * in that 2nd level index. so, dx_probe() may see 2nd -+ * level index w/o hash it looks for. the solution is -+ * to check root index after we locked just founded 2nd -+ * level index -bzzz */ -+ dx_lock_bh(frames[0].bh); -+ dx_insert_block (dir, frames + 0, hash2, newblock, 0); -+ dx_unlock_bh(frames[0].bh); -+ -+ /* now old and new 2nd level index blocks contain -+ * all pointers, so dx_probe() may find it in the both. -+ * it's OK -bzzz */ -+ -+ dx_lock_bh(frame->bh); -+ dx_set_count(entries, icount1); -+ dx_unlock_bh(frame->bh); -+ -+ /* now old 2nd level index block points to first half -+ * of leafs. it's importand that dx_probe() must -+ * check root index block for changes under -+ * dx_lock_bh(frame->bh) -bzzz */ -+ -+ ext3_unlock_htree(dir, ri_lock); -+ - dxtrace(dx_show_index ("node", frames[1].entries)); - dxtrace(dx_show_index ("node", - ((struct dx_node *) bh2->b_data)->entries)); -@@ -1427,38 +1723,61 @@ - goto journal_error; - brelse (bh2); - } else { -+ unsigned long leaf = frame->leaf; -+ - 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_lock_bh(frames[0].bh); - dx_set_count(entries, 1); - dx_set_block(entries + 0, newblock); - ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1; -+ dx_unlock_bh(frames[0].bh); - - /* Add new access path frame */ - frame = frames + 1; - frame->at = at = at - entries + entries2; - frame->entries = entries = entries2; - frame->bh = bh2; -+ frame->curidx = newblock; -+ frame->leaf = leaf; - err = ext3_journal_get_write_access(handle, - frame->bh); - if (err) - goto journal_error; -+ -+ /* first level index was root. it's already initialized */ -+ /* we my unlock it now */ -+ ext3_unlock_htree(dir, idx_lock); -+ -+ /* current index is just created 2nd level index */ -+ curidx = newblock; -+ idx_lock = nb_lock; - } - ext3_journal_dirty_metadata(handle, frames[0].bh); - } -- de = do_split(handle, dir, &bh, frame, &hinfo, &err); -+ de = do_split(handle, dir, &bh, frame, &hinfo, &newleaf_lock, &err); - if (!de) - goto cleanup; -+ -+ /* index splitted */ -+ ext3_unlock_htree(dir, idx_lock); -+ - err = add_dirent_to_buf(handle, dentry, inode, de, bh); -+ -+ if (newleaf_lock) -+ ext3_unlock_htree(dir, newleaf_lock); -+ - bh = 0; - goto cleanup; - - journal_error: - ext3_std_error(dir->i_sb, err); - cleanup: -+ ext3_unlock_htree(dir, leaf_lock); - if (bh) - brelse(bh); - dx_release(frames); -@@ -1902,6 +2221,7 @@ - struct buffer_head * bh; - struct ext3_dir_entry_2 * de; - handle_t *handle; -+ void *lock; - - handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); - if (IS_ERR(handle)) { -@@ -1909,7 +2229,7 @@ - } - - retval = -ENOENT; -- bh = ext3_find_entry (dentry, &de); -+ bh = ext3_find_entry (dentry, &de, 1, &lock); - if (!bh) - goto end_rmdir; - -@@ -1920,14 +2240,19 @@ - DQUOT_INIT(inode); - - retval = -EIO; -- if (le32_to_cpu(de->inode) != inode->i_ino) -+ if (le32_to_cpu(de->inode) != inode->i_ino) { -+ ext3_unlock_htree(dir, lock); - goto end_rmdir; -+ } - - retval = -ENOTEMPTY; -- if (!empty_dir (inode)) -+ if (!empty_dir (inode)) { -+ ext3_unlock_htree(dir, lock); - goto end_rmdir; -+ } - - retval = ext3_delete_entry(handle, dir, de, bh); -+ ext3_unlock_htree(dir, lock); - if (retval) - goto end_rmdir; - if (inode->i_nlink != 2) -@@ -1956,6 +2281,7 @@ - struct buffer_head * bh; - struct ext3_dir_entry_2 * de; - handle_t *handle; -+ void *lock; - - handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); - if (IS_ERR(handle)) { -@@ -1966,7 +2292,7 @@ - handle->h_sync = 1; - - retval = -ENOENT; -- bh = ext3_find_entry (dentry, &de); -+ bh = ext3_find_entry (dentry, &de, 1, &lock); - if (!bh) - goto end_unlink; - -@@ -1974,8 +2300,10 @@ - DQUOT_INIT(inode); - - retval = -EIO; -- if (le32_to_cpu(de->inode) != inode->i_ino) -+ if (le32_to_cpu(de->inode) != inode->i_ino) { -+ ext3_unlock_htree(dir, lock); - goto end_unlink; -+ } - - if (!inode->i_nlink) { - ext3_warning (inode->i_sb, "ext3_unlink", -@@ -1984,6 +2312,7 @@ - inode->i_nlink = 1; - } - retval = ext3_delete_entry(handle, dir, de, bh); -+ ext3_unlock_htree(dir, lock); - if (retval) - goto end_unlink; - dir->i_ctime = dir->i_mtime = CURRENT_TIME; -@@ -2121,6 +2450,7 @@ - struct buffer_head * old_bh, * new_bh, * dir_bh; - struct ext3_dir_entry_2 * old_de, * new_de; - int retval; -+ void *lock1 = NULL, *lock2 = NULL, *lock3 = NULL; - - old_bh = new_bh = dir_bh = NULL; - -@@ -2133,7 +2463,10 @@ - if (IS_SYNC(old_dir) || IS_SYNC(new_dir)) - handle->h_sync = 1; - -- old_bh = ext3_find_entry (old_dentry, &old_de); -+ if (old_dentry->d_parent == new_dentry->d_parent) -+ down(&EXT3_I(old_dentry->d_parent->d_inode)->i_rename_sem); -+ -+ old_bh = ext3_find_entry (old_dentry, &old_de, 1, &lock1 /* FIXME */); - /* - * Check for inode number is _not_ due to possible IO errors. - * We might rmdir the source, keep it as pwd of some process -@@ -2146,7 +2479,7 @@ - goto end_rename; - - new_inode = new_dentry->d_inode; -- new_bh = ext3_find_entry (new_dentry, &new_de); -+ new_bh = ext3_find_entry (new_dentry, &new_de, 1, &lock2 /* FIXME */); - if (new_bh) { - if (!new_inode) { - brelse (new_bh); -@@ -2213,7 +2546,7 @@ - struct buffer_head *old_bh2; - struct ext3_dir_entry_2 *old_de2; - -- old_bh2 = ext3_find_entry(old_dentry, &old_de2); -+ old_bh2 = ext3_find_entry(old_dentry, &old_de2, 1, &lock3 /* FIXME */); - if (old_bh2) { - retval = ext3_delete_entry(handle, old_dir, - old_de2, old_bh2); -@@ -2256,6 +2589,14 @@ - retval = 0; - - end_rename: -+ if (lock1) -+ ext3_unlock_htree(old_dentry->d_parent->d_inode, lock1); -+ if (lock2) -+ ext3_unlock_htree(new_dentry->d_parent->d_inode, lock2); -+ if (lock3) -+ ext3_unlock_htree(old_dentry->d_parent->d_inode, lock3); -+ if (old_dentry->d_parent == new_dentry->d_parent) -+ up(&EXT3_I(old_dentry->d_parent->d_inode)->i_rename_sem); - brelse (dir_bh); - brelse (old_bh); - brelse (new_bh); -@@ -2264,6 +2605,29 @@ - } - - /* -+ * this locking primitives are used to protect parts -+ * of dir's htree. protection unit is block: leaf or index -+ */ -+static inline void *ext3_lock_htree(struct inode *dir, -+ unsigned long value, int rwlock) -+{ -+ void *lock; -+ -+ if (!test_opt(dir->i_sb, PDIROPS)) -+ return NULL; -+ lock = dynlock_lock(&EXT3_I(dir)->i_htree_lock, value, 1, GFP_KERNEL); -+ return lock; -+} -+ -+static inline void ext3_unlock_htree(struct inode *dir, -+ void *lock) -+{ -+ if (!test_opt(dir->i_sb, PDIROPS) || !lock) -+ return; -+ dynlock_unlock(&EXT3_I(dir)->i_htree_lock, lock); -+} -+ -+/* - * directories can handle most operations... - */ - struct inode_operations ext3_dir_inode_operations = { -Index: linux-2.4.20/fs/ext3/super.c -=================================================================== ---- linux-2.4.20.orig/fs/ext3/super.c 2004-05-27 15:10:41.000000000 -0400 -+++ linux-2.4.20/fs/ext3/super.c 2004-05-27 15:10:45.000000000 -0400 -@@ -796,6 +796,8 @@ - return 0; - } - } -+ else if (!strcmp (this_char, "pdirops")) -+ set_opt (sbi->s_mount_opt, PDIROPS); - else if (!strcmp (this_char, "grpid") || - !strcmp (this_char, "bsdgroups")) - set_opt (*mount_options, GRPID); -@@ -822,6 +824,9 @@ - if (want_numeric(value, "sb", sb_block)) - return 0; - } -+ else if (!strcmp (this_char, "pdirops")) { -+ set_opt (sbi->s_mount_opt, PDIROPS); -+ } - #ifdef CONFIG_JBD_DEBUG - else if (!strcmp (this_char, "ro-after")) { - unsigned long v; -@@ -985,6 +990,10 @@ - ext3_check_inodes_bitmap (sb); - } - #endif -+#ifdef S_PDIROPS -+ if (test_opt (sb, PDIROPS)) -+ sb->s_flags |= S_PDIROPS; -+#endif - setup_ro_after(sb); - return res; - } -@@ -1484,6 +1493,11 @@ - test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered": - "writeback"); - -+ if (test_opt(sb, PDIROPS)) { -+ printk (KERN_INFO "EXT3-fs: mounted filesystem with parallel dirops\n"); -+ sb->s_flags |= S_PDIROPS; -+ } -+ - return sb; - - failed_mount3: -Index: linux-2.4.20/fs/ext3/inode.c -=================================================================== ---- linux-2.4.20.orig/fs/ext3/inode.c 2004-05-27 15:10:41.000000000 -0400 -+++ linux-2.4.20/fs/ext3/inode.c 2004-05-27 15:10:45.000000000 -0400 -@@ -2435,6 +2435,9 @@ - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; -+ dynlock_init(&EXT3_I(inode)->i_htree_lock); -+ sema_init(&EXT3_I(inode)->i_rename_sem, 1); -+ sema_init(&EXT3_I(inode)->i_append_sem, 1); - } else if (S_ISLNK(inode->i_mode)) { - if (ext3_inode_is_fast_symlink(inode)) - inode->i_op = &ext3_fast_symlink_inode_operations; -Index: linux-2.4.20/fs/ext3/ialloc.c -=================================================================== ---- linux-2.4.20.orig/fs/ext3/ialloc.c 2004-05-27 15:10:39.000000000 -0400 -+++ linux-2.4.20/fs/ext3/ialloc.c 2004-05-27 15:10:45.000000000 -0400 -@@ -601,6 +601,9 @@ - return ERR_PTR(-EDQUOT); - } - ext3_debug ("allocating inode %lu\n", inode->i_ino); -+ dynlock_init(&EXT3_I(inode)->i_htree_lock); -+ sema_init(&EXT3_I(inode)->i_rename_sem, 1); -+ sema_init(&EXT3_I(inode)->i_append_sem, 1); - return inode; - - fail: -Index: linux-2.4.20/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.20.orig/include/linux/ext3_fs.h 2004-05-27 15:10:40.000000000 -0400 -+++ linux-2.4.20/include/linux/ext3_fs.h 2004-05-27 15:10:45.000000000 -0400 -@@ -306,6 +306,7 @@ - /* - * Mount flags - */ -+#define EXT3_MOUNT_PDIROPS 0x800000/* Parallel dir operations */ - #define EXT3_MOUNT_CHECK 0x0001 /* Do mount-time checks */ - #define EXT3_MOUNT_GRPID 0x0004 /* Create files with directory's group */ - #define EXT3_MOUNT_DEBUG 0x0008 /* Some debugging messages */ -Index: linux-2.4.20/include/linux/ext3_fs_i.h -=================================================================== ---- linux-2.4.20.orig/include/linux/ext3_fs_i.h 2001-11-22 14:46:19.000000000 -0500 -+++ linux-2.4.20/include/linux/ext3_fs_i.h 2004-05-27 15:10:45.000000000 -0400 -@@ -17,6 +17,7 @@ - #define _LINUX_EXT3_FS_I - - #include -+#include - - /* - * second extended file system inode data in memory -@@ -73,6 +74,11 @@ - * by other means, so we have truncate_sem. - */ - struct rw_semaphore truncate_sem; -+ -+ /* following fields for parallel directory operations -bzzz */ -+ struct dynlock i_htree_lock; -+ struct semaphore i_append_sem; -+ struct semaphore i_rename_sem; - }; - - #endif /* _LINUX_EXT3_FS_I */ diff --git a/lustre/kernel_patches/patches/ext3_delete_thread_2.4.20_chaos.patch b/lustre/kernel_patches/patches/ext3_delete_thread_2.4.20_chaos.patch deleted file mode 100644 index 414d60d..0000000 --- a/lustre/kernel_patches/patches/ext3_delete_thread_2.4.20_chaos.patch +++ /dev/null @@ -1,500 +0,0 @@ - fs/ext3/file.c | 4 - fs/ext3/inode.c | 116 ++++++++++++++++++++++ - fs/ext3/super.c | 230 +++++++++++++++++++++++++++++++++++++++++++++ - include/linux/ext3_fs.h | 5 - include/linux/ext3_fs_sb.h | 10 + - 5 files changed, 365 insertions(+) - -Index: linux-2.4.20-rh-20.9/fs/ext3/super.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/fs/ext3/super.c 2004-01-12 19:27:46.000000000 +0300 -+++ linux-2.4.20-rh-20.9/fs/ext3/super.c 2004-01-13 17:20:31.000000000 +0300 -@@ -400,6 +400,221 @@ - } - } - -+#ifdef EXT3_DELETE_THREAD -+/* -+ * Delete inodes in a loop until there are no more to be deleted. -+ * Normally, we run in the background doing the deletes and sleeping again, -+ * and clients just add new inodes to be deleted onto the end of the list. -+ * If someone is concerned about free space (e.g. block allocation or similar) -+ * then they can sleep on s_delete_waiter_queue and be woken up when space -+ * has been freed. -+ */ -+int ext3_delete_thread(void *data) -+{ -+ struct super_block *sb = data; -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ struct task_struct *tsk = current; -+ -+ /* Almost like daemonize, but not quite */ -+ exit_mm(current); -+ tsk->session = 1; -+ tsk->pgrp = 1; -+ tsk->tty = NULL; -+ exit_files(current); -+ reparent_to_init(); -+ -+ sprintf(tsk->comm, "kdelext3-%s", kdevname(sb->s_dev)); -+ sigfillset(&tsk->blocked); -+ -+ /*tsk->flags |= PF_KERNTHREAD;*/ -+ -+ INIT_LIST_HEAD(&sbi->s_delete_list); -+ wake_up(&sbi->s_delete_waiter_queue); -+ ext3_debug("delete thread on %s started\n", kdevname(sb->s_dev)); -+ -+ /* main loop */ -+ for (;;) { -+ wait_event_interruptible(sbi->s_delete_thread_queue, -+ !list_empty(&sbi->s_delete_list) || -+ !test_opt(sb, ASYNCDEL)); -+ ext3_debug("%s woken up: %lu inodes, %lu blocks\n", -+ tsk->comm,sbi->s_delete_inodes,sbi->s_delete_blocks); -+ -+ spin_lock(&sbi->s_delete_lock); -+ if (list_empty(&sbi->s_delete_list)) { -+ clear_opt(sbi->s_mount_opt, ASYNCDEL); -+ memset(&sbi->s_delete_list, 0, -+ sizeof(sbi->s_delete_list)); -+ spin_unlock(&sbi->s_delete_lock); -+ ext3_debug("delete thread on %s exiting\n", -+ kdevname(sb->s_dev)); -+ wake_up(&sbi->s_delete_waiter_queue); -+ break; -+ } -+ -+ while (!list_empty(&sbi->s_delete_list)) { -+ struct inode *inode=list_entry(sbi->s_delete_list.next, -+ struct inode, i_dentry); -+ unsigned long blocks = inode->i_blocks >> -+ (inode->i_blkbits - 9); -+ -+ list_del_init(&inode->i_dentry); -+ spin_unlock(&sbi->s_delete_lock); -+ ext3_debug("%s delete ino %lu blk %lu\n", -+ tsk->comm, inode->i_ino, blocks); -+ -+ iput(inode); -+ -+ spin_lock(&sbi->s_delete_lock); -+ sbi->s_delete_blocks -= blocks; -+ sbi->s_delete_inodes--; -+ } -+ if (sbi->s_delete_blocks != 0 || sbi->s_delete_inodes != 0) { -+ ext3_warning(sb, __FUNCTION__, -+ "%lu blocks, %lu inodes on list?\n", -+ sbi->s_delete_blocks,sbi->s_delete_inodes); -+ sbi->s_delete_blocks = 0; -+ sbi->s_delete_inodes = 0; -+ } -+ spin_unlock(&sbi->s_delete_lock); -+ wake_up(&sbi->s_delete_waiter_queue); -+ } -+ -+ return 0; -+} -+ -+static void ext3_start_delete_thread(struct super_block *sb) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ int rc; -+ -+ spin_lock_init(&sbi->s_delete_lock); -+ init_waitqueue_head(&sbi->s_delete_thread_queue); -+ init_waitqueue_head(&sbi->s_delete_waiter_queue); -+ -+ if (!test_opt(sb, ASYNCDEL)) -+ return; -+ -+ rc = kernel_thread(ext3_delete_thread, sb, CLONE_VM | CLONE_FILES); -+ if (rc < 0) -+ printk(KERN_ERR "EXT3-fs: cannot start delete thread: rc %d\n", -+ rc); -+ else -+ wait_event(sbi->s_delete_waiter_queue, sbi->s_delete_list.next); -+} -+ -+static void ext3_stop_delete_thread(struct ext3_sb_info *sbi) -+{ -+ if (sbi->s_delete_list.next == 0) /* thread never started */ -+ return; -+ -+ clear_opt(sbi->s_mount_opt, ASYNCDEL); -+ wake_up(&sbi->s_delete_thread_queue); -+ wait_event(sbi->s_delete_waiter_queue, -+ sbi->s_delete_list.next == 0 && sbi->s_delete_inodes == 0); -+} -+ -+/* Instead of playing games with the inode flags, destruction, etc we just -+ * create a new inode locally and put it on a list for the truncate thread. -+ * We need large parts of the inode struct in order to complete the -+ * truncate and unlink, so we may as well just have a real inode to do it. -+ * -+ * If we have any problem deferring the delete, just delete it right away. -+ * If we defer it, we also mark how many blocks it would free, so that we -+ * can keep the statfs data correct, and we know if we should sleep on the -+ * delete thread when we run out of space. -+ */ -+static void ext3_delete_inode_thread(struct inode *old_inode) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb); -+ struct ext3_inode_info *nei, *oei = EXT3_I(old_inode); -+ struct inode *new_inode; -+ unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9); -+ -+ if (is_bad_inode(old_inode)) { -+ clear_inode(old_inode); -+ return; -+ } -+ -+ if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next) -+ goto out_delete; -+ -+ /* We may want to delete the inode immediately and not defer it */ -+ if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS) -+ goto out_delete; -+ -+ /* We can't use the delete thread as-is during real orphan recovery, -+ * as we add to the orphan list here, causing ext3_orphan_cleanup() -+ * to loop endlessly. It would be nice to do so, but needs work. -+ */ -+ if (oei->i_state & EXT3_STATE_DELETE || -+ sbi->s_mount_state & EXT3_ORPHAN_FS) { -+ ext3_debug("doing deferred inode %lu delete (%lu blocks)\n", -+ old_inode->i_ino, blocks); -+ goto out_delete; -+ } -+ -+ /* We can iget this inode again here, because our caller has unhashed -+ * old_inode, so new_inode will be in a different inode struct. -+ * -+ * We need to ensure that the i_orphan pointers in the other inodes -+ * point at the new inode copy instead of the old one so the orphan -+ * list doesn't get corrupted when the old orphan inode is freed. -+ */ -+ down(&sbi->s_orphan_lock); -+ -+ sbi->s_mount_state |= EXT3_ORPHAN_FS; -+ new_inode = iget(old_inode->i_sb, old_inode->i_ino); -+ sbi->s_mount_state &= ~EXT3_ORPHAN_FS; -+ if (is_bad_inode(new_inode)) { -+ printk(KERN_WARNING "read bad inode %lu\n", old_inode->i_ino); -+ iput(new_inode); -+ new_inode = NULL; -+ } -+ if (!new_inode) { -+ up(&sbi->s_orphan_lock); -+ ext3_debug("delete inode %lu directly (bad read)\n", -+ old_inode->i_ino); -+ goto out_delete; -+ } -+ J_ASSERT(new_inode != old_inode); -+ -+ J_ASSERT(!list_empty(&oei->i_orphan)); -+ -+ nei = EXT3_I(new_inode); -+ /* Ugh. We need to insert new_inode into the same spot on the list -+ * as old_inode was, to ensure the in-memory orphan list is still -+ * in the same order as the on-disk orphan list (badness otherwise). -+ */ -+ nei->i_orphan = oei->i_orphan; -+ nei->i_orphan.next->prev = &nei->i_orphan; -+ nei->i_orphan.prev->next = &nei->i_orphan; -+ nei->i_state |= EXT3_STATE_DELETE; -+ up(&sbi->s_orphan_lock); -+ -+ clear_inode(old_inode); -+ -+ spin_lock(&sbi->s_delete_lock); -+ J_ASSERT(list_empty(&new_inode->i_dentry)); -+ list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list); -+ sbi->s_delete_blocks += blocks; -+ sbi->s_delete_inodes++; -+ spin_unlock(&sbi->s_delete_lock); -+ -+ ext3_debug("delete inode %lu (%lu blocks) by thread\n", -+ new_inode->i_ino, blocks); -+ -+ wake_up(&sbi->s_delete_thread_queue); -+ return; -+ -+out_delete: -+ ext3_delete_inode(old_inode); -+} -+#else -+#define ext3_start_delete_thread(sbi) do {} while(0) -+#define ext3_stop_delete_thread(sbi) do {} while(0) -+#endif /* EXT3_DELETE_THREAD */ -+ - void ext3_put_super (struct super_block * sb) - { - struct ext3_sb_info *sbi = EXT3_SB(sb); -@@ -407,6 +622,7 @@ - kdev_t j_dev = sbi->s_journal->j_dev; - int i; - -+ J_ASSERT(sbi->s_delete_inodes == 0); - ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { -@@ -455,7 +671,11 @@ - write_inode: ext3_write_inode, /* BKL not held. Don't need */ - dirty_inode: ext3_dirty_inode, /* BKL not held. We take it */ - put_inode: ext3_put_inode, /* BKL not held. Don't need */ -+#ifdef EXT3_DELETE_THREAD -+ delete_inode: ext3_delete_inode_thread,/* BKL not held. We take it */ -+#else - delete_inode: ext3_delete_inode, /* BKL not held. We take it */ -+#endif - put_super: ext3_put_super, /* BKL held */ - write_super: ext3_write_super, /* BKL held */ - sync_fs: ext3_sync_fs, -@@ -524,6 +744,13 @@ - clear_opt (*mount_options, XATTR_USER); - else - #endif -+#ifdef EXT3_DELETE_THREAD -+ if (!strcmp(this_char, "asyncdel")) -+ set_opt(*mount_options, ASYNCDEL); -+ else if (!strcmp(this_char, "noasyncdel")) -+ clear_opt(*mount_options, ASYNCDEL); -+ else -+#endif - if (!strcmp (this_char, "bsddf")) - clear_opt (*mount_options, MINIX_DF); - else if (!strcmp (this_char, "nouid32")) { -@@ -1223,6 +1450,7 @@ - } - - ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); -+ ext3_start_delete_thread(sb); - /* - * akpm: core read_super() calls in here with the superblock locked. - * That deadlocks, because orphan cleanup needs to lock the superblock -@@ -1614,7 +1842,12 @@ - static int ext3_sync_fs(struct super_block *sb) - { - tid_t target; -- -+ -+ if (atomic_read(&sb->s_active) == 0) { -+ /* fs is being umounted: time to stop delete thread */ -+ ext3_stop_delete_thread(EXT3_SB(sb)); -+ } -+ - sb->s_dirt = 0; - target = log_start_commit(EXT3_SB(sb)->s_journal, NULL); - log_wait_commit(EXT3_SB(sb)->s_journal, target); -@@ -1678,6 +1911,9 @@ - if (!parse_options(data, &tmp, sbi, &tmp, 1)) - return -EINVAL; - -+ if (!test_opt(sb, ASYNCDEL) || (*flags & MS_RDONLY)) -+ ext3_stop_delete_thread(sbi); -+ - if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) - ext3_abort(sb, __FUNCTION__, "Abort forced by user"); - -Index: linux-2.4.20-rh-20.9/fs/ext3/inode.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/fs/ext3/inode.c 2004-01-12 19:27:46.000000000 +0300 -+++ linux-2.4.20-rh-20.9/fs/ext3/inode.c 2004-01-13 17:15:48.000000000 +0300 -@@ -2017,6 +2017,122 @@ - ext3_journal_stop(handle, inode); - } - -+#ifdef EXT3_DELETE_THREAD -+/* Move blocks from to-be-truncated inode over to a new inode, and delete -+ * that one from the delete thread instead. This avoids a lot of latency -+ * when truncating large files. -+ * -+ * If we have any problem deferring the truncate, just truncate it right away. -+ * If we defer it, we also mark how many blocks it would free, so that we -+ * can keep the statfs data correct, and we know if we should sleep on the -+ * delete thread when we run out of space. -+ * -+ * During normal filesystem usage, we are always called here with a -+ * transaction already started. The only time ext3_truncate is called -+ * without a started transaction is from ext3_orphan_cleanup(), and we -+ * currently just do a direct truncate in that case. -+ */ -+void ext3_truncate_thread(struct inode *old_inode) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb); -+ struct ext3_inode_info *nei, *oei = EXT3_I(old_inode); -+ struct inode *new_inode; -+ handle_t *handle; -+ unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9); -+ -+ if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next) -+ goto out_truncate; -+ -+ /* XXX This is a temporary limitation for code simplicity. -+ * We could truncate to arbitrary sizes at some later time. -+ */ -+ if (old_inode->i_size != 0) -+ goto out_truncate; -+ -+ /* We may want to truncate the inode immediately and not defer it */ -+ if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS || -+ old_inode->i_size > oei->i_disksize) -+ goto out_truncate; -+ -+ /* We can't use the delete thread as-is during real orphan recovery, -+ * as we add to the orphan list here, causing ext3_orphan_cleanup() -+ * to loop endlessly. It would be nice to do so, but needs work. -+ */ -+ if (oei->i_state & EXT3_STATE_DELETE || -+ sbi->s_mount_state & EXT3_ORPHAN_FS) { -+ ext3_debug("doing deferred inode %lu delete (%lu blocks)\n", -+ old_inode->i_ino, blocks); -+ goto out_truncate; -+ } -+ -+ ext3_discard_prealloc(old_inode); -+ -+ /* old_inode = 1 -+ * new_inode = sb + GDT + ibitmap -+ * orphan list = 1 inode/superblock for add, 2 inodes for del -+ * quota files = 2 * EXT3_SINGLEDATA_TRANS_BLOCKS -+ */ -+ handle = ext3_journal_start(old_inode, 7); -+ if (IS_ERR(handle)) -+ goto out_truncate; -+ -+ new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode); -+ if (IS_ERR(new_inode)) { -+ ext3_debug("truncate inode %lu directly (no new inodes)\n", -+ old_inode->i_ino); -+ goto out_journal; -+ } -+ -+ if (ext3_orphan_add(handle, new_inode) < 0) -+ goto out_journal; -+ -+ if (ext3_orphan_del(handle, old_inode) < 0) { -+ ext3_orphan_del(handle, new_inode); -+ iput(new_inode); -+ goto out_journal; -+ } -+ -+ nei = EXT3_I(new_inode); -+ -+ down_write(&oei->truncate_sem); -+ new_inode->i_size = old_inode->i_size; -+ new_inode->i_blocks = old_inode->i_blocks; -+ new_inode->i_uid = old_inode->i_uid; -+ new_inode->i_gid = old_inode->i_gid; -+ new_inode->i_nlink = 0; -+ -+ /* FIXME when we do arbitrary truncates */ -+ old_inode->i_blocks = oei->i_file_acl ? old_inode->i_blksize / 512 : 0; -+ -+ memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data)); -+ memset(oei->i_data, 0, sizeof(oei->i_data)); -+ -+ nei->i_disksize = oei->i_disksize; -+ nei->i_state |= EXT3_STATE_DELETE; -+ up_write(&oei->truncate_sem); -+ -+ ext3_journal_stop(handle, old_inode); -+ -+ spin_lock(&sbi->s_delete_lock); -+ J_ASSERT(list_empty(&new_inode->i_dentry)); -+ list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list); -+ sbi->s_delete_blocks += blocks; -+ sbi->s_delete_inodes++; -+ spin_unlock(&sbi->s_delete_lock); -+ -+ ext3_debug("delete inode %lu (%lu blocks) by thread\n", -+ new_inode->i_ino, blocks); -+ -+ wake_up(&sbi->s_delete_thread_queue); -+ return; -+ -+out_journal: -+ ext3_journal_stop(handle, old_inode); -+out_truncate: -+ ext3_truncate(old_inode); -+} -+#endif /* EXT3_DELETE_THREAD */ -+ - /* - * ext3_get_inode_loc returns with an extra refcount against the - * inode's underlying buffer_head on success. -Index: linux-2.4.20-rh-20.9/fs/ext3/file.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/fs/ext3/file.c 2004-01-12 19:27:46.000000000 +0300 -+++ linux-2.4.20-rh-20.9/fs/ext3/file.c 2004-01-13 17:15:48.000000000 +0300 -@@ -125,7 +125,11 @@ - }; - - struct inode_operations ext3_file_inode_operations = { -+#ifdef EXT3_DELETE_THREAD -+ truncate: ext3_truncate_thread, /* BKL held */ -+#else - truncate: ext3_truncate, /* BKL held */ -+#endif - setattr: ext3_setattr, /* BKL held */ - setxattr: ext3_setxattr, /* BKL held */ - getxattr: ext3_getxattr, /* BKL held */ -Index: linux-2.4.20-rh-20.9/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.20-rh-20.9.orig/include/linux/ext3_fs.h 2004-01-12 19:27:46.000000000 +0300 -+++ linux-2.4.20-rh-20.9/include/linux/ext3_fs.h 2004-01-13 17:15:48.000000000 +0300 -@@ -193,6 +193,7 @@ - */ - #define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */ - #define EXT3_STATE_NEW 0x00000002 /* inode is newly created */ -+#define EXT3_STATE_DELETE 0x00000010 /* deferred delete inode */ - - /* - * ioctl commands -@@ -320,6 +321,7 @@ - #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ - #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ - #define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ -+#define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -695,6 +697,9 @@ - extern void ext3_dirty_inode(struct inode *); - extern int ext3_change_inode_journal_flag(struct inode *, int); - extern void ext3_truncate (struct inode *); -+#ifdef EXT3_DELETE_THREAD -+extern void ext3_truncate_thread(struct inode *inode); -+#endif - extern void ext3_set_inode_flags(struct inode *); - - /* ioctl.c */ -Index: linux-2.4.20-rh-20.9/include/linux/ext3_fs_sb.h -=================================================================== ---- linux-2.4.20-rh-20.9.orig/include/linux/ext3_fs_sb.h 2004-01-12 19:27:46.000000000 +0300 -+++ linux-2.4.20-rh-20.9/include/linux/ext3_fs_sb.h 2004-01-13 17:15:48.000000000 +0300 -@@ -29,6 +29,8 @@ - - #define EXT3_MAX_GROUP_LOADED 32 - -+#define EXT3_DELETE_THREAD -+ - /* - * third extended-fs super-block data in memory - */ -@@ -76,6 +78,14 @@ - struct timer_list turn_ro_timer; /* For turning read-only (crash simulation) */ - wait_queue_head_t ro_wait_queue; /* For people waiting for the fs to go read-only */ - #endif -+#ifdef EXT3_DELETE_THREAD -+ spinlock_t s_delete_lock; -+ struct list_head s_delete_list; -+ unsigned long s_delete_blocks; -+ unsigned long s_delete_inodes; -+ wait_queue_head_t s_delete_thread_queue; -+ wait_queue_head_t s_delete_waiter_queue; -+#endif - }; - - #endif /* _LINUX_EXT3_FS_SB */ diff --git a/lustre/kernel_patches/patches/ext3_orphan_lock-2.4.20-rh.patch b/lustre/kernel_patches/patches/ext3_orphan_lock-2.4.20-rh.patch deleted file mode 100644 index d029650..0000000 --- a/lustre/kernel_patches/patches/ext3_orphan_lock-2.4.20-rh.patch +++ /dev/null @@ -1,82 +0,0 @@ - fs/ext3/namei.c | 15 +++++++-------- - fs/ext3/super.c | 1 + - include/linux/ext3_fs_sb.h | 1 + - 3 files changed, 9 insertions(+), 8 deletions(-) - ---- linux-rh-2.4.20-8/fs/ext3/namei.c~ext3_orphan_lock-2.4.20-rh 2003-05-05 19:49:15.000000000 +0800 -+++ linux-rh-2.4.20-8-root/fs/ext3/namei.c 2003-05-05 20:01:28.000000000 +0800 -@@ -1747,8 +1747,8 @@ int ext3_orphan_add(handle_t *handle, st - 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; - -@@ -1796,7 +1796,7 @@ int ext3_orphan_add(handle_t *handle, st - 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; - } -@@ -1809,20 +1809,19 @@ 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; -+ 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); - -@@ -1871,7 +1870,7 @@ int ext3_orphan_del(handle_t *handle, st - 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-rh-2.4.20-8/fs/ext3/super.c~ext3_orphan_lock-2.4.20-rh 2003-05-05 19:49:15.000000000 +0800 -+++ linux-rh-2.4.20-8-root/fs/ext3/super.c 2003-05-05 19:54:09.000000000 +0800 -@@ -1151,6 +1151,7 @@ struct super_block * ext3_read_super (st - */ - 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-rh-2.4.20-8/include/linux/ext3_fs_sb.h~ext3_orphan_lock-2.4.20-rh 2003-05-05 19:49:07.000000000 +0800 -+++ linux-rh-2.4.20-8-root/include/linux/ext3_fs_sb.h 2003-05-05 19:54:09.000000000 +0800 -@@ -69,6 +69,7 @@ struct ext3_sb_info { - 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/extN-wantedi-2.4.22-rh.patch b/lustre/kernel_patches/patches/extN-wantedi-2.4.22-rh.patch deleted file mode 100644 index 5ec4dab..0000000 --- a/lustre/kernel_patches/patches/extN-wantedi-2.4.22-rh.patch +++ /dev/null @@ -1,217 +0,0 @@ - fs/ext3/ialloc.c | 41 +++++++++++++++++++++++++++++++++++++++-- - fs/ext3/inode.c | 2 +- - fs/ext3/ioctl.c | 25 +++++++++++++++++++++++++ - fs/ext3/namei.c | 21 +++++++++++++++++---- - include/linux/dcache.h | 5 +++++ - include/linux/ext3_fs.h | 5 ++++- - 6 files changed, 91 insertions(+), 8 deletions(-) - ---- linux-2.4.22-ac1/fs/ext3/ialloc.c~extN-wantedi-2.4.22-rh 2003-09-26 00:57:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/ialloc.c 2003-09-26 01:00:17.000000000 +0400 -@@ -524,7 +524,8 @@ static int find_group_other(struct super - * 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; -@@ -549,7 +550,41 @@ 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) { -+ group = (goal - 1) / EXT3_INODES_PER_GROUP(sb); -+ ino = (goal - 1) % EXT3_INODES_PER_GROUP(sb); -+ gdp = ext3_get_group_desc(sb, group, &bh2); -+ -+ bitmap_nr = load_inode_bitmap (sb, group); -+ if (bitmap_nr < 0) { -+ err = bitmap_nr; -+ 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(ino, 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: - if (S_ISDIR(mode)) { - if (test_opt (sb, OLDALLOC)) -@@ -606,6 +641,8 @@ repeat: - } - goto repeat; - } -+ -+have_bit_and_group: - ino += group * EXT3_INODES_PER_GROUP(sb) + 1; - if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { - ext3_error (sb, "ext3_new_inode", ---- linux-2.4.22-ac1/fs/ext3/inode.c~extN-wantedi-2.4.22-rh 2003-09-26 00:57:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/inode.c 2003-09-26 00:57:29.000000000 +0400 -@@ -2614,7 +2614,7 @@ void ext3_truncate_thread(struct inode * - if (IS_ERR(handle)) - goto out_truncate; - -- new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode); -+ new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode, 0); - if (IS_ERR(new_inode)) { - ext3_debug("truncate inode %lu directly (no new inodes)\n", - old_inode->i_ino); ---- linux-2.4.22-ac1/fs/ext3/ioctl.c~extN-wantedi-2.4.22-rh 2003-09-25 14:16:23.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/ioctl.c 2003-09-26 00:57:29.000000000 +0400 -@@ -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.22-ac1/fs/ext3/namei.c~extN-wantedi-2.4.22-rh 2003-09-26 00:57:28.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/namei.c 2003-09-26 00:57:29.000000000 +0400 -@@ -1534,6 +1534,19 @@ static int ext3_add_nondir(handle_t *han - return err; - } - -+static struct inode * ext3_new_inode_wantedi(handle_t *handle, struct inode *dir, -+ int mode, struct dentry *dentry) -+{ -+ unsigned long inum = 0; -+ -+ if (dentry->d_fsdata != NULL) { -+ struct dentry_params *param = -+ (struct dentry_params *) dentry->d_fsdata; -+ inum = param->p_inum; -+ } -+ return ext3_new_inode(handle, dir, mode, inum); -+} -+ - /* - * By the time this is called, we already have created - * the directory cache entry for the new file, but it -@@ -1557,7 +1570,7 @@ 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_wantedi (handle, dir, mode, dentry); - err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - inode->i_op = &ext3_file_inode_operations; -@@ -1585,7 +1598,7 @@ 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_wantedi (handle, dir, mode, dentry); - err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - init_special_inode(inode, mode, rdev); -@@ -1615,7 +1628,7 @@ 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_wantedi (handle, dir, S_IFDIR | mode, dentry); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; -@@ -2010,7 +2023,7 @@ 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_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; ---- linux-2.4.22-ac1/include/linux/dcache.h~extN-wantedi-2.4.22-rh 2003-09-26 00:57:27.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/dcache.h 2003-09-26 00:57:29.000000000 +0400 -@@ -63,6 +63,11 @@ static inline void intent_init(struct lo - - #define IS_ROOT(x) ((x) == (x)->d_parent) - -+struct dentry_params { -+ unsigned long p_inum; -+ void *p_ptr; -+}; -+ - /* - * "quick string" -- eases parameter passing, but more importantly - * saves "metadata" about the string (ie length and the hash). ---- linux-2.4.22-ac1/include/linux/ext3_fs.h~extN-wantedi-2.4.22-rh 2003-09-26 00:57:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs.h 2003-09-26 00:57:29.000000000 +0400 -@@ -203,6 +203,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 -@@ -676,7 +677,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 *); -@@ -769,4 +771,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/gpl_header-chaos-2.4.20.patch b/lustre/kernel_patches/patches/gpl_header-chaos-2.4.20.patch deleted file mode 100644 index 95213ba..0000000 --- a/lustre/kernel_patches/patches/gpl_header-chaos-2.4.20.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- kernel-2.4.20-6chaos_18_7/include/linux/module.h~gpl-header Wed Jul 16 03:54:37 2003 -+++ kernel-2.4.20-6chaos_18_7/include/linux/module.h Wed Jul 16 03:55:45 2003 -@@ -288,7 +288,7 @@ - "license=" license - - #define GPL_HEADER() \ --static const char cpyright="This software may be freely redistributed under the terms of the GNU General Public License."; -+static const char cpyright[]="This software may be freely redistributed under the terms of the GNU General Public License."; - - /* Define the module variable, and usage macros. */ - extern struct module __this_module; 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 index 3fdf3fd..0000000 --- a/lustre/kernel_patches/patches/iod-rmap-exports-2.4.20.patch +++ /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 -+#include - #include - #include - #include -@@ -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 - */ - -+#include -+#include - #include - #include - #include -@@ -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-stock-24-exports.patch b/lustre/kernel_patches/patches/iod-stock-24-exports.patch deleted file mode 100644 index 2070377..0000000 --- a/lustre/kernel_patches/patches/iod-stock-24-exports.patch +++ /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 -+#include - #include - #include - #include -@@ -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-exports-2.4.22-rh.patch b/lustre/kernel_patches/patches/iod-stock-exports-2.4.22-rh.patch deleted file mode 100644 index 8d8790e..0000000 --- a/lustre/kernel_patches/patches/iod-stock-exports-2.4.22-rh.patch +++ /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.22-ac1/fs/inode.c~iod-stock-exports-2.4.22-rh 2003-09-25 14:45:32.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/inode.c 2003-09-25 14:49:41.000000000 +0400 -@@ -5,6 +5,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -68,7 +69,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.22-ac1/fs/Makefile~iod-stock-exports-2.4.22-rh 2003-09-25 14:16:28.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/Makefile 2003-09-25 14:50:00.000000000 +0400 -@@ -7,7 +7,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 xfs - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ ---- linux-2.4.22-ac1/mm/page_alloc.c~iod-stock-exports-2.4.22-rh 2003-09-25 14:16:28.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/mm/page_alloc.c 2003-09-25 14:49:41.000000000 +0400 -@@ -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/kernel_text_address-2.4.21-suse-171.patch b/lustre/kernel_patches/patches/kernel_text_address-2.4.21-suse-171.patch deleted file mode 100644 index 4088b4f..0000000 --- a/lustre/kernel_patches/patches/kernel_text_address-2.4.21-suse-171.patch +++ /dev/null @@ -1,116 +0,0 @@ -Index: linux-2.4.21-241/arch/um/kernel/Makefile -=================================================================== ---- linux-2.4.21-241.orig/arch/um/kernel/Makefile 2004-10-03 17:30:07.000000000 -0400 -+++ linux-2.4.21-241/arch/um/kernel/Makefile 2004-10-04 02:51:20.000000000 -0400 -@@ -37,7 +37,8 @@ - export-objs-$(CONFIG_GPROF) += gprof_syms.o - export-objs-$(CONFIG_GCOV) += gmon_syms.o - --export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o $(export-objs-y) -+export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o sysrq.o \ -+ $(export-objs-y) - - CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \ - -I/usr/include -I../include -Index: linux-2.4.21-241/arch/um/kernel/sysrq.c -=================================================================== ---- linux-2.4.21-241.orig/arch/um/kernel/sysrq.c 2004-10-03 17:30:07.000000000 -0400 -+++ linux-2.4.21-241/arch/um/kernel/sysrq.c 2004-10-04 02:51:20.000000000 -0400 -@@ -86,6 +86,37 @@ - show_trace((unsigned long *)esp); - } - -+#ifdef CONFIG_MODULES -+extern struct module *module_list; -+extern struct module kernel_module; -+#endif -+ -+int is_kernel_text_address(unsigned long addr) -+{ -+ int retval = 0; -+#ifdef CONFIG_MODULES -+ struct module *mod; -+#endif -+ if (addr >= (unsigned long) &_stext && -+ addr <= (unsigned long) &_etext) -+ return 1; -+ -+#ifdef CONFIG_MODULES -+ for (mod = module_list; mod != &kernel_module; mod = mod->next) { -+ /* mod_bound tests for addr being inside the vmalloc'ed -+ * module area. Of course it'd be better to test only -+ * for the .text subset... */ -+ if (mod_bound(addr, 0, mod)) { -+ retval = 1; -+ break; -+ } -+ } -+#endif -+ return retval; -+} -+ -+EXPORT_SYMBOL(is_kernel_text_address); -+ - /* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically -Index: linux-2.4.21-241/arch/i386/kernel/Makefile -=================================================================== ---- linux-2.4.21-241.orig/arch/i386/kernel/Makefile 2004-10-03 17:31:39.000000000 -0400 -+++ linux-2.4.21-241/arch/i386/kernel/Makefile 2004-10-04 02:52:04.000000000 -0400 -@@ -20,7 +20,8 @@ - - O_TARGET := kernel.o - --export-objs := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o dr_alloc.o -+export-objs := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o \ -+ traps.o dr_alloc.o - - ifdef CONFIG_X86_SPEEDSTEP_ICH - export-objs += speedstep-lib.o -Index: linux-2.4.21-241/arch/i386/kernel/traps.c -=================================================================== ---- linux-2.4.21-241.orig/arch/i386/kernel/traps.c 2004-10-04 02:48:05.000000000 -0400 -+++ linux-2.4.21-241/arch/i386/kernel/traps.c 2004-10-04 02:51:20.000000000 -0400 -@@ -1339,3 +1339,41 @@ - cobalt_init(); - #endif - } -+ -+#ifdef CONFIG_MODULES -+extern struct module *module_list; -+extern struct module kernel_module; -+#endif -+ -+int is_kernel_text_address(unsigned long addr) -+{ -+ int retval = 0; -+#ifdef CONFIG_MODULES -+ struct module *mod; -+#endif -+ if (addr >= (unsigned long) &_stext && -+ addr <= (unsigned long) &_etext); -+ return 1; -+ -+#ifdef CONFIG_MODULES -+ for (mod = module_list; mod != &kernel_module; mod = mod->next) { -+ /* mod_bound tests for addr being inside the vmalloc'ed -+ * module area. Of course it'd be better to test only -+ * for the .text subset... */ -+ if (mod_bound(addr, 0, mod)) { -+ retval = 1; -+ break; -+ } -+ } -+#endif -+ -+ return retval; -+} -+ -+int lookup_symbol(unsigned long address, char *buf, int buflen) -+{ -+ return -ENOSYS; -+} -+ -+EXPORT_SYMBOL_GPL(is_kernel_text_address); -+EXPORT_SYMBOL_GPL(lookup_symbol); 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 index cbf51ea..0000000 --- a/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-chaos.patch +++ /dev/null @@ -1,5531 +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 | 10 - 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 | 36 + - 62 files changed, 4344 insertions(+), 183 deletions(-) - ---- kernel-2.4.20-6chaos_18_7/Documentation/Configure.help~linux-2.4.20-xattr-0.8.54-chaos 2003-06-23 10:39:21.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/Documentation/Configure.help 2003-07-12 15:34:44.000000000 -0600 -@@ -15253,6 +15253,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 -+ 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 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 -@@ -15285,6 +15318,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 -+ 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 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 ---- kernel-2.4.20-6chaos_18_7/arch/alpha/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2002-05-07 15:53:54.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/alpha/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 ---- kernel-2.4.20-6chaos_18_7/arch/alpha/kernel/entry.S~linux-2.4.20-xattr-0.8.54-chaos 2003-05-15 21:11:53.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/alpha/kernel/entry.S 2003-07-12 15:34:44.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) ---- kernel-2.4.20-6chaos_18_7/arch/arm/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2002-05-07 15:53:56.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/arm/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 ---- kernel-2.4.20-6chaos_18_7/arch/arm/kernel/calls.S~linux-2.4.20-xattr-0.8.54-chaos 2002-09-25 11:09:16.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/arm/kernel/calls.S 2003-07-12 15:34:44.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, ---- kernel-2.4.20-6chaos_18_7/arch/i386/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2003-05-15 21:12:00.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/i386/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 ---- kernel-2.4.20-6chaos_18_7/arch/ia64/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2003-05-15 21:12:04.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/ia64/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 ---- kernel-2.4.20-6chaos_18_7/arch/m68k/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2002-05-07 15:53:55.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/m68k/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 - - # ---- kernel-2.4.20-6chaos_18_7/arch/mips/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:58:06.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/mips/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 ---- kernel-2.4.20-6chaos_18_7/arch/mips64/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:58:11.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/mips64/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 ---- kernel-2.4.20-6chaos_18_7/arch/ppc/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2003-05-15 21:12:20.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/ppc/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 ---- kernel-2.4.20-6chaos_18_7/arch/ppc64/kernel/misc.S~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:58:20.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/ppc64/kernel/misc.S 2003-07-12 15:34:44.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 ... */ ---- kernel-2.4.20-6chaos_18_7/arch/s390/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:58:20.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/s390/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 ---- kernel-2.4.20-6chaos_18_7/arch/s390/kernel/entry.S~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:58:20.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/s390/kernel/entry.S 2003-07-12 15:34:44.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 ---- kernel-2.4.20-6chaos_18_7/arch/s390x/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:58:21.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/s390x/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 ---- kernel-2.4.20-6chaos_18_7/arch/s390x/kernel/entry.S~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:58:21.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/s390x/kernel/entry.S 2003-07-12 15:34:44.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 ---- kernel-2.4.20-6chaos_18_7/arch/s390x/kernel/wrapper32.S~linux-2.4.20-xattr-0.8.54-chaos 2002-05-07 15:53:59.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/s390x/kernel/wrapper32.S 2003-07-12 15:34:44.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 -+ -+ ---- kernel-2.4.20-6chaos_18_7/arch/sparc/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2002-09-25 11:10:50.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/sparc/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 - ---- kernel-2.4.20-6chaos_18_7/arch/sparc/kernel/systbls.S~linux-2.4.20-xattr-0.8.54-chaos 2002-09-25 11:10:52.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/sparc/kernel/systbls.S 2003-07-12 15:34:44.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 ---- kernel-2.4.20-6chaos_18_7/arch/sparc64/defconfig~linux-2.4.20-xattr-0.8.54-chaos 2003-05-15 21:12:29.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/sparc64/defconfig 2003-07-12 15:34:44.000000000 -0600 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 ---- kernel-2.4.20-6chaos_18_7/arch/sparc64/kernel/systbls.S~linux-2.4.20-xattr-0.8.54-chaos 2002-09-25 11:10:55.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/arch/sparc64/kernel/systbls.S 2003-07-12 15:34:44.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 ---- kernel-2.4.20-6chaos_18_7/fs/Config.in~linux-2.4.20-xattr-0.8.54-chaos 2003-05-15 21:14:24.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/Config.in 2003-07-12 15:34:44.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 ---- kernel-2.4.20-6chaos_18_7/fs/Makefile~linux-2.4.20-xattr-0.8.54-chaos 2003-07-12 15:33:34.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/Makefile 2003-07-12 15:34:44.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)) - ---- kernel-2.4.20-6chaos_18_7/fs/ext2/Makefile~linux-2.4.20-xattr-0.8.54-chaos 2002-05-07 15:53:46.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext2/Makefile 2003-07-12 15:34:44.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 ---- kernel-2.4.20-6chaos_18_7/fs/ext2/file.c~linux-2.4.20-xattr-0.8.54-chaos 2002-05-07 15:53:46.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext2/file.c 2003-07-12 15:34:44.000000000 -0600 -@@ -20,6 +20,7 @@ - - #include - #include -+#include - #include - - /* -@@ -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, - }; ---- kernel-2.4.20-6chaos_18_7/fs/ext2/ialloc.c~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:59:09.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext2/ialloc.c 2003-07-12 15:34:44.000000000 -0600 -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -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); - } ---- kernel-2.4.20-6chaos_18_7/fs/ext2/inode.c~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:59:09.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext2/inode.c 2003-07-12 15:34:44.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) { ---- kernel-2.4.20-6chaos_18_7/fs/ext2/namei.c~linux-2.4.20-xattr-0.8.54-chaos 2002-05-07 15:53:46.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext2/namei.c 2003-07-12 15:34:44.000000000 -0600 -@@ -31,6 +31,7 @@ - - #include - #include -+#include - #include - - /* -@@ -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, - }; ---- kernel-2.4.20-6chaos_18_7/fs/ext2/super.c~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:59:09.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext2/super.c 2003-07-12 15:34:44.000000000 -0600 -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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; ---- kernel-2.4.20-6chaos_18_7/fs/ext2/symlink.c~linux-2.4.20-xattr-0.8.54-chaos 2002-05-07 15:53:46.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext2/symlink.c 2003-07-12 15:34:44.000000000 -0600 -@@ -19,6 +19,7 @@ - - #include - #include -+#include - - 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 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext2/xattr.c 2003-07-12 15:34:44.000000000 -0600 -@@ -0,0 +1,1212 @@ -+/* -+ * linux/fs/ext2/xattr.c -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ * -+ * Fix by Harrison Xing . -+ * Extended attributes for symlinks and special files added per -+ * suggestion of Luka Renko . -+ */ -+ -+/* -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* 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; iprefix); -+ 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; -+ (void)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); -+ (void)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 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext2/xattr_user.c 2003-07-12 15:34:44.000000000 -0600 -@@ -0,0 +1,103 @@ -+/* -+ * linux/fs/ext2/xattr_user.c -+ * Handler for extended user attributes. -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_EXT2_FS_POSIX_ACL -+# include -+#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); -+} ---- kernel-2.4.20-6chaos_18_7/fs/ext3/Makefile~linux-2.4.20-xattr-0.8.54-chaos 2003-07-12 15:33:38.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/Makefile 2003-07-12 15:34:44.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 -@@ -9,10 +9,14 @@ - - 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) - -+export-objs += xattr.o -+obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o -+obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o -+ - include $(TOPDIR)/Rules.make ---- kernel-2.4.20-6chaos_18_7/fs/ext3/file.c~linux-2.4.20-xattr-0.8.54-chaos 2003-07-12 15:33:38.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/file.c 2003-07-12 15:34:44.000000000 -0600 -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -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 */ - }; - ---- kernel-2.4.20-6chaos_18_7/fs/ext3/ialloc.c~linux-2.4.20-xattr-0.8.54-chaos 2003-05-15 21:14:30.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/ialloc.c 2003-07-12 15:34:44.000000000 -0600 -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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); - ---- kernel-2.4.20-6chaos_18_7/fs/ext3/inode.c~linux-2.4.20-xattr-0.8.54-chaos 2003-05-15 21:14:30.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/inode.c 2003-07-12 15:34:44.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 */ ---- kernel-2.4.20-6chaos_18_7/fs/ext3/namei.c~linux-2.4.20-xattr-0.8.54-chaos 2003-07-12 15:33:43.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/namei.c 2003-07-12 15:34:44.000000000 -0600 -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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 */ -+}; -+ ---- kernel-2.4.20-6chaos_18_7/fs/ext3/super.c~linux-2.4.20-xattr-0.8.54-chaos 2003-07-12 15:33:38.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/super.c 2003-07-12 15:34:44.000000000 -0600 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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"); ---- kernel-2.4.20-6chaos_18_7/fs/ext3/symlink.c~linux-2.4.20-xattr-0.8.54-chaos 2002-05-07 15:53:46.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/symlink.c 2003-07-12 15:34:44.000000000 -0600 -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - 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 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/xattr.c 2003-07-12 15:34:44.000000000 -0600 -@@ -0,0 +1,1225 @@ -+/* -+ * linux/fs/ext3/xattr.c -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ * -+ * Fix by Harrison Xing . -+ * Ext3 code with a lot of help from Eric Jarman . -+ * Extended attributes for symlinks and special files added per -+ * suggestion of Luka Renko . -+ */ -+ -+/* -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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; iprefix); -+ 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; -+ (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_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 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/xattr_user.c 2003-07-12 15:34:44.000000000 -0600 -@@ -0,0 +1,111 @@ -+/* -+ * linux/fs/ext3/xattr_user.c -+ * Handler for extended user attributes. -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+# include -+#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); -+} ---- kernel-2.4.20-6chaos_18_7/fs/jfs/jfs_xattr.h~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:59:11.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/jfs/jfs_xattr.h 2003-07-12 15:34:44.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); ---- kernel-2.4.20-6chaos_18_7/fs/jfs/xattr.c~linux-2.4.20-xattr-0.8.54-chaos 2003-02-14 15:59:11.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/jfs/xattr.c 2003-07-12 15:34:44.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 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/mbcache.c 2003-07-12 15:34:44.000000000 -0600 -@@ -0,0 +1,648 @@ -+/* -+ * linux/fs/mbcache.c -+ * (C) 2001-2002 Andreas Gruenbacher, -+ */ -+ -+/* -+ * 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 -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#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 "); -+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; ne_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; nc_block_hash[n]); -+ for (m=0; mc_indexes_hash[m] = kmalloc(bucket_count * -+ sizeof(struct list_head), -+ GFP_KERNEL); -+ if (!cache->c_indexes_hash[m]) -+ goto fail; -+ for (n=0; nc_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; ne_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<=indexc_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<=indexe_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) -+ ---- kernel-2.4.20-6chaos_18_7/include/asm-arm/unistd.h~linux-2.4.20-xattr-0.8.54-chaos 2003-05-15 21:14:42.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/include/asm-arm/unistd.h 2003-07-12 15:34:44.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, ---- kernel-2.4.20-6chaos_18_7/include/asm-ppc64/unistd.h~linux-2.4.20-xattr-0.8.54-chaos 2002-09-25 11:13:42.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/include/asm-ppc64/unistd.h 2003-07-12 15:34:44.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 - ---- kernel-2.4.20-6chaos_18_7/include/asm-s390/unistd.h~linux-2.4.20-xattr-0.8.54-chaos 2002-09-25 11:13:44.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/include/asm-s390/unistd.h 2003-07-12 15:34:44.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 - ---- kernel-2.4.20-6chaos_18_7/include/asm-s390x/unistd.h~linux-2.4.20-xattr-0.8.54-chaos 2002-09-25 11:13:45.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/include/asm-s390x/unistd.h 2003-07-12 15:34:44.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 - ---- kernel-2.4.20-6chaos_18_7/include/asm-sparc/unistd.h~linux-2.4.20-xattr-0.8.54-chaos 2002-09-25 11:13:46.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/include/asm-sparc/unistd.h 2003-07-12 15:34:44.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 */ ---- kernel-2.4.20-6chaos_18_7/include/asm-sparc64/unistd.h~linux-2.4.20-xattr-0.8.54-chaos 2002-09-25 11:13:48.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/include/asm-sparc64/unistd.h 2003-07-12 15:34:44.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 -+++ kernel-2.4.20-6chaos_18_7-braam/include/linux/cache_def.h 2003-07-12 15:34:44.000000000 -0600 -@@ -0,0 +1,15 @@ -+/* -+ * linux/cache_def.h -+ * Handling of caches defined in drivers, filesystems, ... -+ * -+ * Copyright (C) 2002 by Andreas Gruenbacher, -+ */ -+ -+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 *); ---- kernel-2.4.20-6chaos_18_7/include/linux/errno.h~linux-2.4.20-xattr-0.8.54-chaos 2003-05-15 21:15:06.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/include/linux/errno.h 2003-07-12 15:34:44.000000000 -0600 -@@ -26,4 +26,8 @@ - - #endif - -+/* Defined for extended attributes */ -+#define ENOATTR ENODATA /* No such attribute */ -+#define ENOTSUP EOPNOTSUPP /* Operation not supported */ -+ - #endif ---- kernel-2.4.20-6chaos_18_7/include/linux/ext2_fs.h~linux-2.4.20-xattr-0.8.54-chaos 2003-06-24 11:31:16.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/include/linux/ext2_fs.h 2003-07-12 15:34:44.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| \ -@@ -624,8 +601,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 -+++ kernel-2.4.20-6chaos_18_7-braam/include/linux/ext2_xattr.h 2003-07-12 15:34:44.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, -+*/ -+ -+#include -+#include -+#include -+ -+/* 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<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__ */ -+ ---- kernel-2.4.20-6chaos_18_7/include/linux/ext3_fs.h~linux-2.4.20-xattr-0.8.54-chaos 2003-07-12 15:33:41.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/include/linux/ext3_fs.h 2003-07-12 15:34:44.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 -@@ -521,7 +497,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| \ -@@ -704,6 +680,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 *); - -@@ -773,8 +750,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; - - ---- kernel-2.4.20-6chaos_18_7/include/linux/ext3_jbd.h~linux-2.4.20-xattr-0.8.54-chaos 2003-07-12 15:33:38.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/include/linux/ext3_jbd.h 2003-07-12 15:34:44.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 -+++ kernel-2.4.20-6chaos_18_7-braam/include/linux/ext3_xattr.h 2003-07-12 15:34:44.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, -+*/ -+ -+#include -+#include -+#include -+ -+/* 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<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__ */ -+ ---- kernel-2.4.20-6chaos_18_7/include/linux/fs.h~linux-2.4.20-xattr-0.8.54-chaos 2003-07-12 15:31:35.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/include/linux/fs.h 2003-07-12 15:34:44.000000000 -0600 -@@ -914,7 +914,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 -+++ kernel-2.4.20-6chaos_18_7-braam/include/linux/mbcache.h 2003-07-12 15:34:44.000000000 -0600 -@@ -0,0 +1,69 @@ -+/* -+ File: linux/mbcache.h -+ -+ (C) 2001 by Andreas Gruenbacher, -+*/ -+ -+/* 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 ---- kernel-2.4.20-6chaos_18_7/kernel/ksyms.c~linux-2.4.20-xattr-0.8.54-chaos 2003-07-12 15:14:02.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/kernel/ksyms.c 2003-07-12 15:35:19.000000000 -0600 -@@ -12,6 +12,7 @@ - #define __KERNEL_SYSCALLS__ - #include - #include -+#include - #include - #include - #include -@@ -106,6 +107,7 @@ EXPORT_SYMBOL(do_brk); - EXPORT_SYMBOL(exit_mm); - EXPORT_SYMBOL(exit_files); - EXPORT_SYMBOL(exit_fs); -+EXPORT_SYMBOL(copy_fs_struct); - EXPORT_SYMBOL(exit_sighand); - EXPORT_SYMBOL_GPL(make_pages_present); - -@@ -126,6 +128,8 @@ EXPORT_SYMBOL(kmem_cache_alloc); - EXPORT_SYMBOL(kmem_cache_free); - EXPORT_SYMBOL(kmem_cache_validate); - EXPORT_SYMBOL(kmem_cache_size); -+EXPORT_SYMBOL(register_cache); -+EXPORT_SYMBOL(unregister_cache); - EXPORT_SYMBOL(kmalloc); - EXPORT_SYMBOL(kfree); - EXPORT_SYMBOL(vfree); ---- kernel-2.4.20-6chaos_18_7/mm/vmscan.c~linux-2.4.20-xattr-0.8.54-chaos 2003-07-12 15:33:34.000000000 -0600 -+++ kernel-2.4.20-6chaos_18_7-braam/mm/vmscan.c 2003-07-12 15:34:44.000000000 -0600 -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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 ---- /dev/null 2003-01-30 03:24:37.000000000 -0700 -+++ kernel-2.4.20-6chaos_18_7-braam/fs/ext3/ext3-exports.c 2003-07-12 15:34:44.000000000 -0600 -@@ -0,0 +1,13 @@ -+#include -+#include -+#include -+#include -+#include -+ -+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); - -_ diff --git a/lustre/kernel_patches/patches/linux-2.4.21-xattr-0.8.54-suse.patch b/lustre/kernel_patches/patches/linux-2.4.21-xattr-0.8.54-suse.patch deleted file mode 100644 index 9208772..0000000 --- a/lustre/kernel_patches/patches/linux-2.4.21-xattr-0.8.54-suse.patch +++ /dev/null @@ -1,5349 +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/ia64/kernel/entry.S | 24 - 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 | 10 - 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-ia64/unistd.h | 13 - 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 + - fs/ext3/ext3-exports.c | 14 + - 64 files changed, 4355 insertions(+), 195 deletions(-) - ---- linux-2.4.20/Documentation/Configure.help~linux-2.4.20-xattr-0.8.54 2003-05-05 17:43:06.000000000 +0800 -+++ linux-2.4.20-root/Documentation/Configure.help 2003-05-07 18:08:03.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 -+ 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 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 -+ 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 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 2001-11-20 07:19:42.000000000 +0800 -+++ linux-2.4.20-root/arch/alpha/defconfig 2003-05-07 18:08:03.000000000 +0800 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 2002-08-03 08:39:42.000000000 +0800 -+++ linux-2.4.20-root/arch/alpha/kernel/entry.S 2003-05-07 18:08:03.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 2001-05-20 08:43:05.000000000 +0800 -+++ linux-2.4.20-root/arch/arm/defconfig 2003-05-07 18:08:03.000000000 +0800 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 2002-08-03 08:39:42.000000000 +0800 -+++ linux-2.4.20-root/arch/arm/kernel/calls.S 2003-05-07 18:08:03.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 2002-11-29 07:53:09.000000000 +0800 -+++ linux-2.4.20-root/arch/i386/defconfig 2003-05-07 18:08:03.000000000 +0800 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 2002-11-29 07:53:09.000000000 +0800 -+++ linux-2.4.20-root/arch/ia64/defconfig 2003-05-07 18:08:03.000000000 +0800 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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/m68k/defconfig~linux-2.4.20-xattr-0.8.54 2000-06-20 03:56:08.000000000 +0800 -+++ linux-2.4.20-root/arch/m68k/defconfig 2003-05-07 18:08:03.000000000 +0800 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 2002-11-29 07:53:10.000000000 +0800 -+++ linux-2.4.20-root/arch/mips/defconfig 2003-05-07 18:08:03.000000000 +0800 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 2002-11-29 07:53:10.000000000 +0800 -+++ linux-2.4.20-root/arch/mips64/defconfig 2003-05-07 18:08:03.000000000 +0800 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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/s390/defconfig~linux-2.4.20-xattr-0.8.54 2002-11-29 07:53:11.000000000 +0800 -+++ linux-2.4.20-root/arch/s390/defconfig 2003-05-07 18:08:03.000000000 +0800 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 2002-11-29 07:53:11.000000000 +0800 -+++ linux-2.4.20-root/arch/s390/kernel/entry.S 2003-05-07 18:08:03.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 2002-11-29 07:53:11.000000000 +0800 -+++ linux-2.4.20-root/arch/s390x/defconfig 2003-05-07 18:08:03.000000000 +0800 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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 2002-11-29 07:53:11.000000000 +0800 -+++ linux-2.4.20-root/arch/s390x/kernel/entry.S 2003-05-07 18:08:03.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 2002-02-26 03:37:56.000000000 +0800 -+++ linux-2.4.20-root/arch/s390x/kernel/wrapper32.S 2003-05-07 18:08:03.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/sparc64/defconfig~linux-2.4.20-xattr-0.8.54 2002-11-29 07:53:12.000000000 +0800 -+++ linux-2.4.20-root/arch/sparc64/defconfig 2003-05-07 18:08:03.000000000 +0800 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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/fs/Config.in~linux-2.4.20-xattr-0.8.54 2002-11-29 07:53:15.000000000 +0800 -+++ linux-2.4.20-root/fs/Config.in 2003-05-07 18:08:03.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-05-05 19:00:58.000000000 +0800 -+++ linux-2.4.20-root/fs/Makefile 2003-05-07 18:08:03.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 2001-10-11 23:05:18.000000000 +0800 -+++ linux-2.4.20-root/fs/ext2/Makefile 2003-05-07 18:08:03.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 2001-10-11 23:05:18.000000000 +0800 -+++ linux-2.4.20-root/fs/ext2/file.c 2003-05-07 18:08:03.000000000 +0800 -@@ -20,6 +20,7 @@ - - #include - #include -+#include - #include - - /* -@@ -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 2002-11-29 07:53:15.000000000 +0800 -+++ linux-2.4.20-root/fs/ext2/ialloc.c 2003-05-07 18:08:03.000000000 +0800 -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -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 2002-11-29 07:53:15.000000000 +0800 -+++ linux-2.4.20-root/fs/ext2/inode.c 2003-05-07 18:08:03.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 2001-10-04 13:57:36.000000000 +0800 -+++ linux-2.4.20-root/fs/ext2/namei.c 2003-05-07 18:08:03.000000000 +0800 -@@ -31,6 +31,7 @@ - - #include - #include -+#include - #include - - /* -@@ -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 2002-11-29 07:53:15.000000000 +0800 -+++ linux-2.4.20-root/fs/ext2/super.c 2003-05-07 18:08:03.000000000 +0800 -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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 2000-09-28 04:41:33.000000000 +0800 -+++ linux-2.4.20-root/fs/ext2/symlink.c 2003-05-07 18:08:03.000000000 +0800 -@@ -19,6 +19,7 @@ - - #include - #include -+#include - - 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.20-root/fs/ext2/xattr.c 2003-05-07 18:08:03.000000000 +0800 -@@ -0,0 +1,1212 @@ -+/* -+ * linux/fs/ext2/xattr.c -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ * -+ * Fix by Harrison Xing . -+ * Extended attributes for symlinks and special files added per -+ * suggestion of Luka Renko . -+ */ -+ -+/* -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* 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; iprefix); -+ 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; -+ (void)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); -+ (void)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.20-root/fs/ext2/xattr_user.c 2003-05-07 18:08:03.000000000 +0800 -@@ -0,0 +1,103 @@ -+/* -+ * linux/fs/ext2/xattr_user.c -+ * Handler for extended user attributes. -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_EXT2_FS_POSIX_ACL -+# include -+#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-05-05 19:01:02.000000000 +0800 -+++ linux-2.4.20-root/fs/ext3/Makefile 2003-05-07 18:10:33.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 -@@ -9,10 +9,14 @@ - - 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) - -+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-05-05 19:01:02.000000000 +0800 -+++ linux-2.4.20-root/fs/ext3/file.c 2003-05-07 18:08:03.000000000 +0800 -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -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 2002-11-29 07:53:15.000000000 +0800 -+++ linux-2.4.20-root/fs/ext3/ialloc.c 2003-05-07 18:08:03.000000000 +0800 -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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 2002-11-29 07:53:15.000000000 +0800 -+++ linux-2.4.20-root/fs/ext3/inode.c 2003-05-07 18:08:03.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])); -+ } - ext3_set_inode_flags(inode); - return; - ---- linux-2.4.20/fs/ext3/namei.c~linux-2.4.20-xattr-0.8.54 2003-05-05 19:01:05.000000000 +0800 -+++ linux-2.4.20-root/fs/ext3/namei.c 2003-05-07 18:08:03.000000000 +0800 -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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-05-05 19:01:02.000000000 +0800 -+++ linux-2.4.20-root/fs/ext3/super.c 2003-05-07 18:08:39.000000000 +0800 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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,17 +1783,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-2.4.20/fs/ext3/symlink.c~linux-2.4.20-xattr-0.8.54 2001-11-10 06:25:04.000000000 +0800 -+++ linux-2.4.20-root/fs/ext3/symlink.c 2003-05-07 18:08:03.000000000 +0800 -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - 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.20-root/fs/ext3/xattr.c 2003-05-07 18:09:23.000000000 +0800 -@@ -0,0 +1,1225 @@ -+/* -+ * linux/fs/ext3/xattr.c -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ * -+ * Fix by Harrison Xing . -+ * Ext3 code with a lot of help from Eric Jarman . -+ * Extended attributes for symlinks and special files added per -+ * suggestion of Luka Renko . -+ */ -+ -+/* -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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; iprefix); -+ 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; -+ (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_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.20-root/fs/ext3/xattr_user.c 2003-05-07 18:08:03.000000000 +0800 -@@ -0,0 +1,111 @@ -+/* -+ * linux/fs/ext3/xattr_user.c -+ * Handler for extended user attributes. -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+# include -+#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 2002-11-29 07:53:15.000000000 +0800 -+++ linux-2.4.20-root/fs/jfs/jfs_xattr.h 2003-05-07 18:08:03.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 2002-11-29 07:53:15.000000000 +0800 -+++ linux-2.4.20-root/fs/jfs/xattr.c 2003-05-07 18:08:03.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 2003-01-30 18:24:37.000000000 +0800 -+++ linux-2.4.20-root/fs/mbcache.c 2003-05-07 18:08:03.000000000 +0800 -@@ -0,0 +1,648 @@ -+/* -+ * linux/fs/mbcache.c -+ * (C) 2001-2002 Andreas Gruenbacher, -+ */ -+ -+/* -+ * 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 -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#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 "); -+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; ne_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; nc_block_hash[n]); -+ for (m=0; mc_indexes_hash[m] = kmalloc(bucket_count * -+ sizeof(struct list_head), -+ GFP_KERNEL); -+ if (!cache->c_indexes_hash[m]) -+ goto fail; -+ for (n=0; nc_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; ne_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<=indexc_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<=indexe_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 2002-08-03 08:39:45.000000000 +0800 -+++ linux-2.4.20-root/include/asm-arm/unistd.h 2003-05-07 18:08:03.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-ppc64/unistd.h~linux-2.4.20-xattr-0.8.54 2002-08-03 08:39:45.000000000 +0800 -+++ linux-2.4.20-root/include/asm-ppc64/unistd.h 2003-05-07 18:08:03.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 2002-08-03 08:39:45.000000000 +0800 -+++ linux-2.4.20-root/include/asm-s390/unistd.h 2003-05-07 18:08:03.000000000 +0800 -@@ -212,9 +212,18 @@ - #define __NR_getdents64 220 - #define __NR_fcntl64 221 - #define __NR_readahead 222 --/* -- * 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 2002-08-03 08:39:45.000000000 +0800 -+++ linux-2.4.20-root/include/asm-s390x/unistd.h 2003-05-07 18:08:03.000000000 +0800 -@@ -180,9 +180,18 @@ - #define __NR_mincore 218 - #define __NR_madvise 219 - #define __NR_readahead 222 --/* -- * 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 - ---- /dev/null 2003-01-30 18:24:37.000000000 +0800 -+++ linux-2.4.20-root/include/linux/cache_def.h 2003-05-07 18:08:03.000000000 +0800 -@@ -0,0 +1,15 @@ -+/* -+ * linux/cache_def.h -+ * Handling of caches defined in drivers, filesystems, ... -+ * -+ * Copyright (C) 2002 by Andreas Gruenbacher, -+ */ -+ -+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-14 16:39:03.000000000 +0800 -+++ linux-2.4.20-root/include/linux/errno.h 2003-05-07 18:08:03.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-14 16:39:08.000000000 +0800 -+++ linux-2.4.20-root/include/linux/ext2_fs.h 2003-05-07 18:08:03.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.20-root/include/linux/ext2_xattr.h 2003-05-07 18:08:03.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, -+*/ -+ -+#include -+#include -+#include -+ -+/* 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<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-05-05 19:01:04.000000000 +0800 -+++ linux-2.4.20-root/include/linux/ext3_fs.h 2003-05-07 18:08:03.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-05-05 19:01:02.000000000 +0800 -+++ linux-2.4.20-root/include/linux/ext3_jbd.h 2003-05-07 18:08:03.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 2003-01-30 18:24:37.000000000 +0800 -+++ linux-2.4.20-root/include/linux/ext3_xattr.h 2003-05-07 18:08:03.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, -+*/ -+ -+#include -+#include -+#include -+ -+/* 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<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-05-05 19:00:55.000000000 +0800 -+++ linux-2.4.20-root/include/linux/fs.h 2003-05-07 18:08:03.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 2003-01-30 18:24:37.000000000 +0800 -+++ linux-2.4.20-root/include/linux/mbcache.h 2003-05-07 18:08:03.000000000 +0800 -@@ -0,0 +1,69 @@ -+/* -+ File: linux/mbcache.h -+ -+ (C) 2001 by Andreas Gruenbacher, -+*/ -+ -+/* 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-05-05 17:43:15.000000000 +0800 -+++ linux-2.4.20-root/kernel/ksyms.c 2003-05-07 18:08:03.000000000 +0800 -@@ -11,6 +11,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -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 2002-11-29 07:53:15.000000000 +0800 -+++ linux-2.4.20-root/mm/vmscan.c 2003-05-07 18:08:03.000000000 +0800 -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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 ---- /dev/null 2003-01-30 18:24:37.000000000 +0800 -+++ linux-root/fs/ext3/ext3-exports.c 2003-05-05 18:19:11.000000000 +0800 -@@ -0,0 +1,13 @@ -+#include -+#include -+#include -+#include -+#include -+ -+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); - -_ diff --git a/lustre/kernel_patches/patches/lustre_version.patch b/lustre/kernel_patches/patches/lustre_version.patch index 121c27f..aa8c735 100644 --- a/lustre/kernel_patches/patches/lustre_version.patch +++ b/lustre/kernel_patches/patches/lustre_version.patch @@ -1,3 +1,4 @@ +Version 45: more robust and general dev_read_only for failover (b=4834) Version 44: fix link_path_walk_it() oops creating .foo in deleted "." (b=5548) Version 43: fix remove_suid to not crash 2.6, and do anything on 2.4 (b=5695) Version 42: export show_task() @@ -18,6 +19,6 @@ Version 34: ext3 iopen assertion (b=2517), operations on deleted "." (b=2399) --- /dev/null Fri Aug 30 17:31:37 2002 +++ linux-2.4.18-18.8.0-l12-braam/include/linux/lustre_version.h Thu Feb 13 07:58:33 2003 @@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 44 ++#define LUSTRE_KERNEL_VERSION 45 _ diff --git a/lustre/kernel_patches/patches/netconsole-2.4.20-rh.patch b/lustre/kernel_patches/patches/netconsole-2.4.20-rh.patch deleted file mode 100644 index c5f1ed0..0000000 --- a/lustre/kernel_patches/patches/netconsole-2.4.20-rh.patch +++ /dev/null @@ -1,469 +0,0 @@ -Index: linux-2.4.20-rh/drivers/net/netconsole.c -=================================================================== ---- linux-2.4.20-rh.orig/drivers/net/netconsole.c 2003-07-22 16:02:23.000000000 +0800 -+++ linux-2.4.20-rh/drivers/net/netconsole.c 2003-11-11 07:42:33.000000000 +0800 -@@ -12,6 +12,8 @@ - * - * 2001-09-17 started by Ingo Molnar. - * 2002-03-14 simultaneous syslog packet option by Michael K. Johnson -+ * 2003-10-30 Add sysrq command processing by Wangdi -+ * - */ - - /**************************************************************** -@@ -51,6 +53,7 @@ - #include - #include - #include -+#include "netconsole.h" - - static struct net_device *netconsole_dev; - static u16 source_port, netdump_target_port, netlog_target_port, syslog_target_port; -@@ -62,12 +65,11 @@ - static unsigned int mhz = 500, idle_timeout; - static unsigned long long mhz_cycles, jiffy_cycles; - --#include "netconsole.h" - - #define MAX_UDP_CHUNK 1460 - #define MAX_PRINT_CHUNK (MAX_UDP_CHUNK-HEADER_LEN) - --#define DEBUG 0 -+#define DEBUG 0 - #if DEBUG - # define Dprintk(x...) printk(KERN_INFO x) - #else -@@ -187,6 +189,22 @@ - } - } - } -+void (*irqfunc)(int, void *, struct pt_regs *); -+ -+static void netdump_poll(struct net_device *dev) -+{ -+ int budget = 1; -+ -+ disable_irq(dev->irq); -+ -+ irqfunc(dev->irq, dev, 0); -+ -+ if(dev->poll && test_bit(__LINK_STATE_RX_SCHED, &dev->state)) -+ dev->poll(dev, &budget); -+ -+ enable_irq(dev->irq); -+ -+} - - static struct sk_buff * alloc_netconsole_skb(struct net_device *dev, int len, int reserve) - { -@@ -209,7 +227,7 @@ - once = 0; - } - Dprintk("alloc skb: polling controller ...\n"); -- dev->poll_controller(dev); -+ netdump_poll(dev); - goto repeat; - } - } -@@ -231,7 +249,7 @@ - spin_unlock(&dev->xmit_lock); - - Dprintk("xmit skb: polling controller ...\n"); -- dev->poll_controller(dev); -+ netdump_poll(dev); - zap_completion_queue(); - goto repeat_poll; - } -@@ -426,18 +444,79 @@ - static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED; - static unsigned int log_offset; - -+static int thread_stopped = 0; -+/*Interrupt function for netdump */ -+static int sysrq_mode = 0; -+static int stop_sysrq_thread = 0; -+#define Set_Sysrq_mode() (sysrq_mode = 1) -+#define Clear_Sysrq_mode() (sysrq_mode = 0) -+static char send_cache[MAX_PRINT_CHUNK]; -+static unsigned int send_cache_pos = 0; -+wait_queue_head_t sysrq_thread_queue; -+wait_queue_head_t sysrq_thread_waiter_queue; -+ -+#define SEND_MSG_BUFFER(buf, len) \ -+do \ -+{ \ -+ reply_t reply; \ -+ unsigned int flags; \ -+ __save_flags(flags); \ -+ __cli(); \ -+ reply.code = REPLY_LOG; \ -+ reply.nr = 0; \ -+ reply.info = 0; \ -+ spin_lock(&sequence_lock); \ -+ send_netlog_skb(dev, buf, len, &reply); \ -+ spin_unlock(&sequence_lock); \ -+ __restore_flags(flags); \ -+}while(0); -+ -+void netconsole_do_sysrq(req_t *req) -+{ -+ struct pt_regs regs; -+ struct net_device *dev = netconsole_dev; -+ -+ if (!dev) -+ return; -+ Set_Sysrq_mode(); -+ get_current_regs(®s); -+ handle_sysrq((int)req->from, ®s, NULL); -+ -+ if (send_cache_pos != 0){ -+ SEND_MSG_BUFFER(send_cache, send_cache_pos); -+ memset(send_cache, 0, MAX_PRINT_CHUNK); -+ send_cache_pos = 0; -+ } -+ -+ Clear_Sysrq_mode(); -+} - static void write_netconsole_msg(struct console *con, const char *msg0, unsigned int msg_len) - { - int len, left, i; - struct net_device *dev; - const char *msg = msg0; - reply_t reply; -- -+ - dev = netconsole_dev; - if (!dev || netdump_mode) - return; -- -- if (dev->poll_controller && netif_running(dev)) { -+ if (sysrq_mode){ -+ unsigned long total_len = send_cache_pos + msg_len; -+ unsigned long left_len = msg_len; -+ while (total_len >= MAX_PRINT_CHUNK){ -+ unsigned long send_len = MAX_PRINT_CHUNK - send_cache_pos; -+ memcpy(send_cache + send_cache_pos, msg, send_len); -+ SEND_MSG_BUFFER(send_cache, MAX_PRINT_CHUNK); -+ send_cache_pos = 0; -+ total_len -= MAX_PRINT_CHUNK; -+ left_len -= send_len; -+ } -+ if (left_len > 0){ -+ memcpy(send_cache + send_cache_pos, msg + (msg_len -left_len), left_len); -+ send_cache_pos += left_len; -+ } -+ return; -+ }else if (netif_running(dev)) { - unsigned long flags; - - __save_flags(flags); -@@ -567,8 +646,6 @@ - req_t *req; - struct net_device *dev; - -- if (!netdump_mode) -- return NET_RX_SUCCESS; - #if DEBUG - { - static int packet_count; -@@ -722,8 +799,16 @@ - Dprintk("... netdump from: %08x.\n", req->from); - Dprintk("... netdump to: %08x.\n", req->to); - -- add_new_req(req); -+ if (netdump_mode) -+ add_new_req(req); -+ else if (req->command == COMM_SYSRQ){ -+ add_new_req(req); -+ wake_up(&sysrq_thread_queue); -+ return NET_RX_DROP; -+ } - out: -+ if (!netdump_mode) -+ return NET_RX_SUCCESS; - return NET_RX_DROP; - } - -@@ -763,6 +848,7 @@ - kunmap_atomic(kaddr, KM_NETDUMP); - } - -+ - /* - * This function waits for the client to acknowledge the receipt - * of the netdump startup reply, with the possibility of packets -@@ -792,7 +878,7 @@ - // wait 1 sec. - udelay(100); - Dprintk("handshake: polling controller ...\n"); -- dev->poll_controller(dev); -+ netdump_poll(dev); - zap_completion_queue(); - req = get_new_req(); - if (req) -@@ -904,7 +990,7 @@ - while (netdump_mode) { - __cli(); - Dprintk("main netdump loop: polling controller ...\n"); -- dev->poll_controller(dev); -+ netdump_poll(dev); - zap_completion_queue(); - #if !CLI - __sti(); -@@ -1009,6 +1095,32 @@ - printk("NETDUMP END!\n"); - __restore_flags(flags); - } -+static int netconsole_sysrq_schedule(void *arg) -+{ -+ struct task_struct *tsk = current; -+ -+ sprintf(tsk->comm, "sysrq_schedule"); -+ sigfillset(&tsk->blocked); -+ -+ /* main loop */ -+ thread_stopped = 0; -+ for (;;) { -+ wait_event_interruptible(sysrq_thread_queue, -+ !list_empty(&request_list) || stop_sysrq_thread); -+ while (!list_empty(&request_list)) { -+ req_t *req = get_new_req(); -+ if (req->command == COMM_SYSRQ) -+ netconsole_do_sysrq(req); -+ } -+ if (stop_sysrq_thread) -+ break; -+ wake_up(&sysrq_thread_waiter_queue); -+ } -+ thread_stopped = 1; -+ wake_up(&sysrq_thread_waiter_queue); -+ return 0; -+} -+ - - static char *dev; - static int netdump_target_eth_byte0 = 255; -@@ -1087,11 +1199,12 @@ - - static struct console netconsole = - { flags: CON_ENABLED, write: write_netconsole_msg }; -- - static int init_netconsole(void) - { - struct net_device *ndev = NULL; - struct in_device *in_dev; -+ struct irqaction *action; -+ int rc = 0; - - printk(KERN_INFO "netlog: using network device <%s>\n", dev); - // this will be valid once the device goes up. -@@ -1101,10 +1214,6 @@ - printk(KERN_ERR "netlog: network device %s does not exist, aborting.\n", dev); - return -1; - } -- if (!ndev->poll_controller) { -- printk(KERN_ERR "netlog: %s's network driver does not implement netlogging yet, aborting.\n", dev); -- return -1; -- } - in_dev = in_dev_get(ndev); - if (!in_dev) { - printk(KERN_ERR "netlog: network device %s is not an IP protocol device, aborting.\n", dev); -@@ -1137,8 +1246,6 @@ - if (!netdump_target_ip && !netlog_target_ip && !syslog_target_ip) { - printk(KERN_ERR "netlog: target_ip parameter not specified, aborting.\n"); - return -1; -- } -- if (netdump_target_ip) { - #define IP(x) ((unsigned char *)&netdump_target_ip)[x] - printk(KERN_INFO "netlog: using netdump target IP %u.%u.%u.%u\n", - IP(3), IP(2), IP(1), IP(0)); -@@ -1214,12 +1321,27 @@ - - mhz_cycles = (unsigned long long)mhz * 1000000ULL; - jiffy_cycles = (unsigned long long)mhz * (1000000/HZ); -- -- INIT_LIST_HEAD(&request_list); -- -+ - ndev->rx_hook = netconsole_rx_hook; - netdump_func = netconsole_netdump; - netconsole_dev = ndev; -+ /* find irq function of the ndev*/ -+ action=find_irq_action(ndev->irq, ndev); -+ if (!action) { -+ printk(KERN_ERR "couldn't find irq handler for <%s>", dev); -+ return -1; -+ } -+ irqfunc = action->handler; -+ -+ stop_sysrq_thread = 0; -+ INIT_LIST_HEAD(&request_list); -+ init_waitqueue_head(&sysrq_thread_queue); -+ init_waitqueue_head(&sysrq_thread_waiter_queue); -+ if ((rc = kernel_thread(netconsole_sysrq_schedule, NULL, 0)) < 0 ){ -+ printk(KERN_ERR "Can not start netconsole sysrq thread: rc %d\n", rc); -+ return -1; -+ } -+ - #define STARTUP_MSG "[...network console startup...]\n" - write_netconsole_msg(NULL, STARTUP_MSG, strlen(STARTUP_MSG)); - -@@ -1230,7 +1352,11 @@ - - static void cleanup_netconsole(void) - { -- printk(KERN_INFO "netlog: network logging shut down.\n"); -+ stop_sysrq_thread = 1; -+ -+ wake_up(&sysrq_thread_queue); -+ wait_event(sysrq_thread_waiter_queue, thread_stopped); -+ printk(KERN_INFO"netlog: network logging shut down.\n"); - unregister_console(&netconsole); - - #define SHUTDOWN_MSG "[...network console shutdown...]\n" -Index: linux-2.4.20-rh/drivers/net/netconsole.h -=================================================================== ---- linux-2.4.20-rh.orig/drivers/net/netconsole.h 2003-07-22 16:02:23.000000000 +0800 -+++ linux-2.4.20-rh/drivers/net/netconsole.h 2003-10-30 01:48:45.000000000 +0800 -@@ -29,7 +29,7 @@ - * - ****************************************************************/ - --#define NETCONSOLE_VERSION 0x04 -+#define NETCONSOLE_VERSION 0x03 - - enum netdump_commands { - COMM_NONE = 0, -@@ -42,6 +42,8 @@ - COMM_START_NETDUMP_ACK = 7, - COMM_GET_REGS = 8, - COMM_SHOW_STATE = 9, -+ COMM_START_WRITE_NETDUMP_ACK = 10, -+ COMM_SYSRQ = 11, - }; - - #define NETDUMP_REQ_SIZE (8+4*4) -@@ -69,6 +71,7 @@ - REPLY_REGS = 10, - REPLY_MAGIC = 11, - REPLY_SHOW_STATE = 12, -+ REPLY_SYSRQ = 13, - }; - - typedef struct netdump_reply_s { -@@ -78,4 +81,22 @@ - } reply_t; - - #define HEADER_LEN (1 + sizeof(reply_t)) -- -+/* for netconsole */ -+static inline void get_current_regs(struct pt_regs *regs) -+{ -+ __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx)); -+ __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx)); -+ __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx)); -+ __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi)); -+ __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi)); -+ __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp)); -+ __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax)); -+ __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp)); -+ __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss)); -+ __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs)); -+ __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds)); -+ __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes)); -+ __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags)); -+ regs->eip = (unsigned long)current_text_addr(); -+} -+ -Index: linux-2.4.20-rh/arch/i386/kernel/irq.c -=================================================================== ---- linux-2.4.20-rh.orig/arch/i386/kernel/irq.c 2003-10-30 08:29:38.000000000 +0800 -+++ linux-2.4.20-rh/arch/i386/kernel/irq.c 2003-10-30 08:30:13.000000000 +0800 -@@ -1043,7 +1043,20 @@ - register_irq_proc(irq); - return 0; - } -+struct irqaction *find_irq_action(unsigned int irq, void *dev_id) -+{ -+ struct irqaction *a, *r=0; - -+ spin_lock_irq(&irq_desc[irq].lock); -+ for(a=irq_desc[irq].action; a; a=a->next) { -+ if(a->dev_id == dev_id) { -+ r=a; -+ break; -+ } -+ } -+ spin_unlock_irq(&irq_desc[irq].lock); -+ return r; -+} - - static struct proc_dir_entry * root_irq_dir; - static struct proc_dir_entry * irq_dir [NR_IRQS]; -Index: linux-2.4.20-rh/net/core/dev.c -=================================================================== ---- linux-2.4.20-rh.orig/net/core/dev.c 2003-10-29 01:40:26.000000000 +0800 -+++ linux-2.4.20-rh/net/core/dev.c 2003-10-30 01:48:45.000000000 +0800 -@@ -1475,6 +1475,16 @@ - - skb_bond(skb); - -+ if (unlikely(skb->dev->rx_hook != NULL)) { -+ int ret; -+ -+ ret = skb->dev->rx_hook(skb); -+ if (ret == NET_RX_DROP){ -+ kfree_skb(skb); -+ return ret; -+ } -+ } -+ - netdev_rx_stat[smp_processor_id()].total++; - - #ifdef CONFIG_NET_FASTROUTE -Index: linux-2.4.20-rh/include/asm-i386/irq.h -=================================================================== ---- linux-2.4.20-rh.orig/include/asm-i386/irq.h 2003-10-28 16:18:18.000000000 +0800 -+++ linux-2.4.20-rh/include/asm-i386/irq.h 2003-10-30 10:24:49.000000000 +0800 -@@ -38,7 +38,7 @@ - extern void disable_irq_nosync(unsigned int); - extern void enable_irq(unsigned int); - extern void release_x86_irqs(struct task_struct *); -- -+extern struct irqaction *find_irq_action(unsigned int irq, void *dev_id); - #ifdef CONFIG_X86_LOCAL_APIC - #define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */ - #endif -Index: linux-2.4.20-rh/arch/i386/kernel/i386_ksyms.c -=================================================================== ---- linux-2.4.20-rh.orig/arch/i386/kernel/i386_ksyms.c 2003-10-28 19:44:57.000000000 +0800 -+++ linux-2.4.20-rh/arch/i386/kernel/i386_ksyms.c 2003-10-30 11:14:55.000000000 +0800 -@@ -68,6 +68,7 @@ - EXPORT_SYMBOL(iounmap); - EXPORT_SYMBOL(enable_irq); - EXPORT_SYMBOL(disable_irq); -+EXPORT_SYMBOL(find_irq_action); - EXPORT_SYMBOL(disable_irq_nosync); - EXPORT_SYMBOL(probe_irq_mask); - EXPORT_SYMBOL(kernel_thread); -@@ -199,7 +200,6 @@ - EXPORT_SYMBOL(edd); - EXPORT_SYMBOL(eddnr); - #endif -- - EXPORT_SYMBOL_GPL(show_mem); - EXPORT_SYMBOL_GPL(show_state); - EXPORT_SYMBOL_GPL(show_regs); -Index: linux-2.4.20-rh/kernel/panic.c -=================================================================== ---- linux-2.4.20-rh.orig/kernel/panic.c 2003-10-31 07:25:19.000000000 +0800 -+++ linux-2.4.20-rh/kernel/panic.c 2003-10-31 07:25:59.000000000 +0800 -@@ -219,8 +219,6 @@ - } - #endif - -- if (netdump_func) -- BUG(); - if (in_interrupt()) - printk(KERN_EMERG "In interrupt handler - not syncing\n"); - else if (!current->pid) diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20-rh.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20-rh.patch deleted file mode 100644 index 2f7f190..0000000 --- a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20-rh.patch +++ /dev/null @@ -1,739 +0,0 @@ - fs/Makefile | 3 - fs/file_table.c | 11 ++ - fs/inode.c | 23 ++++- - fs/namei.c | 12 ++ - fs/nfsd/export.c | 5 + - fs/nfsd/nfsfh.c | 65 +++++++++++++- - fs/nfsd/vfs.c | 240 ++++++++++++++++++++++++++++++++++++++++++++++++----- - include/linux/fs.h | 10 ++ - kernel/ksyms.c | 2 - 9 files changed, 337 insertions(+), 34 deletions(-) - ---- linux-2.4.20-rh-20.9/fs/file_table.c~nfs_export_kernel-2.4.20-rh 2002-11-29 02:53:15.000000000 +0300 -+++ linux-2.4.20-rh-20.9-alexey/fs/file_table.c 2003-10-08 10:48:38.000000000 +0400 -@@ -82,7 +82,8 @@ struct file * get_empty_filp(void) - * and call the open function (if any). The caller must verify that - * inode->i_fop is not NULL. - */ --int init_private_file(struct file *filp, struct dentry *dentry, int mode) -+int init_private_file_it(struct file *filp, struct dentry *dentry, int mode, -+ struct lookup_intent *it) - { - memset(filp, 0, sizeof(*filp)); - filp->f_mode = mode; -@@ -90,12 +91,20 @@ int init_private_file(struct file *filp, - filp->f_dentry = dentry; - filp->f_uid = current->fsuid; - filp->f_gid = current->fsgid; -+ if (it) -+ filp->f_it = it; - filp->f_op = dentry->d_inode->i_fop; - if (filp->f_op->open) - return filp->f_op->open(dentry->d_inode, filp); - else - return 0; - } -+EXPORT_SYMBOL(init_private_file_it); -+ -+int init_private_file(struct file *filp, struct dentry *dentry, int mode) -+{ -+ return init_private_file_it(filp, dentry, mode, NULL); -+} - - void fput(struct file * file) - { ---- linux-2.4.20-rh-20.9/fs/inode.c~nfs_export_kernel-2.4.20-rh 2003-09-14 17:35:22.000000000 +0400 -+++ linux-2.4.20-rh-20.9-alexey/fs/inode.c 2003-10-08 10:48:38.000000000 +0400 -@@ -1063,9 +1063,10 @@ struct inode *igrab(struct inode *inode) - } - - --struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque) -+static inline struct inode *ifind(struct super_block *sb, unsigned long ino, -+ struct list_head *head, -+ find_inode_t find_actor, void *opaque) - { -- struct list_head * head = inode_hashtable + hash(sb,ino); - struct inode * inode; - - spin_lock(&inode_lock); -@@ -1078,6 +1079,24 @@ struct inode *iget4(struct super_block * - } - spin_unlock(&inode_lock); - -+ return NULL; -+} -+ -+struct inode *ilookup4(struct super_block *sb, unsigned long ino, -+ find_inode_t find_actor, void *opaque) -+{ -+ struct list_head * head = inode_hashtable + hash(sb,ino); -+ return ifind(sb, ino, head, find_actor, opaque); -+} -+ -+struct inode *iget4(struct super_block *sb, unsigned long ino, -+ find_inode_t find_actor, void *opaque) -+{ -+ struct list_head * head = inode_hashtable + hash(sb,ino); -+ struct inode *inode = ifind(sb, ino, head, find_actor, opaque); -+ if (inode) -+ return inode; -+ - /* - * get_new_inode() will do the right thing, re-trying the search - * in case it had to block at any point. ---- linux-2.4.20-rh-20.9/fs/Makefile~nfs_export_kernel-2.4.20-rh 2003-09-14 17:35:20.000000000 +0400 -+++ linux-2.4.20-rh-20.9-alexey/fs/Makefile 2003-10-08 10:49:33.000000000 +0400 -@@ -9,7 +9,8 @@ - - O_TARGET := fs.o - --export-objs := filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o inode.o -+export-objs := filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o inode.o \ -+ namei.o file_table.o - mod-subdirs := nls - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ ---- linux-2.4.20-rh-20.9/fs/namei.c~nfs_export_kernel-2.4.20-rh 2003-09-14 17:35:22.000000000 +0400 -+++ linux-2.4.20-rh-20.9-alexey/fs/namei.c 2003-10-08 10:48:38.000000000 +0400 -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -100,6 +101,7 @@ void intent_release(struct lookup_intent - it->it_op_release(it); - - } -+EXPORT_SYMBOL(intent_release); - - static void *lock_dir(struct inode *dir, struct qstr *name) - { -@@ -959,7 +961,8 @@ struct dentry * lookup_hash(struct qstr - - - /* 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; -@@ -979,11 +982,16 @@ struct dentry * lookup_one_len(const cha - } - this.hash = end_name_hash(hash); - -- return lookup_hash_it(&this, base, NULL); -+ return lookup_hash_it(&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() - * ---- linux-2.4.20-rh-20.9/fs/nfsd/export.c~nfs_export_kernel-2.4.20-rh 2003-09-13 19:34:35.000000000 +0400 -+++ linux-2.4.20-rh-20.9-alexey/fs/nfsd/export.c 2003-10-08 10:48:38.000000000 +0400 -@@ -222,6 +222,11 @@ exp_export(struct nfsctl_export *nxp) - inode = nd.dentry->d_inode; - dev = inode->i_dev; - ino = inode->i_ino; -+ if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) && -+ !(nxp->ex_flags & NFSEXP_FSID)) { -+ nxp->ex_dev = inode->i_sb->s_dev; -+ nxp->ex_flags |= NFSEXP_FSID; -+ } - err = -EINVAL; - - exp = exp_get(clp, dev, ino); ---- linux-2.4.20-rh-20.9/fs/nfsd/nfsfh.c~nfs_export_kernel-2.4.20-rh 2003-09-13 19:34:15.000000000 +0400 -+++ linux-2.4.20-rh-20.9-alexey/fs/nfsd/nfsfh.c 2003-10-08 10:48:38.000000000 +0400 -@@ -36,6 +36,13 @@ struct nfsd_getdents_callback { - int sequence; /* sequence counter */ - }; - -+static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry) -+{ -+ if (inode->i_op->lookup_it) -+ return inode->i_op->lookup_it(inode, dentry, NULL, 0); -+ return inode->i_op->lookup(inode, dentry); -+} -+ - /* - * A rather strange filldir function to capture - * the name matching the specified inode number. -@@ -75,6 +84,8 @@ static int nfsd_get_name(struct dentry * - int error; - struct file file; - struct nfsd_getdents_callback buffer; -+ struct lookup_intent it; -+ struct file *filp = NULL; - - error = -ENOTDIR; - if (!dir || !S_ISDIR(dir->i_mode)) -@@ -85,9 +96,37 @@ static int nfsd_get_name(struct dentry * - /* - * Open the directory ... - */ -- error = init_private_file(&file, dentry, FMODE_READ); -- if (error) -+ if (dentry->d_op && dentry->d_op->d_revalidate_it) { -+ if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) && -+ (dentry->d_parent == dentry) ) { -+ it.it_op_release = NULL; -+ /* -+ * XXX Temporary Hack: Simulate init_private_file without -+ * f_op->open for disconnected dentry as we don't have -+ * actual dentry->d_name to revalidate in revalidate_it() -+ */ -+ filp = &file; -+ memset(filp, 0, sizeof(*filp)); -+ filp->f_mode = FMODE_READ; -+ atomic_set(&filp->f_count, 1); -+ filp->f_dentry = dentry; -+ filp->f_uid = current->fsuid; -+ filp->f_gid = current->fsgid; -+ filp->f_op = dentry->d_inode->i_fop; -+ error = 0; -+ } else { -+ intent_init(&it, IT_OPEN, 0); -+ error = revalidate_it(dentry, &it); -+ if (error) -+ goto out; -+ error = init_private_file_it(&file, dentry, FMODE_READ, &it); -+ } -+ } else { -+ error = init_private_file_it(&file, dentry, FMODE_READ, NULL); -+ } -+ if (error) - goto out; -+ - error = -EINVAL; - if (!file.f_op->readdir) - goto out_close; -@@ -113,9 +152,12 @@ static int nfsd_get_name(struct dentry * - } - - out_close: -- if (file.f_op->release) -+ if (file.f_op->release && !filp) - file.f_op->release(dir, &file); - out: -+ if (dentry->d_op && dentry->d_op->d_revalidate_it && -+ it.it_op_release && !filp) -+ intent_release(&it); - return error; - } - -@@ -274,7 +317,7 @@ struct dentry *nfsd_findparent(struct de - * it is well connected. But nobody returns different dentrys do they? - */ - down(&child->d_inode->i_sem); -- pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry); -+ pdentry = lookup_it(child->d_inode, tdentry); - up(&child->d_inode->i_sem); - d_drop(tdentry); /* we never want ".." hashed */ - if (!pdentry && tdentry->d_inode == NULL) { -@@ -306,6 +349,8 @@ struct dentry *nfsd_findparent(struct de - igrab(tdentry->d_inode); - pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED; - } -+ if (child->d_op && child->d_op->d_revalidate_it) -+ pdentry->d_op = child->d_op; - } - if (pdentry == NULL) - pdentry = ERR_PTR(-ENOMEM); -@@ -463,6 +508,8 @@ find_fh_dentry(struct super_block *sb, _ - struct dentry *pdentry; - struct inode *parent; - -+ if (result->d_op && result->d_op->d_revalidate_it) -+ dentry->d_op = result->d_op; - pdentry = nfsd_findparent(dentry); - err = PTR_ERR(pdentry); - if (IS_ERR(pdentry)) -@@ -669,6 +716,10 @@ fh_verify(struct svc_rqst *rqstp, struct - - inode = dentry->d_inode; - -+ /* cache coherency for non-device filesystems */ -+ if (inode->i_op && inode->i_op->revalidate_it) -+ inode->i_op->revalidate_it(dentry, NULL); -+ - /* Type check. The correct error return for type mismatches - * does not seem to be generally agreed upon. SunOS seems to - * use EISDIR if file isn't S_IFREG; a comment in the NFSv3 -@@ -912,8 +964,9 @@ out_negative: - dentry->d_parent->d_name.name, dentry->d_name.name); - goto out; - out_uptodate: -- printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n", -- dentry->d_parent->d_name.name, dentry->d_name.name); -+ if (!dentry->d_parent->d_inode->i_op->mkdir_raw) -+ printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n", -+ dentry->d_parent->d_name.name, dentry->d_name.name); - goto out; - } - ---- linux-2.4.20-rh-20.9/fs/nfsd/vfs.c~nfs_export_kernel-2.4.20-rh 2003-09-13 19:34:15.000000000 +0400 -+++ linux-2.4.20-rh-20.9-alexey/fs/nfsd/vfs.c 2003-10-08 10:48:38.000000000 +0400 -@@ -77,6 +77,126 @@ struct raparms { - static struct raparms * raparml; - static struct raparms * raparm_cache; - -+static int link_raw(struct dentry *dold, struct dentry *ddir, -+ struct dentry *dnew) -+{ -+ int err; -+ -+ struct nameidata old_nd = { .dentry = dold }; -+ struct nameidata nd = { .dentry = ddir, .last = dnew->d_name }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->link_raw(&old_nd, &nd); -+ d_instantiate(dnew, dold->d_inode); -+ if (dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it) -+ dold->d_inode->i_op->revalidate_it(dnew, NULL); -+ -+ return err; -+} -+ -+static int unlink_raw(struct dentry *dentry, char *fname, int flen, -+ struct dentry *rdentry) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->unlink_raw(&nd); -+ if (!err) -+ d_delete(rdentry); -+ -+ return err; -+} -+ -+static int rmdir_raw(struct dentry *dentry, char *fname, int flen, -+ struct dentry *rdentry) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->rmdir_raw(&nd); -+ if (!err) { -+ rdentry->d_inode->i_flags |= S_DEAD; -+ d_delete(rdentry); -+ } -+ -+ return err; -+} -+ -+static int symlink_raw(struct dentry *dentry, char *fname, int flen, -+ char *path) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->symlink_raw(&nd, path); -+ -+ return err; -+} -+ -+static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->mkdir_raw(&nd, mode); -+ -+ return err; -+} -+ -+static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode, -+ dev_t dev) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->mknod_raw(&nd, mode, dev); -+ -+ return err; -+} -+ -+static int rename_raw(struct dentry *fdentry, struct dentry *tdentry, -+ struct dentry *odentry, struct dentry *ndentry) -+{ -+ int err; -+ -+ struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name}; -+ struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name}; -+ struct inode_operations *op = old_nd.dentry->d_inode->i_op; -+ err = op->rename_raw(&old_nd, &new_nd); -+ d_move(odentry, ndentry); -+ -+ return err; -+} -+ -+static int setattr_raw(struct inode *inode, struct iattr *iap) -+{ -+ int err; -+ -+ iap->ia_valid |= ATTR_RAW; -+ err = inode->i_op->setattr_raw(inode, iap); -+ -+ return err; -+} -+ -+int revalidate_it(struct dentry *dentry, struct lookup_intent *it) -+{ -+ int err = 0; -+ -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) { -+ if (!dentry->d_op->d_revalidate_it(dentry, 0, it) && -+ !d_invalidate(dentry)) { -+ err = -EINVAL; -+ return err; -+ } -+ } -+ -+ return err; -+} -+ - /* - * Look up one component of a pathname. - * N.B. After this call _both_ fhp and resfh need an fh_put -@@ -302,7 +424,10 @@ nfsd_setattr(struct svc_rqst *rqstp, str - } - err = nfserr_notsync; - if (!check_guard || guardtime == inode->i_ctime) { -- err = notify_change(dentry, iap); -+ if (dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw) -+ err = setattr_raw(dentry->d_inode, iap); -+ else -+ err = notify_change(dentry, iap); - err = nfserrno(err); - } - if (size_change) { -@@ -429,6 +554,7 @@ nfsd_open(struct svc_rqst *rqstp, struct - { - struct dentry *dentry; - struct inode *inode; -+ struct lookup_intent it; - int err; - - /* If we get here, then the client has already done an "open", and (hopefully) -@@ -475,6 +601,18 @@ nfsd_open(struct svc_rqst *rqstp, struct - filp->f_mode = FMODE_READ; - } - -+#ifndef O_OWNER_OVERRIDE -+#define O_OWNER_OVERRIDE 0200000000 -+#endif -+ intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode | -+ O_OWNER_OVERRIDE); -+ -+ err = revalidate_it(dentry, &it); -+ if (err) -+ goto out_nfserr; -+ -+ filp->f_it = ⁢ -+ - err = 0; - if (filp->f_op && filp->f_op->open) { - err = filp->f_op->open(inode, filp); -@@ -489,6 +623,9 @@ nfsd_open(struct svc_rqst *rqstp, struct - } - } - out_nfserr: -+ if (it.it_op_release) -+ intent_release(&it); -+ - if (err) - err = nfserrno(err); - out: -@@ -820,7 +958,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - { - struct dentry *dentry, *dchild; - struct inode *dirp; -- int err; -+ int err, error = -EOPNOTSUPP; - - err = nfserr_perm; - if (!flen) -@@ -836,20 +974,47 @@ nfsd_create(struct svc_rqst *rqstp, stru - dentry = fhp->fh_dentry; - dirp = dentry->d_inode; - -+ switch (type) { -+ case S_IFDIR: -+ if (dirp->i_op->mkdir_raw) -+ error = mkdir_raw(dentry, fname, flen, iap->ia_mode); -+ break; -+ case S_IFCHR: -+ case S_IFBLK: -+ case S_IFIFO: -+ case S_IFSOCK: -+ case S_IFREG: -+ if (dirp->i_op->mknod_raw) { -+ if (type == S_IFREG) -+ rdev = 0; -+ error = mknod_raw(dentry, fname,flen,iap->ia_mode,rdev); -+ } -+ break; -+ default: -+ printk("nfsd: bad file type %o in nfsd_create\n", type); -+ } -+ if (error && error != -EOPNOTSUPP) { -+ err = error; -+ goto out_nfserr; -+ } -+ - err = nfserr_notdir; -- if(!dirp->i_op || !dirp->i_op->lookup) -+ if (!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) - goto out; - /* - * Check whether the response file handle has been verified yet. - * If it has, the parent directory should already be locked. - */ -- if (!resfhp->fh_dentry) { -- /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */ -- fh_lock(fhp); -+ if (!resfhp->fh_dentry || dirp->i_op->lookup_it) { -+ /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create -+ * and nfsd_proc_create in case of lustre */ -+ if (!resfhp->fh_dentry) -+ fh_lock(fhp); - dchild = lookup_one_len(fname, dentry, flen); - err = PTR_ERR(dchild); - if (IS_ERR(dchild)) - goto out_nfserr; -+ resfhp->fh_dentry = NULL; - err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); - if (err) - goto out; -@@ -870,10 +1032,12 @@ nfsd_create(struct svc_rqst *rqstp, stru - * Make sure the child dentry is still negative ... - */ - err = nfserr_exist; -- if (dchild->d_inode) { -- dprintk("nfsd_create: dentry %s/%s not negative!\n", -- dentry->d_name.name, dchild->d_name.name); -- goto out; -+ if (error == -EOPNOTSUPP) { -+ if (dchild->d_inode) { -+ dprintk("nfsd_create: dentry %s/%s not negative!\n", -+ dentry->d_name.name, dchild->d_name.name); -+ goto out; -+ } - } - - if (!(iap->ia_valid & ATTR_MODE)) -@@ -886,16 +1050,19 @@ nfsd_create(struct svc_rqst *rqstp, stru - err = nfserr_perm; - switch (type) { - case S_IFREG: -- err = vfs_create(dirp, dchild, iap->ia_mode); -+ if (error == -EOPNOTSUPP) -+ err = vfs_create(dirp, dchild, iap->ia_mode); - break; - case S_IFDIR: -- err = vfs_mkdir(dirp, dchild, iap->ia_mode); -+ if (error == -EOPNOTSUPP) -+ err = vfs_mkdir(dirp, dchild, iap->ia_mode); - break; - case S_IFCHR: - case S_IFBLK: - case S_IFIFO: - case S_IFSOCK: -- err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); -+ if (error == -EOPNOTSUPP) -+ err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); - break; - default: - printk("nfsd: bad file type %o in nfsd_create\n", type); -@@ -964,7 +1131,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - /* Get all the sanity checks out of the way before - * we lock the parent. */ - err = nfserr_notdir; -- if(!dirp->i_op || !dirp->i_op->lookup) -+ if (dirp->i_op->mknod_raw) { -+ err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0); -+ if (err && err != -EOPNOTSUPP) -+ goto out_nfserr; -+ } -+ -+ if (!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) - goto out; - fh_lock(fhp); - -@@ -1015,6 +1188,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - case NFS3_CREATE_GUARDED: - err = nfserr_exist; - } -+ if (dirp->i_op->mknod_raw) -+ err = 0; - goto out; - } - -@@ -1121,7 +1296,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str - struct iattr *iap) - { - struct dentry *dentry, *dnew; -- int err, cerr; -+ int err, cerr, error = -EOPNOTSUPP; - - err = nfserr_noent; - if (!flen || !plen) -@@ -1135,12 +1310,18 @@ nfsd_symlink(struct svc_rqst *rqstp, str - goto out; - fh_lock(fhp); - dentry = fhp->fh_dentry; -+ -+ if (dentry->d_inode->i_op->symlink_raw) -+ error = symlink_raw(dentry, fname, flen, path); -+ - dnew = lookup_one_len(fname, dentry, flen); - err = PTR_ERR(dnew); - if (IS_ERR(dnew)) - goto out_nfserr; - -- err = vfs_symlink(dentry->d_inode, dnew, path); -+ err = error; -+ if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw) -+ err = vfs_symlink(dentry->d_inode, dnew, path); - if (!err) { - if (EX_ISSYNC(fhp->fh_export)) - nfsd_sync_dir(dentry); -@@ -1150,7 +1331,10 @@ nfsd_symlink(struct svc_rqst *rqstp, str - iap->ia_valid |= ATTR_CTIME; - iap->ia_mode = (iap->ia_mode&S_IALLUGO) - | S_IFLNK; -- err = notify_change(dnew, iap); -+ if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw) -+ err = setattr_raw(dnew->d_inode, iap); -+ else -+ err = notify_change(dnew, iap); - if (!err && EX_ISSYNC(fhp->fh_export)) - write_inode_now(dentry->d_inode, 1); - } -@@ -1208,7 +1392,10 @@ nfsd_link(struct svc_rqst *rqstp, struct - dold = tfhp->fh_dentry; - dest = dold->d_inode; - -- err = vfs_link(dold, dirp, dnew); -+ if (dirp->i_op->link_raw) -+ err = link_raw(dold, ddir, dnew); -+ else -+ err = vfs_link(dold, dirp, dnew); - if (!err) { - if (EX_ISSYNC(ffhp->fh_export)) { - nfsd_sync_dir(ddir); -@@ -1293,7 +1480,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ if (fdir->i_op->rename_raw) -+ err = rename_raw(fdentry, tdentry, odentry, ndentry); -+ else -+ err = vfs_rename(fdir, odentry, tdir, ndentry); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); -@@ -1314,7 +1504,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru - fill_post_wcc(tfhp); - double_up(&tdir->i_sem, &fdir->i_sem); - ffhp->fh_locked = tfhp->fh_locked = 0; -- -+ - out: - return err; - } -@@ -1360,9 +1550,15 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - err = nfserr_perm; - } else - #endif -- err = vfs_unlink(dirp, rdentry); -+ if (dirp->i_op->unlink_raw) -+ err = unlink_raw(dentry, fname, flen, rdentry); -+ else -+ err = vfs_unlink(dirp, rdentry); - } else { /* It's RMDIR */ -- err = vfs_rmdir(dirp, rdentry); -+ if (dirp->i_op->rmdir_raw) -+ err = rmdir_raw(dentry, fname, flen, rdentry); -+ else -+ err = vfs_rmdir(dirp, rdentry); - } - - dput(rdentry); ---- linux-2.4.20-rh-20.9/include/linux/fs.h~nfs_export_kernel-2.4.20-rh 2003-09-14 17:35:22.000000000 +0400 -+++ linux-2.4.20-rh-20.9-alexey/include/linux/fs.h 2003-10-08 10:48:38.000000000 +0400 -@@ -94,6 +94,8 @@ extern int leases_enable, dir_notify_ena - #define FS_SINGLE 8 /* Filesystem that can have only one superblock */ - #define FS_NOMOUNT 16 /* Never mount from userland */ - #define FS_LITTER 32 /* Keeps the tree in dcache */ -+#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for -+ * exporting non device filesystems. */ - #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon - * as nfs_rename() will be cleaned up - */ -@@ -1124,6 +1127,9 @@ extern int open_namei_it(const char *fil - 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 revalidate_it(struct dentry *dentry, struct lookup_intent *it); -+extern int init_private_file_it(struct file *, struct dentry *dentry, int mode, -+ struct lookup_intent *it); - extern int filp_close(struct file *, fl_owner_t id); - extern char * getname(const char *); - -@@ -1423,6 +1429,8 @@ extern void path_release(struct nameidat - extern int follow_down(struct vfsmount **, struct dentry **); - extern int follow_up(struct vfsmount **, struct dentry **); - extern struct dentry * lookup_one_len(const char *, struct dentry *, int); -+extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int, -+ struct lookup_intent *); - 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) -@@ -1439,6 +1447,8 @@ extern ino_t iunique(struct super_block - - typedef int (*find_inode_t)(struct inode *, unsigned long, void *); - extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *); -+extern struct inode * ilookup4(struct super_block *, unsigned long, -+ find_inode_t, void *); - static inline struct inode *iget(struct super_block *sb, unsigned long ino) - { - return iget4(sb, ino, NULL, NULL); ---- linux-2.4.20-rh-20.9/kernel/ksyms.c~nfs_export_kernel-2.4.20-rh 2003-09-14 17:35:20.000000000 +0400 -+++ linux-2.4.20-rh-20.9-alexey/kernel/ksyms.c 2003-10-08 10:48:38.000000000 +0400 -@@ -164,6 +164,7 @@ EXPORT_SYMBOL(fget); - EXPORT_SYMBOL(igrab); - EXPORT_SYMBOL(iunique); - EXPORT_SYMBOL(iget4); -+EXPORT_SYMBOL(ilookup4); - EXPORT_SYMBOL(iput); - EXPORT_SYMBOL(inode_init_once); - EXPORT_SYMBOL(force_delete); -@@ -175,6 +176,7 @@ EXPORT_SYMBOL(path_walk); - EXPORT_SYMBOL(path_release); - EXPORT_SYMBOL(__user_walk); - EXPORT_SYMBOL(lookup_one_len); -+EXPORT_SYMBOL(lookup_one_len_it); - EXPORT_SYMBOL(lookup_hash); - EXPORT_SYMBOL(sys_close); - EXPORT_SYMBOL(sys_read); - -_ diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20.patch deleted file mode 100644 index ba6fa2b..0000000 --- a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20.patch +++ /dev/null @@ -1,735 +0,0 @@ -diff -uprN linux/fs/Makefile linux-2.4.20/fs/Makefile ---- linux/fs/Makefile Sun Oct 5 21:52:51 2003 -+++ linux-2.4.20/fs/Makefile Sun Oct 5 21:47:45 2003 -@@ -7,7 +7,8 @@ - - O_TARGET := fs.o - --export-objs := filesystems.o open.o dcache.o buffer.o inode.o -+export-objs := filesystems.o open.o dcache.o buffer.o inode.o namei.o \ -+ file_table.o - mod-subdirs := nls - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ -diff -uprN linux/fs/file_table.c linux-2.4.20/fs/file_table.c ---- linux/fs/file_table.c Fri Nov 29 05:23:15 2002 -+++ linux-2.4.20/fs/file_table.c Sun Oct 5 21:47:45 2003 -@@ -82,7 +82,8 @@ struct file * get_empty_filp(void) - * and call the open function (if any). The caller must verify that - * inode->i_fop is not NULL. - */ --int init_private_file(struct file *filp, struct dentry *dentry, int mode) -+int init_private_file_it(struct file *filp, struct dentry *dentry, int mode, -+ struct lookup_intent *it) - { - memset(filp, 0, sizeof(*filp)); - filp->f_mode = mode; -@@ -90,12 +91,20 @@ int init_private_file(struct file *filp, - filp->f_dentry = dentry; - filp->f_uid = current->fsuid; - filp->f_gid = current->fsgid; -+ if (it) -+ filp->f_it = it; - filp->f_op = dentry->d_inode->i_fop; - if (filp->f_op->open) - return filp->f_op->open(dentry->d_inode, filp); - else - return 0; - } -+EXPORT_SYMBOL(init_private_file_it); -+ -+int init_private_file(struct file *filp, struct dentry *dentry, int mode) -+{ -+ return init_private_file_it(filp, dentry, mode, NULL); -+} - - void fput(struct file * file) - { -diff -uprN linux/fs/inode.c linux-2.4.20/fs/inode.c ---- linux/fs/inode.c Sun Oct 5 21:52:49 2003 -+++ linux-2.4.20/fs/inode.c Sun Oct 5 21:47:45 2003 -@@ -970,9 +970,10 @@ struct inode *igrab(struct inode *inode) - } - - --struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque) -+static inline struct inode *ifind(struct super_block *sb, unsigned long ino, -+ struct list_head *head, -+ find_inode_t find_actor, void *opaque) - { -- struct list_head * head = inode_hashtable + hash(sb,ino); - struct inode * inode; - - spin_lock(&inode_lock); -@@ -985,6 +986,24 @@ struct inode *iget4(struct super_block * - } - spin_unlock(&inode_lock); - -+ return NULL; -+} -+ -+struct inode *ilookup4(struct super_block *sb, unsigned long ino, -+ find_inode_t find_actor, void *opaque) -+{ -+ struct list_head * head = inode_hashtable + hash(sb,ino); -+ return ifind(sb, ino, head, find_actor, opaque); -+} -+ -+struct inode *iget4(struct super_block *sb, unsigned long ino, -+ find_inode_t find_actor, void *opaque) -+{ -+ struct list_head * head = inode_hashtable + hash(sb,ino); -+ struct inode *inode = ifind(sb, ino, head, find_actor, opaque); -+ if (inode) -+ return inode; -+ - /* - * get_new_inode() will do the right thing, re-trying the search - * in case it had to block at any point. -diff -uprN linux/fs/namei.c linux-2.4.20/fs/namei.c ---- linux/fs/namei.c Sun Oct 5 21:52:48 2003 -+++ linux-2.4.20/fs/namei.c Sun Oct 5 21:47:45 2003 -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -100,6 +101,7 @@ void intent_release(struct lookup_intent - it->it_op_release(it); - - } -+EXPORT_SYMBOL(intent_release); - - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the -@@ -900,7 +902,8 @@ struct dentry * lookup_hash(struct qstr - - - /* 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; -@@ -920,11 +923,16 @@ struct dentry * lookup_one_len(const cha - } - this.hash = end_name_hash(hash); - -- return lookup_hash_it(&this, base, NULL); -+ return lookup_hash_it(&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() - * -diff -uprN linux/fs/nfsd/export.c linux-2.4.20/fs/nfsd/export.c ---- linux/fs/nfsd/export.c Fri Nov 29 05:23:15 2002 -+++ linux-2.4.20/fs/nfsd/export.c Sun Oct 5 22:25:20 2003 -@@ -222,6 +222,11 @@ exp_export(struct nfsctl_export *nxp) - inode = nd.dentry->d_inode; - dev = inode->i_dev; - ino = inode->i_ino; -+ if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) && -+ !(nxp->ex_flags & NFSEXP_FSID)) { -+ nxp->ex_dev = inode->i_sb->s_dev; -+ nxp->ex_flags |= NFSEXP_FSID; -+ } - err = -EINVAL; - - exp = exp_get(clp, dev, ino); -diff -uprN linux/fs/nfsd/nfsfh.c linux-2.4.20/fs/nfsd/nfsfh.c ---- linux/fs/nfsd/nfsfh.c Fri Nov 29 05:23:15 2002 -+++ linux-2.4.20/fs/nfsd/nfsfh.c Sun Oct 5 21:47:45 2003 -@@ -36,6 +36,13 @@ struct nfsd_getdents_callback { - int sequence; /* sequence counter */ - }; - -+static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry) -+{ -+ if (inode->i_op->lookup_it) -+ return inode->i_op->lookup_it(inode, dentry, NULL, 0); -+ return inode->i_op->lookup(inode, dentry); -+} -+ - /* - * A rather strange filldir function to capture - * the name matching the specified inode number. -@@ -75,6 +84,8 @@ static int nfsd_get_name(struct dentry * - int error; - struct file file; - struct nfsd_getdents_callback buffer; -+ struct lookup_intent it; -+ struct file *filp = NULL; - - error = -ENOTDIR; - if (!dir || !S_ISDIR(dir->i_mode)) -@@ -85,9 +96,37 @@ static int nfsd_get_name(struct dentry * - /* - * Open the directory ... - */ -- error = init_private_file(&file, dentry, FMODE_READ); -- if (error) -+ if (dentry->d_op && dentry->d_op->d_revalidate_it) { -+ if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) && -+ (dentry->d_parent == dentry) ) { -+ it.it_op_release = NULL; -+ /* -+ * XXX Temporary Hack: Simulate init_private_file without -+ * f_op->open for disconnected dentry as we don't have -+ * actual dentry->d_name to revalidate in revalidate_it() -+ */ -+ filp = &file; -+ memset(filp, 0, sizeof(*filp)); -+ filp->f_mode = FMODE_READ; -+ atomic_set(&filp->f_count, 1); -+ filp->f_dentry = dentry; -+ filp->f_uid = current->fsuid; -+ filp->f_gid = current->fsgid; -+ filp->f_op = dentry->d_inode->i_fop; -+ error = 0; -+ } else { -+ intent_init(&it, IT_OPEN, 0); -+ error = revalidate_it(dentry, &it); -+ if (error) -+ goto out; -+ error = init_private_file_it(&file, dentry, FMODE_READ, &it); -+ } -+ } else { -+ error = init_private_file_it(&file, dentry, FMODE_READ, NULL); -+ } -+ if (error) - goto out; -+ - error = -EINVAL; - if (!file.f_op->readdir) - goto out_close; -@@ -113,9 +152,12 @@ static int nfsd_get_name(struct dentry * - } - - out_close: -- if (file.f_op->release) -+ if (file.f_op->release && !filp) - file.f_op->release(dir, &file); - out: -+ if (dentry->d_op && dentry->d_op->d_revalidate_it && -+ it.it_op_release && !filp) -+ intent_release(&it); - return error; - } - -@@ -274,7 +317,7 @@ struct dentry *nfsd_findparent(struct de - * it is well connected. But nobody returns different dentrys do they? - */ - down(&child->d_inode->i_sem); -- pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry); -+ pdentry = lookup_it(child->d_inode, tdentry); - up(&child->d_inode->i_sem); - d_drop(tdentry); /* we never want ".." hashed */ - if (!pdentry && tdentry->d_inode == NULL) { -@@ -306,6 +349,8 @@ struct dentry *nfsd_findparent(struct de - igrab(tdentry->d_inode); - pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED; - } -+ if (child->d_op && child->d_op->d_revalidate_it) -+ pdentry->d_op = child->d_op; - } - if (pdentry == NULL) - pdentry = ERR_PTR(-ENOMEM); -@@ -463,6 +508,8 @@ find_fh_dentry(struct super_block *sb, _ - struct dentry *pdentry; - struct inode *parent; - -+ if (result->d_op && result->d_op->d_revalidate_it) -+ dentry->d_op = result->d_op; - pdentry = nfsd_findparent(dentry); - err = PTR_ERR(pdentry); - if (IS_ERR(pdentry)) -@@ -662,6 +709,10 @@ fh_verify(struct svc_rqst *rqstp, struct - - inode = dentry->d_inode; - -+ /* cache coherency for non-device filesystems */ -+ if (inode->i_op && inode->i_op->revalidate_it) -+ inode->i_op->revalidate_it(dentry, NULL); -+ - /* Type check. The correct error return for type mismatches - * does not seem to be generally agreed upon. SunOS seems to - * use EISDIR if file isn't S_IFREG; a comment in the NFSv3 -@@ -900,8 +952,9 @@ out_negative: - dentry->d_parent->d_name.name, dentry->d_name.name); - goto out; - out_uptodate: -- printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n", -- dentry->d_parent->d_name.name, dentry->d_name.name); -+ if (!dentry->d_parent->d_inode->i_op->mkdir_raw) -+ printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n", -+ dentry->d_parent->d_name.name, dentry->d_name.name); - goto out; - } - -diff -uprN linux/fs/nfsd/vfs.c linux-2.4.20/fs/nfsd/vfs.c ---- linux/fs/nfsd/vfs.c Fri Nov 29 05:23:15 2002 -+++ linux-2.4.20/fs/nfsd/vfs.c Sun Oct 5 21:47:45 2003 -@@ -77,6 +77,126 @@ struct raparms { - static struct raparms * raparml; - static struct raparms * raparm_cache; - -+static int link_raw(struct dentry *dold, struct dentry *ddir, -+ struct dentry *dnew) -+{ -+ int err; -+ -+ struct nameidata old_nd = { .dentry = dold }; -+ struct nameidata nd = { .dentry = ddir, .last = dnew->d_name }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->link_raw(&old_nd, &nd); -+ d_instantiate(dnew, dold->d_inode); -+ if (dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it) -+ dold->d_inode->i_op->revalidate_it(dnew, NULL); -+ -+ return err; -+} -+ -+static int unlink_raw(struct dentry *dentry, char *fname, int flen, -+ struct dentry *rdentry) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->unlink_raw(&nd); -+ if (!err) -+ d_delete(rdentry); -+ -+ return err; -+} -+ -+static int rmdir_raw(struct dentry *dentry, char *fname, int flen, -+ struct dentry *rdentry) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->rmdir_raw(&nd); -+ if (!err) { -+ rdentry->d_inode->i_flags |= S_DEAD; -+ d_delete(rdentry); -+ } -+ -+ return err; -+} -+ -+static int symlink_raw(struct dentry *dentry, char *fname, int flen, -+ char *path) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->symlink_raw(&nd, path); -+ -+ return err; -+} -+ -+static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->mkdir_raw(&nd, mode); -+ -+ return err; -+} -+ -+static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode, -+ dev_t dev) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->mknod_raw(&nd, mode, dev); -+ -+ return err; -+} -+ -+static int rename_raw(struct dentry *fdentry, struct dentry *tdentry, -+ struct dentry *odentry, struct dentry *ndentry) -+{ -+ int err; -+ -+ struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name}; -+ struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name}; -+ struct inode_operations *op = old_nd.dentry->d_inode->i_op; -+ err = op->rename_raw(&old_nd, &new_nd); -+ d_move(odentry, ndentry); -+ -+ return err; -+} -+ -+static int setattr_raw(struct inode *inode, struct iattr *iap) -+{ -+ int err; -+ -+ iap->ia_valid |= ATTR_RAW; -+ err = inode->i_op->setattr_raw(inode, iap); -+ -+ return err; -+} -+ -+int revalidate_it(struct dentry *dentry, struct lookup_intent *it) -+{ -+ int err = 0; -+ -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) { -+ if (!dentry->d_op->d_revalidate_it(dentry, 0, it) && -+ !d_invalidate(dentry)) { -+ err = -EINVAL; -+ return err; -+ } -+ } -+ -+ return err; -+} -+ - /* - * Look up one component of a pathname. - * N.B. After this call _both_ fhp and resfh need an fh_put -@@ -300,7 +422,10 @@ nfsd_setattr(struct svc_rqst *rqstp, str - } - err = nfserr_notsync; - if (!check_guard || guardtime == inode->i_ctime) { -- err = notify_change(dentry, iap); -+ if (dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw) -+ err = setattr_raw(dentry->d_inode, iap); -+ else -+ err = notify_change(dentry, iap); - err = nfserrno(err); - } - if (size_change) { -@@ -427,6 +552,7 @@ nfsd_open(struct svc_rqst *rqstp, struct - { - struct dentry *dentry; - struct inode *inode; -+ struct lookup_intent it; - int err; - - /* If we get here, then the client has already done an "open", and (hopefully) -@@ -473,6 +599,18 @@ nfsd_open(struct svc_rqst *rqstp, struct - filp->f_mode = FMODE_READ; - } - -+#ifndef O_OWNER_OVERRIDE -+#define O_OWNER_OVERRIDE 0200000000 -+#endif -+ intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode | -+ O_OWNER_OVERRIDE); -+ -+ err = revalidate_it(dentry, &it); -+ if (err) -+ goto out_nfserr; -+ -+ filp->f_it = ⁢ -+ - err = 0; - if (filp->f_op && filp->f_op->open) { - err = filp->f_op->open(inode, filp); -@@ -487,6 +621,9 @@ nfsd_open(struct svc_rqst *rqstp, struct - } - } - out_nfserr: -+ if (it.it_op_release) -+ intent_release(&it); -+ - if (err) - err = nfserrno(err); - out: -@@ -818,7 +956,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - { - struct dentry *dentry, *dchild; - struct inode *dirp; -- int err; -+ int err, error = -EOPNOTSUPP; - - err = nfserr_perm; - if (!flen) -@@ -834,20 +972,47 @@ nfsd_create(struct svc_rqst *rqstp, stru - dentry = fhp->fh_dentry; - dirp = dentry->d_inode; - -+ switch (type) { -+ case S_IFDIR: -+ if (dirp->i_op->mkdir_raw) -+ error = mkdir_raw(dentry, fname, flen, iap->ia_mode); -+ break; -+ case S_IFCHR: -+ case S_IFBLK: -+ case S_IFIFO: -+ case S_IFSOCK: -+ case S_IFREG: -+ if (dirp->i_op->mknod_raw) { -+ if (type == S_IFREG) -+ rdev = 0; -+ error = mknod_raw(dentry, fname,flen,iap->ia_mode,rdev); -+ } -+ break; -+ default: -+ printk("nfsd: bad file type %o in nfsd_create\n", type); -+ } -+ if (error && error != -EOPNOTSUPP) { -+ err = error; -+ goto out_nfserr; -+ } -+ - err = nfserr_notdir; -- if(!dirp->i_op || !dirp->i_op->lookup) -+ if (!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) - goto out; - /* - * Check whether the response file handle has been verified yet. - * If it has, the parent directory should already be locked. - */ -- if (!resfhp->fh_dentry) { -- /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */ -- fh_lock(fhp); -+ if (!resfhp->fh_dentry || dirp->i_op->lookup_it) { -+ /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create -+ * and nfsd_proc_create in case of lustre */ -+ if (!resfhp->fh_dentry) -+ fh_lock(fhp); - dchild = lookup_one_len(fname, dentry, flen); - err = PTR_ERR(dchild); - if (IS_ERR(dchild)) - goto out_nfserr; -+ resfhp->fh_dentry = NULL; - err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); - if (err) - goto out; -@@ -868,10 +1030,12 @@ nfsd_create(struct svc_rqst *rqstp, stru - * Make sure the child dentry is still negative ... - */ - err = nfserr_exist; -- if (dchild->d_inode) { -- dprintk("nfsd_create: dentry %s/%s not negative!\n", -- dentry->d_name.name, dchild->d_name.name); -- goto out; -+ if (error == -EOPNOTSUPP) { -+ if (dchild->d_inode) { -+ dprintk("nfsd_create: dentry %s/%s not negative!\n", -+ dentry->d_name.name, dchild->d_name.name); -+ goto out; -+ } - } - - if (!(iap->ia_valid & ATTR_MODE)) -@@ -884,16 +1048,19 @@ nfsd_create(struct svc_rqst *rqstp, stru - err = nfserr_perm; - switch (type) { - case S_IFREG: -- err = vfs_create(dirp, dchild, iap->ia_mode); -+ if (error == -EOPNOTSUPP) -+ err = vfs_create(dirp, dchild, iap->ia_mode); - break; - case S_IFDIR: -- err = vfs_mkdir(dirp, dchild, iap->ia_mode); -+ if (error == -EOPNOTSUPP) -+ err = vfs_mkdir(dirp, dchild, iap->ia_mode); - break; - case S_IFCHR: - case S_IFBLK: - case S_IFIFO: - case S_IFSOCK: -- err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); -+ if (error == -EOPNOTSUPP) -+ err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); - break; - default: - printk("nfsd: bad file type %o in nfsd_create\n", type); -@@ -962,7 +1129,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - /* Get all the sanity checks out of the way before - * we lock the parent. */ - err = nfserr_notdir; -- if(!dirp->i_op || !dirp->i_op->lookup) -+ if (dirp->i_op->mknod_raw) { -+ err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0); -+ if (err && err != -EOPNOTSUPP) -+ goto out_nfserr; -+ } -+ -+ if (!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) - goto out; - fh_lock(fhp); - -@@ -1013,6 +1186,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - case NFS3_CREATE_GUARDED: - err = nfserr_exist; - } -+ if (dirp->i_op->mknod_raw) -+ err = 0; - goto out; - } - -@@ -1119,7 +1294,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str - struct iattr *iap) - { - struct dentry *dentry, *dnew; -- int err, cerr; -+ int err, cerr, error = -EOPNOTSUPP; - - err = nfserr_noent; - if (!flen || !plen) -@@ -1133,12 +1308,18 @@ nfsd_symlink(struct svc_rqst *rqstp, str - goto out; - fh_lock(fhp); - dentry = fhp->fh_dentry; -+ -+ if (dentry->d_inode->i_op->symlink_raw) -+ error = symlink_raw(dentry, fname, flen, path); -+ - dnew = lookup_one_len(fname, dentry, flen); - err = PTR_ERR(dnew); - if (IS_ERR(dnew)) - goto out_nfserr; - -- err = vfs_symlink(dentry->d_inode, dnew, path); -+ err = error; -+ if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw) -+ err = vfs_symlink(dentry->d_inode, dnew, path); - if (!err) { - if (EX_ISSYNC(fhp->fh_export)) - nfsd_sync_dir(dentry); -@@ -1148,7 +1329,10 @@ nfsd_symlink(struct svc_rqst *rqstp, str - iap->ia_valid |= ATTR_CTIME; - iap->ia_mode = (iap->ia_mode&S_IALLUGO) - | S_IFLNK; -- err = notify_change(dnew, iap); -+ if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw) -+ err = setattr_raw(dnew->d_inode, iap); -+ else -+ err = notify_change(dnew, iap); - if (!err && EX_ISSYNC(fhp->fh_export)) - write_inode_now(dentry->d_inode, 1); - } -@@ -1206,7 +1390,10 @@ nfsd_link(struct svc_rqst *rqstp, struct - dold = tfhp->fh_dentry; - dest = dold->d_inode; - -- err = vfs_link(dold, dirp, dnew); -+ if (dirp->i_op->link_raw) -+ err = link_raw(dold, ddir, dnew); -+ else -+ err = vfs_link(dold, dirp, dnew); - if (!err) { - if (EX_ISSYNC(ffhp->fh_export)) { - nfsd_sync_dir(ddir); -@@ -1291,7 +1478,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ if (fdir->i_op->rename_raw) -+ err = rename_raw(fdentry, tdentry, odentry, ndentry); -+ else -+ err = vfs_rename(fdir, odentry, tdir, ndentry); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); -@@ -1312,7 +1502,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru - fill_post_wcc(tfhp); - double_up(&tdir->i_sem, &fdir->i_sem); - ffhp->fh_locked = tfhp->fh_locked = 0; -- -+ - out: - return err; - } -@@ -1358,9 +1548,15 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - err = nfserr_perm; - } else - #endif -- err = vfs_unlink(dirp, rdentry); -+ if (dirp->i_op->unlink_raw) -+ err = unlink_raw(dentry, fname, flen, rdentry); -+ else -+ err = vfs_unlink(dirp, rdentry); - } else { /* It's RMDIR */ -- err = vfs_rmdir(dirp, rdentry); -+ if (dirp->i_op->rmdir_raw) -+ err = rmdir_raw(dentry, fname, flen, rdentry); -+ else -+ err = vfs_rmdir(dirp, rdentry); - } - - dput(rdentry); -diff -uprN linux/include/linux/fs.h linux-2.4.20/include/linux/fs.h ---- linux/include/linux/fs.h Sun Oct 5 21:52:56 2003 -+++ linux-2.4.20/include/linux/fs.h Sun Oct 5 22:25:20 2003 -@@ -93,6 +93,8 @@ extern int leases_enable, dir_notify_ena - #define FS_SINGLE 8 /* Filesystem that can have only one superblock */ - #define FS_NOMOUNT 16 /* Never mount from userland */ - #define FS_LITTER 32 /* Keeps the tree in dcache */ -+#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for -+ * exporting non device filesystems. */ - #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon - * as nfs_rename() will be cleaned up - */ -@@ -1099,6 +1102,9 @@ extern int open_namei_it(const char *fil - 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 revalidate_it(struct dentry *dentry, struct lookup_intent *it); -+extern int init_private_file_it(struct file *, struct dentry *dentry, int mode, -+ struct lookup_intent *it); - extern int filp_close(struct file *, fl_owner_t id); - extern char * getname(const char *); - -@@ -1369,6 +1375,8 @@ extern void path_release(struct nameidat - extern int follow_down(struct vfsmount **, struct dentry **); - extern int follow_up(struct vfsmount **, struct dentry **); - extern struct dentry * lookup_one_len(const char *, struct dentry *, int); -+extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int, -+ struct lookup_intent *); - 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) -@@ -1382,6 +1390,8 @@ extern ino_t iunique(struct super_block - - typedef int (*find_inode_t)(struct inode *, unsigned long, void *); - extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *); -+extern struct inode * ilookup4(struct super_block *, unsigned long, -+ find_inode_t, void *); - static inline struct inode *iget(struct super_block *sb, unsigned long ino) - { - return iget4(sb, ino, NULL, NULL); -diff -uprN linux/kernel/ksyms.c linux-2.4.20/kernel/ksyms.c ---- linux/kernel/ksyms.c Sun Oct 5 21:52:51 2003 -+++ linux-2.4.20/kernel/ksyms.c Sun Oct 5 22:25:20 2003 -@@ -146,6 +146,7 @@ EXPORT_SYMBOL(fget); - EXPORT_SYMBOL(igrab); - EXPORT_SYMBOL(iunique); - EXPORT_SYMBOL(iget4); -+EXPORT_SYMBOL(ilookup4); - EXPORT_SYMBOL(iput); - EXPORT_SYMBOL(force_delete); - EXPORT_SYMBOL(follow_up); -@@ -156,6 +157,7 @@ EXPORT_SYMBOL(path_walk); - EXPORT_SYMBOL(path_release); - EXPORT_SYMBOL(__user_walk); - EXPORT_SYMBOL(lookup_one_len); -+EXPORT_SYMBOL(lookup_one_len_it); - EXPORT_SYMBOL(lookup_hash); - EXPORT_SYMBOL(sys_close); - EXPORT_SYMBOL(dcache_lock); diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.22-rh.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.22-rh.patch deleted file mode 100644 index 436d99b..0000000 --- a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.22-rh.patch +++ /dev/null @@ -1,737 +0,0 @@ - fs/Makefile | 3 - fs/file_table.c | 11 ++ - fs/inode.c | 23 ++++- - fs/namei.c | 12 ++ - fs/nfsd/export.c | 5 + - fs/nfsd/nfsfh.c | 65 +++++++++++++- - fs/nfsd/vfs.c | 235 ++++++++++++++++++++++++++++++++++++++++++++++++----- - include/linux/fs.h | 11 ++ - kernel/ksyms.c | 2 - 9 files changed, 333 insertions(+), 34 deletions(-) - ---- linux-2.4.22-ac1/fs/file_table.c~nfs_export_kernel-2.4.22-rh 2002-11-29 02:53:15.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/file_table.c 2003-10-08 13:41:27.000000000 +0400 -@@ -82,7 +82,8 @@ struct file * get_empty_filp(void) - * and call the open function (if any). The caller must verify that - * inode->i_fop is not NULL. - */ --int init_private_file(struct file *filp, struct dentry *dentry, int mode) -+int init_private_file_it(struct file *filp, struct dentry *dentry, int mode, -+ struct lookup_intent *it) - { - memset(filp, 0, sizeof(*filp)); - filp->f_mode = mode; -@@ -90,12 +91,20 @@ int init_private_file(struct file *filp, - filp->f_dentry = dentry; - filp->f_uid = current->fsuid; - filp->f_gid = current->fsgid; -+ if (it) -+ filp->f_it = it; - filp->f_op = dentry->d_inode->i_fop; - if (filp->f_op->open) - return filp->f_op->open(dentry->d_inode, filp); - else - return 0; - } -+EXPORT_SYMBOL(init_private_file_it); -+ -+int init_private_file(struct file *filp, struct dentry *dentry, int mode) -+{ -+ return init_private_file_it(filp, dentry, mode, NULL); -+} - - void fput(struct file * file) - { ---- linux-2.4.22-ac1/fs/inode.c~nfs_export_kernel-2.4.22-rh 2003-09-26 00:57:28.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/inode.c 2003-10-08 13:43:31.000000000 +0400 -@@ -998,9 +998,10 @@ struct inode *igrab(struct inode *inode) - return inode; - } - --struct inode *iget4_locked(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque) -+struct inode *ifind(struct super_block *sb, unsigned long ino, -+ struct list_head *head, -+ find_inode_t find_actor, void *opaque) - { -- struct list_head * head = inode_hashtable + hash(sb,ino); - struct inode * inode; - - spin_lock(&inode_lock); -@@ -1013,6 +1014,24 @@ struct inode *iget4_locked(struct super_ - } - spin_unlock(&inode_lock); - -+ return NULL; -+} -+ -+struct inode *ilookup4(struct super_block *sb, unsigned long ino, -+ find_inode_t find_actor, void *opaque) -+{ -+ struct list_head * head = inode_hashtable + hash(sb,ino); -+ return ifind(sb, ino, head, find_actor, opaque); -+} -+ -+struct inode *iget4_locked(struct super_block *sb, unsigned long ino, -+ find_inode_t find_actor, void *opaque) -+{ -+ struct list_head * head = inode_hashtable + hash(sb,ino); -+ struct inode *inode = ifind(sb, ino, head, find_actor, opaque); -+ if (inode) -+ return inode; -+ - /* - * get_new_inode() will do the right thing, re-trying the search - * in case it had to block at any point. ---- linux-2.4.22-ac1/fs/Makefile~nfs_export_kernel-2.4.22-rh 2003-09-26 00:57:28.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/Makefile 2003-10-08 13:41:55.000000000 +0400 -@@ -7,7 +7,8 @@ - - O_TARGET := fs.o - --export-objs := filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o inode.o -+export-objs := filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o inode.o \ -+ namei.o file_table.o - mod-subdirs := nls xfs - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ ---- linux-2.4.22-ac1/fs/namei.c~nfs_export_kernel-2.4.22-rh 2003-09-26 00:57:27.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/namei.c 2003-10-08 13:41:27.000000000 +0400 -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -100,6 +101,7 @@ void intent_release(struct lookup_intent - it->it_op_release(it); - - } -+EXPORT_SYMBOL(intent_release); - - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the -@@ -903,7 +905,8 @@ struct dentry * lookup_hash(struct qstr - - - /* 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; -@@ -923,11 +926,16 @@ struct dentry * lookup_one_len(const cha - } - this.hash = end_name_hash(hash); - -- return lookup_hash_it(&this, base, NULL); -+ return lookup_hash_it(&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() - * ---- linux-2.4.22-ac1/fs/nfsd/export.c~nfs_export_kernel-2.4.22-rh 2003-09-25 14:16:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/nfsd/export.c 2003-10-08 13:41:27.000000000 +0400 -@@ -223,6 +223,11 @@ exp_export(struct nfsctl_export *nxp) - inode = nd.dentry->d_inode; - dev = inode->i_dev; - ino = inode->i_ino; -+ if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) && -+ !(nxp->ex_flags & NFSEXP_FSID)) { -+ nxp->ex_dev = inode->i_sb->s_dev; -+ nxp->ex_flags |= NFSEXP_FSID; -+ } - err = -EINVAL; - - exp = exp_get(clp, dev, ino); ---- linux-2.4.22-ac1/fs/nfsd/nfsfh.c~nfs_export_kernel-2.4.22-rh 2003-08-25 15:44:43.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/nfsd/nfsfh.c 2003-10-08 13:41:27.000000000 +0400 -@@ -36,6 +36,13 @@ struct nfsd_getdents_callback { - int sequence; /* sequence counter */ - }; - -+static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry) -+{ -+ if (inode->i_op->lookup_it) -+ return inode->i_op->lookup_it(inode, dentry, NULL, 0); -+ return inode->i_op->lookup(inode, dentry); -+} -+ - /* - * A rather strange filldir function to capture - * the name matching the specified inode number. -@@ -75,6 +84,8 @@ static int nfsd_get_name(struct dentry * - int error; - struct file file; - struct nfsd_getdents_callback buffer; -+ struct lookup_intent it; -+ struct file *filp = NULL; - - error = -ENOTDIR; - if (!dir || !S_ISDIR(dir->i_mode)) -@@ -85,9 +96,37 @@ static int nfsd_get_name(struct dentry * - /* - * Open the directory ... - */ -- error = init_private_file(&file, dentry, FMODE_READ); -- if (error) -+ if (dentry->d_op && dentry->d_op->d_revalidate_it) { -+ if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) && -+ (dentry->d_parent == dentry) ) { -+ it.it_op_release = NULL; -+ /* -+ * XXX Temporary Hack: Simulate init_private_file without -+ * f_op->open for disconnected dentry as we don't have -+ * actual dentry->d_name to revalidate in revalidate_it() -+ */ -+ filp = &file; -+ memset(filp, 0, sizeof(*filp)); -+ filp->f_mode = FMODE_READ; -+ atomic_set(&filp->f_count, 1); -+ filp->f_dentry = dentry; -+ filp->f_uid = current->fsuid; -+ filp->f_gid = current->fsgid; -+ filp->f_op = dentry->d_inode->i_fop; -+ error = 0; -+ } else { -+ intent_init(&it, IT_OPEN, 0); -+ error = revalidate_it(dentry, &it); -+ if (error) -+ goto out; -+ error = init_private_file_it(&file, dentry, FMODE_READ, &it); -+ } -+ } else { -+ error = init_private_file_it(&file, dentry, FMODE_READ, NULL); -+ } -+ if (error) - goto out; -+ - error = -EINVAL; - if (!file.f_op->readdir) - goto out_close; -@@ -113,9 +152,12 @@ static int nfsd_get_name(struct dentry * - } - - out_close: -- if (file.f_op->release) -+ if (file.f_op->release && !filp) - file.f_op->release(dir, &file); - out: -+ if (dentry->d_op && dentry->d_op->d_revalidate_it && -+ it.it_op_release && !filp) -+ intent_release(&it); - return error; - } - -@@ -274,7 +317,7 @@ struct dentry *nfsd_findparent(struct de - * it is well connected. But nobody returns different dentrys do they? - */ - down(&child->d_inode->i_sem); -- pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry); -+ pdentry = lookup_it(child->d_inode, tdentry); - up(&child->d_inode->i_sem); - d_drop(tdentry); /* we never want ".." hashed */ - if (!pdentry && tdentry->d_inode == NULL) { -@@ -306,6 +349,8 @@ struct dentry *nfsd_findparent(struct de - igrab(tdentry->d_inode); - pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED; - } -+ if (child->d_op && child->d_op->d_revalidate_it) -+ pdentry->d_op = child->d_op; - } - if (pdentry == NULL) - pdentry = ERR_PTR(-ENOMEM); -@@ -463,6 +508,8 @@ find_fh_dentry(struct super_block *sb, _ - struct dentry *pdentry; - struct inode *parent; - -+ if (result->d_op && result->d_op->d_revalidate_it) -+ dentry->d_op = result->d_op; - pdentry = nfsd_findparent(dentry); - err = PTR_ERR(pdentry); - if (IS_ERR(pdentry)) -@@ -669,6 +716,10 @@ fh_verify(struct svc_rqst *rqstp, struct - - inode = dentry->d_inode; - -+ /* cache coherency for non-device filesystems */ -+ if (inode->i_op && inode->i_op->revalidate_it) -+ inode->i_op->revalidate_it(dentry, NULL); -+ - /* Type check. The correct error return for type mismatches - * does not seem to be generally agreed upon. SunOS seems to - * use EISDIR if file isn't S_IFREG; a comment in the NFSv3 -@@ -902,8 +954,9 @@ out_negative: - dentry->d_parent->d_name.name, dentry->d_name.name); - goto out; - out_uptodate: -- printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n", -- dentry->d_parent->d_name.name, dentry->d_name.name); -+ if (!dentry->d_parent->d_inode->i_op->mkdir_raw) -+ printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n", -+ dentry->d_parent->d_name.name, dentry->d_name.name); - goto out; - } - ---- linux-2.4.22-ac1/fs/nfsd/vfs.c~nfs_export_kernel-2.4.22-rh 2003-08-25 15:44:43.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/nfsd/vfs.c 2003-10-08 13:41:27.000000000 +0400 -@@ -77,6 +77,126 @@ struct raparms { - static struct raparms * raparml; - static struct raparms * raparm_cache; - -+static int link_raw(struct dentry *dold, struct dentry *ddir, -+ struct dentry *dnew) -+{ -+ int err; -+ -+ struct nameidata old_nd = { .dentry = dold }; -+ struct nameidata nd = { .dentry = ddir, .last = dnew->d_name }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->link_raw(&old_nd, &nd); -+ d_instantiate(dnew, dold->d_inode); -+ if (dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it) -+ dold->d_inode->i_op->revalidate_it(dnew, NULL); -+ -+ return err; -+} -+ -+static int unlink_raw(struct dentry *dentry, char *fname, int flen, -+ struct dentry *rdentry) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->unlink_raw(&nd); -+ if (!err) -+ d_delete(rdentry); -+ -+ return err; -+} -+ -+static int rmdir_raw(struct dentry *dentry, char *fname, int flen, -+ struct dentry *rdentry) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->rmdir_raw(&nd); -+ if (!err) { -+ rdentry->d_inode->i_flags |= S_DEAD; -+ d_delete(rdentry); -+ } -+ -+ return err; -+} -+ -+static int symlink_raw(struct dentry *dentry, char *fname, int flen, -+ char *path) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->symlink_raw(&nd, path); -+ -+ return err; -+} -+ -+static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->mkdir_raw(&nd, mode); -+ -+ return err; -+} -+ -+static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode, -+ dev_t dev) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->mknod_raw(&nd, mode, dev); -+ -+ return err; -+} -+ -+static int rename_raw(struct dentry *fdentry, struct dentry *tdentry, -+ struct dentry *odentry, struct dentry *ndentry) -+{ -+ int err; -+ -+ struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name}; -+ struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name}; -+ struct inode_operations *op = old_nd.dentry->d_inode->i_op; -+ err = op->rename_raw(&old_nd, &new_nd); -+ d_move(odentry, ndentry); -+ -+ return err; -+} -+ -+static int setattr_raw(struct inode *inode, struct iattr *iap) -+{ -+ int err; -+ -+ iap->ia_valid |= ATTR_RAW; -+ err = inode->i_op->setattr_raw(inode, iap); -+ -+ return err; -+} -+ -+int revalidate_it(struct dentry *dentry, struct lookup_intent *it) -+{ -+ int err = 0; -+ -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) { -+ if (!dentry->d_op->d_revalidate_it(dentry, 0, it) && -+ !d_invalidate(dentry)) { -+ err = -EINVAL; -+ return err; -+ } -+ } -+ -+ return err; -+} -+ - /* - * Look up one component of a pathname. - * N.B. After this call _both_ fhp and resfh need an fh_put -@@ -302,7 +424,10 @@ nfsd_setattr(struct svc_rqst *rqstp, str - } - err = nfserr_notsync; - if (!check_guard || guardtime == inode->i_ctime) { -- err = notify_change(dentry, iap); -+ if (dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw) -+ err = setattr_raw(dentry->d_inode, iap); -+ else -+ err = notify_change(dentry, iap); - err = nfserrno(err); - } - if (size_change) { -@@ -429,6 +554,7 @@ nfsd_open(struct svc_rqst *rqstp, struct - { - struct dentry *dentry; - struct inode *inode; -+ struct lookup_intent it; - int err; - - /* If we get here, then the client has already done an "open", and (hopefully) -@@ -475,6 +601,18 @@ nfsd_open(struct svc_rqst *rqstp, struct - filp->f_mode = FMODE_READ; - } - -+#ifndef O_OWNER_OVERRIDE -+#define O_OWNER_OVERRIDE 0200000000 -+#endif -+ intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode | -+ O_OWNER_OVERRIDE); -+ -+ err = revalidate_it(dentry, &it); -+ if (err) -+ goto out_nfserr; -+ -+ filp->f_it = ⁢ -+ - err = 0; - if (filp->f_op && filp->f_op->open) { - err = filp->f_op->open(inode, filp); -@@ -489,6 +623,9 @@ nfsd_open(struct svc_rqst *rqstp, struct - } - } - out_nfserr: -+ if (it.it_op_release) -+ intent_release(&it); -+ - if (err) - err = nfserrno(err); - out: -@@ -820,7 +958,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - { - struct dentry *dentry, *dchild; - struct inode *dirp; -- int err; -+ int err, error = -EOPNOTSUPP; - - err = nfserr_perm; - if (!flen) -@@ -836,20 +974,47 @@ nfsd_create(struct svc_rqst *rqstp, stru - dentry = fhp->fh_dentry; - dirp = dentry->d_inode; - -+ switch (type) { -+ case S_IFDIR: -+ if (dirp->i_op->mkdir_raw) -+ error = mkdir_raw(dentry, fname, flen, iap->ia_mode); -+ break; -+ case S_IFCHR: -+ case S_IFBLK: -+ case S_IFIFO: -+ case S_IFSOCK: -+ case S_IFREG: -+ if (dirp->i_op->mknod_raw) { -+ if (type == S_IFREG) -+ rdev = 0; -+ error = mknod_raw(dentry, fname,flen,iap->ia_mode,rdev); -+ } -+ break; -+ default: -+ printk("nfsd: bad file type %o in nfsd_create\n", type); -+ } -+ if (error && error != -EOPNOTSUPP) { -+ err = error; -+ goto out_nfserr; -+ } -+ - err = nfserr_notdir; -- if(!dirp->i_op || !dirp->i_op->lookup) -+ if (!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) - goto out; - /* - * Check whether the response file handle has been verified yet. - * If it has, the parent directory should already be locked. - */ -- if (!resfhp->fh_dentry) { -- /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */ -- fh_lock(fhp); -+ if (!resfhp->fh_dentry || dirp->i_op->lookup_it) { -+ /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create -+ * and nfsd_proc_create in case of lustre */ -+ if (!resfhp->fh_dentry) -+ fh_lock(fhp); - dchild = lookup_one_len(fname, dentry, flen); - err = PTR_ERR(dchild); - if (IS_ERR(dchild)) - goto out_nfserr; -+ resfhp->fh_dentry = NULL; - err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); - if (err) - goto out; -@@ -870,10 +1032,12 @@ nfsd_create(struct svc_rqst *rqstp, stru - * Make sure the child dentry is still negative ... - */ - err = nfserr_exist; -- if (dchild->d_inode) { -- dprintk("nfsd_create: dentry %s/%s not negative!\n", -- dentry->d_name.name, dchild->d_name.name); -- goto out; -+ if (error == -EOPNOTSUPP) { -+ if (dchild->d_inode) { -+ dprintk("nfsd_create: dentry %s/%s not negative!\n", -+ dentry->d_name.name, dchild->d_name.name); -+ goto out; -+ } - } - - if (!(iap->ia_valid & ATTR_MODE)) -@@ -886,16 +1050,19 @@ nfsd_create(struct svc_rqst *rqstp, stru - err = nfserr_perm; - switch (type) { - case S_IFREG: -- err = vfs_create(dirp, dchild, iap->ia_mode); -+ if (error == -EOPNOTSUPP) -+ err = vfs_create(dirp, dchild, iap->ia_mode); - break; - case S_IFDIR: -- err = vfs_mkdir(dirp, dchild, iap->ia_mode); -+ if (error == -EOPNOTSUPP) -+ err = vfs_mkdir(dirp, dchild, iap->ia_mode); - break; - case S_IFCHR: - case S_IFBLK: - case S_IFIFO: - case S_IFSOCK: -- err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); -+ if (error == -EOPNOTSUPP) -+ err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); - break; - default: - printk("nfsd: bad file type %o in nfsd_create\n", type); -@@ -964,7 +1131,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - /* Get all the sanity checks out of the way before - * we lock the parent. */ - err = nfserr_notdir; -- if(!dirp->i_op || !dirp->i_op->lookup) -+ if (dirp->i_op->mknod_raw) { -+ err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0); -+ if (err && err != -EOPNOTSUPP) -+ goto out_nfserr; -+ } -+ -+ if (!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) - goto out; - fh_lock(fhp); - -@@ -1015,6 +1188,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - case NFS3_CREATE_GUARDED: - err = nfserr_exist; - } -+ if (dirp->i_op->mknod_raw) -+ err = 0; - goto out; - } - -@@ -1121,7 +1296,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str - struct iattr *iap) - { - struct dentry *dentry, *dnew; -- int err, cerr; -+ int err, cerr, error = -EOPNOTSUPP; - - err = nfserr_noent; - if (!flen || !plen) -@@ -1135,12 +1310,18 @@ nfsd_symlink(struct svc_rqst *rqstp, str - goto out; - fh_lock(fhp); - dentry = fhp->fh_dentry; -+ -+ if (dentry->d_inode->i_op->symlink_raw) -+ error = symlink_raw(dentry, fname, flen, path); -+ - dnew = lookup_one_len(fname, dentry, flen); - err = PTR_ERR(dnew); - if (IS_ERR(dnew)) - goto out_nfserr; - -- err = vfs_symlink(dentry->d_inode, dnew, path); -+ err = error; -+ if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw) -+ err = vfs_symlink(dentry->d_inode, dnew, path); - if (!err) { - if (EX_ISSYNC(fhp->fh_export)) - nfsd_sync_dir(dentry); -@@ -1148,7 +1329,10 @@ nfsd_symlink(struct svc_rqst *rqstp, str - iap->ia_valid |= ATTR_CTIME; - iap->ia_mode = (iap->ia_mode&S_IALLUGO) - | S_IFLNK; -- err = notify_change(dnew, iap); -+ if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw) -+ err = setattr_raw(dnew->d_inode, iap); -+ else -+ err = notify_change(dnew, iap); - if (err) - err = nfserrno(err); - else if (EX_ISSYNC(fhp->fh_export)) -@@ -1210,7 +1391,10 @@ nfsd_link(struct svc_rqst *rqstp, struct - dold = tfhp->fh_dentry; - dest = dold->d_inode; - -- err = vfs_link(dold, dirp, dnew); -+ if (dirp->i_op->link_raw) -+ err = link_raw(dold, ddir, dnew); -+ else -+ err = vfs_link(dold, dirp, dnew); - if (!err) { - if (EX_ISSYNC(ffhp->fh_export)) { - nfsd_sync_dir(ddir); -@@ -1295,7 +1479,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ if (fdir->i_op->rename_raw) -+ err = rename_raw(fdentry, tdentry, odentry, ndentry); -+ else -+ err = vfs_rename(fdir, odentry, tdir, ndentry); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); -@@ -1316,7 +1503,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru - fill_post_wcc(tfhp); - double_up(&tdir->i_sem, &fdir->i_sem); - ffhp->fh_locked = tfhp->fh_locked = 0; -- -+ - out: - return err; - } -@@ -1362,9 +1549,15 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - err = nfserr_perm; - } else - #endif -- err = vfs_unlink(dirp, rdentry); -+ if (dirp->i_op->unlink_raw) -+ err = unlink_raw(dentry, fname, flen, rdentry); -+ else -+ err = vfs_unlink(dirp, rdentry); - } else { /* It's RMDIR */ -- err = vfs_rmdir(dirp, rdentry); -+ if (dirp->i_op->rmdir_raw) -+ err = rmdir_raw(dentry, fname, flen, rdentry); -+ else -+ err = vfs_rmdir(dirp, rdentry); - } - - dput(rdentry); ---- linux-2.4.22-ac1/include/linux/fs.h~nfs_export_kernel-2.4.22-rh 2003-09-26 01:00:26.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/fs.h 2003-10-08 13:44:53.000000000 +0400 -@@ -93,6 +93,8 @@ extern int leases_enable, dir_notify_ena - #define FS_SINGLE 8 /* Filesystem that can have only one superblock */ - #define FS_NOMOUNT 16 /* Never mount from userland */ - #define FS_LITTER 32 /* Keeps the tree in dcache */ -+#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for -+ * exporting non device filesystems. */ - #define FS_ALWAYS_REVAL 16384 /* Always revalidate dentries returned by - link_path_walk */ - #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon -@@ -1121,6 +1124,9 @@ extern int open_namei_it(const char *fil - 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 revalidate_it(struct dentry *dentry, struct lookup_intent *it); -+extern int init_private_file_it(struct file *, struct dentry *dentry, int mode, -+ struct lookup_intent *it); - extern int filp_close(struct file *, fl_owner_t id); - extern char * getname(const char *); - -@@ -1420,6 +1426,8 @@ extern void path_release(struct nameidat - extern int follow_down(struct vfsmount **, struct dentry **); - extern int follow_up(struct vfsmount **, struct dentry **); - extern struct dentry * lookup_one_len(const char *, struct dentry *, int); -+extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int, -+ struct lookup_intent *); - 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) -@@ -1439,6 +1447,8 @@ typedef int (*find_inode_t)(struct inode - - extern struct inode * iget4_locked(struct super_block *, unsigned long, - find_inode_t, void *); -+extern struct inode * ilookup4(struct super_block *, unsigned long, -+ find_inode_t, void *); - - static inline struct inode *iget4(struct super_block *sb, unsigned long ino, - find_inode_t find_actor, void *opaque) ---- linux-2.4.22-ac1/kernel/ksyms.c~nfs_export_kernel-2.4.22-rh 2003-09-26 00:57:28.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/kernel/ksyms.c 2003-10-08 13:45:20.000000000 +0400 -@@ -165,6 +165,7 @@ EXPORT_SYMBOL(fget); - EXPORT_SYMBOL(igrab); - EXPORT_SYMBOL(iunique); - EXPORT_SYMBOL(iget4_locked); -+EXPORT_SYMBOL(ilookup4); - EXPORT_SYMBOL(unlock_new_inode); - EXPORT_SYMBOL(iput); - EXPORT_SYMBOL(inode_init_once); -@@ -178,6 +179,7 @@ EXPORT_SYMBOL(path_walk); - EXPORT_SYMBOL(path_release); - EXPORT_SYMBOL(__user_walk); - EXPORT_SYMBOL(lookup_one_len); -+EXPORT_SYMBOL(lookup_one_len_it); - EXPORT_SYMBOL(lookup_hash); - EXPORT_SYMBOL(sys_close); - EXPORT_SYMBOL(dcache_lock); diff --git a/lustre/kernel_patches/patches/revert-76chaos.patch b/lustre/kernel_patches/patches/revert-76chaos.patch deleted file mode 100644 index 25f5440..0000000 --- a/lustre/kernel_patches/patches/revert-76chaos.patch +++ /dev/null @@ -1,289 +0,0 @@ -Index: linux/arch/i386/kernel/traps.c -=================================================================== ---- linux.orig/arch/i386/kernel/traps.c 2004-11-05 19:00:03.000000000 -0800 -+++ linux/arch/i386/kernel/traps.c 2004-11-05 19:00:06.000000000 -0800 -@@ -133,141 +133,48 @@ - - #endif - --void scan_stack (unsigned long *stack) -+void show_trace(unsigned long * stack) - { -+#if !CONFIG_FRAME_POINTER - int i; -+#endif - unsigned long addr; -- /* static to not take up stackspace */ -- static char buffer[NR_CPUS][512], *bufp; -+ /* static to not take up stackspace; if we race here too bad */ -+ static char buffer[512]; - -- bufp = buffer[smp_processor_id()]; -+ if (!stack) -+ stack = (unsigned long*)&stack; - -+ printk("Call Trace: "); - /* - * If we have frame pointers then use them to get - * a 100% exact backtrace, up until the entry frame: - */ -+#if CONFIG_FRAME_POINTER -+#define DO(n) \ -+ addr = (int)__builtin_return_address(n); \ -+ if (!kernel_text_address(addr)) \ -+ goto out; \ -+ lookup_symbol(addr, buffer, 512); \ -+ printk("[<%08lx>] %s\n", addr, buffer); -+ -+ DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(7); DO(8); DO(9); -+ DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); DO(17); DO(18); DO(19); -+out: -+#else - i = 1; - while (((long) stack & (THREAD_SIZE-1)) != 0) { - addr = *stack++; - if (kernel_text_address(addr)) { -- lookup_symbol(addr, bufp, 512); -- printk("[<%08lx>] %s (0x%p)\n", addr,bufp,stack-1); -+ lookup_symbol(addr, buffer, 512); -+ printk("[<%08lx>] %s (0x%p)\n", addr,buffer,stack-1); - i++; - } - } --} -- --#if CONFIG_FRAME_POINTER --void show_stack_frame_params (int param_count, unsigned long params[]) --{ -- int i; -- unsigned long *p, task_addr, stack_base; -- -- if (param_count <= 0) -- return; -- -- task_addr = (unsigned long) current; -- stack_base = task_addr + THREAD_SIZE - 1; -- -- printk(" ("); -- -- for (i = 0, p = params; -- ((param_count - i) > 1) && (p >= task_addr) && (p <= stack_base); -- i++, p++) { -- printk("0x%x, ", *p); -- -- if ((i % 4) == 3) -- printk("\n "); -- } -- -- if ((p >= task_addr) && (p <= stack_base)) -- printk("0x%x)\n", *p); --} -- --/* Display a stack trace for the currently executing task. The 'dummy' -- * parameter serves a purpose although its value is unused. We use the -- * address of 'dummy' as a reference point for finding the saved %ebp register -- * value on the stack. -- */ --void frame_pointer_walk (void *dummy) --{ -- int i; -- unsigned long addr, task_addr, *frame_ptr, *next_frame_ptr, *eip_ptr, -- eip, stack_base; -- /* static to not take up stackspace */ -- static char buffer[NR_CPUS][512], *bufp; -- -- bufp = buffer[smp_processor_id()]; -- task_addr = (unsigned long) current; -- stack_base = task_addr + THREAD_SIZE - 1; -- frame_ptr = (unsigned long *) (&dummy - 2); -- -- for (; ; ) { -- next_frame_ptr = (unsigned long *) (*frame_ptr); -- addr = (unsigned long) next_frame_ptr; -- -- /* Stop when we reach a frame pointer that points to a -- * location clearly outside our own kernel stack. -- */ -- if ((addr < task_addr) || (addr > stack_base)) -- break; -- -- eip_ptr = frame_ptr + 1; -- eip = *eip_ptr; -- -- if (kernel_text_address(eip)) { -- lookup_symbol(eip, bufp, 512); -- show_stack_frame_params(4, frame_ptr + 2); -- printk("[<%08lx>] %s (0x%x)\n", eip, bufp, -- eip_ptr); -- } -- -- frame_ptr = next_frame_ptr; -- } --} -- --typedef void (*stack_trace_fn_t) (unsigned long *stack); -- --void show_trace(unsigned long * stack) --{ -- static const stack_trace_fn_t trace_fn_vector[] = -- { scan_stack, frame_pointer_walk }; -- unsigned long addr, task_addr, stack_base; -- int task_is_current; -- -- if (!stack) -- stack = (unsigned long*)&stack; -- -- printk("Call Trace:\n"); -- addr = (unsigned long) stack; -- task_addr = (unsigned long) current; -- stack_base = task_addr + THREAD_SIZE - 1; -- task_is_current = (addr >= task_addr) && (addr <= stack_base); -- -- /* We may use frame pointers to do a stack trace only if the current -- * task is being traced. Tracing some other task in this manner -- * would require a saved %ebp register value. Perhaps in the future -- * I'll consider providing a means of obtaining this. -- */ -- trace_fn_vector[task_is_current](stack); -- -- printk("\n"); --} -- --#else /* CONFIG_FRAME_POINTER */ -- --void show_trace(unsigned long * stack) --{ -- if (!stack) -- stack = (unsigned long*)&stack; -- -- printk("Call Trace:\n"); -- scan_stack(stack); -+#endif - printk("\n"); - } - --#endif /* CONFIG_FRAME_POINTER */ -- - void show_trace_task(struct task_struct *tsk) - { - unsigned long esp = tsk->thread.esp; -Index: linux/fs/namei.c -=================================================================== ---- linux.orig/fs/namei.c 2004-11-05 19:00:03.000000000 -0800 -+++ linux/fs/namei.c 2004-11-05 19:00:06.000000000 -0800 -@@ -1022,7 +1022,7 @@ - * The simplest case - just a plain lookup. - */ - if (!(flag & O_CREAT)) { -- error = path_lookup_it(pathname, lookup_flags(flag), nd); -+ error = path_lookup(pathname, lookup_flags(flag), nd); - if (error) - return error; - dentry = nd->dentry; -Index: linux/include/asm-i386/hw_irq.h -=================================================================== ---- linux.orig/include/asm-i386/hw_irq.h 2004-11-05 19:00:03.000000000 -0800 -+++ linux/include/asm-i386/hw_irq.h 2004-11-05 19:00:06.000000000 -0800 -@@ -158,9 +158,6 @@ - /* there is a second layer of macro just to get the symbolic - name for the vector evaluated. This change is for RTLinux */ - #define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v) -- --#if CONFIG_X86_HIGH_ENTRY -- - #define XBUILD_SMP_INTERRUPT(x,v)\ - asmlinkage void x(void); \ - asmlinkage void call_##x(void); \ -@@ -173,26 +170,7 @@ - "movl $"SYMBOL_NAME_STR(smp_##x)", %ebp; call *%ebp\n\t" \ - "jmp ret_from_intr; .previous\n"); - --#else -- --#define XBUILD_SMP_INTERRUPT(x,v)\ --asmlinkage void x(void); \ --asmlinkage void call_##x(void); \ --__asm__( \ --".section .entry.text,\"ax\"\n"__ALIGN_STR"\n" \ --SYMBOL_NAME_STR(x) ":\n\t" \ -- "pushl $"#v"-256\n\t" \ -- SAVE_ALL_SWITCH \ -- SYMBOL_NAME_STR(call_##x)":\n\t" \ -- "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ -- "jmp ret_from_intr; .previous\n"); -- --#endif -- - #define BUILD_SMP_TIMER_INTERRUPT(x,v) XBUILD_SMP_TIMER_INTERRUPT(x,v) -- --#if CONFIG_X86_HIGH_ENTRY -- - #define XBUILD_SMP_TIMER_INTERRUPT(x,v) \ - asmlinkage void x(struct pt_regs * regs); \ - asmlinkage void call_##x(void); \ -@@ -208,27 +186,6 @@ - "addl $4,%esp\n\t" \ - "jmp ret_from_intr; .previous\n"); - --#else -- --#define XBUILD_SMP_TIMER_INTERRUPT(x,v) \ --asmlinkage void x(struct pt_regs * regs); \ --asmlinkage void call_##x(void); \ --__asm__( \ --".section .entry.text,\"ax\"\n"__ALIGN_STR"\n" \ --SYMBOL_NAME_STR(x) ":\n\t" \ -- "pushl $"#v"-256\n\t" \ -- SAVE_ALL_SWITCH \ -- "movl %esp,%eax\n\t" \ -- "pushl %eax\n\t" \ -- SYMBOL_NAME_STR(call_##x)":\n\t" \ -- "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ -- "addl $4,%esp\n\t" \ -- "jmp ret_from_intr; .previous\n"); -- --#endif -- --#if CONFIG_X86_HIGH_ENTRY -- - #define BUILD_COMMON_IRQ() \ - asmlinkage void call_do_IRQ(void); \ - __asm__( \ -@@ -239,20 +196,6 @@ - "movl $"SYMBOL_NAME_STR(do_IRQ)", %ebp; call *%ebp\n\t" \ - "jmp ret_from_intr; .previous\n"); - --#else -- --#define BUILD_COMMON_IRQ() \ --asmlinkage void call_do_IRQ(void); \ --__asm__( \ -- ".section .entry.text,\"ax\"\n" __ALIGN_STR"\n" \ -- "common_interrupt:\n\t" \ -- SAVE_ALL_SWITCH \ -- SYMBOL_NAME_STR(call_do_IRQ)":\n\t" \ -- "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \ -- "jmp ret_from_intr; .previous\n"); -- --#endif -- - /* - * subtle. orig_eax is used by the signal code to distinct between - * system calls and interrupted 'random user-space'. Thus we have -Index: linux/mm/highmem.c -=================================================================== ---- linux.orig/mm/highmem.c 2004-11-05 08:59:32.000000000 -0800 -+++ linux/mm/highmem.c 2004-11-05 19:00:06.000000000 -0800 -@@ -465,11 +465,7 @@ - /* - * FIXME: assuming PAGE_SIZE buffer_heads - */ -- --/* -- * don't allow SUPERBH_MAX_USERS to go < 1 - mag -- */ --#define SUPERBH_MAX_USERS max(POOL_SIZE * PAGE_SIZE / MAX_SUPERBH, 1) -+#define SUPERBH_MAX_USERS (POOL_SIZE * PAGE_SIZE / MAX_SUPERBH) - - static int superbh_users; - static DECLARE_WAIT_QUEUE_HEAD(superbh_wait); diff --git a/lustre/kernel_patches/patches/sd_iostats-2.6-rhel4.patch b/lustre/kernel_patches/patches/sd_iostats-2.6-rhel4.patch new file mode 100644 index 0000000..d8494ff --- /dev/null +++ b/lustre/kernel_patches/patches/sd_iostats-2.6-rhel4.patch @@ -0,0 +1,457 @@ +Index: linux-2.6.9-5.0.3.EL/drivers/scsi/Kconfig +=================================================================== +--- linux-2.6.9-5.0.3.EL.orig/drivers/scsi/Kconfig 2005-02-25 03:25:42.000000000 -0500 ++++ linux-2.6.9-5.0.3.EL/drivers/scsi/Kconfig 2005-03-03 16:10:10.000000000 -0500 +@@ -61,6 +61,13 @@ + help + SCSI dump support + ++config SD_IOSTATS ++ bool "Enable SCSI disk I/O stats" ++ depends on BLK_DEV_SD ++ ---help--- ++ This enables SCSI disk I/O stats collection. You must also enable ++ /proc file system support if you want this feature. ++ + config CHR_DEV_ST + tristate "SCSI tape support" + depends on SCSI +Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c +=================================================================== +--- linux-2.6.9-5.0.3.EL.orig/drivers/scsi/sd.c 2005-02-25 03:25:40.000000000 -0500 ++++ linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c 2005-03-03 16:11:07.000000000 -0500 +@@ -63,6 +63,38 @@ + + #include "scsi_logging.h" + ++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS)) ++# include ++# include ++ ++typedef struct { ++ unsigned long long iostat_size; ++ unsigned long long iostat_count; ++} iostat_counter_t; ++ ++#define IOSTAT_NCOUNTERS 16 ++typedef struct { ++ iostat_counter_t iostat_read_histogram[IOSTAT_NCOUNTERS]; ++ iostat_counter_t iostat_write_histogram[IOSTAT_NCOUNTERS]; ++ struct timeval iostat_timeval; ++} iostat_stats_t; ++ ++iostat_stats_t **sd_iostats; ++spinlock_t sd_iostats_lock; ++struct proc_dir_entry *sd_iostats_procdir; ++char sd_iostats_procdir_name[] = "sd_iostats"; ++ ++extern void sd_iostats_init(void); ++extern void sd_iostats_init_disk(struct gendisk *); ++extern void sd_iostats_fini(void); ++extern void sd_iostats_bump(int disk, unsigned int nsect, int iswrite); ++#else ++static inline void sd_iostats_init(void) {} ++static inline void sd_iostats_init_disk(struct gendisk *) {} ++static inline void sd_iostats_fini(void) {} ++static inline void sd_iostats_bump(kdev_t dev, unsigned int nsect, int iswrite) {} ++#endif ++ + /* + * More than enough for everybody ;) The huge number of majors + * is a leftover from 16bit dev_t days, we don't really need that +@@ -76,6 +108,7 @@ + */ + #define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26) + ++#define SD_STATS 256 + /* + * Time out in seconds for disks and Magneto-opticals (which are slower). + */ +@@ -276,6 +309,9 @@ + SCSI_LOG_HLQUEUE(2, printk("%s : block=%llu\n", + disk->disk_name, (unsigned long long)block)); + ++ sd_iostats_bump(scsi_disk(disk)->index, this_count, ++ rq_data_dir(SCpnt->request) == WRITE); ++ + /* + * If we have a 1K hardware sectorsize, prevent access to single + * 512 byte sectors. In theory we could handle this - in fact +@@ -472,6 +508,7 @@ + scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT); + } + ++ sd_iostats_init_disk(disk); + return 0; + + error_out: +@@ -1573,6 +1610,327 @@ + sd_sync_cache(sdp); + } + ++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS)) ++static int ++sd_iostats_seq_show(struct seq_file *seq, void *v) ++{ ++ struct timeval now; ++ struct gendisk *disk = seq->private; ++ iostat_stats_t *stats; ++ unsigned long long read_len; ++ unsigned long long read_len_tot; ++ unsigned long read_num; ++ unsigned long read_num_tot; ++ unsigned long long write_len; ++ unsigned long long write_len_tot; ++ unsigned long write_num; ++ unsigned long write_num_tot; ++ int i; ++ int maxi; ++ ++ if (sd_iostats == NULL) { ++ printk(KERN_ERR "sd_iostats_seq_show: NULL stats array\n"); ++ BUG(); ++ } ++ ++ stats = sd_iostats[scsi_disk(disk)->index]; ++ if (stats == NULL) { ++ printk(KERN_ERR "sd_iostats_seq_show: NULL stats entry\n"); ++ BUG(); ++ } ++ ++ do_gettimeofday(&now); ++ now.tv_sec -= stats->iostat_timeval.tv_sec; ++ now.tv_usec -= stats->iostat_timeval.tv_usec; ++ if (now.tv_usec < 0) { ++ now.tv_usec += 1000000; ++ now.tv_sec--; ++ } ++ ++ /* this sampling races with updates */ ++ seq_printf(seq, "index: %lu snapshot_time: %lu.%06lu\n", ++ scsi_disk(disk)->index, now.tv_sec, now.tv_usec); ++ ++ for (i = IOSTAT_NCOUNTERS - 1; i > 0; i--) ++ if (stats->iostat_read_histogram[i].iostat_count != 0 || ++ stats->iostat_write_histogram[i].iostat_count != 0) ++ break; ++ maxi = i; ++ ++ seq_printf(seq, "%8s %8s %12s %8s %12s\n", "size", ++ "reads", "total", "writes", "total"); ++ ++ read_len_tot = write_len_tot = 0; ++ read_num_tot = write_num_tot = 0; ++ for (i = 0; i <= maxi; i++) { ++ read_len = stats->iostat_read_histogram[i].iostat_size; ++ read_len_tot += read_len; ++ read_num = stats->iostat_read_histogram[i].iostat_count; ++ read_num_tot += read_num; ++ ++ write_len = stats->iostat_write_histogram[i].iostat_size; ++ write_len_tot += write_len; ++ write_num = stats->iostat_write_histogram[i].iostat_count; ++ write_num_tot += write_num; ++ ++ seq_printf (seq, "%8d %8lu %12llu %8lu %12llu\n", ++ 512<private_data)->private = PDE(inode)->data; ++ return 0; ++} ++ ++static ssize_t ++sd_iostats_seq_write(struct file *file, const char *buffer, ++ size_t len, loff_t *off) ++{ ++ struct seq_file *seq = file->private_data; ++ struct gendisk *disk = seq->private; ++ iostat_stats_t *stats = sd_iostats[scsi_disk(disk)->index]; ++ unsigned long flags; ++ ++ ++ spin_lock_irqsave (&sd_iostats_lock, flags); ++ memset (stats, 0, sizeof(*stats)); ++ do_gettimeofday(&stats->iostat_timeval); ++ spin_unlock_irqrestore (&sd_iostats_lock, flags); ++ ++ return len; ++} ++ ++static struct file_operations sd_iostats_proc_fops = { ++ .owner = THIS_MODULE, ++ .open = sd_iostats_seq_open, ++ .read = seq_read, ++ .write = sd_iostats_seq_write, ++ .llseek = seq_lseek, ++ .release = seq_release, ++}; ++ ++extern struct proc_dir_entry *proc_scsi; ++ ++void ++sd_iostats_init(void) ++{ ++ int i; ++ ++ spin_lock_init(&sd_iostats_lock); ++ ++ sd_iostats = kmalloc(SD_STATS * sizeof(iostat_stats_t *), GFP_KERNEL); ++ if (sd_iostats == NULL) { ++ printk(KERN_WARNING "Can't keep sd iostats: " ++ "ENOMEM allocating stats array size %ld\n", ++ SD_STATS * sizeof(iostat_stats_t *)); ++ return; ++ } ++ ++ for (i = 0; i < SD_STATS; i++) ++ sd_iostats[i] = NULL; ++ ++ if (proc_scsi == NULL) { ++ printk(KERN_WARNING "No access to sd iostats: " ++ "proc_scsi is NULL\n"); ++ return; ++ } ++ ++ sd_iostats_procdir = create_proc_entry(sd_iostats_procdir_name, ++ S_IFDIR | S_IRUGO | S_IXUGO, ++ proc_scsi); ++ if (sd_iostats_procdir == NULL) { ++ printk(KERN_WARNING "No access to sd iostats: " ++ "can't create /proc/scsi/%s\n", sd_iostats_procdir_name); ++ return; ++ } ++} ++ ++void ++sd_iostats_init_disk(struct gendisk *disk) ++{ ++ struct proc_dir_entry *pde; ++ unsigned long flags; ++ iostat_stats_t *stats; ++ ++ if (sd_iostats == NULL || ++ sd_iostats_procdir == NULL) ++ return; ++ ++ if (scsi_disk(disk)->index > SD_STATS) { ++ printk(KERN_ERR "sd_iostats_init_disk: " ++ "unexpected disk index %d(%d)\n", ++ scsi_disk(disk)->index, SD_STATS); ++ return; ++ } ++ ++ if (sd_iostats[scsi_disk(disk)->index] != NULL) ++ return; ++ ++ stats = kmalloc(sizeof(*stats), GFP_KERNEL); ++ if (stats == NULL) { ++ printk(KERN_WARNING "Can't keep %s iostats: " ++ "ENOMEM allocating stats size %ld\n", ++ disk->disk_name, sizeof(*stats)); ++ return; ++ } ++ ++ memset (stats, 0, sizeof(*stats)); ++ do_gettimeofday(&stats->iostat_timeval); ++ ++ spin_lock_irqsave(&sd_iostats_lock, flags); ++ ++ if (sd_iostats[scsi_disk(disk)->index] != NULL) { ++ spin_unlock_irqrestore(&sd_iostats_lock, flags); ++ kfree (stats); ++ return; ++ } ++ ++ sd_iostats[scsi_disk(disk)->index] = stats; ++ ++ spin_unlock_irqrestore(&sd_iostats_lock, flags); ++ ++ pde = create_proc_entry(disk->disk_name, S_IRUGO | S_IWUSR, ++ sd_iostats_procdir); ++ if (pde == NULL) { ++ printk(KERN_WARNING "Can't create /proc/scsi/%s/%s\n", ++ sd_iostats_procdir_name, disk->disk_name); ++ } else { ++ pde->proc_fops = &sd_iostats_proc_fops; ++ pde->data = disk; ++ } ++} ++ ++static void sd_devname(unsigned int disknum, char *buffer) ++{ ++ if (disknum < 26) ++ sprintf(buffer, "sd%c", 'a' + disknum); ++ else { ++ unsigned int min1; ++ unsigned int min2; ++ /* ++ * For larger numbers of disks, we need to go to a new ++ * naming scheme. ++ */ ++ min1 = disknum / 26; ++ min2 = disknum % 26; ++ sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2); ++ } ++} ++ ++void ++sd_iostats_fini(void) ++{ ++ char name[6]; ++ int i; ++ ++ if (sd_iostats_procdir != NULL) { ++ for (i = 0; i < SD_STATS; i++) { ++ sd_devname(i, name); ++ remove_proc_entry(name, sd_iostats_procdir); ++ } ++ ++ if (proc_scsi == NULL) { ++ printk(KERN_ERR "sd_iostats_fini: proc_scsi NULL\n"); ++ BUG(); ++ } ++ remove_proc_entry(sd_iostats_procdir_name, ++ proc_scsi); ++ ++ sd_iostats_procdir = NULL; ++ } ++ ++ if (sd_iostats != NULL) { ++ for (i = 0; i < SD_STATS; i++) { ++ if (sd_iostats[i] != NULL) ++ kfree (sd_iostats[i]); ++ } ++ ++ kfree(sd_iostats); ++ sd_iostats = NULL; ++ } ++} ++ ++void ++sd_iostats_bump(int disk, unsigned int nsect, int iswrite) ++{ ++ iostat_stats_t *stats; ++ iostat_counter_t *counter; ++ int bucket; ++ int tmp; ++ unsigned long irqflags; ++ ++ if (sd_iostats == NULL) ++ return; ++ ++ if (disk < 0 || disk >= SD_STATS) { ++ printk(KERN_ERR "sd_iostats_bump: unexpected disk index %d([0-%d])\n", ++ disk, SD_STATS); ++ BUG(); ++ } ++ ++ for (bucket = 0, tmp = nsect; tmp > 1; bucket++) ++ tmp /= 2; ++ ++ if (bucket >= IOSTAT_NCOUNTERS) { ++ printk (KERN_ERR "sd_iostats_bump: nsect %d too big\n", nsect); ++ BUG(); ++ } ++ ++ spin_lock_irqsave(&sd_iostats_lock, irqflags); ++ ++ stats = sd_iostats[disk]; ++ if (stats != NULL) { ++ counter = iswrite ? ++ &stats->iostat_write_histogram[bucket] : ++ &stats->iostat_read_histogram[bucket]; ++ ++ counter->iostat_size += nsect; ++ counter->iostat_count++; ++ } ++ ++ spin_unlock_irqrestore(&sd_iostats_lock, irqflags); ++} ++#endif ++ + /** + * init_sd - entry point for this driver (both when built in or when + * a module). +@@ -1582,6 +1940,7 @@ + static int __init init_sd(void) + { + int majors = 0, i; ++ int rc = 0; + + SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n")); + +@@ -1592,7 +1951,10 @@ + if (!majors) + return -ENODEV; + +- return scsi_register_driver(&sd_template.gendrv); ++ rc = scsi_register_driver(&sd_template.gendrv); ++ if (rc == 0) ++ sd_iostats_init(); ++ return rc; + } + + /** +@@ -1606,6 +1968,7 @@ + + SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); + ++ sd_iostats_fini(); + scsi_unregister_driver(&sd_template.gendrv); + for (i = 0; i < SD_MAJORS; i++) + unregister_blkdev(sd_major(i), "sd"); +Index: linux-2.6.9-5.0.3.EL/drivers/scsi/scsi_proc.c +=================================================================== +--- linux-2.6.9-5.0.3.EL.orig/drivers/scsi/scsi_proc.c 2004-10-18 17:53:11.000000000 -0400 ++++ linux-2.6.9-5.0.3.EL/drivers/scsi/scsi_proc.c 2005-03-03 16:10:10.000000000 -0500 +@@ -38,7 +38,8 @@ + /* 4K page size, but our output routines, use some slack for overruns */ + #define PROC_BLOCK_SIZE (3*1024) + +-static struct proc_dir_entry *proc_scsi; ++struct proc_dir_entry *proc_scsi; ++EXPORT_SYMBOL(proc_scsi); + + /* Protect sht->present and sht->proc_dir */ + static DECLARE_MUTEX(global_host_template_sem); diff --git a/lustre/kernel_patches/patches/socket-exports-2.4.22-rh.patch b/lustre/kernel_patches/patches/socket-exports-2.4.22-rh.patch deleted file mode 100644 index 08ca1b2..0000000 --- a/lustre/kernel_patches/patches/socket-exports-2.4.22-rh.patch +++ /dev/null @@ -1,41 +0,0 @@ - include/linux/socket.h | 4 ++++ - net/netsyms.c | 1 + - net/socket.c | 2 +- - 3 files changed, 6 insertions(+), 1 deletion(-) - ---- linux-2.4.22-ac1/include/linux/socket.h~socket-exports-2.4.22-rh 2003-06-13 18:51:39.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/socket.h 2003-09-26 00:49:43.000000000 +0400 -@@ -275,6 +275,10 @@ extern void memcpy_tokerneliovec(struct - extern int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen); - extern int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr); - extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); -+struct socket; -+extern int sock_map_fd(struct socket *sock); -+extern struct socket *sockfd_lookup(int fd, int *err); -+ - #endif - #endif /* not kernel and not glibc */ - #endif /* _LINUX_SOCKET_H */ ---- linux-2.4.22-ac1/net/netsyms.c~socket-exports-2.4.22-rh 2003-09-26 00:49:19.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/net/netsyms.c 2003-09-26 00:50:20.000000000 +0400 -@@ -163,6 +163,7 @@ EXPORT_SYMBOL(put_cmsg); - EXPORT_SYMBOL(sock_kmalloc); - EXPORT_SYMBOL(sock_kfree_s); - EXPORT_SYMBOL(sockfd_lookup); -+EXPORT_SYMBOL(sock_map_fd); - - #ifdef CONFIG_FILTER - EXPORT_SYMBOL(sk_run_filter); ---- linux-2.4.22-ac1/net/socket.c~socket-exports-2.4.22-rh 2003-08-25 15:44:44.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/net/socket.c 2003-09-26 00:49:43.000000000 +0400 -@@ -325,7 +325,7 @@ static struct dentry_operations sockfs_d - * but we take care of internal coherence yet. - */ - --static int sock_map_fd(struct socket *sock) -+int sock_map_fd(struct socket *sock) - { - int fd; - struct qstr this; - -_ diff --git a/lustre/kernel_patches/patches/tcp_zero_copy_2.4.20_chaos.patch b/lustre/kernel_patches/patches/tcp_zero_copy_2.4.20_chaos.patch deleted file mode 100644 index a64ecf9..0000000 --- a/lustre/kernel_patches/patches/tcp_zero_copy_2.4.20_chaos.patch +++ /dev/null @@ -1,476 +0,0 @@ - include/linux/skbuff.h | 30 +++++ - include/net/tcp.h | 5 - net/core/skbuff.c | 25 ++++ - net/ipv4/tcp.c | 252 ++++++++++++++++++++++++++++++++++++++++++++++++- - net/netsyms.c | 2 - 5 files changed, 311 insertions(+), 3 deletions(-) - -Index: linux-2.4.20-rh-20.9/include/linux/skbuff.h -=================================================================== ---- linux-2.4.20-rh-20.9.orig/include/linux/skbuff.h 2003-09-13 19:34:24.000000000 +0400 -+++ linux-2.4.20-rh-20.9/include/linux/skbuff.h 2003-12-19 14:14:55.000000000 +0300 -@@ -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]; - }; - -Index: linux-2.4.20-rh-20.9/include/net/tcp.h -=================================================================== ---- linux-2.4.20-rh-20.9.orig/include/net/tcp.h 2003-09-13 19:34:25.000000000 +0400 -+++ linux-2.4.20-rh-20.9/include/net/tcp.h 2003-12-19 14:14:55.000000000 +0300 -@@ -643,6 +643,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, -@@ -737,6 +739,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); - -Index: linux-2.4.20-rh-20.9/net/netsyms.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/net/netsyms.c 2003-09-13 19:34:24.000000000 +0400 -+++ linux-2.4.20-rh-20.9/net/netsyms.c 2003-12-19 14:15:24.000000000 +0300 -@@ -396,7 +396,7 @@ - EXPORT_SYMBOL(sysctl_tcp_wmem); - EXPORT_SYMBOL(sysctl_tcp_ecn); - EXPORT_SYMBOL(tcp_cwnd_application_limited); --EXPORT_SYMBOL(tcp_sendpage); -+EXPORT_SYMBOL(tcp_recvpackets); - EXPORT_SYMBOL(sysctl_tcp_low_latency); - - EXPORT_SYMBOL(tcp_write_xmit); -@@ -417,6 +417,8 @@ - - #endif - -+EXPORT_SYMBOL(tcp_sendpage); -+EXPORT_SYMBOL(tcp_sendpage_zccd); - EXPORT_SYMBOL(tcp_read_sock); - - EXPORT_SYMBOL(netlink_set_err); -Index: linux-2.4.20-rh-20.9/net/core/skbuff.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/net/core/skbuff.c 2003-09-13 19:34:19.000000000 +0400 -+++ linux-2.4.20-rh-20.9/net/core/skbuff.c 2003-12-19 14:14:56.000000000 +0300 -@@ -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; -@@ -578,6 +586,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: -Index: linux-2.4.20-rh-20.9/net/ipv4/tcp.c -=================================================================== ---- linux-2.4.20-rh-20.9.orig/net/ipv4/tcp.c 2003-09-13 19:34:25.000000000 +0400 -+++ linux-2.4.20-rh-20.9/net/ipv4/tcp.c 2003-12-19 14:14:56.000000000 +0300 -@@ -747,7 +747,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) -@@ -826,7 +826,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; -@@ -874,6 +875,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) { -@@ -884,6 +896,20 @@ - 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; - skb->ip_summed = CHECKSUM_HW; -@@ -947,7 +973,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; -@@ -1771,6 +1821,202 @@ - 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; -+} -+ - /* - * State processing on a close. This implements the state shift for - * sending our FIN frame. Note that we only send a FIN for some diff --git a/lustre/kernel_patches/patches/vfs-pdirops-2.4.20-rh.patch b/lustre/kernel_patches/patches/vfs-pdirops-2.4.20-rh.patch deleted file mode 100644 index 6ab7a21..0000000 --- a/lustre/kernel_patches/patches/vfs-pdirops-2.4.20-rh.patch +++ /dev/null @@ -1,269 +0,0 @@ - fs/inode.c | 1 - fs/namei.c | 66 ++++++++++++++++++++++++++++++++++++++--------------- - include/linux/fs.h | 11 ++++---- - 3 files changed, 54 insertions(+), 24 deletions(-) - -Index: linux-2.4.20-rh/fs/namei.c -=================================================================== ---- linux-2.4.20-rh.orig/fs/namei.c 2003-09-04 20:58:33.000000000 +0800 -+++ linux-2.4.20-rh/fs/namei.c 2003-09-04 21:21:20.000000000 +0800 -@@ -101,6 +101,36 @@ - - } - -+static void *lock_dir(struct inode *dir, struct qstr *name) -+{ -+ unsigned long hash; -+ -+ if (!IS_PDIROPS(dir)) { -+ down(&dir->i_sem); -+ return 0; -+ } -+ -+ /* OK. fs understands parallel directory operations. -+ * so, we try to acquire lock for hash of requested -+ * filename in order to prevent any operations with -+ * same name in same time -bzzz */ -+ -+ /* calculate name hash */ -+ hash = full_name_hash(name->name, name->len); -+ -+ /* lock this hash */ -+ return dynlock_lock(&dir->i_dcache_lock, hash, 1, GFP_ATOMIC); -+} -+ -+static void unlock_dir(struct inode *dir, void *lock) -+{ -+ if (!IS_PDIROPS(dir)) { -+ up(&dir->i_sem); -+ return; -+ } -+ dynlock_unlock(&dir->i_dcache_lock, lock); -+} -+ - /* 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.. -@@ -303,10 +333,11 @@ - struct dentry * result; - struct inode *dir = parent->d_inode; - int counter = 0; -+ void *lock; - - again: - counter++; -- down(&dir->i_sem); -+ lock = lock_dir(dir, name); - /* - * First re-do the cached lookup just in case it was created - * while we waited for the directory semaphore.. -@@ -329,7 +359,7 @@ - else - result = dentry; - } -- up(&dir->i_sem); -+ unlock_dir(dir, lock); - return result; - } - -@@ -337,7 +367,7 @@ - * Uhhuh! Nasty case: the cache was re-populated while - * we waited on the semaphore. Need to revalidate. - */ -- up(&dir->i_sem); -+ unlock_dir(dir, lock); - if (result->d_op && result->d_op->d_revalidate) { - if (!result->d_op->d_revalidate(result, flags) && !d_invalidate(result)) { - dput(result); -@@ -1180,13 +1210,13 @@ - goto exit; - - dir = nd->dentry; -- down(&dir->d_inode->i_sem); -+ nd->lock = lock_dir(dir->d_inode, &nd->last); - dentry = lookup_hash_it(&nd->last, nd->dentry, it); - - do_last: - error = PTR_ERR(dentry); - if (IS_ERR(dentry)) { -- up(&dir->d_inode->i_sem); -+ unlock_dir(dir->d_inode, nd->lock); - goto exit; - } - -@@ -1195,7 +1225,7 @@ - if (!dentry->d_inode) { - error = vfs_create_it(dir->d_inode, dentry, - mode & ~current->fs->umask, it); -- up(&dir->d_inode->i_sem); -+ unlock_dir(dir->d_inode, nd->lock); - dput(nd->dentry); - nd->dentry = dentry; - if (error) -@@ -1209,7 +1239,7 @@ - /* - * It already exists. - */ -- up(&dir->d_inode->i_sem); -+ unlock_dir(dir->d_inode, nd->lock); - - error = -EEXIST; - if (flag & O_EXCL) -@@ -1362,7 +1392,7 @@ - goto exit; - } - dir = nd->dentry; -- down(&dir->d_inode->i_sem); -+ nd->lock = lock_dir(dir->d_inode, &nd->last); - dentry = lookup_hash_it(&nd->last, nd->dentry, it); - putname(nd->last.name); - goto do_last; -@@ -1380,7 +1410,7 @@ - { - struct dentry *dentry; - -- down(&nd->dentry->d_inode->i_sem); -+ nd->lock = lock_dir(nd->dentry->d_inode, &nd->last); - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -@@ -1469,7 +1499,7 @@ - } - dput(dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - out2: - path_release(&nd); - out: -@@ -1532,7 +1562,7 @@ - mode & ~current->fs->umask); - dput(dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - out2: - path_release(&nd); - out: -@@ -1642,14 +1672,14 @@ - if (error != -EOPNOTSUPP) - goto exit1; - } -- down(&nd.dentry->d_inode->i_sem); -+ nd.lock = lock_dir(nd.dentry->d_inode, &nd.last); - 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); - dput(dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - exit1: - path_release(&nd); - exit: -@@ -1708,7 +1738,7 @@ - if (error != -EOPNOTSUPP) - goto exit1; - } -- down(&nd.dentry->d_inode->i_sem); -+ nd.lock = lock_dir(nd.dentry->d_inode, &nd.last); - dentry = lookup_hash_it(&nd.last, nd.dentry, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { -@@ -1719,7 +1749,7 @@ - exit2: - dput(dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - exit1: - path_release(&nd); - exit: -@@ -1789,7 +1819,7 @@ - error = vfs_symlink(nd.dentry->d_inode, dentry, from); - dput(dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - out2: - path_release(&nd); - out: -@@ -1881,7 +1911,7 @@ - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); - dput(new_dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - out_release: - path_release(&nd); - out: -Index: linux-2.4.20-rh/include/linux/fs.h -=================================================================== ---- linux-2.4.20-rh.orig/include/linux/fs.h 2003-09-04 20:59:14.000000000 +0800 -+++ linux-2.4.20-rh/include/linux/fs.h 2003-09-04 21:03:46.000000000 +0800 -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -136,6 +137,7 @@ - #define S_IMMUTABLE 16 /* Immutable file */ - #define S_DEAD 32 /* removed, but still open directory */ - #define S_NOQUOTA 64 /* Inode is not counted to quota */ -+#define S_PDIROPS 256 /* Parallel directory operations */ - - /* - * Note that nosuid etc flags are inode-specific: setting some file-system -@@ -162,6 +164,7 @@ - #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) - #define IS_NOATIME(inode) (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME)) - #define IS_NODIRATIME(inode) __IS_FLG(inode, MS_NODIRATIME) -+#define IS_PDIROPS(inode) __IS_FLG(inode, S_PDIROPS) - - #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) - -@@ -489,6 +492,7 @@ - atomic_t i_writecount; - unsigned int i_attr_flags; - __u32 i_generation; -+ struct dynlock i_dcache_lock; /* for parallel directory ops */ - union { - struct minix_inode_info minix_i; - struct ext2_inode_info ext2_i; -@@ -708,6 +712,7 @@ - unsigned int flags; - int last_type; - struct lookup_intent *intent; -+ void *lock; - }; - - /* -@@ -1621,12 +1626,6 @@ - return dget(dentry->d_parent); - } - --static inline void unlock_dir(struct dentry *dir) --{ -- up(&dir->d_inode->i_sem); -- dput(dir); --} -- - /* - * Whee.. Deadlock country. Happily there are only two VFS - * operations that does this.. -Index: linux-2.4.20-rh/fs/inode.c -=================================================================== ---- linux-2.4.20-rh.orig/fs/inode.c 2003-09-04 20:58:35.000000000 +0800 -+++ linux-2.4.20-rh/fs/inode.c 2003-09-04 21:03:46.000000000 +0800 -@@ -121,6 +121,7 @@ - mapping->host = inode; - mapping->gfp_mask = GFP_HIGHUSER; - inode->i_mapping = mapping; -+ dynlock_init(&inode->i_dcache_lock); - } - return inode; - } 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 index 3133c62..0000000 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch +++ /dev/null @@ -1,1880 +0,0 @@ - fs/dcache.c | 19 ++ - fs/exec.c | 17 +- - fs/namei.c | 333 ++++++++++++++++++++++++++++++++++++++-------- - fs/namespace.c | 28 ++- - fs/open.c | 176 +++++++++++++++++------- - fs/proc/base.c | 3 - fs/stat.c | 28 ++- - include/linux/dcache.h | 60 ++++++++ - include/linux/fs.h | 32 ++++ - include/linux/fs_struct.h | 4 - kernel/exit.c | 3 - kernel/fork.c | 3 - kernel/ksyms.c | 1 - 13 files changed, 578 insertions(+), 129 deletions(-) - -Index: linux-2.4.20/fs/dcache.c -=================================================================== ---- linux-2.4.20.orig/fs/dcache.c Wed Mar 17 13:57:05 2004 -+++ linux-2.4.20/fs/dcache.c Wed Mar 17 13:57:11 2004 -@@ -186,6 +186,13 @@ - 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. -@@ -841,13 +848,19 @@ - * 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 { \ -Index: linux-2.4.20/fs/exec.c -=================================================================== ---- linux-2.4.20.orig/fs/exec.c Wed Mar 17 13:57:05 2004 -+++ linux-2.4.20/fs/exec.c Wed Mar 17 13:57:11 2004 -@@ -114,8 +114,10 @@ - struct file * file; - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_OPEN, -+ .it_flags = FMODE_READ|FMODE_EXEC }; - -- error = user_path_walk(library, &nd); -+ error = user_path_walk_it(library, &nd, &it); - if (error) - goto out; - -@@ -127,7 +129,8 @@ - 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(&it); - error = PTR_ERR(file); - if (IS_ERR(file)) - goto out; -@@ -382,8 +385,10 @@ - struct inode *inode; - struct file *file; - int err = 0; -+ struct lookup_intent it = { .it_op = IT_OPEN, -+ .it_flags = FMODE_READ|FMODE_EXEC }; - -- 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 +400,8 @@ - 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(&it); - if (!IS_ERR(file)) { - err = deny_write_access(file); - if (err) { -@@ -407,6 +413,7 @@ - return file; - } - } -+ intent_release(&it); - path_release(&nd); - } - goto out; -@@ -1296,7 +1303,7 @@ - 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); -Index: linux-2.4.20/fs/namei.c -=================================================================== ---- linux-2.4.20.orig/fs/namei.c Wed Mar 17 13:57:03 2004 -+++ linux-2.4.20/fs/namei.c Wed Mar 17 13:58:01 2004 -@@ -94,6 +94,13 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct lookup_intent *it) -+{ -+ if (it && it->it_op_release) -+ it->it_op_release(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 @@ - * 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_revalidate_it) { -+ if (!dentry->d_op->d_revalidate_it(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,15 @@ - * 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; -+ int counter = 0; - -+again: -+ counter++; - down(&dir->i_sem); - /* - * First re-do the cached lookup just in case it was created -@@ -300,6 +320,9 @@ - result = ERR_PTR(-ENOMEM); - if (dentry) { - lock_kernel(); -+ if (dir->i_op->lookup_it) -+ result = dir->i_op->lookup_it(dir, dentry, it, flags); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -321,6 +344,15 @@ - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate_it) { -+ if (!result->d_op->d_revalidate_it(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ if (counter > 10) -+ result = ERR_PTR(-ESTALE); -+ if (!IS_ERR(result)) -+ goto again; -+ } - } - return result; - } -@@ -334,7 +366,8 @@ - * 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 +381,18 @@ - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -+ nd->intent = it; - err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (!err && it != NULL && !(it->d.lustre.it_int_flags & IT_FL_FOLLOWED)) { -+ /* vfs_follow_link was never called */ -+ intent_release(it); -+ path_release(nd); -+ err = -ENOLINK; -+ } - current->link_count--; - return err; - loop: -+ intent_release(it); - path_release(nd); - return -ELOOP; - } -@@ -381,15 +422,26 @@ - 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_create_mode; -+ } -+ intent_release(it); -+ if (it) { -+ it->it_op = opc; -+ it->it_create_mode = mode; -+ } - dput(*dentry); - mntput(mounted->mnt_parent); - *dentry = dget(mounted->mnt_root); -@@ -401,7 +453,7 @@ - - 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 +489,7 @@ - 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 +501,8 @@ - * - * 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 +579,18 @@ - 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; -@@ -549,7 +601,7 @@ - goto out_dput; - - if (inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ err = do_follow_link(dentry, nd, NULL); - dput(dentry); - if (err) - goto return_err; -@@ -565,7 +617,7 @@ - nd->dentry = dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup_it) - break; - continue; - /* here ends the main loop */ -@@ -592,22 +644,22 @@ - 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); -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -621,7 +673,8 @@ - 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->lookup_it)) - break; - } - goto return_base; -@@ -645,6 +698,34 @@ - * Check the cached dentry for staleness. - */ - dentry = nd->dentry; -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) { -+ err = -ESTALE; -+ if (!dentry->d_op->d_revalidate_it(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, it); -+ if (IS_ERR(new)) { -+ err = PTR_ERR(new); -+ break; -+ } -+ d_invalidate(dentry); -+ dput(dentry); -+ nd->dentry = new; -+ } -+ if (!nd->dentry->d_inode) -+ goto no_inode; -+ if (lookup_flags & LOOKUP_DIRECTORY) { -+ err = -ENOTDIR; -+ if (!nd->dentry->d_inode->i_op || -+ (!nd->dentry->d_inode->i_op->lookup && -+ !nd->dentry->d_inode->i_op->lookup_it)) -+ break; -+ } -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - err = -ESTALE; - if (!dentry->d_op->d_revalidate(dentry, 0)) { -@@ -658,15 +732,28 @@ - dput(dentry); - break; - } -+ if (err) -+ intent_release(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 +838,17 @@ - } - - /* 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; -@@ -765,6 +863,7 @@ - { - nd->last_type = LAST_ROOT; /* if there are only slashes... */ - nd->flags = flags; -+ nd->intent = NULL; - if (*name=='/') - return walk_init_root(name,nd); - read_lock(¤t->fs->lock); -@@ -779,7 +878,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_it(struct qstr *name, struct dentry * base, -+ struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -802,13 +902,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; - lock_kernel(); -+ if (inode->i_op->lookup_it) -+ dentry = inode->i_op->lookup_it(inode, new, it, 0); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -820,6 +923,12 @@ - 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 +950,7 @@ - } - 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 +981,23 @@ - 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. -@@ -969,7 +1095,8 @@ - return retval; - } - --int vfs_create(struct inode *dir, struct dentry *dentry, int mode) -+static int vfs_create_it(struct inode *dir, struct dentry *dentry, int mode, -+ struct lookup_intent *it) - { - int error; - -@@ -982,12 +1109,15 @@ - goto exit_lock; - - error = -EACCES; /* shouldn't it be ENOSYS? */ -- if (!dir->i_op || !dir->i_op->create) -+ if (!dir->i_op || (!dir->i_op->create && !dir->i_op->create_it)) - goto exit_lock; - - DQUOT_INIT(dir); - lock_kernel(); -- error = dir->i_op->create(dir, dentry, mode); -+ if (dir->i_op->create_it) -+ error = dir->i_op->create_it(dir, dentry, mode, it); -+ else -+ error = dir->i_op->create(dir, dentry, mode); - unlock_kernel(); - exit_lock: - up(&dir->i_zombie); -@@ -996,6 +1126,11 @@ - return error; - } - -+int vfs_create(struct inode *dir, struct dentry *dentry, int mode) -+{ -+ return vfs_create_it(dir, dentry, mode, NULL); -+} -+ - /* - * open_namei() - * -@@ -1010,7 +1145,8 @@ - * 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; -@@ -1020,11 +1156,14 @@ - - acc_mode = ACC_MODE(flag); - -+ if (it) -+ it->it_flags = flag; -+ - /* - * 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 +1173,10 @@ - /* - * Create - we need to know the parent. - */ -+ if (it) { -+ it->it_create_mode = mode; -+ it->it_op |= IT_CREAT; -+ } - error = path_lookup(pathname, LOOKUP_PARENT, nd); - if (error) - return error; -@@ -1049,7 +1192,7 @@ - - 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,10 +1201,11 @@ - goto exit; - } - -+ it->it_create_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { -- error = vfs_create(dir->d_inode, dentry, -- mode & ~current->fs->umask); -+ error = vfs_create_it(dir->d_inode, dentry, -+ mode & ~current->fs->umask, it); - up(&dir->d_inode->i_sem); - dput(nd->dentry); - nd->dentry = dentry; -@@ -1086,7 +1230,7 @@ - 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) -@@ -1165,7 +1309,7 @@ - if (!error) { - DQUOT_INIT(inode); - -- error = do_truncate(dentry, 0); -+ error = do_truncate(dentry, 0, 1); - } - put_write_access(inode); - if (error) -@@ -1177,8 +1321,10 @@ - return 0; - - exit_dput: -+ intent_release(it); - dput(dentry); - exit: -+ intent_release(it); - path_release(nd); - return error; - -@@ -1197,7 +1343,16 @@ - * are done. Procfs-like symlinks just set LAST_BIND. - */ - UPDATE_ATIME(dentry->d_inode); -+ nd->intent = it; - error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) { -+ intent_release(it); -+ } else if (it != NULL && !(it->d.lustre.it_int_flags & IT_FL_FOLLOWED)) { -+ /* vfs_follow_link was never called */ -+ intent_release(it); -+ path_release(nd); -+ error = -ENOLINK; -+ } - dput(dentry); - if (error) - return error; -@@ -1219,13 +1374,20 @@ - } - 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 +1395,7 @@ - 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 +1451,20 @@ - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ -+ if (nd.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->mknod_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mknod_raw(&nd, 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 +1485,7 @@ - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1357,7 +1533,18 @@ - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 1); -+ if (nd.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->mkdir_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mkdir_raw(&nd, 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 +1552,7 @@ - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1465,8 +1653,16 @@ - error = -EBUSY; - goto exit1; - } -+ if (nd.dentry->d_inode->i_op->rmdir_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ error = op->rmdir_raw(&nd); -+ /* 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 +1720,15 @@ - error = -EISDIR; - if (nd.last_type != LAST_NORM) - goto exit1; -+ if (nd.dentry->d_inode->i_op->unlink_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->unlink_raw(&nd); -+ /* 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 +1795,27 @@ - error = path_lookup(to, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ if (nd.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->symlink_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->symlink_raw(&nd, 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 +1891,18 @@ - error = -EXDEV; - if (old_nd.mnt != nd.mnt) - goto out_release; -- new_dentry = lookup_create(&nd, 0); -+ if (nd.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out_release; -+ } -+ if (nd.dentry->d_inode->i_op->link_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->link_raw(&old_nd, &nd); -+ /* 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 +1946,7 @@ - * 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) - { - int error; - struct inode *target; -@@ -1799,7 +2025,7 @@ - } - - 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) - { - int error; - -@@ -1887,9 +2113,18 @@ - if (newnd.last_type != LAST_NORM) - goto exit2; - -+ if (old_dir->d_inode->i_op->rename_raw) { -+ lock_kernel(); -+ error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd); -+ unlock_kernel(); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit2; -+ } -+ - 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 +2140,16 @@ - 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; - -+ - lock_kernel(); - error = vfs_rename(old_dir->d_inode, old_dentry, - new_dir->d_inode, new_dentry); - unlock_kernel(); -- - dput(new_dentry); - exit4: - dput(old_dentry); -@@ -1965,20 +2200,28 @@ - } - - 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; - if (IS_ERR(link)) - goto fail; - -+ if (it == NULL) -+ it = nd->intent; -+ else if (it != nd->intent) -+ printk("it != nd->intent: tell phil@clusterfs.com\n"); -+ if (it != NULL) -+ it->d.lustre.it_int_flags |= IT_FL_FOLLOWED; -+ - if (*link == '/') { - path_release(nd); - if (!walk_init_root(link, 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 +2245,13 @@ - - 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 +2293,7 @@ - { - 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); -Index: linux-2.4.20/fs/namespace.c -=================================================================== ---- linux-2.4.20.orig/fs/namespace.c Wed Mar 17 13:57:05 2004 -+++ linux-2.4.20/fs/namespace.c Wed Mar 17 13:57:11 2004 -@@ -99,6 +99,7 @@ - { - old_nd->dentry = mnt->mnt_mountpoint; - old_nd->mnt = mnt->mnt_parent; -+ UNPIN(old_nd->dentry, old_nd->mnt, 1); - mnt->mnt_parent = mnt; - mnt->mnt_mountpoint = mnt->mnt_root; - list_del_init(&mnt->mnt_child); -@@ -110,6 +111,7 @@ - { - mnt->mnt_parent = mntget(nd->mnt); - mnt->mnt_mountpoint = dget(nd->dentry); -+ PIN(nd->dentry, nd->mnt, 1); - list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry)); - list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts); - nd->dentry->d_mounted++; -@@ -485,14 +487,17 @@ - { - struct nameidata old_nd; - struct vfsmount *mnt = NULL; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int err = mount_is_safe(nd); - if (err) - return err; - if (!old_name || !*old_name) - return -EINVAL; -- err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd); -- if (err) -+ err = path_lookup_it(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd, &it); -+ if (err) { -+ intent_release(&it); - return err; -+ } - - down_write(¤t->namespace->sem); - err = -EINVAL; -@@ -515,6 +520,7 @@ - } - - up_write(¤t->namespace->sem); -+ intent_release(&it); - path_release(&old_nd); - return err; - } -@@ -698,6 +704,7 @@ - unsigned long flags, void *data_page) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int retval = 0; - int mnt_flags = 0; - -@@ -722,10 +729,11 @@ - flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV); - - /* ... and get the mountpoint */ -- retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd); -- if (retval) -+ retval = path_lookup_it(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it); -+ if (retval) { -+ intent_release(&it); - return retval; -- -+ } - if (flags & MS_REMOUNT) - retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, - data_page); -@@ -736,6 +744,8 @@ - else - retval = do_add_mount(&nd, type_page, flags, mnt_flags, - dev_name, data_page); -+ -+ intent_release(&it); - path_release(&nd); - return retval; - } -@@ -901,6 +911,8 @@ - { - struct vfsmount *tmp; - struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; -+ struct lookup_intent new_it = { .it_op = IT_GETATTR }; -+ struct lookup_intent old_it = { .it_op = IT_GETATTR }; - int error; - - if (!capable(CAP_SYS_ADMIN)) -@@ -908,14 +920,14 @@ - - lock_kernel(); - -- error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd); -+ error = __user_walk_it(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd, &new_it); - if (error) - goto out0; - error = -EINVAL; - if (!check_mnt(new_nd.mnt)) - goto out1; - -- error = __user_walk(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd); -+ error = __user_walk_it(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd, &old_it); - if (error) - goto out1; - -@@ -970,8 +982,10 @@ - up(&old_nd.dentry->d_inode->i_zombie); - up_write(¤t->namespace->sem); - path_release(&user_nd); -+ intent_release(&old_it); - path_release(&old_nd); - out1: -+ intent_release(&new_it); - path_release(&new_nd); - out0: - unlock_kernel(); -Index: linux-2.4.20/fs/open.c -=================================================================== ---- linux-2.4.20.orig/fs/open.c Wed Mar 17 13:57:03 2004 -+++ linux-2.4.20/fs/open.c Wed Mar 17 13:57:11 2004 -@@ -19,6 +19,8 @@ - #include - - #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 @@ - 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,13 @@ - 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; -+ error = op->setattr_raw(inode, &newattrs); -+ } else -+ error = notify_change(dentry, &newattrs); - up(&inode->i_sem); - return error; - } -@@ -118,12 +127,13 @@ - 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 +173,13 @@ - error = locks_verify_truncate(inode, NULL, length); - if (!error) { - DQUOT_INIT(inode); -- error = do_truncate(nd.dentry, length); -+ intent_release(&it); -+ error = do_truncate(nd.dentry, length, 0); - } - put_write_access(inode); - - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; -@@ -215,7 +227,7 @@ - - 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 +272,13 @@ - 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 +293,25 @@ - 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 = -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 +332,14 @@ - 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 +354,20 @@ - 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 +390,7 @@ - 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 +408,14 @@ - 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(&it); - path_release(&nd); - } - -@@ -385,8 +430,9 @@ - { - 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 +443,7 @@ - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; -@@ -436,9 +483,10 @@ - { - 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,39 +502,56 @@ - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; - } - --asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) -+int chmod_common(struct dentry *dentry, mode_t mode) - { -- struct inode * inode; -- struct dentry * dentry; -- struct file * file; -- int err = -EBADF; -+ struct inode *inode = dentry->d_inode; - struct iattr newattrs; -+ int err = -EROFS; - -- file = fget(fd); -- if (!file) -+ if (IS_RDONLY(inode)) - goto out; - -- dentry = file->f_dentry; -- inode = dentry->d_inode; -+ if (inode->i_op->setattr_raw) { -+ newattrs.ia_mode = mode; -+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -+ newattrs.ia_valid |= ATTR_RAW; -+ err = inode->i_op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (err != -EOPNOTSUPP) -+ goto out; -+ } - -- err = -EROFS; -- if (IS_RDONLY(inode)) -- goto out_putf; - err = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -- goto out_putf; -+ goto out; -+ - if (mode == (mode_t) -1) - mode = inode->i_mode; - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - err = notify_change(dentry, &newattrs); - --out_putf: -+out: -+ return err; -+} -+ -+asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) -+{ -+ struct file * file; -+ int err = -EBADF; -+ -+ file = fget(fd); -+ if (!file) -+ goto out; -+ -+ err = chmod_common(file->f_dentry, mode); -+ - fput(file); - out: - return err; -@@ -495,30 +560,14 @@ - asmlinkage long sys_chmod(const char * filename, mode_t mode) - { - struct nameidata nd; -- struct inode * inode; - int error; -- struct iattr newattrs; - - error = user_path_walk(filename, &nd); - if (error) - goto out; -- inode = nd.dentry->d_inode; -- -- error = -EROFS; -- if (IS_RDONLY(inode)) -- goto dput_and_out; -- -- error = -EPERM; -- if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -- goto dput_and_out; - -- if (mode == (mode_t) -1) -- mode = inode->i_mode; -- newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); -- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -- error = notify_change(nd.dentry, &newattrs); -+ error = chmod_common(nd.dentry, mode); - --dput_and_out: - path_release(&nd); - out: - return error; -@@ -538,6 +587,20 @@ - 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 | 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) -+ return error; -+ } -+ - error = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto out; -@@ -642,8 +705,9 @@ - { - int namei_flags, error; - struct nameidata nd; -- -- flags &= ~O_DIRECT; -+ struct lookup_intent it = { .it_op = IT_OPEN }; -+ -+ //flags &= ~O_DIRECT; - - namei_flags = flags; - if ((namei_flags+1) & O_ACCMODE) -@@ -651,14 +715,15 @@ - 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; -@@ -695,12 +760,15 @@ - } - - if (f->f_op && f->f_op->open) { -+ f->f_it = it; - error = f->f_op->open(inode,f); -+ f->f_it = NULL; - if (error) - goto cleanup_all; - } - f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); - -+ intent_release(it); - return f; - - cleanup_all: -@@ -715,11 +783,17 @@ - cleanup_file: - put_filp(f); - cleanup_dentry: -+ intent_release(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. - */ -Index: linux-2.4.20/fs/proc/base.c -=================================================================== ---- linux-2.4.20.orig/fs/proc/base.c Wed Mar 17 13:57:05 2004 -+++ linux-2.4.20/fs/proc/base.c Wed Mar 17 13:57:11 2004 -@@ -494,6 +494,9 @@ - - error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt); - nd->last_type = LAST_BIND; -+ -+ if (nd->intent != NULL) -+ nd->intent->d.lustre.it_int_flags |= IT_FL_FOLLOWED; - out: - return error; - } -Index: linux-2.4.20/fs/stat.c -=================================================================== ---- linux-2.4.20.orig/fs/stat.c Wed Mar 17 13:57:05 2004 -+++ linux-2.4.20/fs/stat.c Wed Mar 17 13:58:01 2004 -@@ -17,10 +17,12 @@ - * Revalidate the inode. This is required for proper NFS attribute caching. - */ - static __inline__ int --do_revalidate(struct dentry *dentry) -+do_revalidate(struct dentry *dentry, struct lookup_intent *it) - { - struct inode * inode = dentry->d_inode; -- if (inode->i_op && inode->i_op->revalidate) -+ if (inode->i_op && inode->i_op->revalidate_it) -+ return inode->i_op->revalidate_it(dentry, it); -+ else if (inode->i_op && inode->i_op->revalidate) - return inode->i_op->revalidate(dentry); - return 0; - } -@@ -32,13 +34,13 @@ - return inode->i_nlink; - } - --static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -+static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat, struct lookup_intent *it) - { - int res = 0; - unsigned int blocks, indirect; - struct inode *inode = dentry->d_inode; - -- res = do_revalidate(dentry); -+ res = do_revalidate(dentry, it); - if (res) - return res; - -@@ -111,10 +113,12 @@ - { - 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); -+ error = do_getattr(nd.mnt, nd.dentry, stat, &it); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -124,10 +128,12 @@ - { - 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); -+ error = do_getattr(nd.mnt, nd.dentry, stat, &it); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -139,7 +145,7 @@ - int error = -EBADF; - - if (f) { -- error = do_getattr(f->f_vfsmnt, f->f_dentry, stat); -+ error = do_getattr(f->f_vfsmnt, f->f_dentry, stat, NULL); - fput(f); - } - return error; -@@ -286,7 +292,7 @@ - - error = -EINVAL; - if (inode->i_op && inode->i_op->readlink && -- !(error = do_revalidate(nd.dentry))) { -+ !(error = do_revalidate(nd.dentry, NULL))) { - UPDATE_ATIME(inode); - error = inode->i_op->readlink(nd.dentry, buf, bufsiz); - } -Index: linux-2.4.20/include/linux/dcache.h -=================================================================== ---- linux-2.4.20.orig/include/linux/dcache.h Wed Mar 17 13:57:04 2004 -+++ linux-2.4.20/include/linux/dcache.h Wed Mar 17 13:57:11 2004 -@@ -6,6 +6,51 @@ - #include - #include - #include -+#include -+ -+#define IT_OPEN 0x0001 -+#define IT_CREAT 0x0002 -+#define IT_READDIR 0x0004 -+#define IT_GETATTR 0x0008 -+#define IT_LOOKUP 0x0010 -+#define IT_UNLINK 0x0020 -+#define IT_GETXATTR 0x0040 -+#define IT_EXEC 0x0080 -+#define IT_PIN 0x0100 -+ -+#define IT_FL_LOCKED 0x0001 -+#define IT_FL_FOLLOWED 0x0002 /* set by vfs_follow_link */ -+ -+#define INTENT_MAGIC 0x19620323 -+ -+ -+struct lustre_intent_data { -+ int it_disposition; -+ int it_status; -+ __u64 it_lock_handle; -+ void *it_data; -+ int it_lock_mode; -+ int it_int_flags; -+}; -+struct lookup_intent { -+ int it_magic; -+ void (*it_op_release)(struct lookup_intent *); -+ int it_op; -+ int it_flags; -+ int it_create_mode; -+ union { -+ struct lustre_intent_data lustre; -+ } d; -+}; -+ -+static inline void intent_init(struct lookup_intent *it, int op, int flags) -+{ -+ memset(it, 0, sizeof(*it)); -+ it->it_magic = INTENT_MAGIC; -+ it->it_op = op; -+ it->it_flags = flags; -+} -+ - - /* - * linux/include/linux/dcache.h -@@ -96,8 +141,22 @@ - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate_it)(struct dentry *, int, struct lookup_intent *); -+ void (*d_pin)(struct dentry *, struct vfsmount * , int); -+ void (*d_unpin)(struct dentry *, struct vfsmount *, int); - }; - -+#define PIN(de,mnt,flag) if (de && de->d_op && de->d_op->d_pin) \ -+ de->d_op->d_pin(de, mnt, flag); -+#define UNPIN(de,mnt,flag) if (de && de->d_op && de->d_op->d_unpin) \ -+ de->d_op->d_unpin(de, mnt, flag); -+ -+ -+/* defined in fs/namei.c */ -+extern void intent_release(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 +188,7 @@ - * 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; - -Index: linux-2.4.20/include/linux/fs.h -=================================================================== ---- linux-2.4.20.orig/include/linux/fs.h Wed Mar 17 13:57:11 2004 -+++ linux-2.4.20/include/linux/fs.h Wed Mar 17 13:57:11 2004 -@@ -73,6 +73,7 @@ - - #define FMODE_READ 1 - #define FMODE_WRITE 2 -+#define FMODE_EXEC 4 - - #define READ 0 - #define WRITE 1 -@@ -338,6 +339,9 @@ - #define ATTR_MTIME_SET 256 - #define ATTR_FORCE 512 /* Not a change, but a change it */ - #define ATTR_ATTR_FLAG 1024 -+#define ATTR_RAW 0x0800 /* file system, not vfs will massage attrs */ -+#define ATTR_FROM_OPEN 0x1000 /* called from open path, ie O_TRUNC */ -+#define ATTR_CTIME_SET 0x2000 - - /* - * This is the Inode Attributes structure, used for notify_change(). It -@@ -473,6 +477,7 @@ - struct pipe_inode_info *i_pipe; - struct block_device *i_bdev; - struct char_device *i_cdev; -+ void *i_filterdata; - - unsigned long i_dnotify_mask; /* Directory notify events */ - struct dnotify_struct *i_dnotify; /* for directory notifications */ -@@ -575,6 +580,7 @@ - - /* needed for tty driver, and maybe others */ - void *private_data; -+ struct lookup_intent *f_it; - - /* preallocated helper kiobuf to speedup O_DIRECT */ - struct kiobuf *f_iobuf; -@@ -702,6 +708,7 @@ - struct qstr last; - unsigned int flags; - int last_type; -+ struct lookup_intent *intent; - }; - - /* -@@ -822,7 +829,8 @@ - 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); - - /* - * File types -@@ -882,21 +890,32 @@ - - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); -+ int (*create_it) (struct inode *,struct dentry *,int, struct lookup_intent *); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup_it) (struct inode *,struct dentry *, struct lookup_intent *, int flags); - int (*link) (struct dentry *,struct inode *,struct dentry *); -+ int (*link_raw) (struct nameidata *,struct nameidata *); - int (*unlink) (struct inode *,struct dentry *); -+ int (*unlink_raw) (struct nameidata *); - int (*symlink) (struct inode *,struct dentry *,const char *); -+ int (*symlink_raw) (struct nameidata *,const char *); - int (*mkdir) (struct inode *,struct dentry *,int); -+ int (*mkdir_raw) (struct nameidata *,int); - int (*rmdir) (struct inode *,struct dentry *); -+ int (*rmdir_raw) (struct nameidata *); - int (*mknod) (struct inode *,struct dentry *,int,int); -+ int (*mknod_raw) (struct nameidata *,int,dev_t); - int (*rename) (struct inode *, struct dentry *, - struct inode *, struct dentry *); -+ int (*rename_raw) (struct nameidata *, struct nameidata *); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*revalidate) (struct dentry *); -+ int (*revalidate_it) (struct dentry *, struct lookup_intent *); - 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); -@@ -1092,10 +1111,14 @@ - - 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 *); - -@@ -1386,6 +1409,7 @@ - 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 *)); -@@ -1397,6 +1421,8 @@ - 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 *); -@@ -1504,6 +1530,8 @@ - - 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; -Index: linux-2.4.20/include/linux/fs_struct.h -=================================================================== ---- linux-2.4.20.orig/include/linux/fs_struct.h Wed Mar 17 13:57:02 2004 -+++ linux-2.4.20/include/linux/fs_struct.h Wed Mar 17 13:57:11 2004 -@@ -37,10 +37,12 @@ - write_lock(&fs->lock); - old_root = fs->root; - old_rootmnt = fs->rootmnt; -+ PIN(dentry, mnt, 1); - fs->rootmnt = mntget(mnt); - fs->root = dget(dentry); - write_unlock(&fs->lock); - if (old_root) { -+ UNPIN(old_root, old_rootmnt, 1); - dput(old_root); - mntput(old_rootmnt); - } -@@ -60,10 +62,12 @@ - write_lock(&fs->lock); - old_pwd = fs->pwd; - old_pwdmnt = fs->pwdmnt; -+ PIN(dentry, mnt, 0); - fs->pwdmnt = mntget(mnt); - fs->pwd = dget(dentry); - write_unlock(&fs->lock); - if (old_pwd) { -+ UNPIN(old_pwd, old_pwdmnt, 0); - dput(old_pwd); - mntput(old_pwdmnt); - } -Index: linux-2.4.20/kernel/ksyms.c -=================================================================== ---- linux-2.4.20.orig/kernel/ksyms.c Wed Mar 17 13:57:11 2004 -+++ linux-2.4.20/kernel/ksyms.c Wed Mar 17 13:57:11 2004 -@@ -297,6 +297,7 @@ - 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); -Index: linux-2.4.20/kernel/fork.c -=================================================================== ---- linux-2.4.20.orig/kernel/fork.c Wed Mar 17 13:57:05 2004 -+++ linux-2.4.20/kernel/fork.c Wed Mar 17 13:57:11 2004 -@@ -440,10 +440,13 @@ - fs->umask = old->umask; - read_lock(&old->lock); - fs->rootmnt = mntget(old->rootmnt); -+ PIN(old->pwd, old->pwdmnt, 0); -+ PIN(old->root, old->rootmnt, 1); - fs->root = dget(old->root); - fs->pwdmnt = mntget(old->pwdmnt); - fs->pwd = dget(old->pwd); - if (old->altroot) { -+ PIN(old->altroot, old->altrootmnt, 1); - fs->altrootmnt = mntget(old->altrootmnt); - fs->altroot = dget(old->altroot); - } else { -Index: linux-2.4.20/kernel/exit.c -=================================================================== ---- linux-2.4.20.orig/kernel/exit.c Wed Mar 17 13:57:05 2004 -+++ linux-2.4.20/kernel/exit.c Wed Mar 17 13:57:11 2004 -@@ -345,11 +345,14 @@ - { - /* No need to hold fs->lock if we are killing it */ - if (atomic_dec_and_test(&fs->count)) { -+ UNPIN(fs->pwd, fs->pwdmnt, 0); -+ UNPIN(fs->root, fs->rootmnt, 1); - dput(fs->root); - mntput(fs->rootmnt); - dput(fs->pwd); - mntput(fs->pwdmnt); - if (fs->altroot) { -+ UNPIN(fs->altroot, fs->altrootmnt, 1); - dput(fs->altroot); - mntput(fs->altrootmnt); - } diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch deleted file mode 100644 index 8ef6d8f..0000000 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch +++ /dev/null @@ -1,1870 +0,0 @@ - fs/dcache.c | 19 ++ - fs/exec.c | 17 +- - fs/namei.c | 295 +++++++++++++++++++++++++++++++++++++++------- - fs/namespace.c | 28 +++- - fs/open.c | 172 +++++++++++++++++++------- - fs/stat.c | 52 +++++--- - include/linux/dcache.h | 60 +++++++++ - include/linux/fs.h | 32 ++++ - include/linux/fs_struct.h | 4 - kernel/exit.c | 3 - kernel/fork.c | 3 - kernel/ksyms.c | 1 - 12 files changed, 558 insertions(+), 128 deletions(-) - -Index: linux-ia64/fs/dcache.c -=================================================================== ---- linux-ia64.orig/fs/dcache.c 2004-03-17 15:47:15.000000000 -0800 -+++ linux-ia64/fs/dcache.c 2004-03-17 16:05:28.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. -@@ -850,13 +857,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 { \ -Index: linux-ia64/fs/exec.c -=================================================================== ---- linux-ia64.orig/fs/exec.c 2004-03-17 15:47:15.000000000 -0800 -+++ linux-ia64/fs/exec.c 2004-03-17 16:05:28.000000000 -0800 -@@ -119,8 +119,10 @@ asmlinkage long sys_uselib(const char * - struct file * file; - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_OPEN, -+ .it_flags = FMODE_READ|FMODE_EXEC }; - -- error = user_path_walk(library, &nd); -+ error = user_path_walk_it(library, &nd, &it); - if (error) - goto out; - -@@ -132,7 +134,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(&it); - error = PTR_ERR(file); - if (IS_ERR(file)) - goto out; -@@ -400,8 +403,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 = FMODE_READ|FMODE_EXEC }; - -- 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; -@@ -413,7 +418,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(&it); - if (!IS_ERR(file)) { - err = deny_write_access(file); - if (err) { -@@ -425,6 +431,7 @@ out: - return file; - } - } -+ intent_release(&it); - path_release(&nd); - } - goto out; -@@ -1348,7 +1355,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); -Index: linux-ia64/fs/namei.c -=================================================================== ---- linux-ia64.orig/fs/namei.c 2004-03-17 15:47:15.000000000 -0800 -+++ linux-ia64/fs/namei.c 2004-03-17 16:06:13.000000000 -0800 -@@ -94,6 +94,13 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct lookup_intent *it) -+{ -+ if (it && it->it_op_release) -+ it->it_op_release(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_revalidate_it) { -+ if (!dentry->d_op->d_revalidate_it(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,15 @@ 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; -+ int counter = 0; - -+again: -+ counter++; - 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->lookup_it) -+ result = dir->i_op->lookup_it(dir, dentry, it, flags); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -321,6 +344,15 @@ static struct dentry * real_lookup(struc - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate_it) { -+ if (!result->d_op->d_revalidate_it(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ if (counter > 10) -+ result = ERR_PTR(-ESTALE); -+ if (!IS_ERR(result)) -+ goto again; -+ } - } - return result; - } -@@ -332,7 +364,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 >= 8) -@@ -346,10 +379,12 @@ static inline int do_follow_link(struct - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -+ nd->intent = it; - err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -+ intent_release(it); - path_release(nd); - return -ELOOP; - } -@@ -447,7 +482,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; -@@ -524,12 +560,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; -@@ -547,7 +583,7 @@ int link_path_walk(const char * name, st - goto out_dput; - - if (inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ err = do_follow_link(dentry, nd, NULL); - dput(dentry); - if (err) - goto return_err; -@@ -563,7 +599,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->lookup_it) - break; - continue; - /* here ends the main loop */ -@@ -590,12 +626,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; -@@ -605,7 +641,7 @@ 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); -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -619,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->lookup_it)) - break; - } - goto return_base; -@@ -637,12 +672,42 @@ return_reval: - nd->last_type = LAST_DOT; - else if (this.len == 2 && this.name[1] == '.') - nd->last_type = LAST_DOTDOT; -+ else -+ goto return_base; - return_reval: - /* - * We bypassed the ordinary revalidation routines. - * Check the cached dentry for staleness. - */ - dentry = nd->dentry; -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) { -+ err = -ESTALE; -+ if (!dentry->d_op->d_revalidate_it(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, it); -+ if (IS_ERR(new)) { -+ err = PTR_ERR(new); -+ break; -+ } -+ d_invalidate(dentry); -+ dput(dentry); -+ nd->dentry = new; -+ } -+ if (!nd->dentry->d_inode) -+ goto no_inode; -+ if (lookup_flags & LOOKUP_DIRECTORY) { -+ err = -ENOTDIR; -+ if (!nd->dentry->d_inode->i_op || -+ (!nd->dentry->d_inode->i_op->lookup && -+ !nd->dentry->d_inode->i_op->lookup_it)) -+ break; -+ } -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - err = -ESTALE; - if (!dentry->d_op->d_revalidate(dentry, 0)) { -@@ -656,15 +714,28 @@ out_dput: - dput(dentry); - break; - } -+ if (err) -+ intent_release(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 */ -@@ -749,6 +820,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; -@@ -763,6 +845,7 @@ int path_init(const char *name, unsigned - { - nd->last_type = LAST_ROOT; /* if there are only slashes... */ - nd->flags = flags; -+ nd->intent = NULL; - if (*name=='/') - return walk_init_root(name,nd); - read_lock(¤t->fs->lock); -@@ -777,7 +860,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; -@@ -800,13 +884,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->lookup_it) -+ dentry = inode->i_op->lookup_it(inode, new, it, 0); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -818,6 +905,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) - { -@@ -839,7 +932,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); - } -@@ -870,6 +963,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. -@@ -967,7 +1077,8 @@ static inline int lookup_flags(unsigned - return retval; - } - --int vfs_create(struct inode *dir, struct dentry *dentry, int mode) -+static int vfs_create_it(struct inode *dir, struct dentry *dentry, int mode, -+ struct lookup_intent *it) - { - int error; - -@@ -980,12 +1091,15 @@ int vfs_create(struct inode *dir, struct - goto exit_lock; - - error = -EACCES; /* shouldn't it be ENOSYS? */ -- if (!dir->i_op || !dir->i_op->create) -+ if (!dir->i_op || (!dir->i_op->create && !dir->i_op->create_it)) - goto exit_lock; - - DQUOT_INIT(dir); - lock_kernel(); -- error = dir->i_op->create(dir, dentry, mode); -+ if (dir->i_op->create_it) -+ error = dir->i_op->create_it(dir, dentry, mode, it); -+ else -+ error = dir->i_op->create(dir, dentry, mode); - unlock_kernel(); - exit_lock: - up(&dir->i_zombie); -@@ -994,6 +1108,11 @@ exit_lock: - return error; - } - -+int vfs_create(struct inode *dir, struct dentry *dentry, int mode) -+{ -+ return vfs_create_it(dir, dentry, mode, NULL); -+} -+ - /* - * open_namei() - * -@@ -1008,7 +1127,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; -@@ -1018,11 +1138,14 @@ int open_namei(const char * pathname, in - - acc_mode = ACC_MODE(flag); - -+ if (it) -+ it->it_flags = flag; -+ - /* - * 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; -@@ -1032,6 +1155,10 @@ int open_namei(const char * pathname, in - /* - * Create - we need to know the parent. - */ -+ if (it) { -+ it->it_create_mode = mode; -+ it->it_op |= IT_CREAT; -+ } - error = path_lookup(pathname, LOOKUP_PARENT, nd); - if (error) - return error; -@@ -1047,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); -@@ -1056,11 +1183,12 @@ do_last: - goto exit; - } - -+ it->it_create_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - if (!IS_POSIXACL(dir->d_inode)) - mode &= ~current->fs->umask; -- error = vfs_create(dir->d_inode, dentry, mode); -+ error = vfs_create_it(dir->d_inode, dentry, mode, it); - up(&dir->d_inode->i_sem); - dput(nd->dentry); - nd->dentry = dentry; -@@ -1164,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) -@@ -1176,8 +1304,10 @@ ok: - return 0; - - exit_dput: -+ intent_release(it); - dput(dentry); - exit: -+ intent_release(it); - path_release(nd); - return error; - -@@ -1196,7 +1326,10 @@ do_link: - * are done. Procfs-like symlinks just set LAST_BIND. - */ - UPDATE_ATIME(dentry->d_inode); -+ nd->intent = it; - error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) -+ intent_release(it); - dput(dentry); - if (error) - return error; -@@ -1218,13 +1351,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; - -@@ -1232,7 +1372,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) -@@ -1288,7 +1428,20 @@ 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.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->mknod_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mknod_raw(&nd, 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)) -@@ -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,18 @@ 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.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->mkdir_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mkdir_raw(&nd, 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)) -@@ -1366,6 +1531,7 @@ asmlinkage long sys_mkdir(const char * p - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1466,8 +1632,16 @@ asmlinkage long sys_rmdir(const char * p - error = -EBUSY; - goto exit1; - } -+ if (nd.dentry->d_inode->i_op->rmdir_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ error = op->rmdir_raw(&nd); -+ /* 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); -@@ -1525,8 +1699,15 @@ asmlinkage long sys_unlink(const char * - error = -EISDIR; - if (nd.last_type != LAST_NORM) - goto exit1; -+ if (nd.dentry->d_inode->i_op->unlink_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->unlink_raw(&nd); -+ /* 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 */ -@@ -1593,15 +1774,27 @@ asmlinkage long sys_symlink(const char * - error = path_lookup(to, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ if (nd.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->symlink_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->symlink_raw(&nd, 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); -@@ -1677,7 +1870,18 @@ 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.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out_release; -+ } -+ if (nd.dentry->d_inode->i_op->link_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->link_raw(&old_nd, &nd); -+ /* 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); -@@ -1721,7 +1925,7 @@ 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) - { - int error; - struct inode *target; -@@ -1800,7 +2004,7 @@ 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) - { - int error; - -@@ -1888,9 +2092,18 @@ static inline int do_rename(const char * - if (newnd.last_type != LAST_NORM) - goto exit2; - -+ if (old_dir->d_inode->i_op->rename_raw) { -+ lock_kernel(); -+ error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd); -+ unlock_kernel(); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit2; -+ } -+ - 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; -@@ -1906,16 +2119,16 @@ 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; - -+ - lock_kernel(); - error = vfs_rename(old_dir->d_inode, old_dentry, - new_dir->d_inode, new_dentry); - unlock_kernel(); -- - dput(new_dentry); - exit4: - dput(old_dentry); -@@ -1966,20 +2179,26 @@ 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; - if (IS_ERR(link)) - goto fail; - -+ if (it == NULL) -+ it = nd->intent; -+ else if (it != nd->intent) -+ printk("it != nd->intent: tell phil@clusterfs.com\n"); -+ - if (*link == '/') { - path_release(nd); - if (!walk_init_root(link, 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; -@@ -2003,7 +2222,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 */ -@@ -2045,7 +2270,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); -Index: linux-ia64/fs/namespace.c -=================================================================== ---- linux-ia64.orig/fs/namespace.c 2004-03-17 15:47:15.000000000 -0800 -+++ linux-ia64/fs/namespace.c 2004-03-17 16:05:28.000000000 -0800 -@@ -98,6 +98,7 @@ static void detach_mnt(struct vfsmount * - { - old_nd->dentry = mnt->mnt_mountpoint; - old_nd->mnt = mnt->mnt_parent; -+ UNPIN(old_nd->dentry, old_nd->mnt, 1); - mnt->mnt_parent = mnt; - mnt->mnt_mountpoint = mnt->mnt_root; - list_del_init(&mnt->mnt_child); -@@ -109,6 +110,7 @@ static void attach_mnt(struct vfsmount * - { - mnt->mnt_parent = mntget(nd->mnt); - mnt->mnt_mountpoint = dget(nd->dentry); -+ PIN(nd->dentry, nd->mnt, 1); - list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry)); - list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts); - nd->dentry->d_mounted++; -@@ -488,14 +490,17 @@ static int do_loopback(struct nameidata - { - struct nameidata old_nd; - struct vfsmount *mnt = NULL; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int err = mount_is_safe(nd); - if (err) - return err; - if (!old_name || !*old_name) - return -EINVAL; -- err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd); -- if (err) -+ err = path_lookup_it(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd, &it); -+ if (err) { -+ intent_release(&it); - return err; -+ } - - down_write(¤t->namespace->sem); - err = -EINVAL; -@@ -518,6 +523,7 @@ static int do_loopback(struct nameidata - } - - up_write(¤t->namespace->sem); -+ intent_release(&it); - path_release(&old_nd); - return err; - } -@@ -701,6 +707,7 @@ long do_mount(char * dev_name, char * di - unsigned long flags, void *data_page) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int retval = 0; - int mnt_flags = 0; - -@@ -725,10 +732,11 @@ long do_mount(char * dev_name, char * di - flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV); - - /* ... and get the mountpoint */ -- retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd); -- if (retval) -+ retval = path_lookup_it(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it); -+ if (retval) { -+ intent_release(&it); - return retval; -- -+ } - if (flags & MS_REMOUNT) - retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, - data_page); -@@ -739,6 +747,8 @@ long do_mount(char * dev_name, char * di - else - retval = do_add_mount(&nd, type_page, flags, mnt_flags, - dev_name, data_page); -+ -+ intent_release(&it); - path_release(&nd); - return retval; - } -@@ -904,6 +914,8 @@ asmlinkage long sys_pivot_root(const cha - { - struct vfsmount *tmp; - struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; -+ struct lookup_intent new_it = { .it_op = IT_GETATTR }; -+ struct lookup_intent old_it = { .it_op = IT_GETATTR }; - int error; - - if (!capable(CAP_SYS_ADMIN)) -@@ -911,14 +923,14 @@ asmlinkage long sys_pivot_root(const cha - - lock_kernel(); - -- error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd); -+ error = __user_walk_it(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd, &new_it); - if (error) - goto out0; - error = -EINVAL; - if (!check_mnt(new_nd.mnt)) - goto out1; - -- error = __user_walk(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd); -+ error = __user_walk_it(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd, &old_it); - if (error) - goto out1; - -@@ -973,8 +985,10 @@ out2: - up(&old_nd.dentry->d_inode->i_zombie); - up_write(¤t->namespace->sem); - path_release(&user_nd); -+ intent_release(&old_it); - path_release(&old_nd); - out1: -+ intent_release(&new_it); - path_release(&new_nd); - out0: - unlock_kernel(); -Index: linux-ia64/fs/open.c -=================================================================== ---- linux-ia64.orig/fs/open.c 2004-03-17 15:47:15.000000000 -0800 -+++ linux-ia64/fs/open.c 2004-03-17 16:05:28.000000000 -0800 -@@ -19,6 +19,8 @@ - #include - - #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; - -@@ -109,7 +112,13 @@ 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; -+ error = op->setattr_raw(inode, &newattrs); -+ } else -+ error = notify_change(dentry, &newattrs); - up(&inode->i_sem); - up_write(&inode->i_alloc_sem); - return error; -@@ -120,12 +129,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; -@@ -165,11 +175,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(&it); -+ error = do_truncate(nd.dentry, length, 0); - } - put_write_access(inode); - - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; -@@ -217,7 +229,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: -@@ -262,11 +274,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; -@@ -281,11 +295,25 @@ 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 = -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); -@@ -306,12 +334,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; -@@ -326,7 +356,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; -@@ -349,6 +392,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; -@@ -366,13 +410,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(&it); - path_release(&nd); - } - -@@ -387,8 +432,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; - -@@ -399,6 +445,7 @@ asmlinkage long sys_chdir(const char * f - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; -@@ -438,9 +485,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; - -@@ -456,39 +504,56 @@ asmlinkage long sys_chroot(const char * - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; - } - --asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) -+int chmod_common(struct dentry *dentry, mode_t mode) - { -- struct inode * inode; -- struct dentry * dentry; -- struct file * file; -- int err = -EBADF; -+ struct inode *inode = dentry->d_inode; - struct iattr newattrs; -+ int err = -EROFS; - -- file = fget(fd); -- if (!file) -+ if (IS_RDONLY(inode)) - goto out; - -- dentry = file->f_dentry; -- inode = dentry->d_inode; -+ if (inode->i_op->setattr_raw) { -+ newattrs.ia_mode = mode; -+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -+ newattrs.ia_valid |= ATTR_RAW; -+ err = inode->i_op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (err != -EOPNOTSUPP) -+ goto out; -+ } - -- err = -EROFS; -- if (IS_RDONLY(inode)) -- goto out_putf; - err = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -- goto out_putf; -+ goto out; -+ - if (mode == (mode_t) -1) - mode = inode->i_mode; - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - err = notify_change(dentry, &newattrs); - --out_putf: -+out: -+ return err; -+} -+ -+asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) -+{ -+ struct file * file; -+ int err = -EBADF; -+ -+ file = fget(fd); -+ if (!file) -+ goto out; -+ -+ err = chmod_common(file->f_dentry, mode); -+ - fput(file); - out: - return err; -@@ -497,30 +562,14 @@ out: - asmlinkage long sys_chmod(const char * filename, mode_t mode) - { - struct nameidata nd; -- struct inode * inode; - int error; -- struct iattr newattrs; - - error = user_path_walk(filename, &nd); - if (error) - goto out; -- inode = nd.dentry->d_inode; -- -- error = -EROFS; -- if (IS_RDONLY(inode)) -- goto dput_and_out; - -- error = -EPERM; -- if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -- goto dput_and_out; -+ error = chmod_common(nd.dentry, mode); - -- if (mode == (mode_t) -1) -- mode = inode->i_mode; -- newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); -- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -- error = notify_change(nd.dentry, &newattrs); -- --dput_and_out: - path_release(&nd); - out: - return error; -@@ -540,6 +589,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 | 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) -+ return error; -+ } -+ - error = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto out; -@@ -644,6 +707,7 @@ struct file *filp_open(const char * file - { - int namei_flags, error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_OPEN }; - - namei_flags = flags; - if ((namei_flags+1) & O_ACCMODE) -@@ -651,14 +715,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; -@@ -695,7 +760,9 @@ struct file *dentry_open(struct dentry * - } - - if (f->f_op && f->f_op->open) { -+ f->f_it = it; - error = f->f_op->open(inode,f); -+ f->f_it = NULL; - if (error) - goto cleanup_all; - } -@@ -708,6 +775,7 @@ struct file *dentry_open(struct dentry * - inode->i_mapping->a_ops->direct_sector_IO))) - goto cleanup_all; - -+ intent_release(it); - return f; - - cleanup_all: -@@ -722,11 +790,17 @@ cleanup_all: - cleanup_file: - put_filp(f); - cleanup_dentry: -+ intent_release(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. - */ -Index: linux-ia64/fs/stat.c -=================================================================== ---- linux-ia64.orig/fs/stat.c 2004-03-17 15:47:15.000000000 -0800 -+++ linux-ia64/fs/stat.c 2004-03-17 16:06:13.000000000 -0800 -@@ -17,10 +17,12 @@ - * Revalidate the inode. This is required for proper NFS attribute caching. - */ - static __inline__ int --do_revalidate(struct dentry *dentry) -+do_revalidate(struct dentry *dentry, struct lookup_intent *it) - { - struct inode * inode = dentry->d_inode; -- if (inode->i_op && inode->i_op->revalidate) -+ if (inode->i_op && inode->i_op->revalidate_it) -+ return inode->i_op->revalidate_it(dentry, it); -+ else if (inode->i_op && inode->i_op->revalidate) - return inode->i_op->revalidate(dentry); - return 0; - } -@@ -143,13 +145,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -159,13 +163,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -180,13 +186,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -197,13 +205,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -224,7 +234,7 @@ asmlinkage long sys_fstat(unsigned int f - if (f) { - struct dentry * dentry = f->f_dentry; - -- err = do_revalidate(dentry); -+ err = do_revalidate(dentry, NULL); - if (!err) - err = cp_old_stat(dentry->d_inode, statbuf); - fput(f); -@@ -243,7 +253,7 @@ asmlinkage long sys_newfstat(unsigned in - if (f) { - struct dentry * dentry = f->f_dentry; - -- err = do_revalidate(dentry); -+ err = do_revalidate(dentry, NULL); - if (!err) - err = cp_new_stat(dentry->d_inode, statbuf); - fput(f); -@@ -265,7 +275,7 @@ asmlinkage long sys_readlink(const char - - error = -EINVAL; - if (inode->i_op && inode->i_op->readlink && -- !(error = do_revalidate(nd.dentry))) { -+ !(error = do_revalidate(nd.dentry, NULL))) { - UPDATE_ATIME(inode); - error = inode->i_op->readlink(nd.dentry, buf, bufsiz); - } -@@ -341,12 +351,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -356,12 +368,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -376,7 +390,7 @@ asmlinkage long sys_fstat64(unsigned lon - if (f) { - struct dentry * dentry = f->f_dentry; - -- err = do_revalidate(dentry); -+ err = do_revalidate(dentry, NULL); - if (!err) - err = cp_new_stat64(dentry->d_inode, statbuf); - fput(f); -Index: linux-ia64/include/linux/dcache.h -=================================================================== ---- linux-ia64.orig/include/linux/dcache.h 2004-03-17 15:47:15.000000000 -0800 -+++ linux-ia64/include/linux/dcache.h 2004-03-17 16:05:28.000000000 -0800 -@@ -6,6 +6,51 @@ - #include - #include - #include -+#include -+ -+#define IT_OPEN 0x0001 -+#define IT_CREAT 0x0002 -+#define IT_READDIR 0x0004 -+#define IT_GETATTR 0x0008 -+#define IT_LOOKUP 0x0010 -+#define IT_UNLINK 0x0020 -+#define IT_GETXATTR 0x0040 -+#define IT_EXEC 0x0080 -+#define IT_PIN 0x0100 -+ -+#define IT_FL_LOCKED 0x0001 -+#define IT_FL_FOLLOWED 0x0002 /* set by vfs_follow_link */ -+ -+#define INTENT_MAGIC 0x19620323 -+ -+ -+struct lustre_intent_data { -+ int it_disposition; -+ int it_status; -+ __u64 it_lock_handle; -+ void *it_data; -+ int it_lock_mode; -+ int it_int_flags; -+}; -+struct lookup_intent { -+ int it_magic; -+ void (*it_op_release)(struct lookup_intent *); -+ int it_op; -+ int it_flags; -+ int it_create_mode; -+ union { -+ struct lustre_intent_data lustre; -+ } d; -+}; -+ -+static inline void intent_init(struct lookup_intent *it, int op, int flags) -+{ -+ memset(it, 0, sizeof(*it)); -+ it->it_magic = INTENT_MAGIC; -+ it->it_op = op; -+ it->it_flags = flags; -+} -+ - - /* - * linux/include/linux/dcache.h -@@ -96,8 +141,22 @@ struct dentry_operations { - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate_it)(struct dentry *, int, struct lookup_intent *); -+ void (*d_pin)(struct dentry *, struct vfsmount * , int); -+ void (*d_unpin)(struct dentry *, struct vfsmount *, int); - }; - -+#define PIN(de,mnt,flag) if (de && de->d_op && de->d_op->d_pin) \ -+ de->d_op->d_pin(de, mnt, flag); -+#define UNPIN(de,mnt,flag) if (de && de->d_op && de->d_op->d_unpin) \ -+ de->d_op->d_unpin(de, mnt, flag); -+ -+ -+/* defined in fs/namei.c */ -+extern void intent_release(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 +188,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; - -Index: linux-ia64/include/linux/fs.h -=================================================================== ---- linux-ia64.orig/include/linux/fs.h 2004-03-17 16:05:28.000000000 -0800 -+++ linux-ia64/include/linux/fs.h 2004-03-17 16:05:52.000000000 -0800 -@@ -73,6 +73,7 @@ extern int leases_enable, dir_notify_ena - - #define FMODE_READ 1 - #define FMODE_WRITE 2 -+#define FMODE_EXEC 4 - - #define READ 0 - #define WRITE 1 -@@ -359,6 +360,9 @@ 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 0x0800 /* file system, not vfs will massage attrs */ -+#define ATTR_FROM_OPEN 0x1000 /* called from open path, ie O_TRUNC */ -+#define ATTR_CTIME_SET 0x2000 - - /* - * This is the Inode Attributes structure, used for notify_change(). It -@@ -496,6 +500,7 @@ struct inode { - struct pipe_inode_info *i_pipe; - struct block_device *i_bdev; - struct char_device *i_cdev; -+ void *i_filterdata; - - unsigned long i_dnotify_mask; /* Directory notify events */ - struct dnotify_struct *i_dnotify; /* for directory notifications */ -@@ -598,6 +603,7 @@ struct file { - - /* needed for tty driver, and maybe others */ - void *private_data; -+ struct lookup_intent *f_it; - - /* preallocated helper kiobuf to speedup O_DIRECT */ - struct kiobuf *f_iobuf; -@@ -726,6 +732,7 @@ struct nameidata { - struct qstr last; - unsigned int flags; - int last_type; -+ struct lookup_intent *intent; - }; - - /* -@@ -846,7 +853,8 @@ 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); - - /* - * File types -@@ -920,21 +928,32 @@ struct file_operations { - - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); -+ int (*create_it) (struct inode *,struct dentry *,int, struct lookup_intent *); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup_it) (struct inode *,struct dentry *, struct lookup_intent *, int flags); - int (*link) (struct dentry *,struct inode *,struct dentry *); -+ int (*link_raw) (struct nameidata *,struct nameidata *); - int (*unlink) (struct inode *,struct dentry *); -+ int (*unlink_raw) (struct nameidata *); - int (*symlink) (struct inode *,struct dentry *,const char *); -+ int (*symlink_raw) (struct nameidata *,const char *); - int (*mkdir) (struct inode *,struct dentry *,int); -+ int (*mkdir_raw) (struct nameidata *,int); - int (*rmdir) (struct inode *,struct dentry *); -+ int (*rmdir_raw) (struct nameidata *); - int (*mknod) (struct inode *,struct dentry *,int,int); -+ int (*mknod_raw) (struct nameidata *,int,dev_t); - int (*rename) (struct inode *, struct dentry *, - struct inode *, struct dentry *); -+ int (*rename_raw) (struct nameidata *, struct nameidata *); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*revalidate) (struct dentry *); -+ int (*revalidate_it) (struct dentry *, struct lookup_intent *); - 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 *, const void *, size_t, int); - ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); -@@ -1131,10 +1150,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 *); - -@@ -1425,6 +1448,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 *)); -@@ -1436,6 +1460,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 *); -@@ -1599,6 +1625,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; -Index: linux-ia64/include/linux/fs_struct.h -=================================================================== ---- linux-ia64.orig/include/linux/fs_struct.h 2004-03-17 15:47:15.000000000 -0800 -+++ linux-ia64/include/linux/fs_struct.h 2004-03-17 16:05:28.000000000 -0800 -@@ -37,10 +37,12 @@ static inline void set_fs_root(struct fs - write_lock(&fs->lock); - old_root = fs->root; - old_rootmnt = fs->rootmnt; -+ PIN(dentry, mnt, 1); - fs->rootmnt = mntget(mnt); - fs->root = dget(dentry); - write_unlock(&fs->lock); - if (old_root) { -+ UNPIN(old_root, old_rootmnt, 1); - dput(old_root); - mntput(old_rootmnt); - } -@@ -60,10 +62,12 @@ static inline void set_fs_pwd(struct fs_ - write_lock(&fs->lock); - old_pwd = fs->pwd; - old_pwdmnt = fs->pwdmnt; -+ PIN(dentry, mnt, 0); - fs->pwdmnt = mntget(mnt); - fs->pwd = dget(dentry); - write_unlock(&fs->lock); - if (old_pwd) { -+ UNPIN(old_pwd, old_pwdmnt, 0); - dput(old_pwd); - mntput(old_pwdmnt); - } -Index: linux-ia64/kernel/exit.c -=================================================================== ---- linux-ia64.orig/kernel/exit.c 2004-03-17 15:47:15.000000000 -0800 -+++ linux-ia64/kernel/exit.c 2004-03-17 16:05:28.000000000 -0800 -@@ -347,11 +347,14 @@ static inline void __put_fs_struct(struc - { - /* No need to hold fs->lock if we are killing it */ - if (atomic_dec_and_test(&fs->count)) { -+ UNPIN(fs->pwd, fs->pwdmnt, 0); -+ UNPIN(fs->root, fs->rootmnt, 1); - dput(fs->root); - mntput(fs->rootmnt); - dput(fs->pwd); - mntput(fs->pwdmnt); - if (fs->altroot) { -+ UNPIN(fs->altroot, fs->altrootmnt, 1); - dput(fs->altroot); - mntput(fs->altrootmnt); - } -Index: linux-ia64/kernel/fork.c -=================================================================== ---- linux-ia64.orig/kernel/fork.c 2004-03-17 15:47:15.000000000 -0800 -+++ linux-ia64/kernel/fork.c 2004-03-17 16:05:28.000000000 -0800 -@@ -463,10 +463,13 @@ static inline struct fs_struct *__copy_f - fs->umask = old->umask; - read_lock(&old->lock); - fs->rootmnt = mntget(old->rootmnt); -+ PIN(old->pwd, old->pwdmnt, 0); -+ PIN(old->root, old->rootmnt, 1); - fs->root = dget(old->root); - fs->pwdmnt = mntget(old->pwdmnt); - fs->pwd = dget(old->pwd); - if (old->altroot) { -+ PIN(old->altroot, old->altrootmnt, 1); - fs->altrootmnt = mntget(old->altrootmnt); - fs->altroot = dget(old->altroot); - } else { -Index: linux-ia64/kernel/ksyms.c -=================================================================== ---- linux-ia64.orig/kernel/ksyms.c 2004-03-17 16:05:28.000000000 -0800 -+++ linux-ia64/kernel/ksyms.c 2004-03-17 16:05:51.000000000 -0800 -@@ -318,6 +318,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.22-rh.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch deleted file mode 100644 index 2d75566..0000000 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch +++ /dev/null @@ -1,1829 +0,0 @@ - fs/dcache.c | 19 ++ - fs/exec.c | 17 +- - fs/namei.c | 295 +++++++++++++++++++++++++++++++++++++++------- - fs/namespace.c | 28 +++- - fs/open.c | 172 +++++++++++++++++++------- - fs/stat.c | 52 +++++--- - include/linux/dcache.h | 60 +++++++++ - include/linux/fs.h | 32 ++++ - include/linux/fs_struct.h | 4 - kernel/exit.c | 3 - kernel/fork.c | 3 - kernel/ksyms.c | 1 - 12 files changed, 558 insertions(+), 128 deletions(-) - ---- linux-2.4.22-ac1/fs/dcache.c~vfs_intent-2.4.22-rh 2003-09-25 14:16:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/dcache.c 2003-09-25 14:42:46.000000000 +0400 -@@ -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. -@@ -833,13 +840,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.22-ac1/fs/exec.c~vfs_intent-2.4.22-rh 2003-09-25 14:16:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/exec.c 2003-09-25 14:42:46.000000000 +0400 -@@ -115,8 +115,10 @@ asmlinkage long sys_uselib(const char * - struct file * file; - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_OPEN, -+ .it_flags = FMODE_READ|FMODE_EXEC }; - -- error = user_path_walk(library, &nd); -+ error = user_path_walk_it(library, &nd, &it); - if (error) - goto out; - -@@ -128,7 +130,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(&it); - error = PTR_ERR(file); - if (IS_ERR(file)) - goto out; -@@ -390,8 +393,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 = FMODE_READ|FMODE_EXEC }; - -- 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; -@@ -403,7 +408,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(&it); - if (!IS_ERR(file)) { - err = deny_write_access(file); - if (err) { -@@ -415,6 +421,7 @@ out: - return file; - } - } -+ intent_release(&it); - path_release(&nd); - } - goto out; -@@ -1322,7 +1329,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-2.4.22-ac1/fs/namei.c~vfs_intent-2.4.22-rh 2003-09-25 14:16:23.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/namei.c 2003-09-25 14:44:40.000000000 +0400 -@@ -94,6 +94,13 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct lookup_intent *it) -+{ -+ if (it && it->it_op_release) -+ it->it_op_release(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_revalidate_it) { -+ if (!dentry->d_op->d_revalidate_it(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,15 @@ 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; -+ int counter = 0; - -+again: -+ counter++; - 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->lookup_it) -+ result = dir->i_op->lookup_it(dir, dentry, it, flags); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -321,6 +344,15 @@ static struct dentry * real_lookup(struc - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate_it) { -+ if (!result->d_op->d_revalidate_it(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ if (counter > 10) -+ result = ERR_PTR(-ESTALE); -+ if (!IS_ERR(result)) -+ goto again; -+ } - } - return result; - } -@@ -332,7 +364,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 +379,12 @@ static inline int do_follow_link(struct - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -+ nd->intent = it; - err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -+ intent_release(it); - path_release(nd); - return -ELOOP; - } -@@ -447,7 +482,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,9 +556,9 @@ 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; -@@ -540,7 +576,7 @@ int link_path_walk(const char * name, st - goto out_dput; - - if (inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ err = do_follow_link(dentry, nd, NULL); - dput(dentry); - if (err) - goto return_err; -@@ -556,7 +592,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->lookup_it) - break; - continue; - /* here ends the main loop */ -@@ -583,9 +619,9 @@ 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; -@@ -595,7 +631,7 @@ 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); -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -609,7 +645,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->lookup_it)) - break; - } - goto return_base; -@@ -635,6 +672,32 @@ return_reval: - * Check the cached dentry for staleness. - */ - dentry = nd->dentry; -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) { -+ err = -ESTALE; -+ if (!dentry->d_op->d_revalidate_it(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, it); -+ if (IS_ERR(new)) { -+ err = PTR_ERR(new); -+ break; -+ } -+ d_invalidate(dentry); -+ dput(dentry); -+ nd->dentry = new; -+ } -+ if (lookup_flags & LOOKUP_DIRECTORY) { -+ err = -ENOTDIR; -+ if (!nd->dentry->d_inode->i_op || -+ (!nd->dentry->d_inode->i_op->lookup && -+ !nd->dentry->d_inode->i_op->lookup_it)) -+ break; -+ } -+ } else - if (dentry && dentry->d_sb - && (dentry->d_sb->s_type->fs_flags & FS_ALWAYS_REVAL)) { - err = -ESTALE; -@@ -649,15 +705,28 @@ out_dput: - dput(dentry); - break; - } -+ if (err) -+ intent_release(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 */ -@@ -742,6 +811,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; -@@ -756,6 +836,7 @@ int path_init(const char *name, unsigned - { - nd->last_type = LAST_ROOT; /* if there are only slashes... */ - nd->flags = flags; -+ nd->intent = NULL; - if (*name=='/') - return walk_init_root(name,nd); - read_lock(¤t->fs->lock); -@@ -770,7 +851,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; -@@ -793,13 +875,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->lookup_it) -+ dentry = inode->i_op->lookup_it(inode, new, it, 0); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -811,6 +896,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) - { -@@ -832,7 +923,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); - } -@@ -863,6 +954,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. -@@ -958,7 +1066,8 @@ static inline int lookup_flags(unsigned - return retval; - } - --int vfs_create(struct inode *dir, struct dentry *dentry, int mode) -+static int vfs_create_it(struct inode *dir, struct dentry *dentry, int mode, -+ struct lookup_intent *it) - { - int error; - -@@ -971,12 +1080,15 @@ int vfs_create(struct inode *dir, struct - goto exit_lock; - - error = -EACCES; /* shouldn't it be ENOSYS? */ -- if (!dir->i_op || !dir->i_op->create) -+ if (!dir->i_op || (!dir->i_op->create && !dir->i_op->create_it)) - goto exit_lock; - - DQUOT_INIT(dir); - lock_kernel(); -- error = dir->i_op->create(dir, dentry, mode); -+ if (dir->i_op->create_it) -+ error = dir->i_op->create_it(dir, dentry, mode, it); -+ else -+ error = dir->i_op->create(dir, dentry, mode); - unlock_kernel(); - exit_lock: - up(&dir->i_zombie); -@@ -985,6 +1097,11 @@ exit_lock: - return error; - } - -+int vfs_create(struct inode *dir, struct dentry *dentry, int mode) -+{ -+ return vfs_create_it(dir, dentry, mode, NULL); -+} -+ - /* - * open_namei() - * -@@ -999,7 +1116,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; -@@ -1009,11 +1127,14 @@ int open_namei(const char * pathname, in - - acc_mode = ACC_MODE(flag); - -+ if (it) -+ it->it_flags = flag; -+ - /* - * 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; -@@ -1023,6 +1144,10 @@ int open_namei(const char * pathname, in - /* - * Create - we need to know the parent. - */ -+ if (it) { -+ it->it_create_mode = mode; -+ it->it_op |= IT_CREAT; -+ } - error = path_lookup(pathname, LOOKUP_PARENT, nd); - if (error) - return error; -@@ -1038,7 +1163,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); -@@ -1047,10 +1172,11 @@ do_last: - goto exit; - } - -+ it->it_create_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { -- error = vfs_create(dir->d_inode, dentry, -- mode & ~current->fs->umask); -+ error = vfs_create_it(dir->d_inode, dentry, -+ mode & ~current->fs->umask, it); - up(&dir->d_inode->i_sem); - dput(nd->dentry); - nd->dentry = dentry; -@@ -1154,7 +1280,7 @@ ok: - if (!error) { - DQUOT_INIT(inode); - -- error = do_truncate(dentry, 0); -+ error = do_truncate(dentry, 0, 1); - } - put_write_access(inode); - if (error) -@@ -1166,8 +1292,10 @@ ok: - return 0; - - exit_dput: -+ intent_release(it); - dput(dentry); - exit: -+ intent_release(it); - path_release(nd); - return error; - -@@ -1186,7 +1314,10 @@ do_link: - * are done. Procfs-like symlinks just set LAST_BIND. - */ - UPDATE_ATIME(dentry->d_inode); -+ nd->intent = it; - error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) -+ intent_release(it); - dput(dentry); - if (error) - return error; -@@ -1208,13 +1339,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; - -@@ -1222,7 +1360,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) -@@ -1278,7 +1416,20 @@ 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.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->mknod_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mknod_raw(&nd, 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; -@@ -1299,6 +1446,7 @@ asmlinkage long sys_mknod(const char * f - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1346,7 +1494,20 @@ 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.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->mkdir_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mkdir_raw(&nd, 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, -@@ -1354,6 +1509,7 @@ asmlinkage long sys_mkdir(const char * p - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1454,8 +1610,16 @@ asmlinkage long sys_rmdir(const char * p - error = -EBUSY; - goto exit1; - } -+ if (nd.dentry->d_inode->i_op->rmdir_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ error = op->rmdir_raw(&nd); -+ /* 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); -@@ -1513,8 +1677,15 @@ asmlinkage long sys_unlink(const char * - error = -EISDIR; - if (nd.last_type != LAST_NORM) - goto exit1; -+ if (nd.dentry->d_inode->i_op->unlink_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->unlink_raw(&nd); -+ /* 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 */ -@@ -1581,15 +1752,27 @@ asmlinkage long sys_symlink(const char * - error = path_lookup(to, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ if (nd.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->symlink_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->symlink_raw(&nd, 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); -@@ -1665,7 +1844,18 @@ 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.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->link_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->link_raw(&old_nd, &nd); -+ /* 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); -@@ -1709,7 +1895,7 @@ 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) - { - int error; - struct inode *target; -@@ -1788,7 +1974,7 @@ 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) - { - int error; - -@@ -1876,9 +2062,18 @@ static inline int do_rename(const char * - if (newnd.last_type != LAST_NORM) - goto exit2; - -+ if (old_dir->d_inode->i_op->rename_raw) { -+ lock_kernel(); -+ error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd); -+ unlock_kernel(); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit2; -+ } -+ - 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; -@@ -1894,16 +2089,16 @@ 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; - -+ - lock_kernel(); - error = vfs_rename(old_dir->d_inode, old_dentry, - new_dir->d_inode, new_dentry); - unlock_kernel(); -- - dput(new_dentry); - exit4: - dput(old_dentry); -@@ -1954,20 +2149,26 @@ 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; - if (IS_ERR(link)) - goto fail; - -+ if (it == NULL) -+ it = nd->intent; -+ else if (it != nd->intent) -+ printk("it != nd->intent: tell phil@clusterfs.com\n"); -+ - if (*link == '/') { - path_release(nd); - if (!walk_init_root(link, 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; -@@ -1991,7 +2192,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 */ -@@ -2033,7 +2240,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.22-ac1/fs/namespace.c~vfs_intent-2.4.22-rh 2003-09-25 14:16:28.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/namespace.c 2003-09-25 14:42:46.000000000 +0400 -@@ -98,6 +98,7 @@ static void detach_mnt(struct vfsmount * - { - old_nd->dentry = mnt->mnt_mountpoint; - old_nd->mnt = mnt->mnt_parent; -+ UNPIN(old_nd->dentry, old_nd->mnt, 1); - mnt->mnt_parent = mnt; - mnt->mnt_mountpoint = mnt->mnt_root; - list_del_init(&mnt->mnt_child); -@@ -109,6 +110,7 @@ static void attach_mnt(struct vfsmount * - { - mnt->mnt_parent = mntget(nd->mnt); - mnt->mnt_mountpoint = dget(nd->dentry); -+ PIN(nd->dentry, nd->mnt, 1); - list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry)); - list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts); - nd->dentry->d_mounted++; -@@ -488,14 +490,17 @@ static int do_loopback(struct nameidata - { - struct nameidata old_nd; - struct vfsmount *mnt = NULL; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int err = mount_is_safe(nd); - if (err) - return err; - if (!old_name || !*old_name) - return -EINVAL; -- err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd); -- if (err) -+ err = path_lookup_it(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd, &it); -+ if (err) { -+ intent_release(&it); - return err; -+ } - - down_write(¤t->namespace->sem); - err = -EINVAL; -@@ -518,6 +523,7 @@ static int do_loopback(struct nameidata - } - - up_write(¤t->namespace->sem); -+ intent_release(&it); - path_release(&old_nd); - return err; - } -@@ -701,6 +707,7 @@ long do_mount(char * dev_name, char * di - unsigned long flags, void *data_page) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int retval = 0; - int mnt_flags = 0; - -@@ -725,9 +732,11 @@ long do_mount(char * dev_name, char * di - flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV); - - /* ... and get the mountpoint */ -- retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd); -- if (retval) -+ retval = path_lookup_it(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it); -+ if (retval) { -+ intent_release(&it); - return retval; -+ } - - if (flags & MS_REMOUNT) - retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, -@@ -739,6 +747,8 @@ long do_mount(char * dev_name, char * di - else - retval = do_add_mount(&nd, type_page, flags, mnt_flags, - dev_name, data_page); -+ -+ intent_release(&it); - path_release(&nd); - return retval; - } -@@ -904,6 +914,8 @@ asmlinkage long sys_pivot_root(const cha - { - struct vfsmount *tmp; - struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; -+ struct lookup_intent new_it = { .it_op = IT_GETATTR }; -+ struct lookup_intent old_it = { .it_op = IT_GETATTR }; - int error; - - if (!capable(CAP_SYS_ADMIN)) -@@ -911,14 +923,14 @@ asmlinkage long sys_pivot_root(const cha - - lock_kernel(); - -- error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd); -+ error = __user_walk_it(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd, &new_it); - if (error) - goto out0; - error = -EINVAL; - if (!check_mnt(new_nd.mnt)) - goto out1; - -- error = __user_walk(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd); -+ error = __user_walk_it(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd, &old_it); - if (error) - goto out1; - -@@ -973,8 +985,10 @@ out2: - up(&old_nd.dentry->d_inode->i_zombie); - up_write(¤t->namespace->sem); - path_release(&user_nd); -+ intent_release(&old_it); - path_release(&old_nd); - out1: -+ intent_release(&new_it); - path_release(&new_nd); - out0: - unlock_kernel(); ---- linux-2.4.22-ac1/fs/open.c~vfs_intent-2.4.22-rh 2003-08-25 15:44:43.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/open.c 2003-09-25 14:42:46.000000000 +0400 -@@ -19,6 +19,8 @@ - #include - - #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; - -@@ -109,7 +112,13 @@ 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; -+ error = op->setattr_raw(inode, &newattrs); -+ } else -+ error = notify_change(dentry, &newattrs); - up(&inode->i_sem); - up_write(&inode->i_alloc_sem); - return error; -@@ -120,12 +129,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; -@@ -165,11 +175,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(&it); -+ error = do_truncate(nd.dentry, length, 0); - } - put_write_access(inode); - - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; -@@ -217,7 +229,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: -@@ -262,11 +274,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; -@@ -281,11 +295,25 @@ 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 = -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); -@@ -306,12 +334,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; -@@ -326,7 +356,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; -@@ -349,6 +392,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; -@@ -366,13 +410,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(&it); - path_release(&nd); - } - -@@ -387,8 +432,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; - -@@ -399,6 +445,7 @@ asmlinkage long sys_chdir(const char * f - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; -@@ -438,9 +485,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; - -@@ -456,39 +504,56 @@ asmlinkage long sys_chroot(const char * - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; - } - --asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) -+int chmod_common(struct dentry *dentry, mode_t mode) - { -- struct inode * inode; -- struct dentry * dentry; -- struct file * file; -- int err = -EBADF; -+ struct inode *inode = dentry->d_inode; - struct iattr newattrs; -+ int err = -EROFS; - -- file = fget(fd); -- if (!file) -+ if (IS_RDONLY(inode)) - goto out; - -- dentry = file->f_dentry; -- inode = dentry->d_inode; -+ if (inode->i_op->setattr_raw) { -+ newattrs.ia_mode = mode; -+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -+ newattrs.ia_valid |= ATTR_RAW; -+ err = inode->i_op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (err != -EOPNOTSUPP) -+ goto out; -+ } - -- err = -EROFS; -- if (IS_RDONLY(inode)) -- goto out_putf; - err = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -- goto out_putf; -+ goto out; -+ - if (mode == (mode_t) -1) - mode = inode->i_mode; - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - err = notify_change(dentry, &newattrs); - --out_putf: -+out: -+ return err; -+} -+ -+asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) -+{ -+ struct file * file; -+ int err = -EBADF; -+ -+ file = fget(fd); -+ if (!file) -+ goto out; -+ -+ err = chmod_common(file->f_dentry, mode); -+ - fput(file); - out: - return err; -@@ -497,30 +562,14 @@ out: - asmlinkage long sys_chmod(const char * filename, mode_t mode) - { - struct nameidata nd; -- struct inode * inode; - int error; -- struct iattr newattrs; - - error = user_path_walk(filename, &nd); - if (error) - goto out; -- inode = nd.dentry->d_inode; -- -- error = -EROFS; -- if (IS_RDONLY(inode)) -- goto dput_and_out; - -- error = -EPERM; -- if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -- goto dput_and_out; -+ error = chmod_common(nd.dentry, mode); - -- if (mode == (mode_t) -1) -- mode = inode->i_mode; -- newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); -- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -- error = notify_change(nd.dentry, &newattrs); -- --dput_and_out: - path_release(&nd); - out: - return error; -@@ -540,6 +589,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 | 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) -+ return error; -+ } -+ - error = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto out; -@@ -644,6 +707,7 @@ struct file *filp_open(const char * file - { - int namei_flags, error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_OPEN }; - - namei_flags = flags; - if ((namei_flags+1) & O_ACCMODE) -@@ -651,14 +715,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; -@@ -695,12 +760,15 @@ struct file *dentry_open(struct dentry * - } - - if (f->f_op && f->f_op->open) { -+ f->f_it = it; - error = f->f_op->open(inode,f); -+ f->f_it = NULL; - if (error) - goto cleanup_all; - } - f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); - -+ intent_release(it); - return f; - - cleanup_all: -@@ -715,11 +783,17 @@ cleanup_all: - cleanup_file: - put_filp(f); - cleanup_dentry: -+ intent_release(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.22-ac1/fs/stat.c~vfs_intent-2.4.22-rh 2003-09-25 14:16:27.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/stat.c 2003-09-25 14:42:46.000000000 +0400 -@@ -17,10 +17,12 @@ - * Revalidate the inode. This is required for proper NFS attribute caching. - */ - static __inline__ int --do_revalidate(struct dentry *dentry) -+do_revalidate(struct dentry *dentry, struct lookup_intent *it) - { - struct inode * inode = dentry->d_inode; -- if (inode->i_op && inode->i_op->revalidate) -+ if (inode->i_op && inode->i_op->revalidate_it) -+ return inode->i_op->revalidate_it(dentry, it); -+ else if (inode->i_op && inode->i_op->revalidate) - return inode->i_op->revalidate(dentry); - return 0; - } -@@ -143,13 +147,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -159,13 +165,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -180,13 +188,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -197,13 +207,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -224,7 +236,7 @@ asmlinkage long sys_fstat(unsigned int f - if (f) { - struct dentry * dentry = f->f_dentry; - -- err = do_revalidate(dentry); -+ err = do_revalidate(dentry, NULL); - if (!err) - err = cp_old_stat(dentry->d_inode, statbuf); - fput(f); -@@ -243,7 +255,7 @@ asmlinkage long sys_newfstat(unsigned in - if (f) { - struct dentry * dentry = f->f_dentry; - -- err = do_revalidate(dentry); -+ err = do_revalidate(dentry, NULL); - if (!err) - err = cp_new_stat(dentry->d_inode, statbuf); - fput(f); -@@ -265,7 +277,7 @@ asmlinkage long sys_readlink(const char - - error = -EINVAL; - if (inode->i_op && inode->i_op->readlink && -- !(error = do_revalidate(nd.dentry))) { -+ !(error = do_revalidate(nd.dentry, NULL))) { - UPDATE_ATIME(inode); - error = inode->i_op->readlink(nd.dentry, buf, bufsiz); - } -@@ -341,12 +353,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -356,12 +370,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); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -376,7 +392,7 @@ asmlinkage long sys_fstat64(unsigned lon - if (f) { - struct dentry * dentry = f->f_dentry; - -- err = do_revalidate(dentry); -+ err = do_revalidate(dentry, NULL); - if (!err) - err = cp_new_stat64(dentry->d_inode, statbuf); - fput(f); ---- linux-2.4.22-ac1/include/linux/dcache.h~vfs_intent-2.4.22-rh 2003-09-25 14:16:28.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/dcache.h 2003-09-25 14:42:46.000000000 +0400 -@@ -6,6 +6,51 @@ - #include - #include - #include -+#include -+ -+#define IT_OPEN 0x0001 -+#define IT_CREAT 0x0002 -+#define IT_READDIR 0x0004 -+#define IT_GETATTR 0x0008 -+#define IT_LOOKUP 0x0010 -+#define IT_UNLINK 0x0020 -+#define IT_GETXATTR 0x0040 -+#define IT_EXEC 0x0080 -+#define IT_PIN 0x0100 -+ -+#define IT_FL_LOCKED 0x0001 -+#define IT_FL_FOLLOWED 0x0002 /* set by vfs_follow_link */ -+ -+#define INTENT_MAGIC 0x19620323 -+ -+ -+struct lustre_intent_data { -+ int it_disposition; -+ int it_status; -+ __u64 it_lock_handle; -+ void *it_data; -+ int it_lock_mode; -+ int it_int_flags; -+}; -+struct lookup_intent { -+ int it_magic; -+ void (*it_op_release)(struct lookup_intent *); -+ int it_op; -+ int it_flags; -+ int it_create_mode; -+ union { -+ struct lustre_intent_data lustre; -+ } d; -+}; -+ -+static inline void intent_init(struct lookup_intent *it, int op, int flags) -+{ -+ memset(it, 0, sizeof(*it)); -+ it->it_magic = INTENT_MAGIC; -+ it->it_op = op; -+ it->it_flags = flags; -+} -+ - - /* - * linux/include/linux/dcache.h -@@ -95,8 +140,22 @@ struct dentry_operations { - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate_it)(struct dentry *, int, struct lookup_intent *); -+ void (*d_pin)(struct dentry *, struct vfsmount * , int); -+ void (*d_unpin)(struct dentry *, struct vfsmount *, int); - }; - -+#define PIN(de,mnt,flag) if (de && de->d_op && de->d_op->d_pin) \ -+ de->d_op->d_pin(de, mnt, flag); -+#define UNPIN(de,mnt,flag) if (de && de->d_op && de->d_op->d_unpin) \ -+ de->d_op->d_unpin(de, mnt, flag); -+ -+ -+/* defined in fs/namei.c */ -+extern void intent_release(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 -@@ -128,6 +187,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.22-ac1/include/linux/fs.h~vfs_intent-2.4.22-rh 2003-09-25 14:39:01.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/fs.h 2003-09-25 14:42:46.000000000 +0400 -@@ -73,6 +73,7 @@ extern int leases_enable, dir_notify_ena - - #define FMODE_READ 1 - #define FMODE_WRITE 2 -+#define FMODE_EXEC 4 - - #define READ 0 - #define WRITE 1 -@@ -343,6 +344,9 @@ 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 0x0800 /* file system, not vfs will massage attrs */ -+#define ATTR_FROM_OPEN 0x1000 /* called from open path, ie O_TRUNC */ -+#define ATTR_CTIME_SET 0x2000 - - /* - * This is the Inode Attributes structure, used for notify_change(). It -@@ -481,6 +485,7 @@ struct inode { - struct pipe_inode_info *i_pipe; - struct block_device *i_bdev; - struct char_device *i_cdev; -+ void *i_filterdata; - - unsigned long i_dnotify_mask; /* Directory notify events */ - struct dnotify_struct *i_dnotify; /* for directory notifications */ -@@ -583,6 +588,7 @@ struct file { - - /* needed for tty driver, and maybe others */ - void *private_data; -+ struct lookup_intent *f_it; - - /* preallocated helper kiobuf to speedup O_DIRECT */ - struct kiobuf *f_iobuf; -@@ -703,6 +709,7 @@ struct nameidata { - struct qstr last; - unsigned int flags; - int last_type; -+ struct lookup_intent *intent; - }; - - /* -@@ -823,7 +830,8 @@ 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); - - /* - * File types -@@ -883,21 +891,32 @@ struct file_operations { - - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); -+ int (*create_it) (struct inode *,struct dentry *,int, struct lookup_intent *); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup_it) (struct inode *,struct dentry *, struct lookup_intent *, int flags); - int (*link) (struct dentry *,struct inode *,struct dentry *); -+ int (*link_raw) (struct nameidata *,struct nameidata *); - int (*unlink) (struct inode *,struct dentry *); -+ int (*unlink_raw) (struct nameidata *); - int (*symlink) (struct inode *,struct dentry *,const char *); -+ int (*symlink_raw) (struct nameidata *,const char *); - int (*mkdir) (struct inode *,struct dentry *,int); -+ int (*mkdir_raw) (struct nameidata *,int); - int (*rmdir) (struct inode *,struct dentry *); -+ int (*rmdir_raw) (struct nameidata *); - int (*mknod) (struct inode *,struct dentry *,int,int); -+ int (*mknod_raw) (struct nameidata *,int,dev_t); - int (*rename) (struct inode *, struct dentry *, - struct inode *, struct dentry *); -+ int (*rename_raw) (struct nameidata *, struct nameidata *); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*revalidate) (struct dentry *); -+ int (*revalidate_it) (struct dentry *, struct lookup_intent *); - 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); -@@ -1094,10 +1113,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 *); - -@@ -1388,6 +1411,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 *)); -@@ -1399,6 +1423,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 *); -@@ -1538,6 +1564,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.22-ac1/include/linux/fs_struct.h~vfs_intent-2.4.22-rh 2003-09-25 14:16:24.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/fs_struct.h 2003-09-25 14:42:46.000000000 +0400 -@@ -37,10 +37,12 @@ static inline void set_fs_root(struct fs - write_lock(&fs->lock); - old_root = fs->root; - old_rootmnt = fs->rootmnt; -+ PIN(dentry, mnt, 1); - fs->rootmnt = mntget(mnt); - fs->root = dget(dentry); - write_unlock(&fs->lock); - if (old_root) { -+ UNPIN(old_root, old_rootmnt, 1); - dput(old_root); - mntput(old_rootmnt); - } -@@ -60,10 +62,12 @@ static inline void set_fs_pwd(struct fs_ - write_lock(&fs->lock); - old_pwd = fs->pwd; - old_pwdmnt = fs->pwdmnt; -+ PIN(dentry, mnt, 0); - fs->pwdmnt = mntget(mnt); - fs->pwd = dget(dentry); - write_unlock(&fs->lock); - if (old_pwd) { -+ UNPIN(old_pwd, old_pwdmnt, 0); - dput(old_pwd); - mntput(old_pwdmnt); - } ---- linux-2.4.22-ac1/kernel/exit.c~vfs_intent-2.4.22-rh 2003-09-25 14:16:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/kernel/exit.c 2003-09-25 14:42:46.000000000 +0400 -@@ -342,11 +342,14 @@ static inline void __put_fs_struct(struc - { - /* No need to hold fs->lock if we are killing it */ - if (atomic_dec_and_test(&fs->count)) { -+ UNPIN(fs->pwd, fs->pwdmnt, 0); -+ UNPIN(fs->root, fs->rootmnt, 1); - dput(fs->root); - mntput(fs->rootmnt); - dput(fs->pwd); - mntput(fs->pwdmnt); - if (fs->altroot) { -+ UNPIN(fs->altroot, fs->altrootmnt, 1); - dput(fs->altroot); - mntput(fs->altrootmnt); - } ---- linux-2.4.22-ac1/kernel/fork.c~vfs_intent-2.4.22-rh 2003-09-25 14:16:28.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/kernel/fork.c 2003-09-25 14:42:46.000000000 +0400 -@@ -457,10 +457,13 @@ static inline struct fs_struct *__copy_f - fs->umask = old->umask; - read_lock(&old->lock); - fs->rootmnt = mntget(old->rootmnt); -+ PIN(old->pwd, old->pwdmnt, 0); -+ PIN(old->root, old->rootmnt, 1); - fs->root = dget(old->root); - fs->pwdmnt = mntget(old->pwdmnt); - fs->pwd = dget(old->pwd); - if (old->altroot) { -+ PIN(old->altroot, old->altrootmnt, 1); - fs->altrootmnt = mntget(old->altrootmnt); - fs->altroot = dget(old->altroot); - } else { ---- linux-2.4.22-ac1/kernel/ksyms.c~vfs_intent-2.4.22-rh 2003-09-25 14:39:02.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/kernel/ksyms.c 2003-09-25 14:42:46.000000000 +0400 -@@ -295,6 +295,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.6-rhel4.patch b/lustre/kernel_patches/patches/vfs_intent-2.6-rhel4.patch index e00f2f3..3057402 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.6-rhel4.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.6-rhel4.patch @@ -121,9 +121,9 @@ Index: linux-2.6.9-5.0.3.EL/fs/namei.c + struct dentry *dentry = nd->dentry; + int err, counter = 0; + ++ revalidate_again: + if (!dentry->d_op || !dentry->d_op->d_revalidate) + return 0; -+ revalidate_again: + if (!dentry->d_op->d_revalidate(dentry, nd)) { + struct dentry *new; + if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC, nd))) diff --git a/lustre/kernel_patches/patches/x86-fpu-crash.patch b/lustre/kernel_patches/patches/x86-fpu-crash.patch deleted file mode 100644 index ce6b830..0000000 --- a/lustre/kernel_patches/patches/x86-fpu-crash.patch +++ /dev/null @@ -1,36 +0,0 @@ -# This is a BitKeeper generated diff -Nru style patch. -# -# ChangeSet -# 2004/06/14 16:05:28-03:00 marcelo@logos.cnet -# Alexander Nyberg/Andi/Sergey: Fix x86 "clear_cpu()" macro. -# -# Linus's 2.6 changelog: -# -# Fix x86 "clear_cpu()" macro. -# -# We need to clear all exceptions before synchronizing -# with the FPU, since we aren't ready to handle a FP -# exception here and we're getting rid of all FP state. -# -# Special thanks to Alexander Nyberg for reports and -# testing. Alternate patches by Sergey Vlasov and Andi -# Kleen, who both worked on this. -# -# Signed-off-by: Linus Torvalds -# -# include/asm-i386/i387.h -# 2004/06/14 16:04:08-03:00 marcelo@logos.cnet +1 -1 -# Alexander Nyberg/Andi/Sergey: Fix x86 "clear_cpu()" macro. -# -diff -Nru a/include/asm-i386/i387.h b/include/asm-i386/i387.h ---- a/include/asm-i386/i387.h 2004-06-16 11:49:16 -07:00 -+++ b/include/asm-i386/i387.h 2004-06-16 11:49:16 -07:00 -@@ -34,7 +34,7 @@ - - #define clear_fpu( tsk ) do { \ - if ( tsk->flags & PF_USEDFPU ) { \ -- asm volatile("fwait"); \ -+ asm volatile("fnclex ; fwait"); \ - tsk->flags &= ~PF_USEDFPU; \ - stts(); \ - } \ diff --git a/lustre/kernel_patches/patches/xattr-0.8.54-2.4.22-rh.patch b/lustre/kernel_patches/patches/xattr-0.8.54-2.4.22-rh.patch deleted file mode 100644 index 39d40ec..0000000 --- a/lustre/kernel_patches/patches/xattr-0.8.54-2.4.22-rh.patch +++ /dev/null @@ -1,5396 +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 | 90 +++ - arch/sparc/defconfig | 7 - arch/sparc64/defconfig | 7 - 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 | 10 - 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 | 37 + - 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 | 13 - include/asm-s390x/unistd.h | 13 - 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 + - 58 files changed, 4306 insertions(+), 137 deletions(-) - ---- linux-2.4.22-ac1/arch/alpha/defconfig~xattr-0.8.54-2.4.22-rh 2003-06-13 18:51:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/alpha/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/arch/alpha/kernel/entry.S~xattr-0.8.54-2.4.22-rh 2003-09-25 14:16:18.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/alpha/kernel/entry.S 2003-09-25 23:57:02.000000000 +0400 -@@ -1158,6 +1158,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.22-ac1/arch/arm/defconfig~xattr-0.8.54-2.4.22-rh 2001-05-20 04:43:05.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/arm/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/arch/arm/kernel/calls.S~xattr-0.8.54-2.4.22-rh 2003-08-25 15:44:39.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/arm/kernel/calls.S 2003-09-26 00:00:10.000000000 +0400 -@@ -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) /* setxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* lsetxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* fsetxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* getxattr */ --/* 230 */ .long SYMBOL_NAME(sys_ni_syscall) /* lgetxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* fgetxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* listxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* llistxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* flistxattr */ --/* 235 */ .long SYMBOL_NAME(sys_ni_syscall) /* removexattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* lremovexattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* 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) - .long SYMBOL_NAME(sys_ni_syscall) /* sendfile64 */ - /* 240 */ .long SYMBOL_NAME(sys_ni_syscall) /* futex */ ---- linux-2.4.22-ac1/arch/i386/defconfig~xattr-0.8.54-2.4.22-rh 2003-09-25 14:16:18.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/i386/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/arch/ia64/defconfig~xattr-0.8.54-2.4.22-rh 2003-08-25 15:44:39.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/ia64/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/arch/m68k/defconfig~xattr-0.8.54-2.4.22-rh 2000-06-19 23:56:08.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/m68k/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/arch/mips64/defconfig~xattr-0.8.54-2.4.22-rh 2003-08-25 15:44:40.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/mips64/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/arch/mips/defconfig~xattr-0.8.54-2.4.22-rh 2003-08-25 15:44:39.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/mips/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/arch/ppc64/kernel/misc.S~xattr-0.8.54-2.4.22-rh 2003-08-25 15:44:40.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/ppc64/kernel/misc.S 2003-09-25 23:57:02.000000000 +0400 -@@ -805,6 +805,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 -@@ -817,6 +818,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.22-ac1/arch/ppc/defconfig~xattr-0.8.54-2.4.22-rh 2003-06-13 18:51:31.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/ppc/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/arch/s390/defconfig~xattr-0.8.54-2.4.22-rh 2003-09-25 14:16:18.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/s390/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/arch/s390/kernel/entry.S~xattr-0.8.54-2.4.22-rh 2003-09-25 14:16:18.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/s390/kernel/entry.S 2003-09-25 23:57:02.000000000 +0400 -@@ -559,18 +559,18 @@ sys_call_table: - .long sys_fcntl64 - .long sys_readahead - .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.22-ac1/arch/s390x/defconfig~xattr-0.8.54-2.4.22-rh 2003-09-25 14:16:18.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/s390x/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/arch/s390x/kernel/entry.S~xattr-0.8.54-2.4.22-rh 2003-09-25 14:16:18.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/s390x/kernel/entry.S 2003-09-25 23:57:02.000000000 +0400 -@@ -591,18 +591,18 @@ sys_call_table: - .long SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper) - .long SYSCALL(sys_readahead,sys32_readahead) - .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.22-ac1/arch/s390x/kernel/wrapper32.S~xattr-0.8.54-2.4.22-rh 2003-08-25 15:44:40.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/s390x/kernel/wrapper32.S 2003-09-26 00:05:14.000000000 +0400 -@@ -1097,6 +1097,96 @@ 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 - - .globl sys32_stime_wrapper - sys32_stime_wrapper: ---- linux-2.4.22-ac1/arch/sparc64/defconfig~xattr-0.8.54-2.4.22-rh 2003-08-25 15:44:40.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/sparc64/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/arch/sparc/defconfig~xattr-0.8.54-2.4.22-rh 2002-08-03 04:39:43.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/arch/sparc/defconfig 2003-09-25 23:57:02.000000000 +0400 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# 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.22-ac1/Documentation/Configure.help~xattr-0.8.54-2.4.22-rh 2003-09-25 14:16:30.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/Documentation/Configure.help 2003-09-25 23:57:02.000000000 +0400 -@@ -16145,6 +16145,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 -+ 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 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 -@@ -16177,6 +16210,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 -+ 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 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.22-ac1/fs/Config.in~xattr-0.8.54-2.4.22-rh 2003-09-25 14:16:23.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/Config.in 2003-09-25 23:57:02.000000000 +0400 -@@ -29,6 +29,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 -@@ -88,6 +93,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-2.4.22-ac1/fs/ext2/file.c~xattr-0.8.54-2.4.22-rh 2001-10-11 19:05:18.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext2/file.c 2003-09-25 23:57:02.000000000 +0400 -@@ -20,6 +20,7 @@ - - #include - #include -+#include - #include - - /* -@@ -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.22-ac1/fs/ext2/ialloc.c~xattr-0.8.54-2.4.22-rh 2003-06-13 18:51:37.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext2/ialloc.c 2003-09-25 23:57:02.000000000 +0400 -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -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.22-ac1/fs/ext2/inode.c~xattr-0.8.54-2.4.22-rh 2003-06-13 18:51:37.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext2/inode.c 2003-09-25 23:57:02.000000000 +0400 -@@ -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; - -@@ -903,8 +915,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", -@@ -989,10 +1000,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; -@@ -1001,15 +1009,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; - ext2_set_inode_flags(inode); ---- linux-2.4.22-ac1/fs/ext2/Makefile~xattr-0.8.54-2.4.22-rh 2001-10-11 19:05:18.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext2/Makefile 2003-09-25 23:57:02.000000000 +0400 -@@ -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.22-ac1/fs/ext2/namei.c~xattr-0.8.54-2.4.22-rh 2001-10-04 09:57:36.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext2/namei.c 2003-09-25 23:57:02.000000000 +0400 -@@ -31,6 +31,7 @@ - - #include - #include -+#include - #include - - /* -@@ -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.22-ac1/fs/ext2/super.c~xattr-0.8.54-2.4.22-rh 2002-11-29 02:53:15.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/ext2/super.c 2003-09-25 23:57:02.000000000 +0400 -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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.22-ac1/fs/ext2/symlink.c~xattr-0.8.54-2.4.22-rh 2000-09-28 00:41:33.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext2/symlink.c 2003-09-25 23:57:02.000000000 +0400 -@@ -19,6 +19,7 @@ - - #include - #include -+#include - - 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 13:24:37.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/ext2/xattr.c 2003-09-25 23:57:02.000000000 +0400 -@@ -0,0 +1,1212 @@ -+/* -+ * linux/fs/ext2/xattr.c -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ * -+ * Fix by Harrison Xing . -+ * Extended attributes for symlinks and special files added per -+ * suggestion of Luka Renko . -+ */ -+ -+/* -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* 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; iprefix); -+ 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; -+ (void)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); -+ (void)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 13:24:37.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/ext2/xattr_user.c 2003-09-25 23:57:02.000000000 +0400 -@@ -0,0 +1,103 @@ -+/* -+ * linux/fs/ext2/xattr_user.c -+ * Handler for extended user attributes. -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_EXT2_FS_POSIX_ACL -+# include -+#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); -+} ---- /dev/null 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/ext3/ext3-exports.c 2003-09-25 23:57:02.000000000 +0400 -@@ -0,0 +1,13 @@ -+#include -+#include -+#include -+#include -+#include -+ -+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-2.4.22-ac1/fs/ext3/file.c~xattr-0.8.54-2.4.22-rh 2003-09-25 14:55:12.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/file.c 2003-09-25 23:57:02.000000000 +0400 -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -127,5 +128,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.22-ac1/fs/ext3/ialloc.c~xattr-0.8.54-2.4.22-rh 2003-09-25 14:16:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/ialloc.c 2003-09-25 23:57:02.000000000 +0400 -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -217,6 +218,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.22-ac1/fs/ext3/inode.c~xattr-0.8.54-2.4.22-rh 2003-09-25 14:16:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/inode.c 2003-09-26 00:10:09.000000000 +0400 -@@ -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( -@@ -2163,10 +2173,7 @@ void ext3_read_inode(struct inode * inod - inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block]; - INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); - -- 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; -@@ -2174,15 +2181,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])); -+ } - brelse(iloc.bh); - ext3_set_inode_flags(inode); - return; ---- linux-2.4.22-ac1/fs/ext3/Makefile~xattr-0.8.54-2.4.22-rh 2003-09-25 14:55:12.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/Makefile 2003-09-25 23:57:02.000000000 +0400 -@@ -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,14 @@ - - 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) - -+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.22-ac1/fs/ext3/namei.c~xattr-0.8.54-2.4.22-rh 2003-09-25 14:58:37.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/namei.c 2003-09-25 23:57:02.000000000 +0400 -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1614,7 +1615,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; -@@ -1622,7 +1623,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? */ -@@ -1649,9 +1649,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) { -@@ -2020,7 +2017,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-2.4.22-ac1/fs/ext3/super.c~xattr-0.8.54-2.4.22-rh 2003-09-25 14:55:12.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/super.c 2003-09-26 00:12:23.000000000 +0400 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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); -@@ -506,6 +508,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; -@@ -518,6 +521,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")) { -@@ -935,6 +945,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; -@@ -1839,22 +1855,35 @@ static DECLARE_FSTYPE_DEV(ext3_fs_type, - - static int __init init_ext3_fs(void) - { -+ int error; - #ifdef CONFIG_QUOTA - init_dquot_operations(&ext3_qops); - old_sync_dquot = ext3_qops.sync_dquot; - ext3_qops.sync_dquot = ext3_sync_dquot; - #endif -- return register_filesystem(&ext3_fs_type); -+ 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-2.4.22-ac1/fs/ext3/symlink.c~xattr-0.8.54-2.4.22-rh 2001-11-10 01:25:04.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/ext3/symlink.c 2003-09-25 23:57:02.000000000 +0400 -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - 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 13:24:37.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/ext3/xattr.c 2003-09-25 23:57:02.000000000 +0400 -@@ -0,0 +1,1225 @@ -+/* -+ * linux/fs/ext3/xattr.c -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ * -+ * Fix by Harrison Xing . -+ * Ext3 code with a lot of help from Eric Jarman . -+ * Extended attributes for symlinks and special files added per -+ * suggestion of Luka Renko . -+ */ -+ -+/* -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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; iprefix); -+ 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; -+ (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_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 13:24:37.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/ext3/xattr_user.c 2003-09-25 23:57:02.000000000 +0400 -@@ -0,0 +1,111 @@ -+/* -+ * linux/fs/ext3/xattr_user.c -+ * Handler for extended user attributes. -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+# include -+#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.22-ac1/fs/jfs/jfs_xattr.h~xattr-0.8.54-2.4.22-rh 2002-11-29 02:53:15.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/jfs/jfs_xattr.h 2003-09-25 23:57:02.000000000 +0400 -@@ -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.22-ac1/fs/jfs/xattr.c~xattr-0.8.54-2.4.22-rh 2002-11-29 02:53:15.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/jfs/xattr.c 2003-09-25 23:57:02.000000000 +0400 -@@ -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 */ ---- linux-2.4.22-ac1/fs/Makefile~xattr-0.8.54-2.4.22-rh 2003-09-25 14:50:00.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/Makefile 2003-09-25 23:57:02.000000000 +0400 -@@ -82,6 +82,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)) - ---- /dev/null 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/mbcache.c 2003-09-25 23:57:02.000000000 +0400 -@@ -0,0 +1,648 @@ -+/* -+ * linux/fs/mbcache.c -+ * (C) 2001-2002 Andreas Gruenbacher, -+ */ -+ -+/* -+ * 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 -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#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 "); -+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; ne_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; nc_block_hash[n]); -+ for (m=0; mc_indexes_hash[m] = kmalloc(bucket_count * -+ sizeof(struct list_head), -+ GFP_KERNEL); -+ if (!cache->c_indexes_hash[m]) -+ goto fail; -+ for (n=0; nc_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; ne_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<=indexc_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<=indexe_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.22-ac1/include/asm-arm/unistd.h~xattr-0.8.54-2.4.22-rh 2003-08-25 15:44:43.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/asm-arm/unistd.h 2003-09-25 23:57:02.000000000 +0400 -@@ -250,7 +250,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) -@@ -263,7 +262,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) - #if 0 /* allocated in 2.5 */ - #define __NR_sendfile64 (__NR_SYSCALL_BASE+239) ---- linux-2.4.22-ac1/include/asm-ppc64/unistd.h~xattr-0.8.54-2.4.22-rh 2003-06-13 18:51:38.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/asm-ppc64/unistd.h 2003-09-25 23:57:02.000000000 +0400 -@@ -218,6 +218,7 @@ - #define __NR_mincore 206 - #define __NR_gettid 207 - #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 - #define __NR_sched_setaffinity 222 - #define __NR_sched_getaffinity 223 ---- linux-2.4.22-ac1/include/asm-s390/unistd.h~xattr-0.8.54-2.4.22-rh 2003-06-13 18:51:38.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/asm-s390/unistd.h 2003-09-26 00:14:23.000000000 +0400 -@@ -213,6 +213,19 @@ - #define __NR_getdents64 220 - #define __NR_fcntl64 221 - #define __NR_readahead 222 -+#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 -+ - /* - * Numbers 224-235 are reserved for posix acl - */ ---- linux-2.4.22-ac1/include/asm-s390x/unistd.h~xattr-0.8.54-2.4.22-rh 2003-06-13 18:51:38.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/asm-s390x/unistd.h 2003-09-26 00:15:11.000000000 +0400 -@@ -181,6 +181,19 @@ - #define __NR_mincore 218 - #define __NR_madvise 219 - #define __NR_readahead 222 -+#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 -+ - /* - * Numbers 224-235 are reserved for posix acl - */ ---- /dev/null 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/include/linux/cache_def.h 2003-09-25 23:57:02.000000000 +0400 -@@ -0,0 +1,15 @@ -+/* -+ * linux/cache_def.h -+ * Handling of caches defined in drivers, filesystems, ... -+ * -+ * Copyright (C) 2002 by Andreas Gruenbacher, -+ */ -+ -+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.22-ac1/include/linux/errno.h~xattr-0.8.54-2.4.22-rh 2001-02-10 01:46:13.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/include/linux/errno.h 2003-09-25 23:57:02.000000000 +0400 -@@ -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.22-ac1/include/linux/ext2_fs.h~xattr-0.8.54-2.4.22-rh 2003-06-13 18:51:38.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/ext2_fs.h 2003-09-25 23:57:02.000000000 +0400 -@@ -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| \ -@@ -624,8 +601,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 13:24:37.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/include/linux/ext2_xattr.h 2003-09-25 23:57:02.000000000 +0400 -@@ -0,0 +1,157 @@ -+/* -+ File: linux/ext2_xattr.h -+ -+ On-disk format of extended attributes for the ext2 filesystem. -+ -+ (C) 2001 Andreas Gruenbacher, -+*/ -+ -+#include -+#include -+#include -+ -+/* 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<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.22-ac1/include/linux/ext3_fs.h~xattr-0.8.54-2.4.22-rh 2003-09-25 14:58:30.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs.h 2003-09-25 23:57:02.000000000 +0400 -@@ -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 -@@ -346,6 +321,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 -@@ -523,7 +499,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| \ -@@ -707,6 +683,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 *); - -@@ -776,8 +753,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.22-ac1/include/linux/ext3_jbd.h~xattr-0.8.54-2.4.22-rh 2003-09-25 14:55:12.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/ext3_jbd.h 2003-09-25 23:57:02.000000000 +0400 -@@ -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 13:24:37.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/include/linux/ext3_xattr.h 2003-09-25 23:57:02.000000000 +0400 -@@ -0,0 +1,157 @@ -+/* -+ File: linux/ext3_xattr.h -+ -+ On-disk format of extended attributes for the ext3 filesystem. -+ -+ (C) 2001 Andreas Gruenbacher, -+*/ -+ -+#include -+#include -+#include -+ -+/* 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<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.22-ac1/include/linux/fs.h~xattr-0.8.54-2.4.22-rh 2003-09-25 14:45:32.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/fs.h 2003-09-25 23:57:02.000000000 +0400 -@@ -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 13:24:37.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/include/linux/mbcache.h 2003-09-25 23:57:02.000000000 +0400 -@@ -0,0 +1,69 @@ -+/* -+ File: linux/mbcache.h -+ -+ (C) 2001 by Andreas Gruenbacher, -+*/ -+ -+/* 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.22-ac1/kernel/ksyms.c~xattr-0.8.54-2.4.22-rh 2003-09-25 14:42:46.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/kernel/ksyms.c 2003-09-26 00:19:05.000000000 +0400 -@@ -11,6 +11,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -106,6 +107,7 @@ EXPORT_SYMBOL(exit_files); - EXPORT_SYMBOL(exit_fs); - EXPORT_SYMBOL(exit_sighand); - EXPORT_SYMBOL(unshare_files); -+EXPORT_SYMBOL(copy_fs_struct); - - /* internal kernel memory management */ - EXPORT_SYMBOL(_alloc_pages); -@@ -124,6 +126,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.22-ac1/mm/vmscan.c~xattr-0.8.54-2.4.22-rh 2003-09-25 14:16:28.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/mm/vmscan.c 2003-09-25 23:57:02.000000000 +0400 -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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/series/2.6-rhel4.series b/lustre/kernel_patches/series/2.6-rhel4.series index 7c0ae18..46487e1 100644 --- a/lustre/kernel_patches/series/2.6-rhel4.series +++ b/lustre/kernel_patches/series/2.6-rhel4.series @@ -13,3 +13,4 @@ lookup_bdev_init_intent.patch 8kstack-2.6-rhel4.patch remove-suid-2.6-suse.patch export-show_task-2.6-vanilla.patch +sd_iostats-2.6-rhel4.patch diff --git a/lustre/kernel_patches/series/2.6-suse-lnxi.series b/lustre/kernel_patches/series/2.6-suse-lnxi.series index aba1070..e60eebd 100644 --- a/lustre/kernel_patches/series/2.6-suse-lnxi.series +++ b/lustre/kernel_patches/series/2.6-suse-lnxi.series @@ -1,3 +1,4 @@ +dev_read_only-2.6-lnxi.patch sd_iostats-2.6-suse.patch blkdev_tunables-2.6-suse.patch bluesmoke-2.6-suse-lnxi.patch diff --git a/lustre/kernel_patches/series/2.6-vanilla.series b/lustre/kernel_patches/series/2.6-vanilla.series deleted file mode 100644 index 7fa0d34..0000000 --- a/lustre/kernel_patches/series/2.6-vanilla.series +++ /dev/null @@ -1,15 +0,0 @@ -uml-2.6.7-01-bb2.patch -lustre_version.patch -vfs_intent-2.6-vanilla.patch -vfs_nointent-2.6-vanilla.patch -vfs_races-2.6-vanilla.patch -ext3-wantedi-misc-2.6-suse.patch -nfs-cifs-intent-2.6-vanilla.patch -iopen-misc-2.6-suse.patch -export-truncate-2.6-suse.patch -export_symbols-2.6-suse.patch -dev_read_only-2.6-suse.patch -export-2.6-suse.patch -header-guards-2.6-suse.patch -lookup_bdev_init_intent.patch -ext3-super-ntohl.patch diff --git a/lustre/kernel_patches/series/hp-pnnl-2.4.20 b/lustre/kernel_patches/series/hp-pnnl-2.4.20 index 033119a..d846b4d 100644 --- a/lustre/kernel_patches/series/hp-pnnl-2.4.20 +++ b/lustre/kernel_patches/series/hp-pnnl-2.4.20 @@ -1,5 +1,5 @@ configurable-x86-stack-2.4.20.patch -dev_read_only_hp_2.4.20.patch +dev_read_only_2.4.20-rh.patch exports_2.4.20-rh-hp.patch lustre_version.patch vfs_intent-2.4.20-hp.patch @@ -45,6 +45,5 @@ inode-max-readahead-2.4.24.patch dcache_refcount_debug.patch ext3-extents-2.4.24.patch ext3-extents-asyncdel-2.4.24.patch -ext3-mballoc-2.4.24.patch ext3-nlinks-2.4.20-hp_pnnl.patch export-zap-page-range.patch diff --git a/lustre/kernel_patches/series/ldiskfs-2.6-vanilla.series b/lustre/kernel_patches/series/ldiskfs-2.6-vanilla.series deleted file mode 100644 index 13cf85a..0000000 --- a/lustre/kernel_patches/series/ldiskfs-2.6-vanilla.series +++ /dev/null @@ -1,11 +0,0 @@ -ext3-wantedi-2.6-suse.patch -ext3-san-jdike-2.6-suse.patch -iopen-2.6-vanilla.patch -export_symbols-ext3-2.6-suse.patch -ext3-map_inode_page-2.6-suse.patch -ext3-ea-in-inode-2.6-suse.patch -export-ext3-2.6-suse.patch -ext3-include-fixes-2.6-suse.patch -ext3-extents-2.6.7.patch -ext3-mballoc2-2.6.7.patch -ext3-nlinks-2.6.7.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 index 02481d0..0000000 --- a/lustre/kernel_patches/series/rh-2.4.20 +++ /dev/null @@ -1,53 +0,0 @@ -configurable-x86-stack-2.4.20-rh.patch -mcore-2.4.20-8.patch -dsp.patch -dev_read_only_2.4.20-rh.patch -exports_2.4.20-rh-hp.patch -lustre_version.patch -vfs_intent-2.4.20-rh.patch -invalidate_show-2.4.20-rh.patch -iod-rmap-exports-2.4.20.patch -export-truncate.patch -ext-2.4-patch-1-chaos.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-chaos.patch -ext3-2.4.20-fixes.patch -ext3_orphan_lock-2.4.20-rh.patch -ext3_delete_thread_2.4.20_chaos.patch -ext3-noread-2.4.20.patch -extN-wantedi.patch -ext3-san-2.4.20.patch -ext3-map_inode_page.patch -ext3-error-export.patch -iopen-2.4.20.patch -jbd-dont-account-blocks-twice.patch -jbd-commit-tricks.patch -ext3-o_direct-1.2.4.20-rh.patch -ext3-no-write-super-chaos.patch -dynamic-locks-2.4.20-rh.patch -vfs-pdirops-2.4.20-rh.patch -ext3-pdirops-2.4.20-rh.patch -tcp_zero_copy_2.4.20_chaos.patch -gpl_header-chaos-2.4.20.patch -add_page_private.patch -jbd-flushtime.patch -jbd-get_write_access.patch -nfs_export_kernel-2.4.20-rh.patch -ext3-ea-in-inode-2.4.20.patch -listman-2.4.20.patch -ext3-trusted_ea-2.4.20.patch -netconsole-2.4.20-rh.patch -ext3-xattr-ptr-arith-fix.patch -procfs-ndynamic-2.4.patch -ext3-truncate-buffer-head.patch -inode-max-readahead-2.4.24.patch -mkdep-revert-rh-2.4.patch -ext3-extents-2.4.20-rh.patch -ext3-extents-asyncdel-2.4.20-rh.patch -ext3-mballoc-2.4.24.patch -x86-fpu-crash.patch -export-show_task-2.4-rh.patch -export-zap-page-range.patch -grab_cache_page_nowait_gfp-rh-2.4.patch diff --git a/lustre/kernel_patches/series/rh-2.4.22 b/lustre/kernel_patches/series/rh-2.4.22 deleted file mode 100644 index 2e2fa8b..0000000 --- a/lustre/kernel_patches/series/rh-2.4.22 +++ /dev/null @@ -1,30 +0,0 @@ -configurable-x86-stack-2.4.22-rh.patch -dev_read_only_2.4.20-rh.patch -exports_2.4.20-rh-hp.patch -lustre_version.patch -vfs_intent-2.4.22-rh.patch -invalidate_show-2.4.20-rh.patch -export-truncate.patch -iod-stock-exports-2.4.22-rh.patch -ext3-htree-2.4.22-rh.patch -xattr-0.8.54-2.4.22-rh.patch -ext3-orphan_lock-2.4.22-rh.patch -ext3-noread-2.4.20.patch -ext3_delete_thread_2.4.20_chaos.patch -extN-wantedi-2.4.22-rh.patch -ext3-san-2.4.20.patch -ext3-map_inode_page.patch -ext3-error-export.patch -iopen-2.4.20.patch -tcp-zero-copy-2.4.22-rh.patch -jbd-dont-account-blocks-twice.patch -jbd-commit-tricks.patch -add_page_private.patch -socket-exports-2.4.22-rh.patch -nfs_export_kernel-2.4.22-rh.patch -ext3-ea-in-inode-2.4.22-rh.patch -listman-2.4.20.patch -ext3-trusted_ea-2.4.20.patch -ext3-xattr-ptr-arith-fix.patch -procfs-ndynamic-2.4.patch -ext3-truncate-buffer-head.patch diff --git a/lustre/kernel_patches/series/suse-2.4.19 b/lustre/kernel_patches/series/suse-2.4.19 deleted file mode 100644 index 8748256..0000000 --- a/lustre/kernel_patches/series/suse-2.4.19 +++ /dev/null @@ -1,35 +0,0 @@ -dev_read_only_hp_2.4.20.patch -exports_2.4.19-suse.patch -lustre_version.patch -vfs_intent-2.4.19-suse.patch -invalidate_show.patch -export-truncate.patch -iod-stock-24-exports-2.4.19-suse.patch -jbd-2.4.18-jcberr.patch -ext-2.4-patch-1-chaos.patch -ext-2.4-patch-2.patch -ext-2.4-patch-3.patch -ext-2.4-patch-4.patch -linux-2.4.19-xattr-0.8.54-suse.patch -ext3-2.4-ino_t.patch -ext3-largefile.patch -ext3-truncate_blocks.patch -ext3-use-after-free-suse.patch -ext3-orphan_lock-2.4.19-suse.patch -ext3-delete_thread-2.4.19-suse.patch -ext3-noread-2.4.20.patch -extN-wantedi-2.4.19-suse.patch -ext3-san-2.4.20.patch -ext3-map_inode_page.patch -ext3-error-export.patch -iopen-2.4.19-suse.patch -tcp-zero-copy.patch -add_page_private.patch -removepage-2.4.19-suse.patch -jbd-ctx_switch.patch -jbd-flushtime-2.4.19-suse.patch -jbd-get_write_access.patch -ext3-ea-in-inode-2.4.20.patch -listman-2.4.20.patch -ext3-trusted_ea-2.4.20.patch -ext3-truncate-buffer-head.patch diff --git a/lustre/kernel_patches/series/suse-2.4.21 b/lustre/kernel_patches/series/suse-2.4.21 deleted file mode 100644 index 8cf74b3..0000000 --- a/lustre/kernel_patches/series/suse-2.4.21 +++ /dev/null @@ -1,32 +0,0 @@ -configurable-x86-stack-2.4.20.patch -dev_read_only_2.4.20-rh.patch -exports_2.4.20-rh-hp.patch -lustre_version.patch -vfs_intent-2.4.20-vanilla.patch -invalidate_show.patch -export-truncate.patch -iod-stock-24-exports.patch -ext3-htree-suse.patch -linux-2.4.21-xattr-0.8.54-suse.patch -ext3-orphan_lock-suse.patch -ext3-noread-2.4.20.patch -ext3-delete_thread-suse.patch -extN-wantedi.patch -ext3-san-2.4.20.patch -ext3-map_inode_page.patch -ext3-error-export.patch -iopen-2.4.20.patch -tcp-zero-copy-2.4.22-rh.patch -jbd-dont-account-blocks-twice.patch -jbd-commit-tricks.patch -ext3-no-write-super-chaos.patch -add_page_private.patch -socket-exports-vanilla.patch -nfs_export_kernel-2.4.20.patch -ext3-raw-lookup.patch -ext3-ea-in-inode-2.4.20.patch -listman-2.4.20.patch -ext3-trusted_ea-2.4.20.patch -ext3-xattr-ptr-arith-fix.patch -procfs-ndynamic-2.4.patch -ext3-truncate-buffer-head.patch diff --git a/lustre/kernel_patches/series/suse-2.4.21-2 b/lustre/kernel_patches/series/suse-2.4.21-cray similarity index 96% rename from lustre/kernel_patches/series/suse-2.4.21-2 rename to lustre/kernel_patches/series/suse-2.4.21-cray index 52337b9..27928ea 100644 --- a/lustre/kernel_patches/series/suse-2.4.21-2 +++ b/lustre/kernel_patches/series/suse-2.4.21-cray @@ -24,7 +24,7 @@ ext3-no-write-super-chaos.patch add_page_private.patch nfs_export_kernel-2.4.21-suse2.patch ext3-raw-lookup.patch -ext3-ea-in-inode-2.4.21-chaos.patch +ext3-ea-in-inode-2.4.21-suse2.patch listman-2.4.20.patch ext3-xattr-ptr-arith-fix.patch procfs-ndynamic-2.4.21-suse2.patch diff --git a/lustre/kernel_patches/series/vanilla-2.4.24 b/lustre/kernel_patches/series/vanilla-2.4.24 index a2d6649..3dd0d43 100644 --- a/lustre/kernel_patches/series/vanilla-2.4.24 +++ b/lustre/kernel_patches/series/vanilla-2.4.24 @@ -37,7 +37,6 @@ ext3-truncate-buffer-head.patch inode-max-readahead-2.4.24.patch ext3-extents-2.4.24.patch ext3-extents-asyncdel-2.4.24.patch -ext3-mballoc-2.4.24.patch export_num_siblings.patch ext3-nlinks-2.4.24.patch export-show_task-2.4-vanilla.patch diff --git a/lustre/kernel_patches/targets/2.6-rhel4.target.in b/lustre/kernel_patches/targets/2.6-rhel4.target.in new file mode 100644 index 0000000..a44bc0f --- /dev/null +++ b/lustre/kernel_patches/targets/2.6-rhel4.target.in @@ -0,0 +1,24 @@ +lnxmaj="2.6.9" +lnxrel="5.0.3.EL" + +KERNEL=linux-${lnxmaj}-${lnxrel}.tar.bz2 +SERIES=2.6-rhel4.series +VERSION=${lnxmaj} +EXTRA_VERSION=${lnxrel}_lustre.@VERSION@ +RHBUILD=1 +LINUX26=1 + +BASE_ARCHS="i686 x86_64 ia64" +BIGMEM_ARCHS="" +BOOT_ARCHS="" +JENSEN_ARCHS="" +SMP_ARCHS="i686 x86_64 ia64" +UP_ARCHS="" + +# the modules in this kernel do not build with gcc 3.3 or 2.96 +for cc in gcc32 gcc33 ; do + if which $cc >/dev/null 2>/dev/null ; then + export CC=$cc + break + fi +done diff --git a/lustre/kernel_patches/which_patch b/lustre/kernel_patches/which_patch index 8e4ba6f..4d8423e 100644 --- a/lustre/kernel_patches/which_patch +++ b/lustre/kernel_patches/which_patch @@ -1,10 +1,11 @@ -SERIES MNEMONIC COMMENT ARCH +SERIES MNEMONIC COMMENT ARCH SUPPORTED KERNELS: -rhel-2.4.21 linux-2.4.21-20.3EL all -2.6-suse linux-2.6 SLES9 SP1 kernel all +rhel-2.4.21 linux-2.4.21-20.3EL RHEL3 2.4.21 all +2.6-suse linux-2.6-suse SLES9 SP1 kernel all +2.6-rhel4 linux-2.6-rhel4 RHEL4 2.6.9 kernel i386,x86_64 UNSUPPORTED KERNELS; BEING PHASED OUT; MAY BE MISSING CRITICAL BUG FIXES: -hp-pnnl-2.4.20 linux-2.4.20-hp4_pnnl1 same as vanilla but no uml ia64 -vanilla-2.4.24 linux-2.4.24 patch with uml-2.4.24-6 um -suse-2.4.21-jvn linux-2.4.21-241 sles8 2.4 kernel i386 +hp-pnnl-2.4.20 linux-2.4.20-hp4_pnnl1 same as vanilla but no uml ia64 +vanilla-2.4.24 linux-2.4.24 patch with uml-2.4.24-6 um +suse-2.4.21-jvn linux-2.4.21-241 sles8 2.4 kernel i386 diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index 2fb9c66..85830fc 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -211,7 +211,7 @@ err: } -int client_obd_cleanup(struct obd_device *obddev, int flags) +int client_obd_cleanup(struct obd_device *obddev) { struct client_obd *cli = &obddev->u.cli; @@ -227,7 +227,7 @@ int client_obd_cleanup(struct obd_device *obddev, int flags) class_destroy_import(cli->cl_import); cli->cl_import = NULL; - ldlm_put_ref(flags & OBD_OPT_FORCE); + ldlm_put_ref(obddev->obd_force); RETURN(0); } @@ -280,7 +280,7 @@ out_ldlm: obd->obd_namespace = NULL; out_disco: cli->cl_conn_count--; - class_disconnect(exp, 0); + class_disconnect(exp); } else { class_export_put(exp); } @@ -289,7 +289,7 @@ out_sem: return rc; } -int client_disconnect_export(struct obd_export *exp, int failover) +int client_disconnect_export(struct obd_export *exp) { struct obd_device *obd = class_exp2obd(exp); struct client_obd *cli = &obd->u.cli; @@ -335,7 +335,7 @@ int client_disconnect_export(struct obd_export *exp, int failover) EXIT; out_no_disconnect: - err = class_disconnect(exp, 0); + err = class_disconnect(exp); if (!rc && err) rc = err; out_sem: @@ -589,7 +589,7 @@ int target_handle_disconnect(struct ptlrpc_request *req) /* keep the rq_export around so we can send the reply */ exp = class_export_get(req->rq_export); - req->rq_status = obd_disconnect(exp, 0); + req->rq_status = obd_disconnect(exp); RETURN(0); } @@ -692,6 +692,8 @@ void target_cleanup_recovery(struct obd_device *obd) struct list_head *tmp, *n; struct ptlrpc_request *req; + LASSERT(obd->obd_stopping); + spin_lock_bh(&obd->obd_processing_task_lock); if (!obd->obd_recovering) { spin_unlock_bh(&obd->obd_processing_task_lock); @@ -702,7 +704,6 @@ void target_cleanup_recovery(struct obd_device *obd) target_cancel_recovery_timer(obd); spin_unlock_bh(&obd->obd_processing_task_lock); - list_for_each_safe(tmp, n, &obd->obd_delayed_reply_queue) { req = list_entry(tmp, struct ptlrpc_request, rq_list); list_del(&req->rq_list); @@ -732,7 +733,7 @@ void target_abort_recovery(void *data) CERROR("%s: recovery period over; disconnecting unfinished clients.\n", obd->obd_name); - class_disconnect_stale_exports(obd, 0); + class_disconnect_stale_exports(obd); abort_recovery_queue(obd); target_finish_recovery(obd); @@ -1028,13 +1029,23 @@ int target_queue_final_reply(struct ptlrpc_request *req, int rc) LBUG(); memcpy(saved_req, req, sizeof *saved_req); memcpy(reqmsg, req->rq_reqmsg, req->rq_reqlen); + + /* Don't race cleanup */ + spin_lock_bh(&obd->obd_processing_task_lock); + if (obd->obd_stopping) { + spin_unlock_bh(&obd->obd_processing_task_lock); + OBD_FREE(reqmsg, req->rq_reqlen); + OBD_FREE(saved_req, sizeof *req); + req->rq_status = -ENOTCONN; + /* rv is ignored anyhow */ + return -ENOTCONN; + } ptlrpc_rs_addref(req->rq_reply_state); /* +1 ref for saved reply */ req = saved_req; req->rq_reqmsg = reqmsg; class_export_get(req->rq_export); list_add(&req->rq_list, &obd->obd_delayed_reply_queue); - spin_lock_bh(&obd->obd_processing_task_lock); /* only count the first "replay over" request from each export */ if (req->rq_export->exp_replay_needed) { @@ -1044,6 +1055,7 @@ int target_queue_final_reply(struct ptlrpc_request *req, int rc) recovery_done = (obd->obd_recoverable_clients == 0); spin_unlock_bh(&obd->obd_processing_task_lock); + OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS); if (recovery_done) { spin_lock_bh(&obd->obd_processing_task_lock); obd->obd_recovering = obd->obd_abort_recovery = 0; diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c index ec30586..e46c0fe 100644 --- a/lustre/ldlm/ldlm_lockd.c +++ b/lustre/ldlm/ldlm_lockd.c @@ -178,7 +178,7 @@ static void waiting_locks_callback(unsigned long unused) lock = list_entry(waiting_locks_list.next, struct ldlm_lock, l_pending_chain); - if (lock->l_callback_timeout > jiffies) + if (time_after(lock->l_callback_timeout, jiffies)) break; LDLM_ERROR(lock, "lock callback timer expired: evicting client " @@ -245,7 +245,7 @@ static int ldlm_add_waiting_lock(struct ldlm_lock *lock) timeout_rounded = round_timeout(lock->l_callback_timeout); - if (timeout_rounded < waiting_locks_timer.expires || + if (time_before(timeout_rounded, waiting_locks_timer.expires) || !timer_pending(&waiting_locks_timer)) { mod_timer(&waiting_locks_timer, timeout_rounded); } @@ -622,6 +622,21 @@ int ldlm_handle_enqueue(struct ptlrpc_request *req, } } + if (dlm_req->lock_desc.l_resource.lr_type < LDLM_MIN_TYPE || + dlm_req->lock_desc.l_resource.lr_type >= LDLM_MAX_TYPE) { + DEBUG_REQ(D_ERROR, req, "invalid lock request type %d\n", + dlm_req->lock_desc.l_resource.lr_type); + GOTO(out, rc = -EFAULT); + } + + if (dlm_req->lock_desc.l_req_mode < LCK_EX || + dlm_req->lock_desc.l_req_mode > LCK_NL || + dlm_req->lock_desc.l_req_mode & (dlm_req->lock_desc.l_req_mode-1)) { + DEBUG_REQ(D_ERROR, req, "invalid lock request mode %d\n", + dlm_req->lock_desc.l_req_mode); + GOTO(out, rc = -EFAULT); + } + /* The lock's callback data might be set in the policy function */ lock = ldlm_lock_create(obddev->obd_namespace, &dlm_req->lock_handle2, dlm_req->lock_desc.l_resource.lr_name, diff --git a/lustre/ldlm/ldlm_resource.c b/lustre/ldlm/ldlm_resource.c index 71f090b..b362344 100644 --- a/lustre/ldlm/ldlm_resource.c +++ b/lustre/ldlm/ldlm_resource.c @@ -179,15 +179,16 @@ void ldlm_proc_namespace(struct ldlm_namespace *ns) lock_name[MAX_STRING_SIZE] = '\0'; memset(lock_vars, 0, sizeof(lock_vars)); - lock_vars[0].read_fptr = lprocfs_rd_u64; lock_vars[0].name = lock_name; snprintf(lock_name, MAX_STRING_SIZE, "%s/resource_count", ns->ns_name); - lock_vars[0].data = &ns->ns_resources; + lock_vars[0].data = &ns->ns_refcount; + lock_vars[0].read_fptr = lprocfs_rd_atomic; lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0); snprintf(lock_name, MAX_STRING_SIZE, "%s/lock_count", ns->ns_name); lock_vars[0].data = &ns->ns_locks; + lock_vars[0].read_fptr = lprocfs_rd_u64; lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0); if (ns->ns_client) { @@ -237,11 +238,11 @@ struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 client) INIT_LIST_HEAD(&ns->ns_root_list); l_lock_init(&ns->ns_lock); - ns->ns_refcount = 0; + init_waitqueue_head(&ns->ns_refcount_waitq); + atomic_set(&ns->ns_refcount, 0); ns->ns_client = client; spin_lock_init(&ns->ns_counter_lock); ns->ns_locks = 0; - ns->ns_resources = 0; for (bucket = ns->ns_hash + RES_HASH_SIZE - 1; bucket >= ns->ns_hash; bucket--) @@ -353,19 +354,11 @@ int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int flags) cleanup_resource(res, &res->lr_converting, flags); cleanup_resource(res, &res->lr_waiting, flags); - /* XXX what a mess: don't force cleanup if we're - * local_only (which is only used by recovery). In that - * case, we probably still have outstanding lock refs - * which reference these resources. -phil */ - if (!ldlm_resource_putref(res) && - !(flags & LDLM_FL_LOCAL_ONLY)) { + if (!ldlm_resource_putref(res)) { CERROR("Namespace %s resource refcount %d " - "after lock cleanup; forcing cleanup.\n", + "after lock cleanup\n", ns->ns_name, atomic_read(&res->lr_refcount)); - ldlm_resource_dump(D_ERROR, res); - atomic_set(&res->lr_refcount, 1); - ldlm_resource_putref(res); } } } @@ -400,6 +393,25 @@ int ldlm_namespace_free(struct ldlm_namespace *ns, int force) } #endif + if (atomic_read(&ns->ns_refcount) > 0) { + struct l_wait_info lwi = LWI_INTR(NULL, NULL); + int rc; + CDEBUG(D_DLMTRACE, + "dlm namespace %s free waiting on refcount %d\n", + ns->ns_name, atomic_read(&ns->ns_refcount)); + rc = l_wait_event(ns->ns_refcount_waitq, + atomic_read(&ns->ns_refcount) == 0, &lwi); + if (atomic_read(&ns->ns_refcount)) { + CERROR("Lock manager: waiting for the %s namespace " + "was aborted with %d resources in use. (%d)\n" + "I'm going to try to clean up anyway, but I " + "might require a reboot of this node.\n", + ns->ns_name, atomic_read(&ns->ns_refcount), rc); + } + CDEBUG(D_DLMTRACE, + "dlm namespace %s free done waiting\n", ns->ns_name); + } + POISON(ns->ns_hash, 0x5a, sizeof(*ns->ns_hash) * RES_HASH_SIZE); OBD_VFREE(ns->ns_hash, sizeof(*ns->ns_hash) * RES_HASH_SIZE); OBD_FREE(ns->ns_name, strlen(ns->ns_name) + 1); @@ -448,27 +460,23 @@ static struct ldlm_resource *ldlm_resource_new(void) * Returns: newly-allocated, referenced, unlocked resource */ static struct ldlm_resource * ldlm_resource_add(struct ldlm_namespace *ns, struct ldlm_resource *parent, - struct ldlm_res_id name, __u32 type) + struct ldlm_res_id name, ldlm_type_t type) { struct list_head *bucket; struct ldlm_resource *res; ENTRY; - LASSERTF(type >= LDLM_MIN_TYPE && type <= LDLM_MAX_TYPE, - "type: %d", type); + LASSERTF(type >= LDLM_MIN_TYPE && type < LDLM_MAX_TYPE, + "type: %d\n", type); res = ldlm_resource_new(); if (!res) RETURN(NULL); - spin_lock(&ns->ns_counter_lock); - ns->ns_resources++; - spin_unlock(&ns->ns_counter_lock); - l_lock(&ns->ns_lock); memcpy(&res->lr_name, &name, sizeof(res->lr_name)); res->lr_namespace = ns; - ns->ns_refcount++; + atomic_inc(&ns->ns_refcount); res->lr_type = type; res->lr_most_restr = LCK_NL; @@ -493,7 +501,7 @@ ldlm_resource_add(struct ldlm_namespace *ns, struct ldlm_resource *parent, * Returns: referenced, unlocked ldlm_resource or NULL */ struct ldlm_resource * ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent, - struct ldlm_res_id name, __u32 type, int create) + struct ldlm_res_id name, ldlm_type_t type, int create) { struct list_head *bucket, *tmp; struct ldlm_resource *res = NULL; @@ -552,7 +560,7 @@ struct ldlm_resource *ldlm_resource_getref(struct ldlm_resource *res) LASSERT(res != NULL); LASSERT(res != LP_POISON); atomic_inc(&res->lr_refcount); - CDEBUG(D_INFO, "getref res: %p count: %d\n", res, + CDEBUG(D_DLMTRACE, "getref res: %p count: %d\n", res, atomic_read(&res->lr_refcount)); return res; } @@ -563,7 +571,7 @@ int ldlm_resource_putref(struct ldlm_resource *res) int rc = 0; ENTRY; - CDEBUG(D_INFO, "putref res: %p count: %d\n", res, + CDEBUG(D_DLMTRACE, "putref res: %p count: %d\n", res, atomic_read(&res->lr_refcount) - 1); LASSERT(atomic_read(&res->lr_refcount) > 0); LASSERT(atomic_read(&res->lr_refcount) < LI_POISON); @@ -600,7 +608,6 @@ int ldlm_resource_putref(struct ldlm_resource *res) LBUG(); } - ns->ns_refcount--; list_del_init(&res->lr_hash); list_del_init(&res->lr_childof); if (res->lr_lvb_data) @@ -609,9 +616,10 @@ int ldlm_resource_putref(struct ldlm_resource *res) OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof *res); - spin_lock(&ns->ns_counter_lock); - ns->ns_resources--; - spin_unlock(&ns->ns_counter_lock); + if (atomic_dec_and_test(&ns->ns_refcount)) { + CDEBUG(D_DLMTRACE, "last ref on ns %s\n", ns->ns_name); + wake_up(&ns->ns_refcount_waitq); + } rc = 1; EXIT; @@ -674,7 +682,7 @@ void ldlm_namespace_dump(int level, struct ldlm_namespace *ns) struct list_head *tmp; CDEBUG(level, "--- Namespace: %s (rc: %d, client: %d)\n", ns->ns_name, - ns->ns_refcount, ns->ns_client); + atomic_read(&ns->ns_refcount), ns->ns_client); l_lock(&ns->ns_lock); if (time_after(jiffies, ns->ns_next_dump)) { diff --git a/lustre/liblustre/llite_lib.c b/lustre/liblustre/llite_lib.c index b0c6bda..da29c9f 100644 --- a/lustre/liblustre/llite_lib.c +++ b/lustre/liblustre/llite_lib.c @@ -43,7 +43,7 @@ #undef LIST_HEAD #include /* needed for ptpctl.h */ -#include /* needed for parse_dump */ +#include /* needed for parse_dump */ #include #include "llite_lib.h" @@ -183,14 +183,14 @@ int lib_ioctl_nalcmd(int dev_id, int opc, void * ptr) } } - return (0); + return (0); } int lib_ioctl(int dev_id, int opc, void * ptr) { int rc; - if (dev_id == OBD_DEV_ID) { + if (dev_id == OBD_DEV_ID) { struct obd_ioctl_data *ioc = ptr; //XXX hack!!! @@ -204,8 +204,8 @@ int lib_ioctl(int dev_id, int opc, void * ptr) if (rc) return rc; - } - return (0); + } + return (0); } int lllib_init(char *dumpfile) @@ -323,7 +323,7 @@ int liblustre_process_log(struct config_llog_instance *cfg, int allow_recov) CERROR("class_config_parse_llog failed: rc = %d\n", rc); } - err = obd_disconnect(exp, 0); + err = obd_disconnect(exp); out_cleanup: LCFG_INIT(lcfg, LCFG_CLEANUP, name); @@ -410,7 +410,7 @@ void __liblustre_setup_(void) char *root_path = "/"; unsigned mntflgs = 0; - int err; + int err; /* consider tha case of starting multiple liblustre instances * at a same time on single node. @@ -419,10 +419,10 @@ void __liblustre_setup_(void) signal(SIGUSR1, sighandler_USR1); - lustre_path = getenv(ENV_LUSTRE_MNTPNT); - if (!lustre_path) { + lustre_path = getenv(ENV_LUSTRE_MNTPNT); + if (!lustre_path) { lustre_path = "/mnt/lustre"; - } + } target = getenv(ENV_LUSTRE_MNTTGT); if (!target) { @@ -454,38 +454,38 @@ void __liblustre_setup_(void) obd_timeout); } - if (_sysio_init() != 0) { - perror("init sysio"); - exit(1); - } + if (_sysio_init() != 0) { + perror("init sysio"); + exit(1); + } /* cygwin don't need native driver */ #ifndef __CYGWIN__ _sysio_native_init(); #endif - err = _sysio_mount_root(root_path, root_driver, mntflgs, NULL); - if (err) { - perror(root_driver); - exit(1); - } + err = _sysio_mount_root(root_path, root_driver, mntflgs, NULL); + if (err) { + perror(root_driver); + exit(1); + } #if 1 - portal_debug = 0; - portal_subsystem_debug = 0; + portal_debug = 0; + portal_subsystem_debug = 0; #endif - err = lllib_init(dumpfile); - if (err) { - perror("init llite driver"); - exit(1); - } + err = lllib_init(dumpfile); + if (err) { + perror("init llite driver"); + exit(1); + } err = mount("/", lustre_path, lustre_driver, mntflgs, NULL); - if (err) { - errno = -err; - perror(lustre_driver); - exit(1); - } + if (err) { + errno = -err; + perror(lustre_driver); + exit(1); + } #if 0 __sysio_hook_sys_enter = llu_check_request; @@ -495,6 +495,6 @@ void __liblustre_setup_(void) void __liblustre_cleanup_(void) { - _sysio_shutdown(); + _sysio_shutdown(); PtlFini(); } diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c index 1186004..44735fd 100644 --- a/lustre/liblustre/super.c +++ b/lustre/liblustre/super.c @@ -55,7 +55,7 @@ static void llu_fsop_gone(struct filesys *fs) ENTRY; list_del(&sbi->ll_conn_chain); - obd_disconnect(sbi->ll_osc_exp, 0); + obd_disconnect(sbi->ll_osc_exp); /* NULL request to force sync on the MDS, and get the last_committed * value to flush remaining RPCs from the sending queue on client. @@ -66,7 +66,7 @@ static void llu_fsop_gone(struct filesys *fs) if (!obd->obd_no_recov) mdc_getstatus(sbi->ll_mdc_exp, &rootfid); - obd_disconnect(sbi->ll_mdc_exp, 0); + obd_disconnect(sbi->ll_mdc_exp); OBD_FREE(sbi, sizeof(*sbi)); @@ -1433,9 +1433,9 @@ out_inode: out_request: ptlrpc_req_finished(request); out_osc: - obd_disconnect(sbi->ll_osc_exp, 0); + obd_disconnect(sbi->ll_osc_exp); out_mdc: - obd_disconnect(sbi->ll_mdc_exp, 0); + obd_disconnect(sbi->ll_mdc_exp); out_free: OBD_FREE(sbi, sizeof(*sbi)); return err; diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index f29f732..39a53bd 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -322,14 +322,18 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags, rc = 1; /* unfortunately ll_intent_lock may cause a callback and revoke our - dentry */ + * dentry */ spin_lock(&dcache_lock); hlist_del_init(&de->d_hash); __d_rehash(de, 0); spin_unlock(&dcache_lock); out: - if (req != NULL && rc == 1) + /* If we had succesful it lookup on mds, but it happened to be negative, + we do not free request as it will be reused during lookup (see + comment in mdc/mdc_locks.c::mdc_intent_lock(). But if + request was not completed, we need to free it. (bug 5154) */ + if (req != NULL && (rc == 1 || !it_disposition(it, DISP_ENQ_COMPLETE))) ptlrpc_req_finished(req); if (rc == 0) { ll_unhash_aliases(de->d_inode); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 7640446..9e566f9 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -7,6 +7,83 @@ #include +/* +struct lustre_intent_data { + __u64 it_lock_handle[2]; + __u32 it_disposition; + __u32 it_status; + __u32 it_lock_mode; + }; */ + +#define LL_IT2STR(it) ((it) ? ldlm_it2str((it)->it_op) : "0") + +static inline struct lookup_intent *ll_nd2it(struct nameidata *nd) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + return &nd->intent; +#else + return nd->intent; +#endif +} + +struct ll_dentry_data { + int lld_cwd_count; + int lld_mnt_count; + struct obd_client_handle lld_cwd_och; + struct obd_client_handle lld_mnt_och; +}; + +#define ll_d2d(de) ((struct ll_dentry_data*) de->d_fsdata) + +extern struct file_operations ll_pgcache_seq_fops; + +#define LLI_INODE_MAGIC 0x111d0de5 +#define LLI_INODE_DEAD 0xdeadd00d +#define LLI_F_HAVE_OST_SIZE_LOCK 0 +#define LLI_F_HAVE_MDS_SIZE_LOCK 1 +struct ll_inode_info { + int lli_inode_magic; + int lli_size_pid; + struct semaphore lli_size_sem; + struct semaphore lli_open_sem; + struct lov_stripe_md *lli_smd; + char *lli_symlink_name; + __u64 lli_maxbytes; + __u64 lli_io_epoch; + unsigned long lli_flags; + + /* this lock protects s_d_w and p_w_ll and mmap_cnt */ + spinlock_t lli_lock; + struct list_head lli_pending_write_llaps; + int lli_send_done_writing; + atomic_t lli_mmap_cnt; + + struct list_head lli_close_item; + + /* for writepage() only to communicate to fsync */ + int lli_async_rc; + + struct file_operations *ll_save_ifop; + struct file_operations *ll_save_ffop; + struct file_operations *ll_save_wfop; + struct file_operations *ll_save_wrfop; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + struct inode lli_vfs_inode; +#endif +}; + +// FIXME: replace the name of this with LL_I to conform to kernel stuff +// static inline struct ll_inode_info *LL_I(struct inode *inode) +static inline struct ll_inode_info *ll_i2info(struct inode *inode) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + return container_of(inode, struct ll_inode_info, lli_vfs_inode); +#else + return (struct ll_inode_info *)&(inode->u.generic_ip); +#endif +} + + /* default to about 40meg of readahead on a given system. That much tied * up in 512k readahead requests serviced at 40ms each is about 1GB/s. */ #define SBI_DEFAULT_READAHEAD_MAX (40UL << (20 - PAGE_CACHE_SHIFT)) diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index b7a58c4..fbc9200 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -240,9 +240,9 @@ out_root: if (root) iput(root); out_osc: - obd_disconnect(sbi->ll_osc_exp, 0); + obd_disconnect(sbi->ll_osc_exp); out_mdc: - obd_disconnect(sbi->ll_mdc_exp, 0); + obd_disconnect(sbi->ll_mdc_exp); out: lprocfs_unregister_mountpoint(sbi); RETURN(err); @@ -275,11 +275,11 @@ void lustre_dump_dentry(struct dentry *dentry, int recur) subdirs++; CERROR("dentry %p dump: name=%.*s parent=%.*s (%p), inode=%p, count=%u," - " flags=0x%x, vfs_flags=0x%lx, fsdata=%p, %d subdirs\n", dentry, + " flags=0x%x, vfs_flags=0x%x, fsdata=%p, %d subdirs\n", dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_parent->d_name.len, dentry->d_parent->d_name.name, dentry->d_parent, dentry->d_inode, atomic_read(&dentry->d_count), - dentry->d_flags, dentry->d_vfs_flags, dentry->d_fsdata, subdirs); + dentry->d_flags, dentry->d_flags, dentry->d_fsdata, subdirs); if (dentry->d_inode != NULL) lustre_dump_inode(dentry->d_inode); @@ -301,7 +301,7 @@ void lustre_common_put_super(struct super_block *sb) ll_close_thread_shutdown(sbi->ll_lcq); list_del(&sbi->ll_conn_chain); - obd_disconnect(sbi->ll_osc_exp, 0); + obd_disconnect(sbi->ll_osc_exp); lprocfs_unregister_mountpoint(sbi); if (sbi->ll_proc_root) { @@ -309,7 +309,7 @@ void lustre_common_put_super(struct super_block *sb) sbi->ll_proc_root = NULL; } - obd_disconnect(sbi->ll_mdc_exp, 0); + obd_disconnect(sbi->ll_mdc_exp); // We do this to get rid of orphaned dentries. That is not really trw. hlist_for_each_safe(tmp, next, &sbi->ll_orphan_dentry_list) { @@ -398,6 +398,7 @@ void ll_lli_init(struct ll_inode_info *lli) { sema_init(&lli->lli_open_sem, 1); sema_init(&lli->lli_size_sem, 1); + lli->lli_size_pid = 0; lli->lli_flags = 0; lli->lli_maxbytes = PAGE_CACHE_MAXBYTES; spin_lock_init(&lli->lli_lock); @@ -546,11 +547,22 @@ int lustre_process_log(struct lustre_mount_data *lmd, char * profile, */ rc = class_config_dump_llog(ctxt, profile, cfg); #endif - if (rc) { + switch (rc) { + case 0: + break; + case -EINVAL: + LCONSOLE_ERROR("%s: The configuration '%s' could not be read " + "from the MDS. Make sure this client and the " + "MDS are running compatible versions of " + "Lustre.\n", + obd->obd_name, profile); + /* fall through */ + default: CERROR("class_config_parse_llog failed: rc = %d\n", rc); + break; } - err = obd_disconnect(exp, 0); + err = obd_disconnect(exp); out_cleanup: LCFG_INIT(lcfg, LCFG_CLEANUP, name); @@ -1036,10 +1048,12 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) RETURN(rc); down(&lli->lli_size_sem); + lli->lli_size_pid = current->pid; rc = vmtruncate(inode, attr->ia_size); // if vmtruncate returned 0, then ll_truncate dropped _size_sem if (rc != 0) { LASSERT(atomic_read(&lli->lli_size_sem.count) <= 0); + lli->lli_size_pid = 0; up(&lli->lli_size_sem); } diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 8bbd1d8..d88a5d5 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -118,12 +118,19 @@ void ll_truncate(struct inode *inode) CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) to %llu\n", inode->i_ino, inode->i_generation, inode, inode->i_size); + if (lli->lli_size_pid != current->pid) { + EXIT; + return; + } + if (!lsm) { CDEBUG(D_INODE, "truncate on inode %lu with no objects\n", inode->i_ino); GOTO(out_unlock, 0); } + LASSERT(atomic_read(&lli->lli_size_sem.count) <= 0); + if (lov_merge_size(lsm, 0) == inode->i_size) { CDEBUG(D_VFSTRACE, "skipping punch for "LPX64" (size = %llu)\n", lsm->lsm_object_id, inode->i_size); @@ -140,7 +147,7 @@ void ll_truncate(struct inode *inode) obd_adjust_kms(ll_i2obdexp(inode), lsm, inode->i_size, 1); - LASSERT(atomic_read(&lli->lli_size_sem.count) <= 0); + lli->lli_size_pid = 0; up(&lli->lli_size_sem); rc = obd_punch(ll_i2obdexp(inode), &oa, lsm, inode->i_size, @@ -156,7 +163,7 @@ void ll_truncate(struct inode *inode) return; out_unlock: - LASSERT(atomic_read(&lli->lli_size_sem.count) <= 0); + lli->lli_size_pid = 0; up(&lli->lli_size_sem); } /* ll_truncate */ diff --git a/lustre/lov/lov_log.c b/lustre/lov/lov_log.c index 7809366..056d60d 100644 --- a/lustre/lov/lov_log.c +++ b/lustre/lov/lov_log.c @@ -159,7 +159,6 @@ static struct llog_operations lov_size_repl_logops = { lop_cancel: lov_llog_repl_cancel }; - int lov_llog_init(struct obd_device *obd, struct obd_device *tgt, int count, struct llog_catid *logid) { @@ -191,26 +190,21 @@ int lov_llog_init(struct obd_device *obd, struct obd_device *tgt, int lov_llog_finish(struct obd_device *obd, int count) { - struct lov_obd *lov = &obd->u.lov; - int i, rc = 0; + struct llog_ctxt *ctxt; + int rc = 0; ENTRY; - - rc = llog_cleanup(llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT)); - if (rc) - RETURN(rc); - rc = llog_cleanup(llog_get_context(obd, LLOG_SIZE_REPL_CTXT)); + /* cleanup our llogs only if the ctxts have been setup + * (lov1 doesn't setup, lov_mds1 does). */ + ctxt = llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT); + if (ctxt) + rc = llog_cleanup(ctxt); if (rc) RETURN(rc); - LASSERT(lov->desc.ld_tgt_count == count); - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - struct obd_device *child = lov->tgts[i].ltd_exp->exp_obd; - rc = obd_llog_finish(child, 1); - if (rc) { - CERROR("error osc_llog_finish %d\n", i); - break; - } - } + ctxt = llog_get_context(obd, LLOG_SIZE_REPL_CTXT); + if (ctxt) + rc = llog_cleanup(ctxt); + RETURN(rc); } diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 3d4eb32..d9e52c3 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -123,7 +123,7 @@ static int lov_connect(struct lustre_handle *conn, struct obd_device *obd, if (rc) { CERROR("Target %s register_observer error %d\n", tgt_uuid->uuid, rc); - obd_disconnect(tgts->ltd_exp, 0); + obd_disconnect(tgts->ltd_exp); GOTO(out_disc, rc); } @@ -143,16 +143,16 @@ static int lov_connect(struct lustre_handle *conn, struct obd_device *obd, tgts->active = 0; /* save for CERROR below; (we know it's terminated) */ uuid = tgts->uuid; - rc2 = obd_disconnect(tgts->ltd_exp, 0); + rc2 = obd_disconnect(tgts->ltd_exp); if (rc2) CERROR("error: LOV target %s disconnect on OST idx %d: " "rc = %d\n", uuid.uuid, i, rc2); } - class_disconnect(exp, 0); + class_disconnect(exp); RETURN (rc); } -static int lov_disconnect(struct obd_export *exp, int flags) +static int lov_disconnect(struct obd_export *exp) { struct obd_device *obd = class_exp2obd(exp); struct lov_obd *lov = &obd->u.lov; @@ -190,7 +190,7 @@ static int lov_disconnect(struct obd_export *exp, int flags) obd_register_observer(osc_exp->exp_obd, NULL); spin_unlock(&lov->lov_lock); - rc = obd_disconnect(osc_exp, flags); + rc = obd_disconnect(osc_exp); spin_lock(&lov->lov_lock); if (rc) { if (lov->tgts[i].active) { @@ -207,7 +207,7 @@ static int lov_disconnect(struct obd_export *exp, int flags) spin_unlock(&lov->lov_lock); out_local: - rc = class_disconnect(exp, 0); + rc = class_disconnect(exp); RETURN(rc); } @@ -387,11 +387,12 @@ static int lov_setup(struct obd_device *obd, obd_count len, void *buf) RETURN(0); } -static int lov_cleanup(struct obd_device *obd, int flags) +static int lov_cleanup(struct obd_device *obd) { struct lov_obd *lov = &obd->u.lov; lprocfs_obd_cleanup(obd); + obd_llog_finish(obd, 0); OBD_FREE(lov->tgts, lov->bufsize); RETURN(0); @@ -1668,7 +1669,6 @@ static int lov_set_info(struct obd_export *exp, obd_count keylen, RETURN(-EINVAL); for (i = 0; i < lov->desc.ld_tgt_count; i++) { /* initialize all OSCs, even inactive ones */ - err = obd_set_info(lov->tgts[i].ltd_exp, keylen, key, sizeof(obd_id), ((obd_id*)val) + i); diff --git a/lustre/lvfs/fsfilt_ext3.c b/lustre/lvfs/fsfilt_ext3.c index 080d3ad..b9f17ef 100644 --- a/lustre/lvfs/fsfilt_ext3.c +++ b/lustre/lvfs/fsfilt_ext3.c @@ -116,11 +116,26 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private, /* additional block + block bitmap + GDT for long symlink */ nblocks += 3; /* no break */ - case FSFILT_OP_CREATE: + case FSFILT_OP_CREATE: { +#if defined(EXT3_EXTENTS_FL) && defined(EXT3_INDEX_FL) + static int warned; + if (!warned) { + if (!test_opt(inode->i_sb, EXTENTS)) { + warned = 1; + } else if (((EXT3_I(inode)->i_flags & + cpu_to_le32(EXT3_EXTENTS_FL | EXT3_INDEX_FL)) == + cpu_to_le32(EXT3_EXTENTS_FL | EXT3_INDEX_FL))) { + CWARN("extent-mapped directory found - contact " + "CFS: support@clusterfs.com\n"); + warned = 1; + } + } +#endif /* create/update logs for each stripe */ nblocks += (EXT3_INDEX_EXTRA_TRANS_BLOCKS + EXT3_SINGLEDATA_TRANS_BLOCKS) * logs; /* no break */ + } case FSFILT_OP_MKDIR: case FSFILT_OP_MKNOD: /* modify one inode + block bitmap + GDT */ @@ -635,9 +650,9 @@ static int fsfilt_ext3_sync(struct super_block *sb) return ext3_force_commit(sb); } -#ifndef EXT3_EXT_CACHE_NO /* we need this for struct ext3_ext_cache */ -#undef EXT3_MULTIBLOCK_ALLOCATOR +#if defined(EXT3_MULTIBLOCK_ALLOCATOR) && (!defined(EXT3_EXT_CACHE_NO) || defined(EXT_CACHE_MARK)) #warning "kernel code has old extents/mballoc patch, disabling" +#undef EXT3_MULTIBLOCK_ALLOCATOR #endif #ifdef EXT3_MULTIBLOCK_ALLOCATOR @@ -952,16 +967,13 @@ int fsfilt_ext3_map_inode_pages(struct inode *inode, struct page **page, struct semaphore *optional_sem) { int rc; - if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) { #ifdef EXT3_MULTIBLOCK_ALLOCATOR + if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) { rc = fsfilt_ext3_map_ext_inode_pages(inode, page, pages, blocks, created, create); -#else - CERROR("extent-mapped file with unsupported kernel\n"); - rc = -EIO; -#endif return rc; } +#endif if (optional_sem != NULL) down(optional_sem); rc = fsfilt_ext3_map_bm_inode_pages(inode, page, pages, blocks, diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 022b534..64b589c 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -41,7 +41,7 @@ #define REQUEST_MINOR 244 -static int mdc_cleanup(struct obd_device *obd, int flags); +static int mdc_cleanup(struct obd_device *obd); extern int mds_queue_req(struct ptlrpc_request *); /* Helper that implements most of mdc_getstatus and signal_completed_replay. */ @@ -899,7 +899,7 @@ static int mdc_setup(struct obd_device *obd, obd_count len, void *buf) rc = obd_llog_init(obd, obd, 0, NULL); if (rc) { - mdc_cleanup(obd, 0); + mdc_cleanup(obd); CERROR("failed to setup llogging subsystems\n"); } @@ -944,7 +944,7 @@ int mdc_init_ea_size(struct obd_export *mdc_exp, struct obd_export *lov_exp) RETURN(0); } -static int mdc_precleanup(struct obd_device *obd, int flags) +static int mdc_precleanup(struct obd_device *obd) { int rc = 0; @@ -955,7 +955,7 @@ static int mdc_precleanup(struct obd_device *obd, int flags) RETURN(rc); } -static int mdc_cleanup(struct obd_device *obd, int flags) +static int mdc_cleanup(struct obd_device *obd) { struct client_obd *cli = &obd->u.cli; @@ -965,7 +965,7 @@ static int mdc_cleanup(struct obd_device *obd, int flags) lprocfs_obd_cleanup(obd); ptlrpcd_decref(); - return client_obd_cleanup(obd, flags); + return client_obd_cleanup(obd); } diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 8fcf2e1..5dcdadb 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -60,7 +60,7 @@ static int mds_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp, void *req_cookie, ldlm_mode_t mode, int flags, void *data); static int mds_postsetup(struct obd_device *obd); -static int mds_cleanup(struct obd_device *obd, int flags); +static int mds_cleanup(struct obd_device *obd); /* Assumes caller has already pushed into the kernel filesystem context */ static int mds_sendpage(struct ptlrpc_request *req, struct file *file, @@ -295,7 +295,7 @@ static int mds_connect(struct lustre_handle *conn, struct obd_device *obd, out: if (rc) { OBD_FREE(mcd, sizeof(*mcd)); - class_disconnect(exp, 0); + class_disconnect(exp); } class_export_put(exp); @@ -358,14 +358,13 @@ static int mds_destroy_export(struct obd_export *export) } spin_unlock(&med->med_open_lock); pop_ctxt(&saved, &obd->obd_ctxt, NULL); - out: mds_client_free(export, !(export->exp_flags & OBD_OPT_FAILOVER)); RETURN(rc); } -static int mds_disconnect(struct obd_export *exp, int flags) +static int mds_disconnect(struct obd_export *exp) { unsigned long irqflags; int rc; @@ -374,12 +373,8 @@ static int mds_disconnect(struct obd_export *exp, int flags) LASSERT(exp); class_export_get(exp); - spin_lock_irqsave(&exp->exp_lock, irqflags); - exp->exp_flags = flags; - spin_unlock_irqrestore(&exp->exp_lock, irqflags); - /* Disconnect early so that clients can't keep using export */ - rc = class_disconnect(exp, flags); + rc = class_disconnect(exp); ldlm_cancel_locks_for_export(exp); /* complete all outstanding replies */ @@ -1391,8 +1386,6 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf) int rc = 0; ENTRY; - dev_clear_rdonly(2); - if (!lcfg->lcfg_inlbuf1 || !lcfg->lcfg_inlbuf2) RETURN(rc = -EINVAL); @@ -1426,7 +1419,9 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf) } CDEBUG(D_SUPER, "%s: mnt = %p\n", lcfg->lcfg_inlbuf1, mnt); - + + LASSERT(!ll_check_rdonly(ll_sbdev(mnt->mnt_sb))); + sema_init(&mds->mds_orphan_recovery_sem, 1); sema_init(&mds->mds_epoch_sem, 1); spin_lock_init(&mds->mds_transno_lock); @@ -1436,7 +1431,7 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf) sprintf(ns_name, "mds-%s", obd->obd_uuid.uuid); obd->obd_namespace = ldlm_namespace_new(ns_name, LDLM_NAMESPACE_SERVER); if (obd->obd_namespace == NULL) { - mds_cleanup(obd, 0); + mds_cleanup(obd); GOTO(err_put, rc = -ENOMEM); } ldlm_register_intent(obd->obd_namespace, mds_intent_policy); @@ -1502,7 +1497,7 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf) err_fs: /* No extra cleanup needed for llog_init_commit_thread() */ - mds_fs_cleanup(obd, 0); + mds_fs_cleanup(obd); err_ns: ldlm_namespace_free(obd->obd_namespace, 0); obd->obd_namespace = NULL; @@ -1538,8 +1533,22 @@ static int mds_postsetup(struct obd_device *obd) rc = class_config_parse_llog(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT), mds->mds_profile, &cfg); pop_ctxt(&saved, &obd->obd_ctxt, NULL); - if (rc) + switch (rc) { + case 0: + break; + case -EINVAL: + LCONSOLE_ERROR("%s: the profile %s could not be read. " + "If you recently installed a new " + "version of Lustre, you may need to " + "re-run 'lconf --write_conf " + ".xml' command line before " + "restarting the MDS.\n", + obd->obd_name, mds->mds_profile); + /* fall through */ + default: GOTO(err_llog, rc); + break; + } lprof = class_get_profile(mds->mds_profile); if (lprof == NULL) { @@ -1644,24 +1653,33 @@ int mds_lov_clean(struct obd_device *obd) RETURN(0); } -static int mds_precleanup(struct obd_device *obd, int flags) +static int mds_precleanup(struct obd_device *obd) { int rc = 0; ENTRY; - mds_lov_disconnect(obd, flags); + mds_lov_set_cleanup_flags(obd); + target_cleanup_recovery(obd); + mds_lov_disconnect(obd); mds_lov_clean(obd); llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT)); RETURN(rc); } -static int mds_cleanup(struct obd_device *obd, int flags) +static int mds_cleanup(struct obd_device *obd) { struct mds_obd *mds = &obd->u.mds; + ll_sbdev_type save_dev; ENTRY; if (mds->mds_sb == NULL) RETURN(0); + save_dev = ll_sbdev(mds->mds_sb); + + if (mds->mds_osc_exp) + /* lov export was disconnected by mds_lov_clean; + we just need to drop our ref */ + class_export_put(mds->mds_osc_exp); lprocfs_obd_cleanup(obd); @@ -1670,7 +1688,7 @@ static int mds_cleanup(struct obd_device *obd, int flags) OBD_FREE(mds->mds_lov_objids, mds->mds_lov_desc.ld_tgt_count * sizeof(obd_id)); } - mds_fs_cleanup(obd, flags); + mds_fs_cleanup(obd); unlock_kernel(); @@ -1681,10 +1699,9 @@ static int mds_cleanup(struct obd_device *obd, int flags) atomic_read(&obd->u.mds.mds_vfsmnt->mnt_count)); mntput(mds->mds_vfsmnt); + mds->mds_sb = NULL; - mds->mds_sb = 0; - - ldlm_namespace_free(obd->obd_namespace, flags & OBD_OPT_FORCE); + ldlm_namespace_free(obd->obd_namespace, obd->obd_force); spin_lock_bh(&obd->obd_processing_task_lock); if (obd->obd_recovering) { @@ -1693,8 +1710,11 @@ static int mds_cleanup(struct obd_device *obd, int flags) } spin_unlock_bh(&obd->obd_processing_task_lock); + obd_llog_finish(obd, 0); + + ll_clear_rdonly(save_dev); + lock_kernel(); - dev_clear_rdonly(2); fsfilt_put_ops(obd->obd_fsops); LCONSOLE_INFO("MDT %s has stopped.\n", obd->obd_name); @@ -1983,7 +2003,7 @@ err_lprocfs: return rc; } -static int mdt_cleanup(struct obd_device *obd, int flags) +static int mdt_cleanup(struct obd_device *obd) { struct mds_obd *mds = &obd->u.mds; ENTRY; diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c index 42d19c4..ffbf43f 100644 --- a/lustre/mds/mds_fs.c +++ b/lustre/mds/mds_fs.c @@ -364,7 +364,7 @@ static int mds_init_server_data(struct obd_device *obd, struct file *file) RETURN(0); err_client: - class_disconnect_exports(obd, 0); + class_disconnect_exports(obd); err_msd: mds_server_free_data(mds); RETURN(rc); @@ -490,7 +490,7 @@ err_lov_objid: if (mds->mds_lov_objid_filp && filp_close(mds->mds_lov_objid_filp, 0)) CERROR("can't close %s after error\n", LOV_OBJID); err_client: - class_disconnect_exports(obd, 0); + class_disconnect_exports(obd); err_last_rcvd: if (mds->mds_rcvd_filp && filp_close(mds->mds_rcvd_filp, 0)) CERROR("can't close %s after error\n", LAST_RCVD); @@ -506,18 +506,17 @@ err_fid: } -int mds_fs_cleanup(struct obd_device *obd, int flags) +int mds_fs_cleanup(struct obd_device *obd) { struct mds_obd *mds = &obd->u.mds; struct obd_run_ctxt saved; int rc = 0; - if (flags & OBD_OPT_FAILOVER) + if (obd->obd_fail) CERROR("%s: shutting down for failover; client state will" " be preserved.\n", obd->obd_name); - class_disconnect_exports(obd, flags); /* cleans up client info too */ - target_cleanup_recovery(obd); + class_disconnect_exports(obd); /* cleans up client info too */ mds_server_free_data(mds); push_ctxt(&saved, &obd->obd_ctxt, NULL); @@ -656,11 +655,17 @@ int mds_obd_destroy(struct obd_export *exp, struct obdo *oa, down(&parent_inode->i_sem); de = lookup_one_len(fidname, mds->mds_objects_dir, namelen); - if (IS_ERR(de) || de->d_inode == NULL) { - rc = IS_ERR(de) ? PTR_ERR(de) : -ENOENT; + if (IS_ERR(de)) { + rc = IS_ERR(de); + de = NULL; + CERROR("error looking up object "LPU64" %s: rc %d\n", + oa->o_id, fidname, rc); + GOTO(out_dput, rc); + } + if (de->d_inode == NULL) { CERROR("destroying non-existent object "LPU64" %s\n", oa->o_id, fidname); - GOTO(out_dput, rc = IS_ERR(de) ? PTR_ERR(de) : -ENOENT); + GOTO(out_dput, rc = -ENOENT); } /* Stripe count is 1 here since this is some MDS specific stuff diff --git a/lustre/mds/mds_internal.h b/lustre/mds/mds_internal.h index 11ff9e9..3ca6feb 100644 --- a/lustre/mds/mds_internal.h +++ b/lustre/mds/mds_internal.h @@ -137,8 +137,8 @@ int mds_llog_finish(struct obd_device *obd, int count); /* mds/mds_lov.c */ int mds_lov_connect(struct obd_device *obd, char * lov_name); -int mds_lov_disconnect(struct obd_device *obd, int flags); -int mds_get_lovtgts(struct obd_device *, int tgt_count, struct obd_uuid *); +int mds_lov_disconnect(struct obd_device *obd); +void mds_lov_set_cleanup_flags(struct obd_device *); int mds_lov_write_objids(struct obd_device *obd); void mds_lov_update_objids(struct obd_device *obd, obd_id *ids); int mds_lov_set_growth(struct mds_obd *mds, int count); diff --git a/lustre/mds/mds_log.c b/lustre/mds/mds_log.c index b7ebc31..1436948 100644 --- a/lustre/mds/mds_log.c +++ b/lustre/mds/mds_log.c @@ -144,21 +144,19 @@ int mds_llog_init(struct obd_device *obd, struct obd_device *tgt, int mds_llog_finish(struct obd_device *obd, int count) { - struct obd_device *lov_obd = obd->u.mds.mds_osc_obd; - int rc; + struct llog_ctxt *ctxt; + int rc = 0; ENTRY; - rc = llog_cleanup(llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT)); - if (rc) - RETURN(rc); - - rc = llog_cleanup(llog_get_context(obd, LLOG_SIZE_REPL_CTXT)); + ctxt = llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT); + if (ctxt) + rc = llog_cleanup(ctxt); if (rc) RETURN(rc); - rc = obd_llog_finish(lov_obd, count); - if (rc) - CERROR("error lov_llog_finish\n"); - + ctxt = llog_get_context(obd, LLOG_SIZE_REPL_CTXT); + if (ctxt) + rc = llog_cleanup(ctxt); + RETURN(rc); } diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c index f9d9568..92eac6b 100644 --- a/lustre/mds/mds_lov.c +++ b/lustre/mds/mds_lov.c @@ -258,39 +258,61 @@ int mds_lov_connect(struct obd_device *obd, char * lov_name) err_reg: obd_register_observer(mds->mds_osc_obd, NULL); err_discon: - obd_disconnect(mds->mds_osc_exp, 0); + obd_disconnect(mds->mds_osc_exp); mds->mds_osc_exp = NULL; mds->mds_osc_obd = ERR_PTR(rc); RETURN(rc); } -int mds_lov_disconnect(struct obd_device *obd, int flags) +int mds_lov_disconnect(struct obd_device *obd) { struct mds_obd *mds = &obd->u.mds; int rc = 0; ENTRY; if (!IS_ERR(mds->mds_osc_obd) && mds->mds_osc_exp != NULL) { - /* cleanup all llogging subsystems */ - rc = obd_llog_finish(obd, mds->mds_lov_desc.ld_tgt_count); - if (rc) - CERROR("failed to cleanup llogging subsystems\n"); - obd_register_observer(mds->mds_osc_obd, NULL); - rc = obd_disconnect(mds->mds_osc_exp, flags); - /* if obd_disconnect fails (probably because the - * export was disconnected by class_disconnect_exports) - * then we just need to drop our ref. */ - if (rc != 0) - class_export_put(mds->mds_osc_exp); - mds->mds_osc_exp = NULL; - mds->mds_osc_obd = NULL; + /* The actual disconnect of the mds_lov will be called from + * class_disconnect_exports from mds_lov_clean. So we have to + * ensure that class_cleanup doesn't fail due to the extra ref + * we're holding now. The mechanism to do that already exists - + * the obd_force flag. We'll drop the final ref to the + * mds_osc_exp in mds_cleanup. */ + mds->mds_osc_obd->obd_force = 1; } RETURN(rc); } +/* for consistency, let's make the lov and the lov's + * osc's see the same cleanup flags as our mds */ +void mds_lov_set_cleanup_flags(struct obd_device *obd) +{ + struct mds_obd *mds = &obd->u.mds; + struct lov_obd *lov; + + if (IS_ERR(mds->mds_osc_obd) || (mds->mds_osc_exp == NULL)) + return; + + lov = &mds->mds_osc_obd->u.lov; + mds->mds_osc_obd->obd_force = obd->obd_force; + mds->mds_osc_obd->obd_fail = obd->obd_fail; + if (lov->tgts) { + struct obd_export *osc_exp; + int i; + spin_lock(&lov->lov_lock); + for (i = 0; i < lov->desc.ld_tgt_count; i++) { + if (lov->tgts[i].ltd_exp != NULL) { + osc_exp = lov->tgts[i].ltd_exp; + osc_exp->exp_obd->obd_force = obd->obd_force; + osc_exp->exp_obd->obd_fail = obd->obd_fail; + } + } + spin_unlock(&lov->lov_lock); + } +} + int mds_iocontrol(unsigned int cmd, struct obd_export *exp, int len, void *karg, void *uarg) { @@ -338,7 +360,7 @@ int mds_iocontrol(unsigned int cmd, struct obd_export *exp, int len, RETURN(-EBUSY); push_ctxt(&saved, &obd->obd_ctxt, NULL); - rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT), + rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT), &mds->mds_cfg_llh, NULL, name); if (rc == 0) { llog_init_handle(mds->mds_cfg_llh, LLOG_F_IS_PLAIN, @@ -412,6 +434,12 @@ int mds_iocontrol(unsigned int cmd, struct obd_export *exp, int len, RETURN(rc); } + case OBD_IOC_SYNC: { + CDEBUG(D_HA, "syncing mds %s\n", obd->obd_name); + rc = fsfilt_sync(obd, obd->u.mds.mds_sb); + RETURN(rc); + } + case OBD_IOC_SET_READONLY: { void *handle; struct inode *inode = obd->u.mds.mds_sb->s_root->d_inode; @@ -420,10 +448,13 @@ int mds_iocontrol(unsigned int cmd, struct obd_export *exp, int len, ll_bdevname(obd->u.mds.mds_sb, tmp)); handle = fsfilt_start(obd, inode, FSFILT_OP_MKNOD, NULL); - LASSERT(handle); - rc = fsfilt_commit(obd, inode, handle, 1); + if (!IS_ERR(handle)) + rc = fsfilt_commit(obd, inode, handle, 1); + + CDEBUG(D_HA, "syncing mds %s\n", obd->obd_name); + rc = fsfilt_sync(obd, obd->u.mds.mds_sb); - dev_set_rdonly(ll_sbdev(obd->u.mds.mds_sb), 2); + ll_set_rdonly(ll_sbdev(obd->u.mds.mds_sb)); RETURN(0); } @@ -504,7 +535,7 @@ int mds_lov_synchronize(void *data) LASSERT(obd != NULL); LASSERT(uuid != NULL); - rc = obd_set_info(obd->u.mds.mds_osc_exp, strlen("mds_conn"), + rc = obd_set_info(obd->u.mds.mds_osc_exp, strlen("mds_conn"), "mds_conn", 0, uuid); if (rc != 0) RETURN(rc); @@ -513,7 +544,7 @@ int mds_lov_synchronize(void *data) obd->u.mds.mds_lov_desc.ld_tgt_count, NULL, NULL, uuid); if (rc != 0) { - CERROR("%s: failed at llog_origin_connect: %d\n", + CERROR("%s: failed at llog_origin_connect: %d\n", obd->obd_name, rc); RETURN(rc); } @@ -522,7 +553,7 @@ int mds_lov_synchronize(void *data) obd->obd_name, uuid->uuid); rc = mds_lov_clearorphans(&obd->u.mds, uuid); if (rc != 0) { - CERROR("%s: failed at mds_lov_clearorphans: %d\n", + CERROR("%s: failed at mds_lov_clearorphans: %d\n", obd->obd_name, rc); RETURN(rc); } @@ -546,10 +577,10 @@ int mds_lov_start_synchronize(struct obd_device *obd, struct obd_uuid *uuid) rc = kernel_thread(mds_lov_synchronize, mlsi, CLONE_VM | CLONE_FILES); if (rc < 0) - CERROR("%s: error starting mds_lov_synchronize: %d\n", + CERROR("%s: error starting mds_lov_synchronize: %d\n", obd->obd_name, rc); else { - CDEBUG(D_HA, "%s: mds_lov_synchronize thread: %d\n", + CDEBUG(D_HA, "%s: mds_lov_synchronize thread: %d\n", obd->obd_name, rc); rc = 0; } diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index 3f4e67e..98ade8a 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -326,7 +326,11 @@ static int mds_create_objects(struct ptlrpc_request *req, int offset, /* replay case */ if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY) { - LASSERT (rec->ur_fid2->id); + if (rec->ur_fid2->id == 0) { + DEBUG_REQ(D_ERROR, req, "fid2 not set on open replay"); + RETURN(-EFAULT); + } + body->valid |= OBD_MD_FLBLKSZ | OBD_MD_FLEASIZE; lmm_size = rec->ur_eadatalen; lmm = rec->ur_eadata; @@ -828,11 +832,17 @@ int mds_open(struct mds_update_record *rec, int offset, rec, rep); if (rc != -ENOENT) RETURN(rc); + /* We didn't find the correct inode on disk either, so we * need to re-create it via a regular replay. */ - LASSERT(rec->ur_flags & MDS_OPEN_CREAT); - } else { - LASSERT(!rec->ur_fid2->id); + if (!(rec->ur_flags & MDS_OPEN_CREAT)) { + DEBUG_REQ(D_ERROR, req,"OPEN_CREAT not in open replay"); + RETURN(-EFAULT); + } + } else if (rec->ur_fid2->id) { + DEBUG_REQ(D_ERROR, req, "fid2 "LPU64"/%u on open non-replay", + rec->ur_fid2->id, rec->ur_fid2->generation); + RETURN(-EFAULT); } LASSERT(offset == 2); /* If we got here, we must be called via intent */ @@ -851,8 +861,15 @@ int mds_open(struct mds_update_record *rec, int offset, rec->ur_namelen - 1); if (IS_ERR(dparent)) { rc = PTR_ERR(dparent); - if (rc != -ENOENT) - CERROR("parent lookup error %d\n", rc); + if (rc != -ENOENT) { + CERROR("parent "LPU64"/%u lookup error %d\n", + rec->ur_fid1->id, rec->ur_fid1->generation, rc); + } else { + /* Just cannot find parent - make it look like + * usual negative lookup to avoid extra MDS RPC */ + intent_set_disposition(rep, DISP_LOOKUP_EXECD); + intent_set_disposition(rep, DISP_LOOKUP_NEG); + } GOTO(cleanup, rc); } LASSERT(dparent->d_inode != NULL); diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index f4813a2..150948c 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -88,8 +88,8 @@ int proc_version; /* The following are visible and mutable through /proc/sys/lustre/. */ unsigned int obd_fail_loc; unsigned int obd_dump_on_timeout; -unsigned int obd_timeout = 100; -unsigned int ldlm_timeout = 6; +unsigned int obd_timeout = 100; /* seconds */ +unsigned int ldlm_timeout = 6; /* seconds */ char obd_lustre_upcall[128] = "DEFAULT"; /* or NONE or /full/path/to/upcall */ unsigned int obd_sync_filter; /* = 0, don't sync by default */ @@ -646,7 +646,7 @@ static void cleanup_obdclass(void) * kernel patch */ #include #define LUSTRE_MIN_VERSION 32 -#define LUSTRE_MAX_VERSION 44 +#define LUSTRE_MAX_VERSION 45 #if (LUSTRE_KERNEL_VERSION < LUSTRE_MIN_VERSION) # error Cannot continue: Your Lustre kernel patch is older than the sources #elif (LUSTRE_KERNEL_VERSION > LUSTRE_MAX_VERSION) diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index 662a03b..4cb163d 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -213,9 +213,10 @@ void class_release_dev(struct obd_device *obd) int minor = obd->obd_minor; spin_lock(&obd_dev_lock); + memset(obd, 0x5a, sizeof(*obd)); obd->obd_type = NULL; - //memset(obd, 0, sizeof(*obd)); obd->obd_minor = minor; + obd->obd_name = NULL; spin_unlock(&obd_dev_lock); } @@ -460,10 +461,7 @@ void __class_export_put(struct obd_export *exp) obd_destroy_export(exp); OBD_FREE(exp, sizeof(*exp)); - if (obd->obd_set_up) { - atomic_dec(&obd->obd_refcount); - wake_up(&obd->obd_refcount_waitq); - } + class_decref(obd); } } @@ -625,7 +623,7 @@ int class_connect(struct lustre_handle *conn, struct obd_device *obd, * hash entry and one for the export pointer passed in. The export * pointer passed to this function is destroyed should not be used * again. */ -int class_disconnect(struct obd_export *export, int flags) +int class_disconnect(struct obd_export *export) { ENTRY; @@ -661,6 +659,7 @@ static void class_disconnect_export_list(struct list_head *list, int flags) while(!list_empty(list)) { exp = list_entry(list->next, struct obd_export, exp_obd_chain); class_export_get(exp); + exp->exp_flags = flags; if (obd_uuid_equals(&exp->exp_client_uuid, &exp->exp_obd->obd_uuid)) { @@ -680,7 +679,8 @@ static void class_disconnect_export_list(struct list_head *list, int flags) class_export_put(exp); continue; } - rc = obd_disconnect(fake_exp, flags); + fake_exp->exp_flags = flags; + rc = obd_disconnect(fake_exp); class_export_put(exp); if (rc) { CDEBUG(D_HA, "disconnecting export %p failed: %d\n", @@ -692,7 +692,13 @@ static void class_disconnect_export_list(struct list_head *list, int flags) EXIT; } -void class_disconnect_exports(struct obd_device *obd, int flags) +static inline int get_exp_flags_from_obd(struct obd_device *obd) +{ + return ((obd->obd_fail ? OBD_OPT_FAILOVER : 0) | + (obd->obd_force ? OBD_OPT_FORCE : 0)); +} + +void class_disconnect_exports(struct obd_device *obd) { struct list_head work_list; ENTRY; @@ -705,13 +711,13 @@ void class_disconnect_exports(struct obd_device *obd, int flags) CDEBUG(D_HA, "OBD device %d (%p) has exports, " "disconnecting them\n", obd->obd_minor, obd); - class_disconnect_export_list(&work_list, flags); + class_disconnect_export_list(&work_list, get_exp_flags_from_obd(obd)); EXIT; } /* Remove exports that have not completed recovery. */ -void class_disconnect_stale_exports(struct obd_device *obd, int flags) +void class_disconnect_stale_exports(struct obd_device *obd) { struct list_head work_list; struct list_head *pos, *n; @@ -733,7 +739,7 @@ void class_disconnect_stale_exports(struct obd_device *obd, int flags) CDEBUG(D_ERROR, "%s: disconnecting %d stale clients\n", obd->obd_name, cnt); - class_disconnect_export_list(&work_list, flags); + class_disconnect_export_list(&work_list, get_exp_flags_from_obd(obd)); EXIT; } diff --git a/lustre/obdclass/llog_obd.c b/lustre/obdclass/llog_obd.c index cdbcce8..c22316c 100644 --- a/lustre/obdclass/llog_obd.c +++ b/lustre/obdclass/llog_obd.c @@ -42,15 +42,13 @@ int llog_setup(struct obd_device *obd, int index, struct obd_device *disk_obd, obd->obd_llog_ctxt[index] = ctxt; ctxt->loc_obd = obd; - ctxt->loc_exp = class_export_get(disk_obd->obd_self_export); + ctxt->loc_exp = disk_obd->obd_self_export; ctxt->loc_idx = index; ctxt->loc_logops = op; sema_init(&ctxt->loc_sem, 1); if (op->lop_setup) rc = op->lop_setup(obd, index, disk_obd, count, logid); - if (ctxt && rc) - OBD_FREE(ctxt, sizeof(*ctxt)); RETURN(rc); } @@ -61,13 +59,15 @@ int llog_cleanup(struct llog_ctxt *ctxt) int rc = 0; ENTRY; - LASSERT(ctxt); - + if (!ctxt) { + CERROR("No ctxt\n"); + RETURN(-ENODEV); + } + if (CTXTP(ctxt, cleanup)) rc = CTXTP(ctxt, cleanup)(ctxt); ctxt->loc_obd->obd_llog_ctxt[ctxt->loc_idx] = NULL; - class_export_put(ctxt->loc_exp); ctxt->loc_exp = NULL; OBD_FREE(ctxt, sizeof(*ctxt)); @@ -97,7 +97,11 @@ int llog_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec, int rc; ENTRY; - LASSERT(ctxt); + if (!ctxt) { + CERROR("No ctxt\n"); + RETURN(-ENODEV); + } + CTXT_CHECK_OP(ctxt, add, -EOPNOTSUPP); rc = CTXTP(ctxt, add)(ctxt, rec, lsm, logcookies, numcookies); @@ -111,7 +115,11 @@ int llog_cancel(struct llog_ctxt *ctxt, struct lov_stripe_md *lsm, int rc; ENTRY; - LASSERT(ctxt); + if (!ctxt) { + CERROR("No ctxt\n"); + RETURN(-ENODEV); + } + CTXT_CHECK_OP(ctxt, cancel, -EOPNOTSUPP); rc = CTXTP(ctxt, cancel)(ctxt, lsm, count, cookies, flags); RETURN(rc); @@ -149,7 +157,6 @@ static int cat_cancel_cb(struct llog_handle *cathandle, rc = llog_destroy(loghandle); if (rc) CERROR("failure destroying log in postsetup: %d\n", rc); - LASSERT(rc == 0); index = loghandle->u.phd.phd_cookie.lgc_index; llog_free_handle(loghandle); @@ -225,7 +232,7 @@ int llog_obd_origin_cleanup(struct llog_ctxt *ctxt) ENTRY; if (!ctxt) - return 0; + RETURN(0); cathandle = ctxt->loc_handle; if (cathandle) { @@ -240,7 +247,6 @@ int llog_obd_origin_cleanup(struct llog_ctxt *ctxt) if (rc) CERROR("failure destroying log during " "cleanup: %d\n", rc); - LASSERT(rc == 0); index = loghandle->u.phd.phd_cookie.lgc_index; llog_free_handle(loghandle); @@ -256,7 +262,7 @@ int llog_obd_origin_cleanup(struct llog_ctxt *ctxt) } llog_cat_put(ctxt->loc_handle); } - return 0; + RETURN(0); } EXPORT_SYMBOL(llog_obd_origin_cleanup); diff --git a/lustre/obdclass/llog_test.c b/lustre/obdclass/llog_test.c index 88ac16c..5c8af06 100644 --- a/lustre/obdclass/llog_test.c +++ b/lustre/obdclass/llog_test.c @@ -482,7 +482,7 @@ parse_out: CERROR("6: llog_close failed: rc = %d\n", rc); } - rc = obd_disconnect(exp, 0); + rc = obd_disconnect(exp); RETURN(rc); } @@ -602,7 +602,7 @@ static int llog_test_llog_finish(struct obd_device *obd, int count) RETURN(rc); } -static int llog_test_cleanup(struct obd_device *obd, int flags) +static int llog_test_cleanup(struct obd_device *obd) { int rc = obd_llog_finish(obd, 0); if (rc) @@ -641,7 +641,7 @@ static int llog_test_setup(struct obd_device *obd, obd_count len, void *buf) rc = llog_run_tests(obd); if (rc) - llog_test_cleanup(obd, 0); + llog_test_cleanup(obd); lprocfs_init_vars(llog_test, &lvars); lprocfs_obd_setup(obd, lvars.obd_vars); diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 7a5d0c9..7b838e1 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -192,6 +192,15 @@ int lprocfs_rd_u64(char *page, char **start, off_t off, return snprintf(page, count, LPU64"\n", *(__u64 *)data); } +int lprocfs_rd_atomic(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + atomic_t *atom = (atomic_t *)data; + LASSERT(atom != NULL); + *eof = 1; + return snprintf(page, count, "%d\n", atomic_read(atom)); +} + int lprocfs_rd_uuid(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -873,6 +882,7 @@ EXPORT_SYMBOL(lprocfs_alloc_obd_stats); EXPORT_SYMBOL(lprocfs_free_obd_stats); EXPORT_SYMBOL(lprocfs_rd_u64); +EXPORT_SYMBOL(lprocfs_rd_atomic); EXPORT_SYMBOL(lprocfs_rd_uuid); EXPORT_SYMBOL(lprocfs_rd_name); EXPORT_SYMBOL(lprocfs_rd_fstype); diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 4bb616d..cd04ae0 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -112,7 +112,6 @@ int class_attach(struct lustre_cfg *lcfg) spin_lock_init(&obd->obd_dev_lock); spin_lock_init(&obd->obd_osfs_lock); obd->obd_osfs_age = jiffies - 1000 * HZ; - init_waitqueue_head(&obd->obd_refcount_waitq); /* XXX belongs in setup not attach */ /* recovery data */ @@ -140,6 +139,9 @@ int class_attach(struct lustre_cfg *lcfg) GOTO(out, rc = -EINVAL); } + /* The attach is our first obd reference */ + atomic_set(&obd->obd_refcount, 1); + obd->obd_attached = 1; type->typ_refcnt++; CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n", @@ -190,8 +192,6 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg) obd->obd_starting = 1; spin_unlock(&obd->obd_dev_lock); - atomic_set(&obd->obd_refcount, 0); - exp = class_new_export(obd); if (exp == NULL) RETURN(err); @@ -206,19 +206,42 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg) obd->obd_type->typ_refcnt++; obd->obd_set_up = 1; - + CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n", + obd->obd_name, obd->obd_uuid.uuid); + RETURN(0); err_exp: class_unlink_export(obd->obd_self_export); obd->obd_self_export = NULL; + obd->obd_starting = 0; RETURN(err); } -int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg) +static int __class_detach(struct obd_device *obd) { int err = 0; + if (OBP(obd, detach)) + err = OBP(obd,detach)(obd); + + if (obd->obd_name) { + OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1); + obd->obd_name = NULL; + } else { + CERROR("device %d: no name at detach\n", obd->obd_minor); + } + + LASSERT(OBT(obd)); + /* Attach took type refcount */ + obd->obd_type->typ_refcnt--; + class_put_type(obd->obd_type); + class_release_dev(obd); + return (err); +} + +int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg) +{ ENTRY; if (obd->obd_set_up) { CERROR("OBD device %d still set up\n", obd->obd_minor); @@ -234,21 +257,11 @@ int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg) obd->obd_attached = 0; spin_unlock(&obd->obd_dev_lock); - if (OBP(obd, detach)) - err = OBP(obd,detach)(obd); - - if (obd->obd_name) { - OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1); - obd->obd_name = NULL; - } else { - CERROR("device %d: no name at detach\n", obd->obd_minor); - } + CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n", + obd->obd_name, obd->obd_uuid.uuid); - LASSERT(OBT(obd)); - obd->obd_type->typ_refcnt--; - class_put_type(obd->obd_type); - class_release_dev(obd); - RETURN(err); + class_decref(obd); + RETURN(0); } static void dump_exports(struct obd_device *obd) @@ -267,7 +280,7 @@ static void dump_exports(struct obd_device *obd) nreplies++; } - CERROR("%s: %p %s %d %d %d: %p %s\n", + CDEBUG(D_IOCTL, "%s: %p %s %d %d %d: %p %s\n", obd->obd_name, exp, exp->exp_client_uuid.uuid, atomic_read(&exp->exp_refcount), exp->exp_failed, nreplies, first_reply, @@ -277,11 +290,12 @@ static void dump_exports(struct obd_device *obd) int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) { - int flags = 0; int err = 0; char *flag; ENTRY; + OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS); + if (!obd->obd_set_up) { CERROR("Device %d not setup\n", obd->obd_minor); RETURN(-ENODEV); @@ -301,78 +315,83 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) for (flag = lcfg->lcfg_inlbuf1; *flag != 0; flag++) switch (*flag) { case 'F': - flags |= OBD_OPT_FORCE; + obd->obd_force = 1; break; case 'A': - flags |= OBD_OPT_FAILOVER; + obd->obd_fail = 1; + obd->obd_no_transno = 1; + LCONSOLE_WARN("Failing %s by user command\n", + obd->obd_name); + /* Set the obd readonly if we can */ + if (OBP(obd, iocontrol)) + obd_iocontrol(OBD_IOC_SET_READONLY, + obd->obd_self_export, + 0, NULL, NULL); break; default: CERROR("unrecognised flag '%c'\n", *flag); } } - - /* The one reference that should be remaining is the - * obd_self_export */ - if (atomic_read(&obd->obd_refcount) > 1) { - struct l_wait_info lwi = LWI_TIMEOUT_INTR(1 * HZ, NULL, - NULL, NULL); - int rc; - - if (!(flags & OBD_OPT_FORCE)) { - CERROR("OBD device %d (%p) has refcount %d\n", - obd->obd_minor, obd, - atomic_read(&obd->obd_refcount)); + + /* The two references that should be remaining are the + * obd_self_export and the attach reference. */ + if (atomic_read(&obd->obd_refcount) > 2) { + if (!(obd->obd_fail || obd->obd_force)) { + CERROR("OBD %s is still busy with %d references\n" + "You should stop active file system users," + " or use the --force option to cleanup.\n", + obd->obd_name, atomic_read(&obd->obd_refcount)); dump_exports(obd); GOTO(out, err = -EBUSY); } - class_disconnect_exports(obd, flags); - CDEBUG(D_IOCTL, - "%s: waiting for obd refs to go away: %d\n", + CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n", obd->obd_name, atomic_read(&obd->obd_refcount)); - - rc = l_wait_event(obd->obd_refcount_waitq, - atomic_read(&obd->obd_refcount) < 2, &lwi); - if (rc == 0) { - LASSERT(atomic_read(&obd->obd_refcount) == 1); - } else { - CERROR("wait cancelled cleaning anyway. " - "refcount: %d\n", - atomic_read(&obd->obd_refcount)); - dump_exports(obd); - } - CDEBUG(D_IOCTL, "%s: awake, now finishing cleanup\n", - obd->obd_name); + dump_exports(obd); + class_disconnect_exports(obd); } + LASSERT(obd->obd_self_export); if (obd->obd_self_export) { - err = obd_precleanup(obd, flags); - if (err) - GOTO(out, err); - class_unlink_export(obd->obd_self_export); - obd->obd_self_export = NULL; - } - - err = obd_cleanup(obd, flags); + /* mds_precleanup will clean up the lov (and osc's)*/ + err = obd_precleanup(obd); + if (err) + GOTO(out, err); + obd->obd_self_export->exp_flags |= + (obd->obd_fail ? OBD_OPT_FAILOVER : 0) | + (obd->obd_force ? OBD_OPT_FORCE : 0); + class_unlink_export(obd->obd_self_export); + obd->obd_self_export = NULL; + } + + obd->obd_set_up = 0; + obd->obd_type->typ_refcnt--; + RETURN(0); out: - if (!err) { - obd->obd_set_up = 0; - obd->obd_type->typ_refcnt--; - /* XXX this should be an LASSERT */ - if (atomic_read(&obd->obd_refcount) > 0) - CERROR("%s still has refcount %d after " - "cleanup.\n", obd->obd_name, - atomic_read(&obd->obd_refcount)); - } else { - /* Allow a failed cleanup to try again. Note this may be - unsafe, since we don't know where this one died. */ - obd->obd_stopping = 0; - } - + /* Allow a failed cleanup to try again. */ + obd->obd_stopping = 0; RETURN(err); - } +void class_decref(struct obd_device *obd) +{ + if (atomic_dec_and_test(&obd->obd_refcount)) { + int err; + CDEBUG(D_IOCTL, "finishing cleanup of obd %s (%s)\n", + obd->obd_name, obd->obd_uuid.uuid); + LASSERT(!obd->obd_attached); + if (obd->obd_stopping) { + /* If we're not stopping, we never set up */ + err = obd_cleanup(obd); + if (err) + CERROR("Cleanup returned %d\n", err); + } + err = __class_detach(obd); + if (err) + CERROR("Detach returned %d\n", err); + } +} + LIST_HEAD(lustre_profile_list); struct lustre_profile *class_get_profile(char * prof) diff --git a/lustre/obdclass/sysctl.c b/lustre/obdclass/sysctl.c index b7fa894..e4704f2 100644 --- a/lustre/obdclass/sysctl.c +++ b/lustre/obdclass/sysctl.c @@ -57,8 +57,26 @@ enum { OBD_LDLM_TIMEOUT, /* LDLM timeout for ASTs before client eviction */ }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) int proc_fail_loc(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp); + void *buffer, size_t *lenp) +#else +int proc_fail_loc(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp, loff_t *ppos) +#endif +{ + int rc; + int old_fail_loc = obd_fail_loc; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) + rc = proc_dointvec(table,write,filp,buffer,lenp); +#else + rc = proc_dointvec(table,write,filp,buffer,lenp,ppos); +#endif + if (old_fail_loc != obd_fail_loc) + wake_up(&obd_race_waitq); + return rc; +} static ctl_table obd_table[] = { {OBD_FAIL_LOC, "fail_loc", &obd_fail_loc, sizeof(int), 0644, NULL, @@ -100,15 +118,3 @@ void obd_sysctl_clean (void) obd_table_header = NULL; #endif } - -int proc_fail_loc(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) -{ - int rc; - int old_fail_loc = obd_fail_loc; - - rc = proc_dointvec(table,write,filp,buffer,lenp); - if (old_fail_loc != obd_fail_loc) - wake_up(&obd_race_waitq); - return rc; -} diff --git a/lustre/obdecho/echo.c b/lustre/obdecho/echo.c index 3f12f12..63d8f99 100644 --- a/lustre/obdecho/echo.c +++ b/lustre/obdecho/echo.c @@ -64,7 +64,7 @@ static int echo_connect(struct lustre_handle *conn, struct obd_device *obd, return class_connect(conn, obd, cluuid); } -static int echo_disconnect(struct obd_export *exp, int flags) +static int echo_disconnect(struct obd_export *exp) { unsigned long irqflags; @@ -72,10 +72,6 @@ static int echo_disconnect(struct obd_export *exp, int flags) ldlm_cancel_locks_for_export(exp); - spin_lock_irqsave(&exp->exp_lock, irqflags); - exp->exp_flags = flags; - spin_unlock_irqrestore(&exp->exp_lock, irqflags); - /* complete all outstanding replies */ spin_lock_irqsave(&exp->exp_lock, irqflags); while (!list_empty(&exp->exp_outstanding_replies)) { @@ -91,7 +87,7 @@ static int echo_disconnect(struct obd_export *exp, int flags) } spin_unlock_irqrestore(&exp->exp_lock, irqflags); - return class_disconnect(exp, flags); + return class_disconnect(exp); } static int echo_destroy_export(struct obd_export *exp) @@ -502,7 +498,7 @@ static int echo_setup(struct obd_device *obd, obd_count len, void *buf) RETURN(0); } -static int echo_cleanup(struct obd_device *obd, int flags) +static int echo_cleanup(struct obd_device *obd) { int leaked; ENTRY; @@ -517,7 +513,7 @@ static int echo_cleanup(struct obd_device *obd, int flags) set_current_state (TASK_UNINTERRUPTIBLE); schedule_timeout (HZ); - ldlm_namespace_free(obd->obd_namespace, flags & OBD_OPT_FORCE); + ldlm_namespace_free(obd->obd_namespace, obd->obd_force); leaked = atomic_read(&obd->u.echo.eo_prep); if (leaked != 0) diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c index 58d2358..fb67492 100644 --- a/lustre/obdecho/echo_client.c +++ b/lustre/obdecho/echo_client.c @@ -1355,7 +1355,7 @@ echo_client_setup(struct obd_device *obddev, obd_count len, void *buf) RETURN(rc); } -static int echo_client_cleanup(struct obd_device *obddev, int flags) +static int echo_client_cleanup(struct obd_device *obddev) { struct list_head *el; struct ec_object *eco; @@ -1379,7 +1379,7 @@ static int echo_client_cleanup(struct obd_device *obddev, int flags) echo_put_object(eco); } - rc = obd_disconnect(ec->ec_exp, 0); + rc = obd_disconnect(ec->ec_exp); if (rc != 0) CERROR("fail to disconnect device: %d\n", rc); @@ -1402,7 +1402,7 @@ static int echo_client_connect(struct lustre_handle *conn, RETURN (rc); } -static int echo_client_disconnect(struct obd_export *exp, int flags) +static int echo_client_disconnect(struct obd_export *exp) { struct obd_device *obd; struct echo_client_obd *ec; @@ -1432,7 +1432,7 @@ static int echo_client_disconnect(struct obd_export *exp, int flags) OBD_FREE (ecl, sizeof (*ecl)); } - rc = class_disconnect(exp, 0); + rc = class_disconnect(exp); GOTO(out, rc); out: return rc; diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index a93f1b2..d7fb733 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -218,7 +218,7 @@ static int filter_client_add(struct obd_device *obd, struct filter_obd *filter, RETURN(0); } -static int filter_client_free(struct obd_export *exp, int flags) +static int filter_client_free(struct obd_export *exp) { struct filter_export_data *fed = &exp->exp_filter_data; struct filter_obd *filter = &exp->exp_obd->u.filter; @@ -231,8 +231,8 @@ static int filter_client_free(struct obd_export *exp, int flags) if (fed->fed_fcd == NULL) RETURN(0); - - if (flags & OBD_OPT_FAILOVER) + + if (exp->exp_flags & OBD_OPT_FAILOVER) GOTO(free, 0); /* XXX if fcd_uuid were a real obd_uuid, I could use obd_uuid_equals */ @@ -517,7 +517,7 @@ out: RETURN(0); err_client: - class_disconnect_exports(obd, 0); + class_disconnect_exports(obd); err_fsd: filter_free_server_data(filter); RETURN(rc); @@ -1190,8 +1190,6 @@ int filter_common_setup(struct obd_device *obd, obd_count len, void *buf, int rc = 0; ENTRY; - dev_clear_rdonly(2); - if (!lcfg->lcfg_inlbuf1 || !lcfg->lcfg_inlbuf2) RETURN(-EINVAL); @@ -1200,11 +1198,13 @@ int filter_common_setup(struct obd_device *obd, obd_count len, void *buf, RETURN(PTR_ERR(obd->obd_fsops)); mnt = do_kern_mount(lcfg->lcfg_inlbuf2, MS_NOATIME | MS_NODIRATIME, - lcfg->lcfg_inlbuf1, option); + lcfg->lcfg_inlbuf1, (void *)option); rc = PTR_ERR(mnt); if (IS_ERR(mnt)) GOTO(err_ops, rc); + LASSERT(!ll_check_rdonly(ll_sbdev(mnt->mnt_sb))); + if (lcfg->lcfg_inllen3 > 0 && lcfg->lcfg_inlbuf3) { if (*lcfg->lcfg_inlbuf3 == 'f') { obd->obd_replayable = 1; @@ -1337,29 +1337,36 @@ static int filter_setup(struct obd_device *obd, obd_count len, void *buf) return rc; } -static int filter_cleanup(struct obd_device *obd, int flags) +static int filter_precleanup(struct obd_device *obd) +{ + target_cleanup_recovery(obd); + return (0); +} + +static int filter_cleanup(struct obd_device *obd) { struct filter_obd *filter = &obd->u.filter; + ll_sbdev_type save_dev; ENTRY; - - if (flags & OBD_OPT_FAILOVER) + + if (obd->obd_fail) CERROR("%s: shutting down for failover; client state will" " be preserved.\n", obd->obd_name); if (!list_empty(&obd->obd_exports)) { CERROR("%s: still has clients!\n", obd->obd_name); - class_disconnect_exports(obd, flags); + class_disconnect_exports(obd); if (!list_empty(&obd->obd_exports)) { CERROR("still has exports after forced cleanup?\n"); RETURN(-EBUSY); } } - target_cleanup_recovery(obd); - ldlm_namespace_free(obd->obd_namespace, flags & OBD_OPT_FORCE); + ldlm_namespace_free(obd->obd_namespace, obd->obd_force); if (filter->fo_sb == NULL) RETURN(0); + save_dev = ll_sbdev(filter->fo_sb); lprocfs_free_obd_stats(obd); lprocfs_obd_cleanup(obd); @@ -1367,7 +1374,6 @@ static int filter_cleanup(struct obd_device *obd, int flags) filter_post(obd); shrink_dcache_parent(filter->fo_sb->s_root); - filter->fo_sb = 0; if (atomic_read(&filter->fo_vfsmnt->mnt_count) > 1) CERROR("%s: mount point %p busy, mnt_count: %d\n", @@ -1378,13 +1384,16 @@ static int filter_cleanup(struct obd_device *obd, int flags) mntput(filter->fo_vfsmnt); //destroy_buffers(filter->fo_sb->s_dev); filter->fo_sb = NULL; + + obd_llog_finish(obd, 0); + + ll_clear_rdonly(save_dev); + fsfilt_put_ops(obd->obd_fsops); lock_kernel(); - dev_clear_rdonly(2); - LCONSOLE_INFO("OST %s has stopped.\n", obd->obd_name); - + RETURN(0); } @@ -1430,25 +1439,13 @@ cleanup: if (rc) { if (fcd) OBD_FREE(fcd, sizeof(*fcd)); - class_disconnect(exp, 0); + class_disconnect(exp); } else { class_export_put(exp); } return rc; } -static int filter_precleanup(struct obd_device *obd, int flags) -{ - int rc = 0; - ENTRY; - - rc = obd_llog_finish(obd, 0); - if (rc) - CERROR("failed to cleanup llogging subsystem\n"); - - RETURN(rc); -} - /* Do extra sanity checks for grant accounting. We do this at connect, * disconnect, and statfs RPC time, so it shouldn't be too bad. We can * always get rid of it or turn it off when we know accounting is good. */ @@ -1567,9 +1564,10 @@ static int filter_destroy_export(struct obd_export *exp) target_destroy_export(exp); if (exp->exp_obd->obd_replayable) - filter_client_free(exp, exp->exp_flags); + filter_client_free(exp); filter_grant_discard(exp); + if (!(exp->exp_flags & OBD_OPT_FORCE)) filter_grant_sanity_check(exp->exp_obd, __FUNCTION__); @@ -1577,10 +1575,9 @@ static int filter_destroy_export(struct obd_export *exp) } /* also incredibly similar to mds_disconnect */ -static int filter_disconnect(struct obd_export *exp, int flags) +static int filter_disconnect(struct obd_export *exp) { struct obd_device *obd = exp->exp_obd; - unsigned long irqflags; struct llog_ctxt *ctxt; int rc, err; ENTRY; @@ -1588,16 +1585,12 @@ static int filter_disconnect(struct obd_export *exp, int flags) LASSERT(exp); class_export_get(exp); - spin_lock_irqsave(&exp->exp_lock, irqflags); - exp->exp_flags = flags; - spin_unlock_irqrestore(&exp->exp_lock, irqflags); - - if (!(flags & OBD_OPT_FORCE)) + if (!(exp->exp_flags & OBD_OPT_FORCE)) filter_grant_sanity_check(obd, __FUNCTION__); filter_grant_discard(exp); /* Disconnect early so that clients can't keep using export */ - rc = class_disconnect(exp, flags); + rc = class_disconnect(exp); ldlm_cancel_locks_for_export(exp); @@ -2393,10 +2386,17 @@ int filter_iocontrol(unsigned int cmd, struct obd_export *exp, int rc = 0; switch (cmd) { - case OBD_IOC_ABORT_RECOVERY: + case OBD_IOC_ABORT_RECOVERY: { CERROR("aborting recovery for device %s\n", obd->obd_name); target_abort_recovery(obd); RETURN(0); + } + + case OBD_IOC_SYNC: { + CDEBUG(D_HA, "syncing ost %s\n", obd->obd_name); + rc = fsfilt_sync(obd, obd->u.filter.fo_sb); + RETURN(rc); + } case OBD_IOC_SET_READONLY: { void *handle; @@ -2407,10 +2407,13 @@ int filter_iocontrol(unsigned int cmd, struct obd_export *exp, ll_bdevname(sb, tmp)); handle = fsfilt_start(obd, inode, FSFILT_OP_MKNOD, NULL); - LASSERT(handle); - (void)fsfilt_commit(obd, inode, handle, 1); + if (!IS_ERR(handle)) + rc = fsfilt_commit(obd, inode, handle, 1); + + CDEBUG(D_HA, "syncing ost %s\n", obd->obd_name); + rc = fsfilt_sync(obd, obd->u.filter.fo_sb); - dev_set_rdonly(ll_sbdev(obd->u.filter.fo_sb), 2); + ll_set_rdonly(ll_sbdev(obd->u.filter.fo_sb)); RETURN(0); } diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index f3cac9d..2681a46 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -254,7 +254,7 @@ static int osc_setattr(struct obd_export *exp, struct obdo *oa, request = ptlrpc_prep_req(class_exp2cliimp(exp), OST_SETATTR, 1, &size, NULL); if (!request) - RETURN(-ENOMEM); + RETURN(-ENOMEM); body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof(*body)); memcpy(&body->oa, oa, sizeof(*oa)); @@ -2725,10 +2725,10 @@ static int osc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) MOD_INC_USE_COUNT; #else - if (!try_module_get(THIS_MODULE)) { - CERROR("Can't get module. Is it alive?"); - return -EINVAL; - } + if (!try_module_get(THIS_MODULE)) { + CERROR("Can't get module. Is it alive?"); + return -EINVAL; + } #endif switch (cmd) { case OBD_IOC_LOV_GET_CONFIG: { @@ -2796,7 +2796,7 @@ out: #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) MOD_DEC_USE_COUNT; #else - module_put(THIS_MODULE); + module_put(THIS_MODULE); #endif return err; } @@ -2858,7 +2858,7 @@ static int osc_set_info(struct obd_export *exp, obd_count keylen, memcmp(key, "next_id", strlen("next_id")) == 0) { if (vallen != sizeof(obd_id)) RETURN(-EINVAL); - obd->u.cli.cl_oscc.oscc_next_id = *((obd_id*)val) + 1; + obd->u.cli.cl_oscc.oscc_next_id = *((obd_id*)val) + 1; CDEBUG(D_HA, "%s: set oscc_next_id = "LPU64"\n", exp->exp_obd->obd_name, obd->u.cli.cl_oscc.oscc_next_id); @@ -2870,7 +2870,7 @@ static int osc_set_info(struct obd_export *exp, obd_count keylen, memcmp(key, "growth_count", strlen("growth_count")) == 0) { if (vallen != sizeof(int)) RETURN(-EINVAL); - obd->u.cli.cl_oscc.oscc_grow_count = *((int*)val); + obd->u.cli.cl_oscc.oscc_grow_count = *((int*)val); RETURN(0); } @@ -2955,14 +2955,20 @@ static int osc_llog_init(struct obd_device *obd, struct obd_device *tgt, static int osc_llog_finish(struct obd_device *obd, int count) { - int rc; + struct llog_ctxt *ctxt; + int rc = 0; ENTRY; - rc = llog_cleanup(llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT)); + ctxt = llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT); + if (ctxt) + rc = llog_cleanup(ctxt); if (rc) RETURN(rc); + + ctxt = llog_get_context(obd, LLOG_SIZE_REPL_CTXT); + if (ctxt) + rc = llog_cleanup(ctxt); - rc = llog_cleanup(llog_get_context(obd, LLOG_SIZE_REPL_CTXT)); RETURN(rc); } @@ -2977,7 +2983,7 @@ static int osc_connect(struct lustre_handle *exph, return rc; } -static int osc_disconnect(struct obd_export *exp, int flags) +static int osc_disconnect(struct obd_export *exp) { struct obd_device *obd = class_exp2obd(exp); struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_SIZE_REPL_CTXT); @@ -2987,7 +2993,7 @@ static int osc_disconnect(struct obd_export *exp, int flags) /* flush any remaining cancel messages out to the target */ llog_sync(ctxt, exp); - rc = client_disconnect_export(exp, flags); + rc = client_disconnect_export(exp); return rc; } @@ -3080,7 +3086,7 @@ int osc_setup(struct obd_device *obd, obd_count len, void *buf) RETURN(rc); } -int osc_cleanup(struct obd_device *obd, int flags) +int osc_cleanup(struct obd_device *obd) { struct osc_creator *oscc = &obd->u.cli.cl_oscc; int rc; @@ -3093,8 +3099,9 @@ int osc_cleanup(struct obd_device *obd, int flags) oscc->oscc_flags |= OSCC_FLAG_EXITING; spin_unlock(&oscc->oscc_lock); - rc = client_obd_cleanup(obd, flags); + rc = client_obd_cleanup(obd); ptlrpcd_decref(); + obd_llog_finish(obd, 0); RETURN(rc); } diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index ae67814..44d4467 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -1182,7 +1182,7 @@ out_lprocfs: RETURN(rc); } -static int ost_cleanup(struct obd_device *obd, int flags) +static int ost_cleanup(struct obd_device *obd) { struct ost_obd *ost = &obd->u.ost; int err = 0; diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c index e5ed15f..96901f1 100644 --- a/lustre/ptlrpc/client.c +++ b/lustre/ptlrpc/client.c @@ -210,7 +210,8 @@ struct ptlrpc_request *ptlrpc_prep_req(struct obd_import *imp, int opcode, request->rq_send_state = LUSTRE_IMP_FULL; request->rq_type = PTL_RPC_MSG_REQUEST; request->rq_import = class_import_get(imp); - + request->rq_export = NULL; + request->rq_req_cbid.cbid_fn = request_out_callback; request->rq_req_cbid.cbid_arg = request; @@ -486,7 +487,7 @@ static int after_reply(struct ptlrpc_request *req) /* Either we've been evicted, or the server has failed for * some reason. Try to reconnect, and if that fails, punt to the * upcall. */ - if (rc == -ENOTCONN) { + if ((rc == -ENOTCONN) || (rc == -ENODEV)) { if (req->rq_send_state != LUSTRE_IMP_FULL || imp->imp_obd->obd_no_recov || imp->imp_dlm_fake) { RETURN(-ENOTCONN); diff --git a/lustre/ptlrpc/niobuf.c b/lustre/ptlrpc/niobuf.c index 637e546..ee2257e 100644 --- a/lustre/ptlrpc/niobuf.c +++ b/lustre/ptlrpc/niobuf.c @@ -322,8 +322,17 @@ int ptlrpc_send_reply (struct ptlrpc_request *req, int may_be_difficult) LASSERT (req->rq_repmsg == &rs->rs_msg); LASSERT (rs->rs_cb_id.cbid_fn == reply_out_callback); LASSERT (rs->rs_cb_id.cbid_arg == rs); - LASSERT (req->rq_repmsg != NULL); + + if (req->rq_export && req->rq_export->exp_obd && + req->rq_export->exp_obd->obd_fail) { + /* Failed obd's only send ENODEV */ + req->rq_type = PTL_RPC_MSG_ERR; + req->rq_status = -ENODEV; + CDEBUG(D_HA, "sending ENODEV from failed obd %d\n", + req->rq_export->exp_obd->obd_minor); + } + if (req->rq_type != PTL_RPC_MSG_ERR) req->rq_type = PTL_RPC_MSG_REPLY; @@ -389,6 +398,15 @@ int ptl_send_rpc(struct ptlrpc_request *request) * cleanly from the previous attempt */ LASSERT (!request->rq_receiving_reply); + if (request->rq_import->imp_obd && + request->rq_import->imp_obd->obd_fail) { + CDEBUG(D_HA, "muting rpc for failed imp obd %s\n", + request->rq_import->imp_obd->obd_name); + /* this prevents us from waiting in ptlrpc_queue_wait */ + request->rq_err = 1; + RETURN(-ENODEV); + } + connection = request->rq_import->imp_connection; if (request->rq_bulk != NULL) { diff --git a/lustre/ptlrpc/pinger.c b/lustre/ptlrpc/pinger.c index 299fc34..05172e2 100644 --- a/lustre/ptlrpc/pinger.c +++ b/lustre/ptlrpc/pinger.c @@ -64,6 +64,11 @@ int ptlrpc_ping(struct obd_import *imp) RETURN(rc); } +static inline void ptlrpc_update_next_ping(struct obd_import *imp) +{ + imp->imp_next_ping = jiffies + obd_timeout * HZ; +} + #ifdef __KERNEL__ static int ptlrpc_pinger_main(void *arg) { @@ -114,13 +119,13 @@ static int ptlrpc_pinger_main(void *arg) imp->imp_force_verify = 0; spin_unlock_irqrestore(&imp->imp_lock, flags); - if (imp->imp_next_ping <= this_ping || force) { + if (force || + time_after_eq(this_ping, imp->imp_next_ping)) { if (level == LUSTRE_IMP_DISCON && !imp->imp_deactive) { /* wait at least a timeout before trying recovery again. */ - imp->imp_next_ping = jiffies + - (obd_timeout * HZ); + ptlrpc_update_next_ping(imp); ptlrpc_initiate_recovery(imp); } else if (level != LUSTRE_IMP_FULL || @@ -135,20 +140,25 @@ static int ptlrpc_pinger_main(void *arg) ptlrpc_ping(imp); } - } else { - if (imp->imp_pingable) - CDEBUG(D_HA, "don't need to ping %s " - "(%lu > %lu)\n", - imp->imp_target_uuid.uuid, - imp->imp_next_ping, this_ping); + } else if (!imp->imp_pingable) { + continue; } + + CDEBUG(D_HA, "don't need to ping %s (%lu > %lu)\n", + imp->imp_target_uuid.uuid, + imp->imp_next_ping, this_ping); + + /* obd_timeout might have changed */ + if (time_after(imp->imp_next_ping, + this_ping + obd_timeout * HZ)) + ptlrpc_update_next_ping(imp); } up(&pinger_sem); /* Wait until the next ping time, or until we're stopped. */ time_to_next_ping = this_ping + (obd_timeout * HZ) - jiffies; CDEBUG(D_HA, "next ping in %lu (%lu)\n", time_to_next_ping, - this_ping + (obd_timeout * HZ)); + this_ping + obd_timeout * HZ); if (time_to_next_ping > 0) { lwi = LWI_TIMEOUT(time_to_next_ping, NULL, NULL); l_wait_event(thread->t_ctl_waitq, @@ -235,7 +245,7 @@ int ptlrpc_stop_pinger(void) void ptlrpc_pinger_sending_on_import(struct obd_import *imp) { - imp->imp_next_ping = jiffies + (obd_timeout * HZ); + ptlrpc_update_next_ping(imp); } int ptlrpc_pinger_add_import(struct obd_import *imp) @@ -247,7 +257,7 @@ int ptlrpc_pinger_add_import(struct obd_import *imp) down(&pinger_sem); CDEBUG(D_HA, "adding pingable import %s->%s\n", imp->imp_obd->obd_uuid.uuid, imp->imp_target_uuid.uuid); - imp->imp_next_ping = jiffies + (obd_timeout * HZ); + ptlrpc_update_next_ping(imp); /* XXX sort, blah blah */ list_add_tail(&imp->imp_pinger_chain, &pinger_imports); class_import_get(imp); @@ -289,14 +299,14 @@ void ptlrpc_pinger_wake_up() static struct pinger_data { int pd_recursion; - unsigned long pd_this_ping; - unsigned long pd_next_ping; + unsigned long pd_this_ping; /* jiffies */ + unsigned long pd_next_ping; /* jiffies */ struct ptlrpc_request_set *pd_set; } pinger_args; static int pinger_check_rpcs(void *arg) { - unsigned long curtime = time(NULL); + unsigned long curtime = jiffies; struct ptlrpc_request *req; struct ptlrpc_request_set *set; struct list_head *iter; @@ -312,7 +322,7 @@ static int pinger_check_rpcs(void *arg) } /* have we reached ping point? */ - if (!pd->pd_set && pd->pd_next_ping > curtime) { + if (!pd->pd_set && time_before(curtime, pd->pd_next_ping)) { pd->pd_recursion--; return 0; } @@ -332,12 +342,11 @@ static int pinger_check_rpcs(void *arg) down(&pinger_sem); list_for_each(iter, &pinger_imports) { struct obd_import *imp = - list_entry(iter, struct obd_import, - imp_pinger_chain); + list_entry(iter, struct obd_import, imp_pinger_chain); int generation, level; unsigned long flags; - if (imp->imp_next_ping <= pd->pd_this_ping) { + if (time_after_eq(pd->pd_this_ping, imp->imp_next_ping)) { /* Add a ping. */ spin_lock_irqsave(&imp->imp_lock, flags); generation = imp->imp_generation; @@ -390,7 +399,7 @@ do_check_set: rc = ptlrpc_check_set(set); /* not finished, and we are not expired, simply return */ - if (!rc && curtime < pd->pd_this_ping + obd_timeout) { + if (!rc && time_before(curtime, pd->pd_this_ping + obd_timeout * HZ)) { CDEBUG(D_HA, "not finished, but also not expired\n"); pd->pd_recursion--; return 0; @@ -421,7 +430,7 @@ do_check_set: ptlrpc_set_destroy(set); pd->pd_set = NULL; - pd->pd_next_ping = pd->pd_this_ping + obd_timeout; + pd->pd_next_ping = pd->pd_this_ping + obd_timeout * HZ; pd->pd_this_ping = 0; /* XXX for debug */ CDEBUG(D_HA, "finished a round ping\n"); @@ -453,11 +462,11 @@ int ptlrpc_stop_pinger(void) void ptlrpc_pinger_sending_on_import(struct obd_import *imp) { down(&pinger_sem); - imp->imp_next_ping = time(NULL) + obd_timeout; + ptlrpc_update_next_ping(imp); if (pinger_args.pd_set == NULL && - pinger_args.pd_next_ping > imp->imp_next_ping) { + time_before(imp->imp_next_ping, pinger_args.pd_next_ping)) { CDEBUG(D_HA, "set next ping to %ld(cur %ld)\n", - imp->imp_next_ping, time(NULL)); + imp->imp_next_ping, jiffies); pinger_args.pd_next_ping = imp->imp_next_ping; } up(&pinger_sem); diff --git a/lustre/ptlrpc/recover.c b/lustre/ptlrpc/recover.c index 8fe7108..1b264cea 100644 --- a/lustre/ptlrpc/recover.c +++ b/lustre/ptlrpc/recover.c @@ -418,7 +418,7 @@ void ptlrpc_fail_export(struct obd_export *exp) * (request, for example) in addition to the one from the hash table. * We don't have such a reference here, so make one. */ class_export_get(exp); - rc = obd_disconnect(exp, 0); + rc = obd_disconnect(exp); if (rc) CERROR("disconnecting export %p failed: %d\n", exp, rc); } diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c index 5cd30eb..5f837e4 100644 --- a/lustre/ptlrpc/service.c +++ b/lustre/ptlrpc/service.c @@ -516,6 +516,16 @@ ptlrpc_server_handle_request (struct ptlrpc_service *svc) request->rq_export->exp_conn_cnt); goto put_conn; } + if (request->rq_export->exp_obd + && request->rq_export->exp_obd->obd_fail) { + /* Failing over, don't handle any more reqs, send + error response instead. */ + CDEBUG(D_HA, "Dropping req %p for failed obd %s\n", + request, request->rq_export->exp_obd->obd_name); + request->rq_status = -ENODEV; + ptlrpc_error(request); + goto put_conn; + } request->rq_export->exp_last_request_time = CURRENT_SECONDS; } diff --git a/lustre/tests/Makefile.am b/lustre/tests/Makefile.am index 96f9e7d..e3ebe1d 100644 --- a/lustre/tests/Makefile.am +++ b/lustre/tests/Makefile.am @@ -24,7 +24,7 @@ noinst_PROGRAMS += wantedi statone runas openfile getdents o_directory noinst_PROGRAMS += small_write multiop sleeptest ll_sparseness_verify cmknod noinst_PROGRAMS += ll_sparseness_write mrename ll_dirstripe_verify mkdirmany rmdirmany noinst_PROGRAMS += openfilleddirunlink rename_many memhog iopentest1 iopentest2 -noinst_PROGRAMS += mmap_sanity +noinst_PROGRAMS += mmap_sanity writemany if MPITESTS noinst_PROGRAMS += write_append_truncate createmany_mpi endif diff --git a/lustre/tests/Makefile.mk b/lustre/tests/Makefile.mk index de01e97..7e9181e 100644 --- a/lustre/tests/Makefile.mk +++ b/lustre/tests/Makefile.mk @@ -11,7 +11,8 @@ host-progs := openunlink testreq truncate directio openme writeme \ stat createmany statmany multifstat createtest mlink \ opendirunlink opendevunlink unlinkmany fchdir_test \ checkstat wantedi statone runas openfile \ - mcreate mkdirmany utime o_directory small_write multiop + mcreate mkdirmany utime o_directory small_write multiop \ + writemany always := $(host-progs) @@ -50,3 +51,5 @@ utime-objs :=utime.o o_directory-objs :=o_directory.o small_write-objs :=small_write.o multiop-objs :=multiop.o +writemany-objs := writemany.o + diff --git a/lustre/tests/cfg/insanity-local.sh b/lustre/tests/cfg/insanity-local.sh index 2ca1485..f39bd8f 100644 --- a/lustre/tests/cfg/insanity-local.sh +++ b/lustre/tests/cfg/insanity-local.sh @@ -3,7 +3,7 @@ mdsfailover_HOST=${mdsfailover_HOST:-""} ost1_HOST=${ost1_HOST:-"`hostname`"} ost2_HOST=${ost2_HOST:-"`hostname`"} EXTRA_OSTS=${EXTRA_OSTS:-"`hostname`"} -client_HOST="'*'" +client_HOST=${client_HOST:-"'*'"} LIVE_CLIENT=${LIVE_CLIENT:-"`hostname`"} # This should always be a list, not a regexp FAIL_CLIENTS=${FAIL_CLIENTS:-""} diff --git a/lustre/tests/local.sh b/lustre/tests/local.sh index d97d094..5812c97 100755 --- a/lustre/tests/local.sh +++ b/lustre/tests/local.sh @@ -34,14 +34,20 @@ ${LMC} --add net --node localhost --nid `hostname` --nettype $NETTYPE || exit 1 ${LMC} --add net --node client --nid '*' --nettype $NETTYPE || exit 12 # configure mds server -${LMC} --add mds --nspath /mnt/mds_ns --node localhost --mds mds1 --fstype $FSTYPE --dev $MDSDEV --size $MDSSIZE $JARG $IARG || exit 20 +${LMC} --add mds --node localhost --mds mds1 --fstype $FSTYPE \ + --dev $MDSDEV --size $MDSSIZE $JARG $IARG $MDSOPT || exit 20 # configure ost -${LMC} -m $config --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 || exit 20 +${LMC} -m $config --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES \ + --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 $LOVOPT || exit 20 # only specify "--mkfsoptions='-i 8192'" here because test fs is so small, # on a real fs this is not needed unless all files tiny with many stripes -${LMC} --add ost --nspath /mnt/ost_ns --node localhost --lov lov1 --fstype $FSTYPE --dev $OSTDEV --size $OSTSIZE --mkfsoptions="-i 8192" $JARG || exit 30 +${LMC} --add ost --nspath /mnt/ost_ns --node localhost --lov lov1 \ + --fstype $FSTYPE --dev $OSTDEV --size $OSTSIZE \ + --mkfsoptions="-i 8192" $JARG $OSTOPT || exit 30 # create client config -${LMC} --add mtpt --node localhost --path $MOUNT --mds mds1 --lov lov1 || exit 40 -${LMC} --add mtpt --node client --path $MOUNT2 --mds mds1 --lov lov1 || exit 41 +${LMC} --add mtpt --node localhost --path $MOUNT --mds mds1 --lov lov1 \ + $CLIENTOPT || exit 40 +${LMC} --add mtpt --node client --path $MOUNT2 --mds mds1 --lov lov1 \ + $CLIENTOPT || exit 41 diff --git a/lustre/tests/lov.sh b/lustre/tests/lov.sh index 709de03..dd782c6 100755 --- a/lustre/tests/lov.sh +++ b/lustre/tests/lov.sh @@ -39,10 +39,12 @@ ${LMC} --add net --node localhost --nid `hostname` --nettype $NETTYPE || exit 1 ${LMC} --add net --node client --nid '*' --nettype $NETTYPE || exit 12 # configure mds server -${LMC} --format --add mds --node localhost --mds mds1 --fstype $FSTYPE --dev $MDSDEV --size $MDSSIZE || exit 20 +${LMC} --format --add mds --node localhost --mds mds1 --fstype $FSTYPE \ + --dev $MDSDEV --size $MDSSIZE $MDSOPT || exit 20 # configure ost -${LMC} --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 || exit 20 +${LMC} --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES \ + --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 $LOVOPT || exit 20 for num in `seq $OSTCOUNT`; do OST=ost$num @@ -50,14 +52,18 @@ for num in `seq $OSTCOUNT`; do eval $DEVPTR=${!DEVPTR:=$TMP/$OST-`hostname`} # only specify "--mkfsoptions='-i 8192'" here because test fs is so small, # on a real fs this is not needed unless all files tiny with many stripes - ${LMC} --add ost --node localhost --lov lov1 --ost $OST --fstype $FSTYPE --dev ${!DEVPTR} --size $OSTSIZE --mkfsoptions="-i 8192" $JARG || exit 30 + ${LMC} --add ost --node localhost --lov lov1 --ost $OST --fstype $FSTYPE \ + --dev ${!DEVPTR} --size $OSTSIZE --mkfsoptions="-i 8192" \ + $JARG $OSTOPT || exit 30 done if [ -z "$ECHO_CLIENT" ]; then # create client config - ${LMC} --add mtpt --node localhost --path $MOUNT --mds mds1 --lov lov1 || exit 40 - ${LMC} --add mtpt --node client --path $MOUNT2 --mds mds1 --lov lov1 || exit 41 + ${LMC} --add mtpt --node localhost --path $MOUNT --mds mds1 --lov lov1 \ + $CLIENTOPT || exit 40 + ${LMC} --add mtpt --node client --path $MOUNT2 --mds mds1 --lov lov1 \ + $CLIENTOPT || exit 41 else ${LMC} --add echo_client --node localhost --ost lov1 || exit 42 fi diff --git a/lustre/tests/recovery-small.sh b/lustre/tests/recovery-small.sh index 7412010..ba7084f 100755 --- a/lustre/tests/recovery-small.sh +++ b/lustre/tests/recovery-small.sh @@ -21,7 +21,7 @@ build_test_filter # setting SETUP=" " and CLEANUP=" " SETUP=${SETUP:-"setup"} CLEANUP=${CLEANUP:-"cleanup"} - +FORCE=${FORCE:-"--force"} make_config() { rm -f $XMLCONFIG @@ -246,7 +246,6 @@ test_17() { sysctl -w lustre.fail_loc=0x80000503 # need to write enough to ensure we send an RPC do_facet client dd if=/dev/zero of=$DIR/$tfile bs=1024k count=2 - sleep $TIMEOUT sysctl -w lustre.fail_loc=0 do_facet client "df $DIR" @@ -379,7 +378,7 @@ run_test 20b "ldlm_handle_enqueue error (should return error)" test_24() { # bug 2248 - eviction fails writeback but app doesn't see it mkdir -p $DIR/$tdir cancel_lru_locks OSC - multiop $DIR/$tdir/$tfile Owyw_yc & + multiop $DIR/$tdir/$tfile Owy_wyc & MULTI_PID=$! usleep 500 # OBD_FAIL_PTLRPC_BULK_PUT_NET|OBD_FAIL_ONCE @@ -391,4 +390,88 @@ test_24() { # bug 2248 - eviction fails writeback but app doesn't see it } run_test 24 "fsync error (should return error)" + +test_25a() { + mkdir -p $DIR/$tdir + # put a load of file creates/writes/deletes for 10 min. + do_facet client "writemany -q -a $DIR/$tdir/$tfile 600 5" & + CLIENT_PID=$! + echo writemany pid $CLIENT_PID + sleep 10 + FAILURE_MODE="SOFT" + fail mds + # wait for client to reconnect to MDS + sleep 60 + fail mds + sleep 60 + fail mds + # client process should see no problems even though MDS went down + wait $CLIENT_PID + rc=$? + echo writemany returned $rc + return $rc +} +run_test 25a "failover MDS under load" + +test_25b() { + mkdir -p $DIR/$tdir + # put a load of file creates/writes/deletes + do_facet client "writemany -q -a $DIR/$tdir/$tfile 300 5" & + CLIENT_PID=$! + echo writemany pid $CLIENT_PID + sleep 1 + FAILURE_MODE="SOFT" + facet_failover mds + # failover at various points during recovery + sleep 1 + facet_failover mds + sleep 5 + facet_failover mds + sleep 10 + facet_failover mds + sleep 20 + facet_failover mds + # client process should see no problems even though MDS went down + # and recovery was interrupted + wait $CLIENT_PID + rc=$? + echo writemany returned $rc + return $rc +} +run_test 25b "failover MDS during recovery" + +test_25c_guts() { + do_facet client "writemany -q $DIR/$tdir/$tfile 600 5" & + CLIENT_PID=$! + echo writemany pid $CLIENT_PID + sleep 10 + FAILURE_MODE="SOFT" + fail ost + rc=0 + wait $CLIENT_PID || rc=$? + # active client process should see an EIO for down OST + [ $rc -eq 5 ] && { echo "writemany correctly failed $rc" && return 0; } + # but timing or failover setup may allow success + [ $rc -eq 0 ] && { echo "writemany succeeded" && return 0; } + echo "writemany returned $rc" + return $rc +} + +test_25c() { + mkdir -p $DIR/$tdir + test_25c_guts + rc=$? + [ $rc -ne 0 ] && { return $rc; } + # wait for client to reconnect to OST + sleep 30 + test_25c_guts + rc=$? + [ $rc -ne 0 ] && { return $rc; } + sleep 30 + test_25c_guts + rc=$? + return $rc +} +run_test 25c "failover OST under load" + $CLEANUP diff --git a/lustre/tests/replay-dual.sh b/lustre/tests/replay-dual.sh index 742cc8c..9f6b778 100755 --- a/lustre/tests/replay-dual.sh +++ b/lustre/tests/replay-dual.sh @@ -11,6 +11,7 @@ init_test_env $@ SETUP=${SETUP:-"setup"} CLEANUP=${CLEANUP:-"cleanup"} +FORCE=${FORCE:-"--force"} gen_config() { rm -f $XMLCONFIG @@ -40,7 +41,7 @@ cleanup() { umount $MOUNT2 || true umount $MOUNT || true - rmmod llite + rmmod llite || true stop mds ${FORCE} stop ost2 ${FORCE} stop ost ${FORCE} --dump $TMP/replay-dual-`hostname`.log diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 02e1214..9044078 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -8,7 +8,7 @@ set -e ONLY=${ONLY:-"$*"} # bug number for skipped test: 2108 3637 3561 5188/5749 -ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"42a 42c 45 68"} +ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"42a 42c 45 68"} # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT! [ "$ALWAYS_EXCEPT$EXCEPT" ] && \ @@ -54,7 +54,7 @@ SAVE_PWD=$PWD clean() { echo -n "cln.." - sh llmountcleanup.sh > /dev/null || exit 20 + sh llmountcleanup.sh ${FORCE} > /dev/null || exit 20 I_MOUNTED=no } CLEAN=${CLEAN:-:} @@ -1782,8 +1782,8 @@ test_48e() { # bug 4134 $TRACE rmdir $DIR/d48e || error "remove parent $DIR/d48e failed" $TRACE touch $DIR/d48e || error "'touch $DIR/d48e' failed" $TRACE chmod +x $DIR/d48e || error "'chmod +x $DIR/d48e' failed" - $TRACE wait $cdpid && error "'cd ..' worked after recreate parent" - $TRACE rm $DIR/d48e || error "'$DIR/d48e' failed" + $TRACE wait $cdpid && echo "'cd ..' worked after recreate parent" + $TRACE rm $DIR/d48e || error "rm '$DIR/d48e' failed" } run_test 48e "Access to recreated parent subdir (should return errors)" diff --git a/lustre/tests/sanityN.sh b/lustre/tests/sanityN.sh index d2135ca..94e2ebc 100644 --- a/lustre/tests/sanityN.sh +++ b/lustre/tests/sanityN.sh @@ -37,7 +37,7 @@ SAVE_PWD=$PWD clean() { echo -n "cln.." - sh llmountcleanup.sh > /dev/null || exit 20 + sh llmountcleanup.sh ${FORCE} > /dev/null || exit 20 } CLEAN=${CLEAN:-} diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index 3551c27..a0f8c9b 100644 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -90,11 +90,14 @@ zconf_mount() { do_node $client mkdir $mnt 2> /dev/null || : if [ -x /sbin/mount.lustre ] ; then - do_node $client mount -t lustre -o nettype=$NETTYPE `facet_active_host mds`:/mds_svc/client_facet $mnt || return 1 + do_node $client mount -t lustre -o nettype=$NETTYPE,$MOUNTOPT \ + `facet_active_host mds`:/mds_svc/client_facet $mnt || return 1 else - # this is so cheating - do_node $client $LCONF --nosetup --node client_facet $XMLCONFIG > /dev/null || return 2 - do_node $client $LLMOUNT -o nettype=$NETTYPE `facet_active_host mds`:/mds_svc/client_facet $mnt || return 4 + # this is so cheating + do_node $client $LCONF --nosetup --node client_facet $XMLCONFIG > \ + /dev/null || return 2 + do_node $client $LLMOUNT -o nettype=$NETTYPE,$MOUNTOPT \ + `facet_active_host mds`:/mds_svc/client_facet $mnt || return 4 fi [ -d /r ] && $LCTL modules > /r/tmp/ogdb-`hostname` @@ -123,6 +126,8 @@ reboot_facet() { facet=$1 if [ "$FAILURE_MODE" = HARD ]; then $POWER_UP `facet_active_host $facet` + else + sleep 10 fi } @@ -322,14 +327,16 @@ add_mds() { shift rm -f ${facet}active add_facet $facet - do_lmc --add mds --node ${facet}_facet --mds ${facet}_svc --fstype $FSTYPE $* + do_lmc --add mds --node ${facet}_facet --mds ${facet}_svc \ + --fstype $FSTYPE $* $MDSOPT } add_mdsfailover() { facet=$1 shift add_facet ${facet}failover --lustre_upcall $UPCALL - do_lmc --add mds --node ${facet}failover_facet --mds ${facet}_svc --fstype $FSTYPE $* + do_lmc --add mds --node ${facet}failover_facet --mds ${facet}_svc \ + --fstype $FSTYPE $* $MDSOPT } add_ost() { @@ -337,22 +344,23 @@ add_ost() { shift rm -f ${facet}active add_facet $facet - do_lmc --add ost --node ${facet}_facet --ost ${facet}_svc --fstype $FSTYPE $* + do_lmc --add ost --node ${facet}_facet --ost ${facet}_svc \ + --fstype $FSTYPE $* $OSTOPT } add_ostfailover() { facet=$1 shift add_facet ${facet}failover - do_lmc --add ost --failover --node ${facet}failover_facet --ost ${facet}_svc --fstype $FSTYPE $* + do_lmc --add ost --failover --node ${facet}failover_facet \ + --ost ${facet}_svc --fstype $FSTYPE $* $OSTOPT } add_lov() { lov=$1 mds_facet=$2 shift; shift - do_lmc --add lov --mds ${mds_facet}_svc --lov $lov $* - + do_lmc --add lov --mds ${mds_facet}_svc --lov $lov $* $LOVOPT } add_client() { @@ -360,8 +368,7 @@ add_client() { mds=$2 shift; shift add_facet $facet --lustre_upcall $UPCALL - do_lmc --add mtpt --node ${facet}_facet --mds ${mds}_svc $* - + do_lmc --add mtpt --node ${facet}_facet --mds ${mds}_svc $* $CLIENTOPT } diff --git a/lustre/tests/uml.sh b/lustre/tests/uml.sh index fbdd284..7ec18ae 100644 --- a/lustre/tests/uml.sh +++ b/lustre/tests/uml.sh @@ -86,10 +86,12 @@ done # configure mds server echo; echo "adding MDS on: $MDSNODE" -${LMC} -m $config --add mds --format --node $MDSNODE --mds mds1 --fstype $FSTYPE --dev $MDSDEV --size $MDSSIZE ||exit 10 +${LMC} -m $config --add mds --node $MDSNODE --mds mds1 --fstype $FSTYPE \ + --dev $MDSDEV --size $MDSSIZE $MDSOPT || exit 10 # configure ost -${LMC} -m $config --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES --stripe_cnt $STRIPECNT --stripe_pattern 0 || exit 20 +${LMC} -m $config --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES \ + --stripe_cnt $STRIPECNT --stripe_pattern 0 $LOVOPT || exit 20 COUNT=1 echo -n "adding OST on:" for NODE in $OSTNODES; do @@ -104,7 +106,8 @@ for NODE in $OSTNODES; do OSTARGS="--osdtype=obdecho" ;; esac - ${LMC} -m $config --add ost --node $NODE --lov lov1 $OSTARGS $OSTFAILOVER || exit 21 + ${LMC} -m $config --add ost --node $NODE --lov lov1 $OSTARGS \ + $OSTFAILOVER $OSTOPT || exit 21 COUNT=`expr $COUNT + 1` done @@ -112,6 +115,7 @@ done echo; echo -n "adding CLIENT on:" for NODE in $CLIENTS; do echo -n " $NODE" - ${LMC} -m $config --add mtpt --node $NODE --path $MOUNT --mds mds1 --lov lov1 || exit 30 + ${LMC} -m $config --add mtpt --node $NODE --path $MOUNT --mds mds1 \ + --lov lov1 $CLIENTOPT || exit 30 done echo diff --git a/lustre/tests/writemany.c b/lustre/tests/writemany.c new file mode 100644 index 0000000..5d4e42e --- /dev/null +++ b/lustre/tests/writemany.c @@ -0,0 +1,250 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define difftime(a, b) \ + ((double)(a)->tv_sec - (b)->tv_sec + \ + ((double)((a)->tv_usec - (b)->tv_usec) / 1000000)) + + + +char cmdname[512]; +int o_abort = 0; +int o_quiet = 0; + +struct kid_list_t { + pid_t kid; + struct kid_list_t *next; +}; + +struct kid_list_t *head = NULL; + +void push_kid(pid_t kid) +{ + struct kid_list_t *new; + new = (struct kid_list_t *)malloc(sizeof(struct kid_list_t)); + new->kid = kid; + new->next = head; + head = new; +} + +void kill_kids(void) +{ + while(head) { + kill(head->kid, SIGTERM); + head = head->next; + } +} + +int wait_for_threads(int live_threads) +{ + int rc = 0; + + while (live_threads > 0) { + int status; + pid_t ret; + + ret = waitpid(0, &status, 0); + if (ret == 0) { + continue; + } + + if (ret < 0) { + fprintf(stderr, "%s: error: wait - %s\n", + cmdname, strerror(errno)); + if (!rc) + rc = errno; + } else { + /* + * This is a hack. We _should_ be able to use + * WIFEXITED(status) to see if there was an + * error, but it appears to be broken and it + * always returns 1 (OK). See wait(2). + */ + int err = WEXITSTATUS(status); + if (err || WIFSIGNALED(status)) + fprintf(stderr, + "%s: error: PID %d had rc=%d\n", + cmdname, ret, err); + /* Record first error */ + if (!rc) + rc = err; + + /* Give up on first error */ + if (rc && o_abort) { + kill_kids(); + break; + } + + live_threads--; + } + } + if (!o_quiet) + printf("%s done, rc = %d\n", cmdname, rc); + return rc; +} + +void print_err(char *op, char *filename, struct timeval *time, int err) +{ + fprintf(stderr, "%s: %d.%.06d error: %s(%s): %s\n", + cmdname, (int)(time->tv_sec), (int)(time->tv_usec), op, + filename, strerror(errno)); +} + +int run_one_child(char *file, int thread, int seconds) +{ + struct timeval start, cur; + double diff; + char filename[1024]; + char buf[1024]; + int fd, rc = 0, rand, maxrand, len; + long nfiles = 0, nbytes = 0; + + if (!o_quiet) + printf("%s: running thread #%d\n", cmdname, thread); + + srandom(thread); + /* Higher thread numbers will produce bigger random files. + Thread 1 will produce only 0-len files. */ + maxrand = 1; rand = thread; + while (--rand) + maxrand *= 10; + + gettimeofday(&start, NULL); + + while(!rc) { + gettimeofday(&cur, NULL); + if (cur.tv_sec > (start.tv_sec + seconds)) + break; + + sprintf(filename, "%s-%d-%ld", file, thread, nfiles); + + fd = open(filename, O_RDWR | O_CREAT, 0666); + if (fd < 0) { + print_err("open", filename, &cur, errno); + rc = errno; + break; + } + + sprintf(buf, "%s %010ld %.19s.%012d\n", cmdname, + nfiles++, ctime(&cur.tv_sec), (int)cur.tv_usec); + len = strlen(buf); + + rand = random() % maxrand; + while (rand-- > 0) { + if (write(fd, buf, len) != len) { + print_err("write", filename, &cur, errno); + rc = errno; + break; + } + nbytes += len; + } + + if (close(fd) < 0) { + print_err("close", filename, &cur, errno); + rc = errno; + break; + } + if (unlink(filename) < 0) { + print_err("unlink", filename, &cur, errno); + rc = errno; + break; + } + } + + diff = difftime(&cur, &start); + if (!o_quiet) + printf("%s: %7ld files, %4ld MB in %.2fs (%7.2f files/s, " + "%5.2f MB/s): rc = %d\n", + cmdname, nfiles, nbytes >> 20, diff, + (double)nfiles / diff, (double)nbytes/1024/1024 / diff, + rc); + + return rc; +} + +void usage(char *name) +{ + fprintf(stderr, + "usage: %s [opts] \n", + name); + fprintf(stderr, " -q quiet\n"); + fprintf(stderr, " -a abort other children on first err\n"); + exit(1); +} + +int main(int argc, char *argv[]) +{ + unsigned long duration; + int threads = 0; + char *end; + char *directory; + int i = 1, rc = 0; + + sprintf(cmdname, "%s", argv[0]); + + while((i < argc) && (argv[i][0] == '-')) { + switch (argv[i][1]) { + case 'q': + o_quiet++; + break; + case 'a': + o_abort++; + break; + } + i++; + } + + if ((argc - i) < 3) + usage(argv[0]); + + directory = argv[i]; + duration = strtoul(argv[++i], &end, 0); + if (*end) { + fprintf(stderr, "%s: error: bad number of seconds '%s'\n", + cmdname, argv[i]); + exit(2); + } + + threads = strtoul(argv[++i], &end, 0); + if (*end) { + fprintf(stderr, "%s: error: bad thread count '%s'\n", + cmdname, argv[i]); + exit(2); + } + + for (i = 1; i <= threads; i++) { + rc = fork(); + if (rc < 0) { + if (!o_quiet) + fprintf(stderr, "%s: error: #%d - %s\n", + cmdname, i, strerror(rc = errno)); + return (rc); + } + if (rc == 0) { + /* children */ + sprintf(cmdname, "%s-%d", argv[0], i); + return (run_one_child(directory, i, duration)); + } else { + /* parent */ + push_kid(rc); + } + } + /* parent process */ + if (!o_quiet) + printf("%s will run for %ld minutes\n", cmdname, duration/60); + return (wait_for_threads(threads)); +} diff --git a/lustre/utils/lconf b/lustre/utils/lconf index a823c2f..1777fd0 100755 --- a/lustre/utils/lconf +++ b/lustre/utils/lconf @@ -1725,17 +1725,19 @@ class MDSDEV(Module): Module.cleanup(self) clean_loop(self.devpath) - def msd_remaining(self): + def mds_remaining(self): out = lctl.device_list() for s in out: if string.split(s)[2] in ('mds',): + if string.split(s)[1] in ('ST',): + return 0 return 1 def safe_to_clean(self): return self.active def safe_to_clean_modules(self): - return not self.msd_remaining() + return not self.mds_remaining() def cleanup(self): if not self.active: @@ -1751,7 +1753,7 @@ class MDSDEV(Module): e.dump() cleanup_error(e.rc) Module.cleanup(self) - if not self.msd_remaining() and is_prepared('MDT'): + if not self.mds_remaining() and is_prepared('MDT'): try: lctl.cleanup("MDT", "MDT_UUID", config.force, config.failover) -- 1.8.3.1