From b1fbe0023f80f6109cdd61b525bbe06943ce7f1b Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Mon, 23 Dec 2002 23:59:07 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'unlabeled-1.1.2.1.2'. --- lustre/cobd/.cvsignore | 3 - lustre/cobd/Makefile.am | 15 - lustre/cobd/cache_obd.c | 330 -- lustre/cobd/lproc_cache.c | 100 - lustre/extN/.cvsignore | 11 - lustre/extN/extN-2.4.18-exports.diff | 11 - lustre/extN/extN-2.4.18-ino_sb_fixup.diff | 33 - lustre/extN/extN-misc-fixup.diff | 15 - lustre/extN/htree-ext3-2.4.18.diff | 1213 ------- lustre/extN/linux-2.4.18ea-0.8.26.diff | 1875 ----------- lustre/include/linux/lustre_debug.h | 51 - lustre/include/linux/lustre_fsfilt.h | 151 - lustre/include/linux/obd_cache.h | 13 - lustre/include/linux/obd_lov.h | 26 - lustre/kernel_patches/lustre-2.5-from809-812.patch | 3374 -------------------- lustre/kernel_patches/lustre-2.5-from811-812.patch | 189 -- lustre/kernel_patches/patches/lin-2.5.44.patch | 3374 -------------------- lustre/kernel_patches/patches/lustre-2.5.patch | 552 ---- .../patches/uml_check_get_page.patch | 31 - lustre/kernel_patches/patches/uml_no_panic.patch | 31 - lustre/kernel_patches/pc/lin-2.5.44.pc | 30 - .../pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc | 23 - lustre/kernel_patches/pc/vanilla-2.4.18.pc | 23 - lustre/kernel_patches/pc/vanilla-2.4.19.pc | 23 - lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc | 8 - lustre/kernel_patches/pc/vfs_intent.pc | 8 - lustre/kernel_patches/prepare_tree.sh | 88 - lustre/kernel_patches/scripts/apatch | 98 - lustre/kernel_patches/scripts/patchfns | 239 -- lustre/kernel_patches/scripts/poppatch | 70 - lustre/kernel_patches/scripts/pushpatch | 84 - lustre/kernel_patches/scripts/refpatch | 31 - lustre/kernel_patches/scripts/rpatch | 69 - lustre/kernel_patches/series/chaos | 5 - lustre/kernel_patches/series/hp-pnnl | 1 - lustre/kernel_patches/series/lin-2.5.44 | 1 - lustre/kernel_patches/series/rh-2.4.18-18 | 8 - lustre/kernel_patches/series/vanilla-2.4.18 | 1 - lustre/kernel_patches/series/vanilla-2.4.19 | 1 - lustre/kernel_patches/txt/lin-2.5.44.txt | 3 - lustre/kernel_patches/txt/vfs_intent.txt | 3 - lustre/kernel_patches/which_patch | 5 - lustre/lib/debug.c | 89 - lustre/lib/ll_pack.c | 59 - lustre/lib/lov_pack.c | 44 - lustre/llite/dcache.c | 52 - lustre/llite/iod.c | 502 --- lustre/llite/lproc_llite.c | 176 - lustre/llite/recover.c | 44 - lustre/lov/lov_pack.c | 176 - lustre/lov/lproc_lov.c | 211 -- lustre/mdc/lproc_mdc.c | 128 - lustre/mds/lproc_mds.c | 187 -- lustre/mds/mds_fs.c | 463 --- lustre/obdclass/fsfilt.c | 110 - lustre/obdclass/fsfilt_ext3.c | 327 -- lustre/obdclass/fsfilt_extN.c | 449 --- lustre/obdclass/lprocfs_status.c | 360 --- lustre/obdecho/echo_client.c | 262 -- lustre/obdecho/lproc_echo.c | 67 - lustre/obdfilter/lproc_obdfilter.c | 151 - lustre/osc/lproc_osc.c | 126 - lustre/ost/lproc_ost.c | 174 - lustre/patches/patch-2.4.18-chaos11 | 1498 --------- lustre/patches/patch-2.4.18-hp1_pnnl18.2.8qsnet | 1673 ---------- lustre/patches/patch-2.4.9-chaos14 | 331 -- lustre/ptlrpc/connmgr.c | 155 - lustre/ptlrpc/lproc_ptlrpc.c | 53 - lustre/scripts/lustre | 70 - lustre/scripts/nodelustre | 46 - lustre/scripts/version_tag.pl | 105 - lustre/tests/ba-echo.sh | 39 - lustre/tests/ba-mount.sh | 54 - lustre/tests/checkstat.c | 314 -- lustre/tests/client-mount.cfg | 6 - lustre/tests/cobd.sh | 41 - lustre/tests/createmany.c | 38 - lustre/tests/directio.c | 62 - lustre/tests/elan-client.cfg | 10 - lustre/tests/elan-server.cfg | 5 - lustre/tests/llcleanup.sh | 16 - lustre/tests/llmount2-hack.sh | 21 - lustre/tests/llmount2-hackcleanup.sh | 21 - lustre/tests/llmountcleanup2-hack.sh | 25 - lustre/tests/llrsetup.sh | 12 - lustre/tests/llsetup.sh | 12 - lustre/tests/local2-hack.xml | 43 - lustre/tests/mds-failover.xml | 90 - lustre/tests/mds.cfg | 6 - lustre/tests/mkdirmany.c | 38 - lustre/tests/mount2.sh | 35 - lustre/tests/mount2fs.sh | 43 - lustre/tests/multifstat.c | 62 - lustre/tests/net-client.cfg | 11 - lustre/tests/net-local.cfg | 6 - lustre/tests/net-server.cfg | 6 - lustre/tests/openunlink.c | 122 - lustre/tests/runfailure-client-mds-recover.sh | 21 - lustre/tests/runregression-net.sh | 59 - lustre/tests/sanity.sh | 132 - lustre/tests/sanityN.sh | 63 - lustre/tests/stat.c | 24 - lustre/tests/writeme.c | 32 - lustre/utils/automatic-reconnect-sample | 34 - lustre/utils/genXml | 271 -- lustre/utils/ha_assist.sh | 13 - lustre/utils/ha_assist2 | 150 - lustre/utils/lconf.in | 1796 ----------- lustre/utils/llparser.pm | 153 - lustre/utils/lstripe.c | 101 - lustre/utils/lustre.dtd | 71 - lustre/utils/lustreLdap.py | 1785 ----------- lustre/utils/lutils.py | 2643 --------------- 113 files changed, 28794 deletions(-) delete mode 100644 lustre/cobd/.cvsignore delete mode 100644 lustre/cobd/Makefile.am delete mode 100644 lustre/cobd/cache_obd.c delete mode 100644 lustre/cobd/lproc_cache.c delete mode 100644 lustre/extN/.cvsignore delete mode 100644 lustre/extN/extN-2.4.18-exports.diff delete mode 100644 lustre/extN/extN-2.4.18-ino_sb_fixup.diff delete mode 100644 lustre/extN/extN-misc-fixup.diff delete mode 100644 lustre/extN/htree-ext3-2.4.18.diff delete mode 100644 lustre/extN/linux-2.4.18ea-0.8.26.diff delete mode 100644 lustre/include/linux/lustre_debug.h delete mode 100644 lustre/include/linux/lustre_fsfilt.h delete mode 100644 lustre/include/linux/obd_cache.h delete mode 100644 lustre/include/linux/obd_lov.h delete mode 100644 lustre/kernel_patches/lustre-2.5-from809-812.patch delete mode 100644 lustre/kernel_patches/lustre-2.5-from811-812.patch delete mode 100644 lustre/kernel_patches/patches/lin-2.5.44.patch delete mode 100644 lustre/kernel_patches/patches/lustre-2.5.patch delete mode 100644 lustre/kernel_patches/patches/uml_check_get_page.patch delete mode 100644 lustre/kernel_patches/patches/uml_no_panic.patch delete mode 100644 lustre/kernel_patches/pc/lin-2.5.44.pc delete mode 100644 lustre/kernel_patches/pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc delete mode 100644 lustre/kernel_patches/pc/vanilla-2.4.18.pc delete mode 100644 lustre/kernel_patches/pc/vanilla-2.4.19.pc delete mode 100644 lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc delete mode 100644 lustre/kernel_patches/pc/vfs_intent.pc delete mode 100755 lustre/kernel_patches/prepare_tree.sh delete mode 100755 lustre/kernel_patches/scripts/apatch delete mode 100644 lustre/kernel_patches/scripts/patchfns delete mode 100755 lustre/kernel_patches/scripts/poppatch delete mode 100755 lustre/kernel_patches/scripts/pushpatch delete mode 100755 lustre/kernel_patches/scripts/refpatch delete mode 100755 lustre/kernel_patches/scripts/rpatch delete mode 100644 lustre/kernel_patches/series/chaos delete mode 100644 lustre/kernel_patches/series/hp-pnnl delete mode 100644 lustre/kernel_patches/series/lin-2.5.44 delete mode 100644 lustre/kernel_patches/series/rh-2.4.18-18 delete mode 100644 lustre/kernel_patches/series/vanilla-2.4.18 delete mode 100644 lustre/kernel_patches/series/vanilla-2.4.19 delete mode 100644 lustre/kernel_patches/txt/lin-2.5.44.txt delete mode 100644 lustre/kernel_patches/txt/vfs_intent.txt delete mode 100644 lustre/kernel_patches/which_patch delete mode 100644 lustre/lib/debug.c delete mode 100644 lustre/lib/ll_pack.c delete mode 100644 lustre/lib/lov_pack.c delete mode 100644 lustre/llite/dcache.c delete mode 100644 lustre/llite/iod.c delete mode 100644 lustre/llite/lproc_llite.c delete mode 100644 lustre/llite/recover.c delete mode 100644 lustre/lov/lov_pack.c delete mode 100644 lustre/lov/lproc_lov.c delete mode 100644 lustre/mdc/lproc_mdc.c delete mode 100644 lustre/mds/lproc_mds.c delete mode 100644 lustre/mds/mds_fs.c delete mode 100644 lustre/obdclass/fsfilt.c delete mode 100644 lustre/obdclass/fsfilt_ext3.c delete mode 100644 lustre/obdclass/fsfilt_extN.c delete mode 100644 lustre/obdclass/lprocfs_status.c delete mode 100644 lustre/obdecho/echo_client.c delete mode 100644 lustre/obdecho/lproc_echo.c delete mode 100644 lustre/obdfilter/lproc_obdfilter.c delete mode 100644 lustre/osc/lproc_osc.c delete mode 100644 lustre/ost/lproc_ost.c delete mode 100644 lustre/patches/patch-2.4.18-chaos11 delete mode 100644 lustre/patches/patch-2.4.18-hp1_pnnl18.2.8qsnet delete mode 100644 lustre/patches/patch-2.4.9-chaos14 delete mode 100644 lustre/ptlrpc/connmgr.c delete mode 100644 lustre/ptlrpc/lproc_ptlrpc.c delete mode 100755 lustre/scripts/lustre delete mode 100755 lustre/scripts/nodelustre delete mode 100644 lustre/scripts/version_tag.pl delete mode 100644 lustre/tests/ba-echo.sh delete mode 100644 lustre/tests/ba-mount.sh delete mode 100644 lustre/tests/checkstat.c delete mode 100644 lustre/tests/client-mount.cfg delete mode 100755 lustre/tests/cobd.sh delete mode 100644 lustre/tests/createmany.c delete mode 100644 lustre/tests/directio.c delete mode 100644 lustre/tests/elan-client.cfg delete mode 100644 lustre/tests/elan-server.cfg delete mode 100755 lustre/tests/llcleanup.sh delete mode 100644 lustre/tests/llmount2-hack.sh delete mode 100644 lustre/tests/llmount2-hackcleanup.sh delete mode 100644 lustre/tests/llmountcleanup2-hack.sh delete mode 100644 lustre/tests/llrsetup.sh delete mode 100644 lustre/tests/llsetup.sh delete mode 100644 lustre/tests/local2-hack.xml delete mode 100644 lustre/tests/mds-failover.xml delete mode 100644 lustre/tests/mds.cfg delete mode 100755 lustre/tests/mkdirmany.c delete mode 100644 lustre/tests/mount2.sh delete mode 100644 lustre/tests/mount2fs.sh delete mode 100644 lustre/tests/multifstat.c delete mode 100644 lustre/tests/net-client.cfg delete mode 100644 lustre/tests/net-local.cfg delete mode 100644 lustre/tests/net-server.cfg delete mode 100644 lustre/tests/openunlink.c delete mode 100755 lustre/tests/runfailure-client-mds-recover.sh delete mode 100644 lustre/tests/runregression-net.sh delete mode 100644 lustre/tests/sanity.sh delete mode 100644 lustre/tests/sanityN.sh delete mode 100644 lustre/tests/stat.c delete mode 100644 lustre/tests/writeme.c delete mode 100755 lustre/utils/automatic-reconnect-sample delete mode 100755 lustre/utils/genXml delete mode 100755 lustre/utils/ha_assist.sh delete mode 100755 lustre/utils/ha_assist2 delete mode 100755 lustre/utils/lconf.in delete mode 100644 lustre/utils/llparser.pm delete mode 100644 lustre/utils/lstripe.c delete mode 100644 lustre/utils/lustre.dtd delete mode 100755 lustre/utils/lustreLdap.py delete mode 100644 lustre/utils/lutils.py diff --git a/lustre/cobd/.cvsignore b/lustre/cobd/.cvsignore deleted file mode 100644 index e995588..0000000 --- a/lustre/cobd/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.deps -Makefile -Makefile.in diff --git a/lustre/cobd/Makefile.am b/lustre/cobd/Makefile.am deleted file mode 100644 index 781c6ce..0000000 --- a/lustre/cobd/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2002 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= - -MODULE = cobd -modulefs_DATA = cobd.o -EXTRA_PROGRAMS = cobd -LINX= - -cobd_SOURCES = cache_obd.c lproc_cache.c $(LINX) - -include $(top_srcdir)/Rules diff --git a/lustre/cobd/cache_obd.c b/lustre/cobd/cache_obd.c deleted file mode 100644 index 721b01d..0000000 --- a/lustre/cobd/cache_obd.c +++ /dev/null @@ -1,330 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2001, 2002 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ - -#define DEBUG_SUBSYSTEM S_COBD - -#include -#include -#include -#include -#include -#include - -extern struct lprocfs_vars status_var_nm_1[]; -extern struct lprocfs_vars status_class_var[]; - -static int -cobd_attach (struct obd_device *dev, obd_count len, void *data) -{ - return (lprocfs_reg_obd (dev, status_var_nm_1, dev)); -} - -static int -cobd_detach (struct obd_device *dev) -{ - return (lprocfs_dereg_obd (dev)); -} - -static int -cobd_setup (struct obd_device *dev, obd_count len, void *buf) -{ - struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf; - struct cache_obd *cobd = &dev->u.cobd; - struct obd_device *target; - struct obd_device *cache; - int rc; - - if (data->ioc_inlbuf1 == NULL || - data->ioc_inlbuf2 == NULL) - return (-EINVAL); - - target = class_uuid2obd (data->ioc_inlbuf1); - cache = class_uuid2obd (data->ioc_inlbuf2); - if (target == NULL || - cache == NULL) - return (-EINVAL); - - /* don't bother checking attached/setup; - * obd_connect() should, and it can change underneath us */ - - rc = obd_connect (&cobd->cobd_target, target, NULL, NULL, NULL); - if (rc != 0) - return (rc); - - rc = obd_connect (&cobd->cobd_cache, cache, NULL, NULL, NULL); - if (rc != 0) - goto fail_0; - - MOD_INC_USE_COUNT; - return (0); - - fail_0: - obd_disconnect (&cobd->cobd_target); - return (rc); -} - -static int -cobd_cleanup (struct obd_device *dev) -{ - struct cache_obd *cobd = &dev->u.cobd; - int rc; - - if (!list_empty (&dev->obd_exports)) - return (-EBUSY); - - rc = obd_disconnect (&cobd->cobd_cache); - if (rc != 0) - CERROR ("error %d disconnecting cache\n", rc); - - rc = obd_disconnect (&cobd->cobd_target); - if (rc != 0) - CERROR ("error %d disconnecting target\n", rc); - - MOD_DEC_USE_COUNT; - return (0); -} - -static int -cobd_connect (struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - int rc = class_connect (conn, obd, cluuid); - - CERROR ("rc %d\n", rc); - return (rc); -} - -static int -cobd_disconnect (struct lustre_handle *conn) -{ - int rc = class_disconnect (conn); - - CERROR ("rc %d\n", rc); - return (rc); -} - -static int -cobd_get_info(struct lustre_handle *conn, obd_count keylen, - void *key, obd_count *vallen, void **val) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - cobd = &obd->u.cobd; - - /* intercept cache utilisation info? */ - - return (obd_get_info (&cobd->cobd_target, - keylen, key, vallen, val)); -} - -static int -cobd_statfs(struct lustre_handle *conn, struct obd_statfs *osfs) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - cobd = &obd->u.cobd; - return (obd_statfs (&cobd->cobd_target, osfs)); -} - -static int -cobd_getattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - cobd = &obd->u.cobd; - return (obd_getattr (&cobd->cobd_target, oa, lsm)); -} - -static int -cobd_open(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - cobd = &obd->u.cobd; - return (obd_open (&cobd->cobd_target, oa, lsm)); -} - -static int -cobd_close(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - cobd = &obd->u.cobd; - return (obd_close (&cobd->cobd_target, oa, lsm)); -} - -static int -cobd_preprw(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_remote *nb, - struct niobuf_local *res, void **desc_private) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - if ((cmd & OBD_BRW_WRITE) != 0) - return -EOPNOTSUPP; - - cobd = &obd->u.cobd; - return (obd_preprw (cmd, &cobd->cobd_target, - objcount, obj, - niocount, nb, - res, desc_private)); -} - -static int -cobd_commitrw(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_local *local, - void *desc_private) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - if ((cmd & OBD_BRW_WRITE) != 0) - return -EOPNOTSUPP; - - cobd = &obd->u.cobd; - return (obd_commitrw (cmd, &cobd->cobd_target, - objcount, obj, - niocount, local, - desc_private)); -} - -static inline int -cobd_brw(int cmd, struct lustre_handle *conn, - struct lov_stripe_md *lsm, obd_count oa_bufs, - struct brw_page *pga, struct obd_brw_set *set) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - if ((cmd & OBD_BRW_WRITE) != 0) - return -EOPNOTSUPP; - - cobd = &obd->u.cobd; - return (obd_brw (cmd, &cobd->cobd_target, - lsm, oa_bufs, pga, set)); -} - -static int -cobd_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len, - void *karg, void *uarg) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - /* intercept? */ - - cobd = &obd->u.cobd; - return (obd_iocontrol (cmd, &cobd->cobd_target, len, karg, uarg)); -} - -static struct obd_ops cobd_ops = { - o_attach: cobd_attach, - o_detach: cobd_detach, - - o_setup: cobd_setup, - o_cleanup: cobd_cleanup, - - o_connect: cobd_connect, - o_disconnect: cobd_disconnect, - - o_get_info: cobd_get_info, - o_statfs: cobd_statfs, - - o_getattr: cobd_getattr, - o_open: cobd_open, - o_close: cobd_close, - o_preprw: cobd_preprw, - o_commitrw: cobd_commitrw, - o_brw: cobd_brw, - o_iocontrol: cobd_iocontrol, -}; - -static int __init -cobd_init (void) -{ - int rc; - - printk (KERN_INFO "Lustre Caching OBD driver\n"); - - rc = class_register_type (&cobd_ops, status_class_var, - OBD_CACHE_DEVICENAME); - return (rc); -} - -static void __exit -cobd_exit (void) -{ - class_unregister_type (OBD_CACHE_DEVICENAME); -} - -MODULE_AUTHOR("Cluster Filesystems Inc. "); -MODULE_DESCRIPTION("Lustre Caching OBD driver"); -MODULE_LICENSE("GPL"); - -module_init(cobd_init); -module_exit(cobd_exit); - - diff --git a/lustre/cobd/lproc_cache.c b/lustre/cobd/lproc_cache.c deleted file mode 100644 index b20eff4..0000000 --- a/lustre/cobd/lproc_cache.c +++ /dev/null @@ -1,100 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#include - -/* - * Common STATUS namespace - */ - -static int -rd_uuid (char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device* dev = (struct obd_device*)data; - - return (snprintf(page, count, "%s\n", dev->obd_uuid)); -} - -static int -rd_target (char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device *dev = (struct obd_device*)data; - struct cache_obd *cobd = &dev->u.cobd; - struct lustre_handle *conn = &cobd->cobd_target; - struct obd_export *exp; - int rc; - - if ((dev->obd_flags & OBD_SET_UP) == 0) - rc = snprintf (page, count, "not set up\n"); - else { - exp = class_conn2export (conn); - LASSERT (exp != NULL); - rc = snprintf(page, count, "%s\n", exp->exp_obd->obd_uuid); - } - return (rc); -} - -static int -rd_cache (char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device *dev = (struct obd_device*)data; - struct cache_obd *cobd = &dev->u.cobd; - struct lustre_handle *conn = &cobd->cobd_cache; - struct obd_export *exp; - int rc; - - if ((dev->obd_flags & OBD_SET_UP) == 0) - rc = snprintf (page, count, "not set up\n"); - else { - exp = class_conn2export (conn); - LASSERT (exp != NULL); - rc = snprintf(page, count, "%s\n", exp->exp_obd->obd_uuid); - } - return (rc); -} - -struct lprocfs_vars status_var_nm_1[] = { - {"status/uuid", rd_uuid, 0, 0}, - {"status/target_uuid", rd_target, 0, 0}, - {"status/cache_uuid", rd_cache, 0, 0}, - - {0} -}; - -int -rd_numrefs (char* page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_type* class = (struct obd_type*)data; - - return (snprintf(page, count, "%d\n", class->typ_refcnt)); -} - -struct lprocfs_vars status_class_var[] = { - {"status/num_refs", rd_numrefs, 0, 0}, - {0} -}; diff --git a/lustre/extN/.cvsignore b/lustre/extN/.cvsignore deleted file mode 100644 index 86f28a0..0000000 --- a/lustre/extN/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -balloc.c -bitmap.c -dir.c -file.c -fsync.c -ialloc.c -inode.c -ioctl.c -namei.c -super.c -symlink.c diff --git a/lustre/extN/extN-2.4.18-exports.diff b/lustre/extN/extN-2.4.18-exports.diff deleted file mode 100644 index 8780209..0000000 --- a/lustre/extN/extN-2.4.18-exports.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- linux-2.4.17/fs/extN/super.c.orig Fri Dec 21 10:41:55 2001 -+++ linux-2.4.17/fs/extN/super.c Fri Mar 22 11:00:41 2002 -@@ -1742,7 +1742,7 @@ - unregister_filesystem(&extN_fs_type); - } - --EXPORT_NO_SYMBOLS; -+EXPORT_SYMBOL(extN_bread); - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); - MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); diff --git a/lustre/extN/extN-2.4.18-ino_sb_fixup.diff b/lustre/extN/extN-2.4.18-ino_sb_fixup.diff deleted file mode 100644 index f6bebf9..0000000 --- a/lustre/extN/extN-2.4.18-ino_sb_fixup.diff +++ /dev/null @@ -1,33 +0,0 @@ ---- ./include/linux/extN_fs.h.orig Tue May 7 17:06:03 2002 -+++ ./include/linux/extN_fs.h Tue May 7 17:07:11 2002 -@@ -17,6 +17,8 @@ - #define _LINUX_EXTN_FS_H - - #include -+#include -+#include - - /* - * The second extended filesystem constants/structures -@@ -86,8 +88,8 @@ - #define EXTN_MIN_BLOCK_LOG_SIZE 10 - - #ifdef __KERNEL__ --#define EXTN_SB(sb) (&((sb)->u.extN_sb)) --#define EXTN_I(inode) (&((inode)->u.extN_i)) -+#define EXTN_SB(sb) ((struct extN_sb_info *)&((sb)->u.generic_sbp)) -+#define EXTN_I(inode) ((struct extN_inode_info *)&((inode)->u.generic_ip)) - - #define EXTN_BLOCK_SIZE(s) ((s)->s_blocksize) - #define EXTN_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -@@ -445,7 +445,9 @@ - }; - - #define NEXT_ORPHAN(inode) EXTN_I(inode)->i_dtime --#define orphan_list_entry(l) list_entry((l), struct inode, u.extN_i.i_orphan) -+#define orphan_list_entry(l) ((struct inode *)((char *)(l) - \ -+ (unsigned long)(offsetof(struct inode, u.generic_ip) + \ -+ offsetof(struct extN_inode_info, i_orphan)))) - - /* - * Codes for operating systems diff --git a/lustre/extN/extN-misc-fixup.diff b/lustre/extN/extN-misc-fixup.diff deleted file mode 100644 index 29b36fb..0000000 --- a/lustre/extN/extN-misc-fixup.diff +++ /dev/null @@ -1,15 +0,0 @@ ---- linux-2.4.17/fs/extN/super.c.orig Fri Dec 21 10:41:55 2001 -+++ linux-2.4.17/fs/extN/super.c Fri Mar 22 11:00:41 2002 -@@ -1344,10 +1342,10 @@ - printk(KERN_ERR "EXTN-fs: I/O error on journal device\n"); - goto out_journal; - } -- if (ntohl(journal->j_superblock->s_nr_users) != 1) { -+ if (be32_to_cpu(journal->j_superblock->s_nr_users) != 1) { - printk(KERN_ERR "EXTN-fs: External journal has more than one " - "user (unsupported) - %d\n", -- ntohl(journal->j_superblock->s_nr_users)); -+ be32_to_cpu(journal->j_superblock->s_nr_users)); - goto out_journal; - } - EXTN_SB(sb)->journal_bdev = bdev; diff --git a/lustre/extN/htree-ext3-2.4.18.diff b/lustre/extN/htree-ext3-2.4.18.diff deleted file mode 100644 index 605e850..0000000 --- a/lustre/extN/htree-ext3-2.4.18.diff +++ /dev/null @@ -1,1213 +0,0 @@ ---- ./fs/ext3/dir.c 2002/03/05 06:18:59 2.1 -+++ ./fs/ext3/dir.c 2002/03/05 06:26:56 -@@ -26,7 +26,7 @@ - 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); -+int ext3_readdir(struct file *, void *, filldir_t); - - struct file_operations ext3_dir_operations = { - read: generic_read_dir, -@@ -65,7 +65,7 @@ - return error_msg == NULL ? 1 : 0; - } - --static int ext3_readdir(struct file * filp, -+int ext3_readdir(struct file * filp, - void * dirent, filldir_t filldir) - { - int error = 0; ---- ./fs/ext3/super.c 2002/03/05 06:18:59 2.1 -+++ ./fs/ext3/super.c 2002/03/05 06:26:56 -@@ -529,6 +529,12 @@ - "EXT3 Check option not supported\n"); - #endif - } -+ else if (!strcmp (this_char, "index")) -+#ifdef CONFIG_EXT3_INDEX -+ set_opt (*mount_options, INDEX); -+#else -+ printk("EXT3 index option not supported\n"); -+#endif - else if (!strcmp (this_char, "debug")) - set_opt (*mount_options, DEBUG); - else if (!strcmp (this_char, "errors")) { -@@ -712,6 +718,10 @@ - EXT3_BLOCKS_PER_GROUP(sb), - EXT3_INODES_PER_GROUP(sb), - sbi->s_mount_opt); -+ -+ if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) -+ set_opt (EXT3_SB(sb)->s_mount_opt, INDEX); -+ - printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ", - bdevname(sb->s_dev)); - if (EXT3_SB(sb)->s_journal->j_inode == NULL) { ---- ./fs/ext3/namei.c 2002/03/05 06:18:59 2.1 -+++ ./fs/ext3/namei.c 2002/03/06 00:13:18 -@@ -16,6 +16,10 @@ - * David S. Miller (davem@caip.rutgers.edu), 1995 - * Directory entry file type support and forward compatibility hooks - * for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998 -+ * Hash Tree Directory indexing (c) -+ * Daniel Phillips, 2001 -+ * Hash Tree Directory indexing porting -+ * Christopher Li, 2002 - */ - - #include -@@ -38,6 +42,435 @@ - #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) - #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b)) - -+void ext3_add_compat_feature (struct super_block *sb, unsigned feature) -+{ -+ if (!EXT3_HAS_COMPAT_FEATURE(sb, feature)) -+ { -+ lock_super(sb); -+ ext3_update_dynamic_rev(sb); -+ EXT3_SET_COMPAT_FEATURE(sb, feature); -+ ext3_write_super(sb); -+ unlock_super(sb); -+ } -+} -+ -+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_journal_get_write_access(handle,bh); -+ } -+ return bh; -+} -+ -+#ifndef assert -+#define assert(test) do if (!(test)) BUG(); while (0) -+#endif -+ -+#ifndef swap -+#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0) -+#endif -+ -+typedef struct { u32 v; } le_u32; -+typedef struct { u16 v; } le_u16; -+ -+#define dxtrace_on(command) command -+#define dxtrace_off(command) -+#define dxtrace dxtrace_off -+ -+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 fake1; -+ char dot1[4]; -+ struct fake_dirent fake2; -+ char dot2[4]; -+ struct dx_root_info -+ { -+ le_u32 reserved_zero; -+ u8 hash_version; /* 0 now, 1 at release */ -+ u8 info_length; /* 8 */ -+ u8 indirect_levels; -+ u8 unused_flags; -+ } -+ info; -+ struct dx_entry entries[0]; -+}; -+ -+struct dx_node -+{ -+ struct fake_dirent fake; -+ struct dx_entry entries[0]; -+}; -+ -+ -+struct dx_frame -+{ -+ struct buffer_head *bh; -+ struct dx_entry *entries; -+ struct dx_entry *at; -+}; -+ -+struct dx_map_entry -+{ -+ u32 hash; -+ u32 offs; -+}; -+ -+typedef struct ext3_dir_entry_2 ext3_dirent; -+static inline unsigned dx_get_block (struct dx_entry *entry); -+static void dx_set_block (struct dx_entry *entry, unsigned value); -+static inline unsigned dx_get_hash (struct dx_entry *entry); -+static void dx_set_hash (struct dx_entry *entry, unsigned value); -+static unsigned dx_get_count (struct dx_entry *entries); -+static unsigned dx_get_limit (struct dx_entry *entries); -+static void dx_set_count (struct dx_entry *entries, unsigned value); -+static void dx_set_limit (struct dx_entry *entries, unsigned value); -+static unsigned dx_root_limit (struct inode *dir, unsigned infosize); -+static unsigned dx_node_limit (struct inode *dir); -+static unsigned dx_hack_hash (const u8 *name, int len); -+static struct dx_frame *dx_probe (struct inode *dir, u32 hash, struct dx_frame *frame); -+static void dx_release (struct dx_frame *frames); -+static int dx_make_map (ext3_dirent *de, int size, struct dx_map_entry map[]); -+static void dx_sort_map(struct dx_map_entry *map, unsigned count); -+static ext3_dirent *dx_copy_dirents (char *from, char *to, -+ struct dx_map_entry *map, int count); -+static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); -+ -+ -+#ifdef CONFIG_EXT3_INDEX -+/* -+ * Future: use high four bits of block for coalesce-on-delete flags -+ * Mask them off for now. -+ */ -+ -+static inline unsigned dx_get_block (struct dx_entry *entry) -+{ -+ return le32_to_cpu(entry->block.v) & 0x0fffffff; -+} -+ -+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 - 24 - 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 - sizeof(struct fake_dirent); -+ return 0? 22: entry_space / sizeof(struct dx_entry); -+} -+ -+/* Hash function - not bad, but still looking for an ideal default */ -+ -+static unsigned dx_hack_hash (const u8 *name, int len) -+{ -+ u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; -+ while (len--) -+ { -+ u32 hash = hash1 + (hash0 ^ (*name++ * 7152373)); -+ if (hash & 0x80000000) hash -= 0x7fffffff; -+ hash1 = hash0; -+ hash0 = hash; -+ } -+ return 80; /* FIXME: for test only */ -+ return hash0; -+} -+ -+#define dx_hash(s,n) (dx_hack_hash(s,n) << 1) -+ -+/* -+ * Debug -+ */ -+static void dx_show_index (char * label, struct dx_entry *entries) -+{ -+ int i, n = dx_get_count (entries); -+ printk("%s index ", label); -+ for (i = 0; i < n; i++) -+ { -+ printk("%x->%u ", i? dx_get_hash(entries + i): 0, dx_get_block(entries + i)); -+ } -+ printk("\n"); -+} -+ -+struct stats -+{ -+ unsigned names; -+ unsigned space; -+ unsigned bcount; -+}; -+ -+static struct stats dx_show_leaf (ext3_dirent *de, int size, int show_names) -+{ -+ unsigned names = 0, space = 0; -+ char *base = (char *) de; -+ printk("names: "); -+ while ((char *) de < base + size) -+ { -+ if (de->inode) -+ { -+ if (show_names) -+ { -+ int len = de->name_len; -+ char *name = de->name; -+ while (len--) printk("%c", *name++); -+ printk(":%x.%u ", dx_hash (de->name, de->name_len), ((char *) de - base)); -+ } -+ space += EXT3_DIR_REC_LEN(de->name_len); -+ names++; -+ } -+ de = (ext3_dirent *) ((char *) de + le16_to_cpu(de->rec_len)); -+ } -+ printk("(%i)\n", names); -+ return (struct stats) { names, space, 1 }; -+} -+ -+struct stats dx_show_entries (struct inode *dir, struct dx_entry *entries, int levels) -+{ -+ unsigned blocksize = dir->i_sb->s_blocksize; -+ unsigned count = dx_get_count (entries), names = 0, space = 0, i; -+ unsigned bcount = 0; -+ struct buffer_head *bh; -+ int err; -+ printk("%i indexed blocks...\n", count); -+ for (i = 0; i < count; i++, entries++) -+ { -+ u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0; -+ u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash; -+ struct stats stats; -+ printk("%s%3u:%03u hash %8x/%8x ",levels?"":" ", i, block, hash, range); -+ if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue; -+ stats = levels? -+ dx_show_entries (dir, ((struct dx_node *) bh->b_data)->entries, levels - 1): -+ dx_show_leaf ((ext3_dirent *) bh->b_data, blocksize, 0); -+ names += stats.names; -+ space += stats.space; -+ bcount += stats.bcount; -+ brelse (bh); -+ } -+ if (bcount) -+ printk("%snames %u, fullness %u (%u%%)\n", levels?"":" ", -+ names, space/bcount,(space/bcount)*100/blocksize); -+ return (struct stats) { names, space, bcount}; -+} -+ -+static void dx_show_buckets (struct inode *dir) -+{ -+ struct buffer_head *bh; -+ struct dx_root *root; -+ int err; -+ if (!(bh = ext3_bread (NULL,dir, 0, 0,&err))) return; -+ root = (struct dx_root *) bh->b_data; -+ dx_show_entries (dir, root->entries, root->info.indirect_levels); -+ brelse (bh); -+} -+ -+ssize_t hack_show_dir (struct file * filp, void * dirent, filldir_t filldir) -+{ -+ if (is_dx (filp->f_dentry->d_inode) && !filp->f_pos) -+ dx_show_buckets (filp->f_dentry->d_inode); -+ return ext3_readdir(filp,dirent,filldir); -+} -+ -+/* -+ * Probe for a directory leaf block to search -+ */ -+ -+static struct dx_frame *dx_probe (struct inode *dir, u32 hash, struct dx_frame *frame) -+{ -+ unsigned count, indirect; -+ struct dx_entry *at, *entries, *p, *q, *m; -+ struct dx_root *root; -+ struct buffer_head *bh; -+ int err; -+ if (!(bh = ext3_bread (NULL,dir, 0, 0,&err))) -+ goto fail; -+ root = (struct dx_root *) bh->b_data; -+ if (root->info.hash_version > 0 || root->info.unused_flags & 1) -+ goto fail; -+ if ((indirect = root->info.indirect_levels) > 1) -+ 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: -+ brelse(frame->bh); -+fail: -+ return NULL; -+} -+ -+static void dx_release (struct dx_frame *frames) -+{ -+ if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels) -+ brelse (frames[1].bh); -+ brelse (frames[0].bh); -+} -+ -+/* -+ * Directory block splitting, compacting -+ */ -+ -+static int dx_make_map (ext3_dirent *de, int size, struct dx_map_entry map[]) -+{ -+ int count = 0; -+ char *base = (char *) de; -+ while ((char *) de < base + size) -+ { -+ map[count].hash = dx_hash (de->name, de->name_len); -+ map[count].offs = (u32) ((char *) de - base); -+ de = (ext3_dirent *) ((char *) de + le16_to_cpu(de->rec_len)); -+ count++; -+ } -+ 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, *at = frame->at; -+ assert (dx_get_count (entries) < dx_get_limit (entries)); -+ memmove (at + 2, at+1, (char *) (entries + dx_get_count(entries)) - (char *) (at)); -+ dx_set_hash(at + 1, hash); -+ dx_set_block(at + 1, block); -+ dx_set_count(entries, dx_get_count(entries) + 1); -+} -+#endif -+ - /* - * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure. - * -@@ -95,6 +529,15 @@ - } - - /* -+ * p is at least 6 bytes before the end of page -+ */ -+static inline ext3_dirent *ext3_next_entry(ext3_dirent *p) -+{ -+ return (ext3_dirent *)((char*)p + le16_to_cpu(p->rec_len)); -+} -+ -+ -+/* - * ext3_find_entry() - * - * finds an entry in the specified directory with the wanted name. It -@@ -105,6 +548,8 @@ - * The returned buffer_head has ->b_count elevated. The caller is expected - * to brelse() it when appropriate. - */ -+ -+ - static struct buffer_head * ext3_find_entry (struct dentry *dentry, - struct ext3_dir_entry_2 ** res_dir) - { -@@ -119,10 +564,76 @@ - int num = 0; - int nblocks, i, err; - struct inode *dir = dentry->d_parent->d_inode; -+ int namelen; -+ const u8 *name; -+ unsigned blocksize; -+ ext3_dirent *de, *top; - - *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; -+ if (ext3_dx && is_dx(dir)) { -+ u32 hash = dx_hash (name, namelen); -+ struct dx_frame frames[2], *frame; -+ if (!(frame = dx_probe (dir, hash, frames))) -+ return NULL; -+dxnext: -+ block = dx_get_block(frame->at); -+ if (!(bh = ext3_bread (NULL,dir, block, 0, &err))) -+ goto dxfail; -+ de = (struct ext3_dir_entry_2 *) bh->b_data; -+ top = (struct ext3_dir_entry_2 *) ((char *) de + 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 dxfail; -+ } -+ *res_dir = de; -+ goto dxfound; -+ } -+ brelse (bh); -+ /* Same hash continues in next block? Search on. */ -+ if (++(frame->at) == frame->entries + dx_get_count(frame->entries)) -+ { -+ struct buffer_head *bh2; -+ if (frame == frames) -+ goto dxfail; -+ if (++(frames->at) == frames->entries + dx_get_count(frames->entries)) -+ goto dxfail; -+ /* should omit read if not continued */ -+ if (!(bh2 = ext3_bread (NULL, dir, -+ dx_get_block(frames->at), -+ 0, &err))) -+ goto dxfail; -+ brelse (frame->bh); -+ frame->bh = bh2; -+ frame->at = frame->entries = ((struct dx_node *) bh2->b_data)->entries; -+ /* Subtle: the 0th entry has the count, find the hash in frame above */ -+ if ((dx_get_hash(frames->at) & -2) == hash) -+ goto dxnext; -+ goto dxfail; -+ } -+ if ((dx_get_hash(frame->at) & -2) == hash) -+ goto dxnext; -+dxfail: -+ dxtrace(printk("%s not found\n", name)); -+ dx_release (frames); -+ return NULL; -+dxfound: -+ dx_release (frames); -+ return bh; - -+ } -+ - nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb); - start = dir->u.ext3_i.i_dir_start_lookup; - if (start >= nblocks) -@@ -237,6 +748,88 @@ - de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; - } - -+static ext3_dirent * -+dx_copy_dirents (char *from, char *to, struct dx_map_entry *map, int count) -+{ -+ unsigned rec_len = 0; -+ -+ while (count--) { -+ ext3_dirent *de = (ext3_dirent *) (from + map->offs); -+ rec_len = EXT3_DIR_REC_LEN(de->name_len); -+ memcpy (to, de, rec_len); -+ ((ext3_dirent *) to)->rec_len = rec_len; -+ to += rec_len; -+ map++; -+ } -+ return (ext3_dirent *) (to - rec_len); -+} -+ -+#ifdef CONFIG_EXT3_INDEX -+static ext3_dirent *do_split(handle_t *handle, struct inode *dir, -+ struct buffer_head **bh,struct dx_frame *frame, -+ u32 hash, int *error) -+{ -+ unsigned blocksize = dir->i_sb->s_blocksize; -+ unsigned count, continued; -+ struct buffer_head *bh2; -+ u32 newblock; -+ unsigned MAX_DX_MAP = PAGE_CACHE_SIZE/EXT3_DIR_REC_LEN(1) + 1; -+ u32 hash2; -+ struct dx_map_entry map[MAX_DX_MAP]; -+ char *data1 = (*bh)->b_data, *data2, *data3; -+ unsigned split; -+ ext3_dirent *de, *de2; -+ -+ bh2 = ext3_append (handle, dir, &newblock, error); -+ if (!(bh2)) -+ { -+ brelse(*bh); -+ *bh = NULL; -+ return (ext3_dirent *)bh2; -+ } -+ -+ BUFFER_TRACE(*bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, *bh); -+ BUFFER_TRACE(frame->bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, frame->bh); -+ -+ data2 = bh2->b_data; -+ -+ count = dx_make_map ((ext3_dirent *) data1, blocksize, map); -+ 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_copy_dirents (data1, data2, map + split, count - split); -+ data3 = (char *) de2 + de2->rec_len; -+ de = dx_copy_dirents (data1, data3, map, split); -+ memcpy(data1, data3, (char *) de + de->rec_len - data3); -+ de = (ext3_dirent *) ((char *) de - data3 + data1); // relocate de -+ de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); -+ de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2); -+ dxtrace(dx_show_leaf ((ext3_dirent *) data1, blocksize, 1)); -+ dxtrace(dx_show_leaf ((ext3_dirent *) data2, blocksize, 1)); -+ -+ /* Which block gets the new entry? */ -+ if (hash >= hash2) -+ { -+ swap(*bh, bh2); -+ de = de2; -+ } -+ dx_insert_block (frame, hash2 + continued, newblock); -+ ext3_journal_dirty_metadata (handle, bh2); -+ brelse (bh2); -+ ext3_journal_dirty_metadata (handle, frame->bh); -+ dxtrace(dx_show_index ("frame", frame->entries)); -+ return de; -+} -+#endif -+ -+ - /* - * ext3_add_entry() - * -@@ -251,6 +844,7 @@ - /* - * 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) - { -@@ -258,117 +852,284 @@ - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; - unsigned long offset; -- unsigned short rec_len; - struct buffer_head * bh; - struct ext3_dir_entry_2 * de, * de1; -- struct super_block * sb; -+ struct super_block * sb = dir->i_sb; - int retval; -+ unsigned short reclen = EXT3_DIR_REC_LEN(namelen); - -- sb = dir->i_sb; -+ unsigned blocksize = sb->s_blocksize; -+ unsigned nlen, rlen; -+ u32 block; -+ char *top; - - if (!namelen) - return -EINVAL; -- bh = ext3_bread (handle, dir, 0, 0, &retval); -- if (!bh) -- return retval; -- rec_len = EXT3_DIR_REC_LEN(namelen); -- offset = 0; -- de = (struct ext3_dir_entry_2 *) bh->b_data; -- while (1) { -- if ((char *)de >= sb->s_blocksize + bh->b_data) { -- brelse (bh); -- bh = NULL; -- bh = ext3_bread (handle, dir, -- offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval); -- if (!bh) -- return retval; -- if (dir->i_size <= offset) { -- if (dir->i_size == 0) { -- brelse(bh); -- return -ENOENT; -+ if (ext3_dx && is_dx(dir)) -+ { -+ struct dx_frame frames[2], *frame; -+ struct dx_entry *entries, *at; -+ u32 hash; -+ char *data1; -+ -+ hash = dx_hash (name, namelen); -+ frame = dx_probe (dir, hash, frames); // do something if null -+ entries = frame->entries; -+ at = frame->at; -+ -+ if (!(bh = ext3_bread (handle,dir, dx_get_block(frame->at), 0,&retval))) -+ goto dxfail1; -+ -+ BUFFER_TRACE(bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, bh); -+ -+ data1 = bh->b_data; -+ de = (ext3_dirent *) data1; -+ top = data1 + (0? 200: blocksize); -+ while ((char *) de < top) -+ { -+ /* FIXME: check EEXIST and dir */ -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ if ((de->inode? rlen - nlen: rlen) >= reclen) -+ goto dx_add; -+ de = (ext3_dirent *) ((char *) de + rlen); -+ } -+ /* Block full, should compress but for now just split */ -+ dxtrace(printk("using %u of %u node entries\n", -+ dx_get_count(entries), dx_get_limit(entries))); -+ /* Need to split index? */ -+ if (dx_get_count(entries) == dx_get_limit(entries)) -+ { -+ u32 newblock; -+ unsigned icount = dx_get_count(entries); -+ char *idata2; -+ int levels = frame - frames; -+ struct dx_entry *entries2; -+ struct buffer_head *bh2; -+ if (levels && dx_get_count(frames->entries) == dx_get_limit(frames->entries)) -+ goto dxfull; -+ bh2 = ext3_append (handle, dir, &newblock, &retval); -+ if (!(bh2)) -+ goto dxfail2; -+ idata2 = bh2->b_data; -+ entries2 = ((struct dx_node *) idata2)->entries; -+ ((struct dx_node *) idata2)->fake.rec_len = cpu_to_le16(blocksize); -+ /* fake.inode already 0 */ -+ /* Seems that is not true. We still need to set inode = 0 -Chrisl*/ -+ ((struct dx_node *) idata2)->fake.inode = 0; -+ BUFFER_TRACE(frame->bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, frame->bh); -+ if (levels) -+ { -+ unsigned icount1 = icount/2, icount2 = icount - icount1; -+ unsigned hash2 = dx_get_hash(entries + icount1); -+ dxtrace(printk("Split index %i/%i\n", icount1, icount2)); -+ -+ BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */ -+ ext3_journal_get_write_access(handle, frames[0].bh); -+ -+ memcpy ((char *) entries2, (char *) (entries + icount1), -+ icount2 * sizeof(struct dx_entry)); -+ dx_set_count (entries, icount1); -+ dx_set_count (entries2, icount2); -+ dx_set_limit (entries2, dx_node_limit(dir)); -+ -+ /* Which index block gets the new entry? */ -+ if (at - entries > icount1) { -+ frame->at = at = at - entries - icount1 + entries2; -+ frame->entries = entries = entries2; -+ swap(frame->bh, bh2); - } -- -- ext3_debug ("creating next block\n"); -- -- BUFFER_TRACE(bh, "get_write_access"); -- ext3_journal_get_write_access(handle, bh); -- de = (struct ext3_dir_entry_2 *) bh->b_data; -- de->inode = 0; -- de->rec_len = le16_to_cpu(sb->s_blocksize); -- dir->u.ext3_i.i_disksize = -- dir->i_size = offset + sb->s_blocksize; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -- ext3_mark_inode_dirty(handle, dir); -+ dx_insert_block (frames + 0, hash2, newblock); -+ dxtrace(dx_show_index ("node", frames[1].entries)); -+ dxtrace(dx_show_index ("node", -+ ((struct dx_node *) bh2->b_data)->entries)); -+ ext3_journal_dirty_metadata(handle, bh2); -+ brelse (bh2); - } else { -- -- ext3_debug ("skipping to next block\n"); -- -- de = (struct ext3_dir_entry_2 *) bh->b_data; -+ dxtrace(printk("Creating second level index...\n")); -+ memcpy((char *) entries2, (char *) entries, -+ icount * sizeof(struct dx_entry)); -+ dx_set_limit(entries2, dx_node_limit(dir)); -+ -+ /* Set up root */ -+ dx_set_count(entries, 1); -+ dx_set_block(entries + 0, newblock); -+ ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1; -+ -+ /* Add new access path frame */ -+ frame = frames + 1; -+ frame->at = at = at - entries + entries2; -+ frame->entries = entries = entries2; -+ frame->bh = bh2; -+ ext3_journal_get_write_access(handle, frame->bh); - } -+ ext3_journal_dirty_metadata(handle, frames[0].bh); - } -- if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh, -- offset)) { -- brelse (bh); -- return -ENOENT; -- } -- if (ext3_match (namelen, name, de)) { -+ de = do_split(handle, dir, &bh, frame, hash, &retval); -+ dx_release (frames); -+ if (!(de)) -+ goto fail; -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ goto add; -+ -+dx_add: -+ dx_release (frames); -+ goto add; -+ -+dxfull: -+ ext3_warning(sb, __FUNCTION__, "Directory index full!\n"); -+ retval = -ENOSPC; -+dxfail2: -+ brelse(bh); -+dxfail1: -+ dx_release (frames); -+ goto fail1; -+ } -+ block = offset = 0; -+ while (offset < dir->i_size) { -+ bh = ext3_bread (handle, dir, block, 0, &retval); -+ if(!bh) -+ return retval; -+ de = (struct ext3_dir_entry_2 *) bh->b_data; -+ top = bh->b_data+blocksize-reclen; -+ while ((char *) de <= top) { -+ -+ if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, -+ bh,offset)) { -+ brelse (bh); -+ return -ENOENT; -+ } -+ if (ext3_match (namelen, name, de)) { - brelse (bh); - return -EEXIST; -- } -- if ((le32_to_cpu(de->inode) == 0 && -- le16_to_cpu(de->rec_len) >= rec_len) || -- (le16_to_cpu(de->rec_len) >= -- EXT3_DIR_REC_LEN(de->name_len) + rec_len)) { -- BUFFER_TRACE(bh, "get_write_access"); -- ext3_journal_get_write_access(handle, bh); -- /* By now the buffer is marked for journaling */ -- offset += le16_to_cpu(de->rec_len); -- if (le32_to_cpu(de->inode)) { -- de1 = (struct ext3_dir_entry_2 *) ((char *) de + -- EXT3_DIR_REC_LEN(de->name_len)); -- de1->rec_len = -- cpu_to_le16(le16_to_cpu(de->rec_len) - -- EXT3_DIR_REC_LEN(de->name_len)); -- de->rec_len = cpu_to_le16( -- EXT3_DIR_REC_LEN(de->name_len)); -- de = de1; - } -- de->file_type = EXT3_FT_UNKNOWN; -- if (inode) { -- de->inode = cpu_to_le32(inode->i_ino); -- ext3_set_de_type(dir->i_sb, de, inode->i_mode); -- } else -- de->inode = 0; -- de->name_len = namelen; -- memcpy (de->name, name, namelen); -- /* -- * XXX shouldn't update any times until successful -- * completion of syscall, but too many callers depend -- * on this. -- * -- * XXX similarly, too many callers depend on -- * ext3_new_inode() setting the times, but error -- * recovery deletes the inode, so the worst that can -- * happen is that the times are slightly out of date -- * and/or different from the directory change time. -- */ -- dir->i_mtime = dir->i_ctime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -- ext3_mark_inode_dirty(handle, dir); -- dir->i_version = ++event; -- BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -- ext3_journal_dirty_metadata(handle, bh); -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ if ((de->inode? rlen - nlen: rlen) >= reclen) -+ goto add; -+ de = (struct ext3_dir_entry_2 *) ((char *) de + rlen); -+ offset += rlen; -+ } -+ if (ext3_dx && dir->i_size==blocksize && test_opt(sb, INDEX)) -+ goto dx_make_index; -+ brelse(bh); -+ } -+ bh = ext3_append(handle, dir, &block, &retval); -+ if (!bh) -+ return retval; -+ de = (struct ext3_dir_entry_2 *) bh->b_data; -+ de->inode = 0; -+ de->rec_len = cpu_to_le16(rlen = blocksize); -+ nlen = 0; -+ goto add; -+ -+add: -+ BUFFER_TRACE(bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, bh); -+ /* By now the buffer is marked for journaling */ -+ if (de->inode) { -+ 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_I(dir)->i_flags &= ~EXT3_INDEX_FL; */ -+ ext3_mark_inode_dirty(handle, dir); -+ dir->i_version = ++event; -+ BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -+ ext3_journal_dirty_metadata(handle, bh); -+ brelse(bh); -+ return 0; -+ -+dx_make_index: -+ { -+ struct buffer_head *bh2; -+ struct dx_root *root; -+ struct dx_frame frames[2], *frame; -+ struct dx_entry *entries; -+ struct ext3_dir_entry_2 *de2; -+ char *data1; -+ unsigned len; -+ u32 hash; -+ -+ dxtrace(printk("Creating index\n")); -+ ext3_journal_get_write_access(handle, bh); -+ root = (struct dx_root *) bh->b_data; -+ -+ ext3_add_compat_feature (sb, EXT3_FEATURE_COMPAT_DIR_INDEX); -+ EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; -+ bh2 = ext3_append (handle, dir, &block, &retval); -+ if (!(bh2)) -+ { - brelse(bh); -- return 0; -+ return retval; - } -- offset += le16_to_cpu(de->rec_len); -- de = (struct ext3_dir_entry_2 *) -- ((char *) de + le16_to_cpu(de->rec_len)); -+ data1 = bh2->b_data; -+ -+ /* The 0th block becomes the root, move the dirents out */ -+ de = (ext3_dirent *) &root->info; -+ len = ((char *) root) + blocksize - (char *) de; -+ memcpy (data1, de, len); -+ de = (ext3_dirent *) data1; -+ top = data1 + len; -+ while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top) -+ de = de2; -+ de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); -+ /* Initialize the root; the dot dirents already exist */ -+ de = (ext3_dirent *) (&root->fake2); -+ 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); -+ entries = root->entries; -+ dx_set_block (entries, 1); -+ dx_set_count (entries, 1); -+ dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info))); -+ -+ /* Initialize as for dx_probe */ -+ hash = dx_hash (name, namelen); -+ frame = frames; -+ frame->entries = entries; -+ frame->at = entries; -+ frame->bh = bh; -+ bh = bh2; -+ de = do_split(handle,dir, &bh, frame, hash, &retval); -+ dx_release (frames); -+ if (!(de)) -+ return retval; -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ goto add; - } -- brelse (bh); -- return -ENOSPC; -+fail1: -+ return retval; -+fail: -+ return -ENOENT; - } - -+ - /* - * ext3_delete_entry deletes a directory entry by merging it with the - * previous entry -@@ -451,7 +1212,8 @@ - struct inode * inode; - int err; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -478,7 +1240,8 @@ - struct inode *inode; - int err; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -507,7 +1270,8 @@ - if (dir->i_nlink >= EXT3_LINK_MAX) - return -EMLINK; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -832,7 +1596,7 @@ - ext3_mark_inode_dirty(handle, inode); - dir->i_nlink--; - inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ // EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL; - ext3_mark_inode_dirty(handle, dir); - - end_rmdir: -@@ -878,7 +1642,7 @@ - if (retval) - goto end_unlink; - dir->i_ctime = dir->i_mtime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ // EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL; - ext3_mark_inode_dirty(handle, dir); - inode->i_nlink--; - if (!inode->i_nlink) -@@ -904,7 +1668,8 @@ - if (l > dir->i_sb->s_blocksize) - return -ENAMETOOLONG; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -959,7 +1724,8 @@ - if (inode->i_nlink >= EXT3_LINK_MAX) - return -EMLINK; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -995,7 +1761,8 @@ - - old_bh = new_bh = dir_bh = NULL; - -- handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2); -+ handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -1077,7 +1844,7 @@ - new_inode->i_ctime = CURRENT_TIME; - } - old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; -- old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ // EXT3_I(old_dir)->i_flags &= ~EXT3_INDEX_FL; - if (dir_bh) { - BUFFER_TRACE(dir_bh, "get_write_access"); - ext3_journal_get_write_access(handle, dir_bh); -@@ -1089,7 +1856,7 @@ - new_inode->i_nlink--; - } else { - new_dir->i_nlink++; -- new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ // EXT3_I(new_dir)->i_flags &= ~EXT3_INDEX_FL; - ext3_mark_inode_dirty(handle, new_dir); - } - } ---- ./include/linux/ext3_fs.h 2002/03/05 06:18:59 2.1 -+++ ./include/linux/ext3_fs.h 2002/03/05 06:26:56 -@@ -339,6 +339,7 @@ - #define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */ - #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ - #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ -+#define EXT3_MOUNT_INDEX 0x4000 /* Enable directory index */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -575,6 +576,24 @@ - #define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) - #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ - ~EXT3_DIR_ROUND) -+/* -+ * Hash Tree Directory indexing -+ * (c) Daniel Phillips, 2001 -+ */ -+ -+#define CONFIG_EXT3_INDEX -+ -+#ifdef CONFIG_EXT3_INDEX -+ enum {ext3_dx = 1}; -+ #define is_dx(dir) (EXT3_I(dir)->i_flags & EXT3_INDEX_FL) -+#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) -+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) -+#else -+ enum {ext3_dx = 0}; -+ #define is_dx(dir) 0 -+#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX) -+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2) -+#endif - - #ifdef __KERNEL__ - /* ---- ./include/linux/ext3_jbd.h 2002/03/05 06:18:59 2.1 -+++ ./include/linux/ext3_jbd.h 2002/03/05 06:33:54 -@@ -63,6 +63,8 @@ - - #define EXT3_RESERVE_TRANS_BLOCKS 12 - -+#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 -+ - int - ext3_mark_iloc_dirty(handle_t *handle, - struct inode *inode, diff --git a/lustre/extN/linux-2.4.18ea-0.8.26.diff b/lustre/extN/linux-2.4.18ea-0.8.26.diff deleted file mode 100644 index e650ce0..0000000 --- a/lustre/extN/linux-2.4.18ea-0.8.26.diff +++ /dev/null @@ -1,1875 +0,0 @@ -Linux Extended Attributes -- Kernel Patch -24 April 2002, 11:31:18 - - -This patch is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This patch is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this patch; if not, write to the Free Software Foundation, -Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -After extracting the linux-2.4.18.tar.gz package, apply this patch as follows: - - cd linux - patch -p1 < ../linux-2.4.18ea-0.8.26.patch - -diff -Nur linux-2.4.18/fs/ext3/file.c linux-2.4.18ea/fs/ext3/file.c ---- linux-2.4.18/fs/ext3/file.c Thu Nov 15 22:37:55 2001 -+++ linux-2.4.18ea/fs/ext3/file.c Sun Feb 24 04:34:43 2002 -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -90,5 +91,9 @@ - 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 */ - }; - -diff -Nur linux-2.4.18/fs/ext3/ialloc.c linux-2.4.18ea/fs/ext3/ialloc.c ---- linux-2.4.18/fs/ext3/ialloc.c Sun Feb 24 04:42:59 2002 -+++ linux-2.4.18ea/fs/ext3/ialloc.c Sun Feb 24 04:34:43 2002 -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -216,6 +217,7 @@ - * as writing the quota to disk may need the lock as well. - */ - DQUOT_INIT(inode); -+ ext3_xattr_drop_inode(handle, inode); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); - -diff -Nur linux-2.4.18/fs/ext3/inode.c linux-2.4.18ea/fs/ext3/inode.c ---- linux-2.4.18/fs/ext3/inode.c Sun Feb 24 04:42:59 2002 -+++ linux-2.4.18ea/fs/ext3/inode.c Thu Mar 14 21:51:59 2002 -@@ -39,6 +39,18 @@ - */ - #undef SEARCH_FROM_ZERO - -+/* -+ * Test whether an inode is a fast symlink. -+ */ -+static inline int ext3_inode_is_fast_symlink(struct inode *inode) -+{ -+ int ea_blocks = EXT3_I(inode)->i_file_acl ? -+ (inode->i_sb->s_blocksize >> 9) : 0; -+ -+ return (S_ISLNK(inode->i_mode) && -+ inode->i_blocks - ea_blocks == 0); -+} -+ - /* The ext3 forget function must perform a revoke if we are freeing data - * which has been journaled. Metadata (eg. indirect blocks) must be - * revoked in all cases. -@@ -48,7 +60,7 @@ - * still needs to be revoked. - */ - --static int ext3_forget(handle_t *handle, int is_metadata, -+int ext3_forget(handle_t *handle, int is_metadata, - struct inode *inode, struct buffer_head *bh, - int blocknr) - { -@@ -164,9 +176,7 @@ - { - 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(); -@@ -1845,6 +1855,8 @@ - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return; -+ if (ext3_inode_is_fast_symlink(inode)) -+ return; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - return; - -@@ -1992,8 +2004,6 @@ - struct ext3_group_desc * gdp; - - if ((inode->i_ino != EXT3_ROOT_INO && -- inode->i_ino != EXT3_ACL_IDX_INO && -- inode->i_ino != EXT3_ACL_DATA_INO && - inode->i_ino != EXT3_JOURNAL_INO && - inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) || - inode->i_ino > le32_to_cpu( -@@ -2120,10 +2130,7 @@ - - brelse (iloc.bh); - -- if (inode->i_ino == EXT3_ACL_IDX_INO || -- inode->i_ino == EXT3_ACL_DATA_INO) -- /* Nothing to do */ ; -- else if (S_ISREG(inode->i_mode)) { -+ if (S_ISREG(inode->i_mode)) { - inode->i_op = &ext3_file_inode_operations; - inode->i_fop = &ext3_file_operations; - inode->i_mapping->a_ops = &ext3_aops; -@@ -2131,13 +2138,15 @@ - 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 */ -diff -Nur linux-2.4.18/fs/ext3/namei.c linux-2.4.18ea/fs/ext3/namei.c ---- linux-2.4.18/fs/ext3/namei.c Fri Nov 9 23:25:04 2001 -+++ linux-2.4.18ea/fs/ext3/namei.c Mon Mar 11 03:27:00 2002 -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -466,6 +467,8 @@ - inode->i_mapping->a_ops = &ext3_aops; - ext3_mark_inode_dirty(handle, inode); - err = ext3_add_nondir(handle, dentry, inode); -+ if (err) -+ ext3_xattr_drop_inode(handle, inode); - } - ext3_journal_stop(handle, dir); - return err; -@@ -491,6 +494,8 @@ - init_special_inode(inode, mode, rdev); - ext3_mark_inode_dirty(handle, inode); - err = ext3_add_nondir(handle, dentry, inode); -+ if (err) -+ ext3_xattr_drop_inode(handle, inode); - } - ext3_journal_stop(handle, dir); - return err; -@@ -514,7 +519,7 @@ - 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; -@@ -522,7 +527,6 @@ - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; -- inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize; -- inode->i_blocks = 0; -+ inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; - dir_block = ext3_bread (handle, inode, 0, 1, &err); - if (!dir_block) { - inode->i_nlink--; /* is this nlink == 0? */ -@@ -549,9 +553,6 @@ - BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata"); - ext3_journal_dirty_metadata(handle, dir_block); - brelse (dir_block); -- inode->i_mode = S_IFDIR | mode; -- if (dir->i_mode & S_ISGID) -- inode->i_mode |= S_ISGID; - ext3_mark_inode_dirty(handle, inode); - err = ext3_add_entry (handle, dentry, inode); - if (err) -@@ -565,6 +566,7 @@ - return err; - - out_no_entry: -+ ext3_xattr_drop_inode(handle, inode); - inode->i_nlink = 0; - ext3_mark_inode_dirty(handle, inode); - iput (inode); -@@ -917,7 +919,7 @@ - goto out_stop; - -- if (l > sizeof (inode->u.ext3_i.i_data)) { -- inode->i_op = &page_symlink_inode_operations; -+ if (l > sizeof(EXT3_I(inode)->i_data)) { -+ inode->i_op = &ext3_symlink_inode_operations; - inode->i_mapping->a_ops = &ext3_aops; - /* - * block_symlink() calls back into ext3_prepare/commit_write. -@@ -1122,4 +1124,16 @@ - 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 */ -+}; -+ -diff -Nur linux-2.4.18/fs/ext3/super.c linux-2.4.18ea/fs/ext3/super.c ---- linux-2.4.18/fs/ext3/super.c Sun Feb 24 04:42:59 2002 -+++ linux-2.4.18ea/fs/ext3/super.c Thu Apr 4 21:41:05 2002 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -404,6 +405,7 @@ - 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); -@@ -1734,14 +1772,25 @@ - - static DECLARE_FSTYPE_DEV(ext3_fs_type, "ext3", ext3_read_super); - --static int __init init_ext3_fs(void) -+static void exit_ext3_fs(void) - { -- return register_filesystem(&ext3_fs_type); -+ unregister_filesystem(&ext3_fs_type); -+ exit_ext3_xattr_user(); -+ exit_ext3_xattr(); - } - --static void __exit exit_ext3_fs(void) -+static int __init init_ext3_fs(void) - { -- unregister_filesystem(&ext3_fs_type); -+ int error = init_ext3_xattr(); -+ if (!error) -+ error = init_ext3_xattr_user(); -+ if (!error) -+ error = register_filesystem(&ext3_fs_type); -+ if (!error) -+ return 0; -+ -+ exit_ext3_fs(); -+ return error; - } - - EXPORT_NO_SYMBOLS; -diff -Nur linux-2.4.18/fs/ext3/symlink.c linux-2.4.18ea/fs/ext3/symlink.c ---- linux-2.4.18/fs/ext3/symlink.c Fri Nov 9 23:25:04 2001 -+++ linux-2.4.18ea/fs/ext3/symlink.c Mon Mar 11 03:27:00 2002 -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen) - { -@@ -33,7 +34,20 @@ - 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 */ - }; -diff -Nur linux-2.4.18/fs/ext3/xattr.c linux-2.4.18ea/fs/ext3/xattr.c ---- linux-2.4.18/fs/ext3/xattr.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.18ea/fs/ext3/xattr.c Wed Apr 3 13:19:05 2002 -@@ -0,0 +1,1241 @@ -+/* -+ * 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 -+#ifdef CONFIG_EXT3_FS_XATTR_SHARING -+#include -+#endif -+#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) do {} while(0) -+# define ext3_xattr_rehash(header, entry) do {} while(0) -+#endif -+ -+/* -+ * If a file system does not share extended attributes among inodes, -+ * we should not need the ext3_xattr_sem semaphore. However, the -+ * filesystem may still contain shared blocks, so we always take -+ * the lock. -+ */ -+ -+DECLARE_MUTEX(ext3_xattr_sem); -+ -+static inline void -+ext3_xattr_lock(void) -+{ -+ down(&ext3_xattr_sem); -+} -+ -+static inline void -+ext3_xattr_unlock(void) -+{ -+ up(&ext3_xattr_sem); -+} -+ -+static inline int -+ext3_xattr_new_block(handle_t *handle, struct inode *inode, -+ int * errp, int force) -+{ -+ struct super_block *sb = inode->i_sb; -+ int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + -+ EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb); -+ -+ /* How can we enforce the allocation? */ -+ int block = ext3_new_block(handle, inode, goal, 0, 0, errp); -+#ifdef OLD_QUOTAS -+ if (!*errp) -+ inode->i_blocks += inode->i_sb->s_blocksize >> 9; -+#endif -+ return block; -+} -+ -+static inline int -+ext3_xattr_quota_alloc(struct inode *inode, int force) -+{ -+ /* How can we enforce the allocation? */ -+#ifdef OLD_QUOTAS -+ int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1); -+ if (!error) -+ inode->i_blocks += inode->i_sb->s_blocksize >> 9; -+#else -+ int error = DQUOT_ALLOC_BLOCK(inode, 1); -+#endif -+ return error; -+} -+ -+#ifdef OLD_QUOTAS -+ -+static inline void -+ext3_xattr_quota_free(struct inode *inode) -+{ -+ DQUOT_FREE_BLOCK(inode->i_sb, inode, 1); -+ inode->i_blocks -= inode->i_sb->s_blocksize >> 9; -+} -+ -+static inline void -+ext3_xattr_free_block(handle_t *handle, struct inode * inode, -+ unsigned long block) -+{ -+ ext3_free_blocks(handle, inode, block, 1); -+ inode->i_blocks -= inode->i_sb->s_blocksize >> 9; -+} -+ -+#else -+# define ext3_xattr_quota_free(inode) \ -+ DQUOT_FREE_BLOCK(inode, 1) -+# define ext3_xattr_free_block(handle, inode, block) \ -+ ext3_free_blocks(handle, inode, block, 1) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) -+ -+static inline struct buffer_head * -+sb_bread(struct super_block *sb, int block) -+{ -+ return bread(sb->s_dev, block, sb->s_blocksize); -+} -+ -+static inline struct buffer_head * -+sb_getblk(struct super_block *sb, int block) -+{ -+ return getblk(sb->s_dev, block, sb->s_blocksize); -+} -+ -+#endif -+ -+struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX]; -+rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED; -+ -+int -+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler) -+{ -+ int error = -EINVAL; -+ -+ if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ if (!ext3_xattr_handlers[name_index-1]) { -+ ext3_xattr_handlers[name_index-1] = handler; -+ error = 0; -+ } -+ write_unlock(&ext3_handler_lock); -+ } -+ return error; -+} -+ -+void -+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler) -+{ -+ if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ ext3_xattr_handlers[name_index-1] = NULL; -+ write_unlock(&ext3_handler_lock); -+ } -+} -+ -+static inline const char * -+strcmp_prefix(const char *a, const char *a_prefix) -+{ -+ while (*a_prefix && *a == *a_prefix) { -+ a++; -+ a_prefix++; -+ } -+ return *a_prefix ? NULL : a; -+} -+ -+/* -+ * Decode the extended attribute name, and translate it into -+ * the name_index and name suffix. -+ */ -+static inline struct ext3_xattr_handler * -+ext3_xattr_resolve_name(const char **name) -+{ -+ struct ext3_xattr_handler *handler = NULL; -+ int i; -+ -+ if (!*name) -+ return NULL; -+ read_lock(&ext3_handler_lock); -+ for (i=0; 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, -+ void *value, size_t size, int flags) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ if (size == 0) -+ value = ""; /* empty EA, do not remove */ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -ENOTSUP; -+ return handler->set(inode, name, value, size, flags); -+} -+ -+/* -+ * Inode operation removexattr() -+ * -+ * dentry->d_inode->i_sem down -+ * BKL held [before 2.5.x] -+ */ -+int -+ext3_removexattr(struct dentry *dentry, const char *name) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -ENOTSUP; -+ return handler->set(inode, name, NULL, 0, XATTR_REPLACE); -+} -+ -+/* -+ * ext3_xattr_get() -+ * -+ * Copy an extended attribute into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_entry *entry; -+ unsigned int block, size; -+ char *end; -+ int name_len, error; -+ -+ ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", -+ name_index, name, buffer, (long)buffer_size); -+ -+ if (name == NULL) -+ return -EINVAL; -+ if (!EXT3_I(inode)->i_file_acl) -+ return -ENOATTR; -+ block = EXT3_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(inode->i_sb, "ext3_xattr_get", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* find named attribute */ -+ name_len = strlen(name); -+ -+ error = -ERANGE; -+ if (name_len > 255) -+ goto cleanup; -+ entry = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (name_index == entry->e_name_index && -+ name_len == entry->e_name_len && -+ memcmp(name, entry->e_name, name_len) == 0) -+ goto found; -+ entry = next; -+ } -+ /* Check the remaining name entries */ -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ entry = next; -+ } -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ error = -ENOATTR; -+ goto cleanup; -+found: -+ /* check the buffer size */ -+ if (entry->e_value_block != 0) -+ goto bad_block; -+ size = le32_to_cpu(entry->e_value_size); -+ if (size > inode->i_sb->s_blocksize || -+ le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize) -+ goto bad_block; -+ -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (buffer) { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ /* return value of attribute */ -+ memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs), -+ size); -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_list() -+ * -+ * Copy a list of attribute names into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_entry *entry; -+ unsigned int block, size = 0; -+ char *buf, *end; -+ int error; -+ -+ ea_idebug(inode, "buffer=%p, buffer_size=%ld", -+ buffer, (long)buffer_size); -+ -+ if (!EXT3_I(inode)->i_file_acl) -+ return 0; -+ block = EXT3_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(inode->i_sb, "ext3_xattr_list", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* compute the size required for the list of attribute names */ -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT3_XATTR_NEXT(entry)) { -+ struct ext3_xattr_handler *handler; -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ -+ handler = ext3_xattr_handler(entry->e_name_index); -+ if (handler) { -+ size += handler->list(NULL, inode, entry->e_name, -+ entry->e_name_len) + 1; -+ } -+ } -+ -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (!buffer) { -+ error = size; -+ goto cleanup; -+ } else { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ } -+ -+ /* list the attribute names */ -+ buf = buffer; -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT3_XATTR_NEXT(entry)) { -+ struct ext3_xattr_handler *handler; -+ -+ handler = ext3_xattr_handler(entry->e_name_index); -+ if (handler) { -+ buf += handler->list(buf, inode, entry->e_name, -+ entry->e_name_len); -+ *buf++ = '\0'; -+ } -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is -+ * not set, set it. -+ */ -+static void ext3_xattr_update_super_block(handle_t *handle, -+ struct super_block *sb) -+{ -+ if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) -+ return; -+ -+ lock_super(sb); -+ ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) -+ EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR; -+#endif -+ EXT3_SB(sb)->s_es->s_feature_compat |= -+ cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR); -+ sb->s_dirt = 1; -+ ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -+ unlock_super(sb); -+} -+ -+/* -+ * ext3_xattr_set() -+ * -+ * Create, replace or remove an extended attribute for this inode. Buffer -+ * is NULL to remove an existing extended attribute, and non-NULL to -+ * either replace an existing extended attribute, or create a new extended -+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE -+ * specify that an extended attribute must exist and must not exist -+ * previous to the call, respectively. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+int -+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, void *value, size_t value_len, int flags) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_header *header = NULL; -+ struct ext3_xattr_entry *here, *last; -+ unsigned int name_len; -+ int min_offs = sb->s_blocksize, not_found = 1, free, error; -+ char *end; -+ -+ /* -+ * header -- Points either into bh, or to a temporarily -+ * allocated buffer. -+ * here -- The named entry found, or the place for inserting, within -+ * the block pointed to by header. -+ * last -- Points right after the last named entry within the block -+ * pointed to by header. -+ * min_offs -- The offset of the first value (values are aligned -+ * towards the end of the block). -+ * end -- Points right after the block pointed to by header. -+ */ -+ -+ ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld", -+ name_index, name, value, (long)value_len); -+ -+ if (IS_RDONLY(inode)) -+ return -EROFS; -+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -+ return -EPERM; -+ if (value == NULL) -+ value_len = 0; -+ if (name == NULL) -+ return -EINVAL; -+ name_len = strlen(name); -+ if (name_len > 255 || value_len > sb->s_blocksize) -+ return -ERANGE; -+ ext3_xattr_lock(); -+ -+ if (EXT3_I(inode)->i_file_acl) { -+ /* The inode already has an extended attribute block. */ -+ int block = EXT3_I(inode)->i_file_acl; -+ -+ bh = sb_bread(sb, block); -+ error = -EIO; -+ if (!bh) -+ goto cleanup; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), -+ le32_to_cpu(HDR(bh)->h_refcount)); -+ header = HDR(bh); -+ end = bh->b_data + bh->b_size; -+ if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ header->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(sb, "ext3_xattr_set", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* Find the named attribute. */ -+ here = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(here)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!here->e_value_block && here->e_value_size) { -+ int offs = le16_to_cpu(here->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ not_found = name_index - here->e_name_index; -+ if (!not_found) -+ not_found = name_len - here->e_name_len; -+ if (!not_found) -+ not_found = memcmp(name, here->e_name,name_len); -+ if (not_found <= 0) -+ break; -+ here = next; -+ } -+ last = here; -+ /* We still need to compute min_offs and last. */ -+ while (!IS_LAST_ENTRY(last)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!last->e_value_block && last->e_value_size) { -+ int offs = le16_to_cpu(last->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ last = next; -+ } -+ -+ /* Check whether we have enough space left. */ -+ free = min_offs - ((char*)last - (char*)header) - sizeof(__u32); -+ } else { -+ /* We will use a new extended attribute block. */ -+ free = sb->s_blocksize - -+ sizeof(struct ext3_xattr_header) - sizeof(__u32); -+ here = last = NULL; /* avoid gcc uninitialized warning. */ -+ } -+ -+ if (not_found) { -+ /* Request to remove a nonexistent attribute? */ -+ error = -ENOATTR; -+ if (flags & XATTR_REPLACE) -+ goto cleanup; -+ error = 0; -+ if (value == NULL) -+ goto cleanup; -+ else -+ free -= EXT3_XATTR_LEN(name_len); -+ } else { -+ /* Request to create an existing attribute? */ -+ error = -EEXIST; -+ if (flags & XATTR_CREATE) -+ goto cleanup; -+ if (!here->e_value_block && here->e_value_size) { -+ unsigned int size = le32_to_cpu(here->e_value_size); -+ -+ if (le16_to_cpu(here->e_value_offs) + size > -+ sb->s_blocksize || size > sb->s_blocksize) -+ goto bad_block; -+ free += EXT3_XATTR_SIZE(size); -+ } -+ } -+ free -= EXT3_XATTR_SIZE(value_len); -+ error = -ENOSPC; -+ if (free < 0) -+ goto cleanup; -+ -+ /* Here we know that we can set the new attribute. */ -+ -+ if (header) { -+ if (header->h_refcount == cpu_to_le32(1)) { -+ ea_bdebug(bh, "modifying in-place"); -+ ext3_xattr_cache_remove(bh); -+ error = ext3_journal_get_write_access(handle, bh); -+ if (error) -+ goto cleanup; -+ } else { -+ int offset; -+ -+ ea_bdebug(bh, "cloning"); -+ header = kmalloc(bh->b_size, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memcpy(header, HDR(bh), bh->b_size); -+ header->h_refcount = cpu_to_le32(1); -+ offset = (char *)header - bh->b_data; -+ here = ENTRY((char *)here + offset); -+ last = ENTRY((char *)last + offset); -+ } -+ } else { -+ /* Allocate a buffer where we construct the new block. */ -+ header = kmalloc(sb->s_blocksize, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memset(header, 0, sb->s_blocksize); -+ end = (char *)header + sb->s_blocksize; -+ header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC); -+ header->h_blocks = header->h_refcount = cpu_to_le32(1); -+ last = here = ENTRY(header+1); -+ } -+ -+ if (not_found) { -+ /* Insert the new name. */ -+ int size = EXT3_XATTR_LEN(name_len); -+ int rest = (char *)last - (char *)here; -+ memmove((char *)here + size, here, rest); -+ memset(here, 0, size); -+ here->e_name_index = name_index; -+ here->e_name_len = name_len; -+ memcpy(here->e_name, name, name_len); -+ } else { -+ /* Remove the old value. */ -+ if (!here->e_value_block && here->e_value_size) { -+ char *first_val = (char *)header + min_offs; -+ int offs = le16_to_cpu(here->e_value_offs); -+ char *val = (char *)header + offs; -+ size_t size = EXT3_XATTR_SIZE( -+ le32_to_cpu(here->e_value_size)); -+ memmove(first_val + size, first_val, val - first_val); -+ memset(first_val, 0, size); -+ here->e_value_offs = 0; -+ min_offs += size; -+ -+ /* Adjust all value offsets. */ -+ last = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(last)) { -+ int o = le16_to_cpu(last->e_value_offs); -+ if (!last->e_value_block && o < offs) -+ last->e_value_offs = -+ cpu_to_le16(o + size); -+ last = EXT3_XATTR_NEXT(last); -+ } -+ } -+ if (value == NULL) { -+ /* Remove this attribute. */ -+ if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) { -+ /* This block is now empty. */ -+ error = ext3_xattr_set2(handle, inode, bh,NULL); -+ goto cleanup; -+ } else { -+ /* Remove the old name. */ -+ int size = EXT3_XATTR_LEN(name_len); -+ last = ENTRY((char *)last - size); -+ memmove(here, (char*)here + size, -+ (char*)last - (char*)here); -+ memset(last, 0, size); -+ } -+ } -+ } -+ -+ if (value != NULL) { -+ /* Insert the new value. */ -+ here->e_value_size = cpu_to_le32(value_len); -+ if (value_len) { -+ size_t size = EXT3_XATTR_SIZE(value_len); -+ char *val = (char *)header + min_offs - size; -+ here->e_value_offs = -+ cpu_to_le16((char *)val - (char *)header); -+ memset(val + size - EXT3_XATTR_PAD, 0, -+ EXT3_XATTR_PAD); /* Clear the pad bytes. */ -+ memcpy(val, value, value_len); -+ } -+ } -+ ext3_xattr_rehash(header, here); -+ -+ error = ext3_xattr_set2(handle, inode, bh, header); -+ -+cleanup: -+ brelse(bh); -+ if (!(bh && header == HDR(bh))) -+ kfree(header); -+ ext3_xattr_unlock(); -+ -+ return error; -+} -+ -+/* -+ * Second half of ext3_xattr_set(): Update the file system. -+ */ -+static int -+ext3_xattr_set2(handle_t *handle, struct inode *inode, -+ struct buffer_head *old_bh, struct ext3_xattr_header *header) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *new_bh = NULL; -+ int error; -+ -+ if (header) { -+ new_bh = ext3_xattr_cache_find(inode, header); -+ if (new_bh) { -+ /* -+ * We found an identical block in the cache. -+ * The old block will be released after updating -+ * the inode. -+ */ -+ ea_bdebug(old_bh, "reusing block %ld", -+ new_bh->b_blocknr); -+ -+ error = -EDQUOT; -+ if (ext3_xattr_quota_alloc(inode, 1)) -+ goto cleanup; -+ -+ error = ext3_journal_get_write_access(handle, new_bh); -+ if (error) -+ goto cleanup; -+ HDR(new_bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(new_bh)->h_refcount) + 1); -+ ea_bdebug(new_bh, "refcount now=%d", -+ le32_to_cpu(HDR(new_bh)->h_refcount)); -+ } else if (old_bh && header == HDR(old_bh)) { -+ /* Keep this block. */ -+ new_bh = old_bh; -+ ext3_xattr_cache_insert(new_bh); -+ } else { -+ /* We need to allocate a new block */ -+ int force = EXT3_I(inode)->i_file_acl != 0; -+ int block = ext3_xattr_new_block(handle, inode, -+ &error, force); -+ if (error) -+ goto cleanup; -+ ea_idebug(inode, "creating block %d", block); -+ -+ new_bh = sb_getblk(sb, block); -+ if (!new_bh) { -+getblk_failed: ext3_xattr_free_block(handle, inode, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ lock_buffer(new_bh); -+ error = ext3_journal_get_create_access(handle, new_bh); -+ if (error) { -+ unlock_buffer(new_bh); -+ goto getblk_failed; -+ } -+ memcpy(new_bh->b_data, header, new_bh->b_size); -+ mark_buffer_uptodate(new_bh, 1); -+ unlock_buffer(new_bh); -+ ext3_xattr_cache_insert(new_bh); -+ ext3_xattr_update_super_block(handle, sb); -+ } -+ error = ext3_journal_dirty_metadata(handle, new_bh); -+ if (error) -+ goto cleanup; -+ } -+ -+ /* Update the inode. */ -+ EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0; -+ inode->i_ctime = CURRENT_TIME; -+ ext3_mark_inode_dirty(handle, inode); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ -+ error = 0; -+ if (old_bh && old_bh != new_bh) { -+ /* -+ * If there was an old block, and we are not still using it, -+ * we now release the old block. -+ */ -+ unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount); -+ -+ error = ext3_journal_get_write_access(handle, old_bh); -+ if (error) -+ goto cleanup; -+ if (refcount == 1) { -+ /* Free the old block. */ -+ ea_bdebug(old_bh, "freeing"); -+ ext3_xattr_free_block(handle, inode, old_bh->b_blocknr); -+ -+ /* ext3_forget() calls bforget() for us, but we -+ let our caller release old_bh, so we need to -+ duplicate the handle before. */ -+ get_bh(old_bh); -+ ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr); -+ } else { -+ /* Decrement the refcount only. */ -+ refcount--; -+ HDR(old_bh)->h_refcount = cpu_to_le32(refcount); -+ ext3_xattr_quota_free(inode); -+ ext3_journal_dirty_metadata(handle, old_bh); -+ ea_bdebug(old_bh, "refcount now=%d", refcount); -+ } -+ } -+ -+cleanup: -+ if (old_bh != new_bh) -+ brelse(new_bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_drop_inode() -+ * -+ * Free extended attribute resources associated with this inode. This -+ * is called immediately before an inode is freed. -+ */ -+void -+ext3_xattr_drop_inode(handle_t *handle, struct inode *inode) -+{ -+ struct buffer_head *bh; -+ unsigned int block = EXT3_I(inode)->i_file_acl; -+ -+ if (!block) -+ return; -+ ext3_xattr_lock(); -+ -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_drop_inode", -+ "inode %ld: block %d read error", inode->i_ino, block); -+ goto cleanup; -+ } -+ ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count))); -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+ ext3_error(inode->i_sb, "ext3_xattr_drop_inode", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ goto cleanup; -+ } -+ ext3_journal_get_write_access(handle, bh); -+ ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ if (HDR(bh)->h_refcount == cpu_to_le32(1)) { -+ ext3_xattr_cache_remove(bh); -+ ext3_xattr_free_block(handle, inode, block); -+ ext3_forget(handle, 1, inode, bh, block); -+ bh = NULL; -+ } else { -+ HDR(bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ ext3_journal_dirty_metadata(handle, bh); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ ext3_xattr_quota_free(inode); -+ } -+ EXT3_I(inode)->i_file_acl = 0; -+ -+cleanup: -+ brelse(bh); -+ ext3_xattr_unlock(); -+} -+ -+/* -+ * ext3_xattr_put_super() -+ * -+ * This is called when a file system is unmounted. -+ */ -+void -+ext3_xattr_put_super(struct super_block *sb) -+{ -+#ifdef CONFIG_EXT3_FS_XATTR_SHARING -+ mb_cache_shrink(ext3_xattr_cache, sb->s_dev); -+#endif -+} -+ -+#ifdef CONFIG_EXT3_FS_XATTR_SHARING -+ -+/* -+ * ext3_xattr_cache_insert() -+ * -+ * Create a new entry in the extended attribute cache, and insert -+ * it unless such an entry is already in the cache. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+static int -+ext3_xattr_cache_insert(struct buffer_head *bh) -+{ -+ __u32 hash = le32_to_cpu(HDR(bh)->h_hash); -+ struct mb_cache_entry *ce; -+ int error; -+ -+ ce = mb_cache_entry_alloc(ext3_xattr_cache); -+ if (!ce) -+ return -ENOMEM; -+ error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash); -+ if (error) { -+ mb_cache_entry_free(ce); -+ if (error == -EBUSY) { -+ ea_bdebug(bh, "already in cache (%d cache entries)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ error = 0; -+ } -+ } else { -+ ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash, -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ mb_cache_entry_release(ce); -+ } -+ return error; -+} -+ -+/* -+ * ext3_xattr_cmp() -+ * -+ * Compare two extended attribute blocks for equality. -+ * -+ * Returns 0 if the blocks are equal, 1 if they differ, and -+ * a negative error number on errors. -+ */ -+static int -+ext3_xattr_cmp(struct ext3_xattr_header *header1, -+ struct ext3_xattr_header *header2) -+{ -+ struct ext3_xattr_entry *entry1, *entry2; -+ -+ entry1 = ENTRY(header1+1); -+ entry2 = ENTRY(header2+1); -+ while (!IS_LAST_ENTRY(entry1)) { -+ if (IS_LAST_ENTRY(entry2)) -+ return 1; -+ if (entry1->e_hash != entry2->e_hash || -+ entry1->e_name_len != entry2->e_name_len || -+ entry1->e_value_size != entry2->e_value_size || -+ memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len)) -+ return 1; -+ if (entry1->e_value_block != 0 || entry2->e_value_block != 0) -+ return -EIO; -+ if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), -+ (char *)header2 + le16_to_cpu(entry2->e_value_offs), -+ le32_to_cpu(entry1->e_value_size))) -+ return 1; -+ -+ entry1 = EXT3_XATTR_NEXT(entry1); -+ entry2 = EXT3_XATTR_NEXT(entry2); -+ } -+ if (!IS_LAST_ENTRY(entry2)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * ext3_xattr_cache_find() -+ * -+ * Find an identical extended attribute block. -+ * -+ * Returns a pointer to the block found, or NULL if such a block was -+ * not found or an error occurred. -+ */ -+static struct buffer_head * -+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header) -+{ -+ __u32 hash = le32_to_cpu(header->h_hash); -+ struct mb_cache_entry *ce; -+ -+ if (!header->h_hash) -+ return NULL; /* never share */ -+ ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); -+ ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash); -+ while (ce) { -+ struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block); -+ -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_cache_find", -+ "inode %ld: block %ld read error", -+ inode->i_ino, ce->e_block); -+ } else if (le32_to_cpu(HDR(bh)->h_refcount) > -+ EXT3_XATTR_REFCOUNT_MAX) { -+ ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block, -+ le32_to_cpu(HDR(bh)->h_refcount), -+ EXT3_XATTR_REFCOUNT_MAX); -+ } else if (!ext3_xattr_cmp(header, HDR(bh))) { -+ ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count))); -+ mb_cache_entry_release(ce); -+ return bh; -+ } -+ brelse(bh); -+ ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash); -+ } -+ return NULL; -+} -+ -+/* -+ * ext3_xattr_cache_remove() -+ * -+ * Remove the cache entry of a block from the cache. Called when a -+ * block becomes invalid. -+ */ -+static void -+ext3_xattr_cache_remove(struct buffer_head *bh) -+{ -+ struct mb_cache_entry *ce; -+ -+ ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr); -+ if (ce) { -+ ea_bdebug(bh, "removing (%d cache entries remaining)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)-1); -+ mb_cache_entry_free(ce); -+ } else -+ ea_bdebug(bh, "no cache entry"); -+} -+ -+#define NAME_HASH_SHIFT 5 -+#define VALUE_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_hash_entry() -+ * -+ * Compute the hash of an extended attribute. -+ */ -+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ __u32 hash = 0; -+ char *name = entry->e_name; -+ int n; -+ -+ for (n=0; n < entry->e_name_len; n++) { -+ hash = (hash << NAME_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ -+ *name++; -+ } -+ -+ if (entry->e_value_block == 0 && entry->e_value_size != 0) { -+ __u32 *value = (__u32 *)((char *)header + -+ le16_to_cpu(entry->e_value_offs)); -+ for (n = (le32_to_cpu(entry->e_value_size) + -+ EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) { -+ hash = (hash << VALUE_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ -+ le32_to_cpu(*value++); -+ } -+ } -+ entry->e_hash = cpu_to_le32(hash); -+} -+ -+#undef NAME_HASH_SHIFT -+#undef VALUE_HASH_SHIFT -+ -+#define BLOCK_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_rehash() -+ * -+ * Re-compute the extended attribute hash value after an entry has changed. -+ */ -+static void ext3_xattr_rehash(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ struct ext3_xattr_entry *here; -+ __u32 hash = 0; -+ -+ ext3_xattr_hash_entry(header, entry); -+ here = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(here)) { -+ if (!here->e_hash) { -+ /* Block is not shared if an entry's hash value == 0 */ -+ hash = 0; -+ break; -+ } -+ hash = (hash << BLOCK_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^ -+ le32_to_cpu(here->e_hash); -+ here = EXT3_XATTR_NEXT(here); -+ } -+ header->h_hash = cpu_to_le32(hash); -+} -+ -+#undef BLOCK_HASH_SHIFT -+ -+int __init -+init_ext3_xattr(void) -+{ -+ ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL, -+ sizeof(struct mb_cache_entry) + -+ sizeof(struct mb_cache_entry_index), 1, 61); -+ if (!ext3_xattr_cache) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+void -+exit_ext3_xattr(void) -+{ -+ if (ext3_xattr_cache) -+ mb_cache_destroy(ext3_xattr_cache); -+ ext3_xattr_cache = NULL; -+} -+ -+#else /* CONFIG_EXT3_FS_XATTR_SHARING */ -+ -+int __init -+init_ext3_xattr(void) -+{ -+ return 0; -+} -+ -+void -+exit_ext3_xattr(void) -+{ -+} -+ -+#endif /* CONFIG_EXT3_FS_XATTR_SHARING */ -diff -Nur linux-2.4.18/include/linux/ext3_fs.h linux-2.4.18ea/include/linux/ext3_fs.h ---- linux-2.4.18/include/linux/ext3_fs.h Sun Feb 24 04:42:59 2002 -+++ linux-2.4.18ea/include/linux/ext3_fs.h Mon Mar 11 03:27:00 2002 -@@ -58,8 +58,6 @@ - */ - #define EXT3_BAD_INO 1 /* Bad blocks inode */ - #define EXT3_ROOT_INO 2 /* Root inode */ --#define EXT3_ACL_IDX_INO 3 /* ACL inode */ --#define EXT3_ACL_DATA_INO 4 /* ACL inode */ - #define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ - #define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ - #define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ -@@ -89,7 +87,6 @@ - #else - # define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) - #endif --#define EXT3_ACLE_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry)) - #define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) - #ifdef __KERNEL__ - # define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -@@ -124,28 +121,6 @@ - #endif - - /* -- * ACL structures -- */ --struct ext3_acl_header /* Header of Access Control Lists */ --{ -- __u32 aclh_size; -- __u32 aclh_file_count; -- __u32 aclh_acle_count; -- __u32 aclh_first_acle; --}; -- --struct ext3_acl_entry /* Access Control List Entry */ --{ -- __u32 acle_size; -- __u16 acle_perms; /* Access permissions */ -- __u16 acle_type; /* Type of entry */ -- __u16 acle_tag; /* User or group identity */ -- __u16 acle_pad1; -- __u32 acle_next; /* Pointer on next entry for the */ -- /* same inode or on next free entry */ --}; -- --/* - * Structure of a blocks group descriptor - */ - struct ext3_group_desc -@@ -512,7 +487,7 @@ - #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ - #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ - --#define EXT3_FEATURE_COMPAT_SUPP 0 -+#define EXT3_FEATURE_COMPAT_SUPP EXT3_FEATURE_COMPAT_EXT_ATTR - #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ - EXT3_FEATURE_INCOMPAT_RECOVER) - #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ -@@ -603,4 +578,22 @@ - */ - -+/* Defined for extended attributes */ -+#define CONFIG_EXT3_FS_XATTR y -+#ifndef ENOATTR -+#define ENOATTR ENODATA /* No such attribute */ -+#endif -+#ifndef ENOTSUP -+#define ENOTSUP EOPNOTSUPP /* Operation not supported */ -+#endif -+#ifndef XATTR_NAME_MAX -+#define XATTR_NAME_MAX 255 /* # chars in an extended attribute name */ -+#define XATTR_SIZE_MAX 65536 /* size of an extended attribute value (64k) */ -+#define XATTR_LIST_MAX 65536 /* size of extended attribute namelist (64k) */ -+#endif -+#ifndef XATTR_CREATE -+#define XATTR_CREATE 1 /* set value, fail if attr already exists */ -+#define XATTR_REPLACE 2 /* set value, fail if attr does not exist */ -+#endif -+ - /* - * Ok, these declarations are also in but none of the -@@ -628,6 +603,7 @@ - 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 *); - -@@ -694,8 +670,10 @@ - - /* namei.c */ - extern struct inode_operations ext3_dir_inode_operations; -+extern struct inode_operations ext3_special_inode_operations; - - /* symlink.c */ -+extern struct inode_operations ext3_symlink_inode_operations; - extern struct inode_operations ext3_fast_symlink_inode_operations; - - -diff -Nur linux-2.4.18/include/linux/ext3_jbd.h linux-2.4.18ea/include/linux/ext3_jbd.h ---- linux-2.4.18/include/linux/ext3_jbd.h Fri Dec 21 18:42:03 2001 -+++ linux-2.4.18ea/include/linux/ext3_jbd.h Mon Mar 25 00:11:36 2002 -@@ -30,13 +30,19 @@ - - #define EXT3_SINGLEDATA_TRANS_BLOCKS 8 - -+/* Extended attributes may touch two data buffers, two bitmap buffers, -+ * and two group and summaries. */ -+ -+#define EXT3_XATTR_TRANS_BLOCKS 8 -+ - /* Define the minimum size for a transaction which modifies data. This - * needs to take into account the fact that we may end up modifying two - * quota files too (one for the group, one for the user quota). The - * superblock only gets updated once, of course, so don't bother - * counting that again for the quota updates. */ - --#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2) -+#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \ -+ EXT3_XATTR_TRANS_BLOCKS - 2) - - extern int ext3_writepage_trans_blocks(struct inode *inode); - -diff -Nur linux-2.4.18/include/linux/ext3_xattr.h linux-2.4.18ea/include/linux/ext3_xattr.h ---- linux-2.4.18/include/linux/ext3_xattr.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.18ea/include/linux/ext3_xattr.h Fri Apr 5 10:08:01 2002 -@@ -0,0 +1,155 @@ -+/* -+ 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 -+ -+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, void *buffer, -+ size_t size, int flags); -+}; -+ -+extern int ext3_xattr_register(int, struct ext3_xattr_handler *); -+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *); -+ -+extern int ext3_setxattr(struct dentry *, const char *, void *, size_t, int); -+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t); -+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); -+extern int ext3_removexattr(struct dentry *, const char *); -+ -+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t); -+extern int ext3_xattr_list(struct inode *, char *, size_t); -+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, void *, size_t, int); -+ -+extern void ext3_xattr_drop_inode(handle_t *, struct inode *); -+extern void ext3_xattr_put_super(struct super_block *); -+ -+extern int init_ext3_xattr(void) __init; -+extern void exit_ext3_xattr(void); -+ -+# else /* CONFIG_EXT3_FS_XATTR */ -+# define ext3_setxattr NULL -+# define ext3_getxattr NULL -+# define ext3_listxattr NULL -+# define ext3_removexattr NULL -+ -+static inline int -+ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t size, int flags) -+{ -+ return -ENOTSUP; -+} -+ -+static inline int -+ext3_xattr_list(struct inode *inode, void *buffer, size_t size, int flags) -+{ -+ return -ENOTSUP; -+} -+ -+static inline int -+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, void *value, size_t size, int flags) -+{ -+ return -ENOTSUP; -+} -+ -+static inline void -+ext3_xattr_drop_inode(handle_t *handle, struct inode *inode) -+{ -+} -+ -+static inline void -+ext3_xattr_put_super(struct super_block *sb) -+{ -+} -+ -+static inline int -+init_ext3_xattr(void) -+{ -+ return 0; -+} -+ -+static inline void -+exit_ext3_xattr(void) -+{ -+} -+ -+# endif /* CONFIG_EXT3_FS_XATTR */ -+ -+# ifdef CONFIG_EXT3_FS_XATTR_USER -+ -+extern int init_ext3_xattr_user(void) __init; -+extern void exit_ext3_xattr_user(void); -+ -+# else /* CONFIG_EXT3_FS_XATTR_USER */ -+ -+static inline int -+init_ext3_xattr_user(void) -+{ -+ return 0; -+} -+ -+static inline void -+exit_ext3_xattr_user(void) -+{ -+} -+ -+#endif /* CONFIG_EXT3_FS_XATTR_USER */ -+ -+#endif /* __KERNEL__ */ -+ -diff -Nur linux-2.4.18/include/linux/xattr.h linux-2.4.18ea/include/linux/xattr.h ---- linux-2.4.18/include/linux/xattr.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.18ea/include/linux/xattr.h Sun Mar 24 23:42:21 2002 -@@ -0,0 +1,15 @@ -+/* -+ File: linux/xattr.h -+ -+ Extended attributes handling. -+ -+ Copyright (C) 2001 by Andreas Gruenbacher -+ Copyright (C) 2001 SGI - Silicon Graphics, Inc -+*/ -+#ifndef _LINUX_XATTR_H -+#define _LINUX_XATTR_H -+ -+#define XATTR_CREATE 1 /* set value, fail if attr already exists */ -+#define XATTR_REPLACE 2 /* set value, fail if attr does not exist */ -+ -+#endif /* _LINUX_XATTR_H */ diff --git a/lustre/include/linux/lustre_debug.h b/lustre/include/linux/lustre_debug.h deleted file mode 100644 index a31430d..0000000 --- a/lustre/include/linux/lustre_debug.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _LUSTRE_DEBUG_H -#define _LUSTRE_DEBUG_H - -#include - -#define ASSERT_MAX_SIZE_MB 60000ULL -#define ASSERT_PAGE_INDEX(index, OP) \ -do { if (index > ASSERT_MAX_SIZE_MB << (20 - PAGE_SHIFT)) { \ - CERROR("bad page index %lu > %Lu\n", index, \ - ASSERT_MAX_SIZE_MB << (20 - PAGE_SHIFT)); \ - portal_debug = ~0UL; \ - OP; \ -}} while(0) - -#define ASSERT_FILE_OFFSET(offset, OP) \ -do { if (offset > ASSERT_MAX_SIZE_MB << 20) { \ - CERROR("bad file offset %Lu > %Lu\n", offset, \ - ASSERT_MAX_SIZE_MB << 20); \ - portal_debug = ~0UL; \ - OP; \ -}} while(0) - -/* lib/debug.c */ -int dump_lniobuf(struct niobuf_local *lnb); -int dump_rniobuf(struct niobuf_remote *rnb); -int dump_ioo(struct obd_ioobj *nb); -int dump_req(struct ptlrpc_request *req); -int dump_obdo(struct obdo *oa); -#endif diff --git a/lustre/include/linux/lustre_fsfilt.h b/lustre/include/linux/lustre_fsfilt.h deleted file mode 100644 index eeae647..0000000 --- a/lustre/include/linux/lustre_fsfilt.h +++ /dev/null @@ -1,151 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2001 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Filesystem interface helper. - * - */ - -#ifndef _LUSTRE_FSFILT_H -#define _LUSTRE_FSFILT_H - -#ifdef __KERNEL__ - -#include -#include - -typedef void (*fsfilt_cb_t)(struct obd_device *obd, __u64 last_rcvd, int error); - -struct fsfilt_objinfo { - struct dentry *fso_dentry; - int fso_bufcnt; -}; - -struct fsfilt_operations { - struct list_head fs_list; - struct module *fs_owner; - char *fs_type; - void *(* fs_start)(struct inode *inode, int op); - void *(* fs_brw_start)(int objcount, struct fsfilt_objinfo *fso, - int niocount, struct niobuf_remote *nb); - int (* fs_commit)(struct inode *inode, void *handle); - int (* fs_setattr)(struct dentry *dentry, void *handle, - struct iattr *iattr); - int (* fs_set_md)(struct inode *inode, void *handle, void *md, - int size); - int (* fs_get_md)(struct inode *inode, void *md, int size); - ssize_t (* fs_readpage)(struct file *file, char *buf, size_t count, - loff_t *offset); - int (* fs_journal_data)(struct file *file); - int (* fs_set_last_rcvd)(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func); - int (* fs_statfs)(struct super_block *sb, struct obd_statfs *osfs); -}; - -extern int fsfilt_register_ops(struct fsfilt_operations *fs_ops); -extern void fsfilt_unregister_ops(struct fsfilt_operations *fs_ops); -extern struct fsfilt_operations *fsfilt_get_ops(char *type); -extern void fsfilt_put_ops(struct fsfilt_operations *fs_ops); - -#define FSFILT_OP_UNLINK 1 -#define FSFILT_OP_RMDIR 2 -#define FSFILT_OP_RENAME 3 -#define FSFILT_OP_CREATE 4 -#define FSFILT_OP_MKDIR 5 -#define FSFILT_OP_SYMLINK 6 -#define FSFILT_OP_MKNOD 7 -#define FSFILT_OP_SETATTR 8 -#define FSFILT_OP_LINK 9 - -static inline void *fsfilt_start(struct obd_device *obd, - struct inode *inode, int op) -{ - return obd->obd_fsops->fs_start(inode, op); -} - -static inline void *fsfilt_brw_start(struct obd_device *obd, int objcount, - struct fsfilt_objinfo *fso, int niocount, - struct niobuf_remote *nb) -{ - return obd->obd_fsops->fs_brw_start(objcount, fso, niocount, nb); -} - -static inline int fsfilt_commit(struct obd_device *obd, struct inode *inode, - void *handle) -{ - return obd->obd_fsops->fs_commit(inode, handle); -} - -static inline int fsfilt_setattr(struct obd_device *obd, struct dentry *dentry, - void *handle, struct iattr *iattr) -{ - int rc; - /* - * NOTE: we probably don't need to take i_sem here when changing - * ATTR_SIZE because the MDS never needs to truncate a file. - * The ext2/ext3 code never truncates a directory, and files - * stored on the MDS are entirely sparse (no data blocks). - * If we do need to get it, we can do it here. - */ - lock_kernel(); - rc = obd->obd_fsops->fs_setattr(dentry, handle, iattr); - unlock_kernel(); - - return rc; -} - -static inline int fsfilt_set_md(struct obd_device *obd, struct inode *inode, - void *handle, void *md, int size) -{ - return obd->obd_fsops->fs_set_md(inode, handle, md, size); -} - -static inline int fsfilt_get_md(struct obd_device *obd, struct inode *inode, - void *md, int size) -{ - return obd->obd_fsops->fs_get_md(inode, md, size); -} - -static inline ssize_t fsfilt_readpage(struct obd_device *obd, - struct file *file, char *buf, - size_t count, loff_t *offset) -{ - return obd->obd_fsops->fs_readpage(file, buf, count, offset); -} - -static inline int fsfilt_journal_data(struct obd_device *obd, struct file *file) -{ - return obd->obd_fsops->fs_journal_data(file); -} - -static inline int fsfilt_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func) -{ - return obd->obd_fsops->fs_set_last_rcvd(obd, last_rcvd,handle,cb_func); -} - -static inline int fsfilt_statfs(struct obd_device *obd, struct super_block *fs, - struct obd_statfs *osfs) -{ - return obd->obd_fsops->fs_statfs(fs, osfs); -} - -#endif /* __KERNEL__ */ - -#endif diff --git a/lustre/include/linux/obd_cache.h b/lustre/include/linux/obd_cache.h deleted file mode 100644 index e75b9f4..0000000 --- a/lustre/include/linux/obd_cache.h +++ /dev/null @@ -1,13 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - */ - -#ifndef _OBD_CACHE_H__ -#define _OBD_CACHE_H__ - -#ifdef __KERNEL__ - -#define OBD_CACHE_DEVICENAME "cobd" - -#endif -#endif diff --git a/lustre/include/linux/obd_lov.h b/lustre/include/linux/obd_lov.h deleted file mode 100644 index 9cfbd85..0000000 --- a/lustre/include/linux/obd_lov.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - */ - -#ifndef _OBD_LOV_H__ -#define _OBD_LOV_H__ - -#ifdef __KERNEL__ - -#define OBD_LOV_DEVICENAME "lov" - -struct lov_object_id { /* per-child structure */ - __u64 l_object_id; - __u32 l_device_id; -}; - -struct lov_md { - __u64 lmd_object_id; /* lov object id */ - __u64 lmd_stripe_count; - __u32 lmd_stripe_size; - __u32 lmd_stripe_pattern; /* per-lov object stripe pattern */ - struct lov_object_id lmd_objects[0]; -}; - -#endif -#endif diff --git a/lustre/kernel_patches/lustre-2.5-from809-812.patch b/lustre/kernel_patches/lustre-2.5-from809-812.patch deleted file mode 100644 index 07618d6..0000000 --- a/lustre/kernel_patches/lustre-2.5-from809-812.patch +++ /dev/null @@ -1,3374 +0,0 @@ -# This is a BitKeeper generated patch for the following project: -# Project Name: Linux kernel tree -# This patch format is intended for GNU patch command version 2.5 or higher. -# This patch includes the following deltas: -# ChangeSet 1.809 -> 1.812 -# kernel/ksyms.c 1.149 -> 1.151 -# fs/ext3/Makefile 1.4 -> 1.5 -# include/linux/ext3_jbd.h 1.5 -> 1.6 -# fs/driverfs/inode.c 1.52 -> 1.53 -# include/linux/fs.h 1.175 -> 1.177 -# include/linux/namei.h 1.3 -> 1.4 -# fs/namei.c 1.56 -> 1.58 -# fs/nfsd/vfs.c 1.44 -> 1.45 -# arch/um/kernel/mem.c 1.5 -> 1.6 -# fs/ext3/ialloc.c 1.17 -> 1.18 -# fs/ext3/symlink.c 1.3 -> 1.4 -# fs/Makefile 1.42 -> 1.43 -# fs/ext3/namei.c 1.22 -> 1.23 -# include/linux/ext3_fs.h 1.11 -> 1.12 -# net/unix/af_unix.c 1.29 -> 1.30 -# fs/Config.in 1.39 -> 1.40 -# fs/ext3/inode.c 1.42 -> 1.43 -# fs/Config.help 1.21 -> 1.22 -# mm/slab.c 1.33 -> 1.34 -# fs/sysfs/inode.c 1.55 -> 1.56 -# fs/ext3/super.c 1.33 -> 1.34 -# fs/ext3/file.c 1.9 -> 1.10 -# include/linux/slab.h 1.13 -> 1.14 -# include/linux/dcache.h 1.19 -> 1.20 -# (new) -> 1.1 fs/ext3/xattr.h -# (new) -> 1.1 include/linux/mbcache.h -# (new) -> 1.1 include/linux/lustre_version.h -# (new) -> 1.2 fs/ext3/xattr.c -# (new) -> 1.1 fs/mbcache.c -# (new) -> 1.1 fs/ext3/xattr_user.c -# -# The following is the BitKeeper ChangeSet Log -# -------------------------------------------- -# 02/10/20 braam@clusterfs.com 1.810 -# xattrs for UML bk repository -# -------------------------------------------- -# 02/10/20 braam@clusterfs.com 1.811 -# Changes for Lustre -# -------------------------------------------- -# 02/12/11 root@kai.(none) 1.812 -# changed for lustre -# -------------------------------------------- -# -diff -Nru a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c ---- a/arch/um/kernel/mem.c Thu Dec 12 20:58:37 2002 -+++ b/arch/um/kernel/mem.c Thu Dec 12 20:58:37 2002 -@@ -656,6 +656,22 @@ - return(phys_mem_map(pte_val(pte))); - } - -+struct page *check_get_page(unsigned long kaddr) -+{ -+ struct page *page; -+ struct mem_region *mr; -+ unsigned long phys = __pa(kaddr); -+ unsigned int n = phys_region_index(phys); -+ -+ if(regions[n] == NULL) -+ return NULL; -+ -+ mr = regions[n]; -+ page = (struct page *) mr->mem_map; -+ return page + ((phys_addr(phys)) >> PAGE_SHIFT); -+} -+ -+ - struct mem_region *page_region(struct page *page, int *index_out) - { - int i; -@@ -743,7 +759,7 @@ - (addr <= region->start + region->len)) - return(mk_phys(addr - region->start, i)); - } -- panic("region_pa : no region for virtual address"); -+ //panic("region_pa : no region for virtual address"); - return(0); - } - -diff -Nru a/fs/Config.help b/fs/Config.help ---- a/fs/Config.help Thu Dec 12 20:58:37 2002 -+++ b/fs/Config.help Thu Dec 12 20:58:37 2002 -@@ -154,6 +154,13 @@ - of your root partition (the one containing the directory /) cannot - be compiled as a module, and so this may be dangerous. - -+CONFIG_EXT3_FS_XATTR -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page, or visit -+ for details). -+ -+ If unsure, say N. -+ - CONFIG_JBD - This is a generic journaling layer for block devices. It is - currently used by the ext3 file system, but it could also be used to -diff -Nru a/fs/Config.in b/fs/Config.in ---- a/fs/Config.in Thu Dec 12 20:58:37 2002 -+++ b/fs/Config.in Thu Dec 12 20:58:37 2002 -@@ -27,6 +27,7 @@ - dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL - - tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS -+dep_mbool ' Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS - # CONFIG_JBD could be its own option (even modular), but until there are - # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS - # dep_tristate ' Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS -@@ -180,6 +181,17 @@ - define_tristate CONFIG_ZISOFS_FS $CONFIG_ISO9660_FS - else - define_tristate CONFIG_ZISOFS_FS n -+fi -+ -+# Meta block cache for Extended Attributes (ext2/ext3) -+if [ "$CONFIG_EXT2_FS_XATTR" = "y" -o "$CONFIG_EXT3_FS_XATTR" = "y" ]; then -+ if [ "$CONFIG_EXT2_FS" = "y" -o "$CONFIG_EXT3_FS" = "y" ]; then -+ define_tristate CONFIG_FS_MBCACHE y -+ else -+ if [ "$CONFIG_EXT2_FS" = "m" -o "$CONFIG_EXT3_FS" = "m" ]; then -+ define_tristate CONFIG_FS_MBCACHE m -+ fi -+ fi - fi - - mainmenu_option next_comment -diff -Nru a/fs/Makefile b/fs/Makefile ---- a/fs/Makefile Thu Dec 12 20:58:37 2002 -+++ b/fs/Makefile Thu Dec 12 20:58:37 2002 -@@ -6,7 +6,7 @@ - # - - export-objs := open.o dcache.o buffer.o bio.o inode.o dquot.o mpage.o aio.o \ -- fcntl.o read_write.o dcookies.o -+ fcntl.o read_write.o dcookies.o mbcache.o - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ - bio.o super.o block_dev.o char_dev.o stat.o exec.o pipe.o \ -@@ -29,6 +29,8 @@ - obj-y += binfmt_script.o - - obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o -+ -+obj-$(CONFIG_FS_MBCACHE) += mbcache.o - - obj-$(CONFIG_QUOTA) += dquot.o - obj-$(CONFIG_QFMT_V1) += quota_v1.o -diff -Nru a/fs/driverfs/inode.c b/fs/driverfs/inode.c ---- a/fs/driverfs/inode.c Thu Dec 12 20:58:37 2002 -+++ b/fs/driverfs/inode.c Thu Dec 12 20:58:37 2002 -@@ -523,7 +523,7 @@ - qstr.name = name; - qstr.len = strlen(name); - qstr.hash = full_name_hash(name,qstr.len); -- return lookup_hash(&qstr,parent); -+ return lookup_hash(&qstr,parent, NULL); - } - - /** -diff -Nru a/fs/ext3/Makefile b/fs/ext3/Makefile ---- a/fs/ext3/Makefile Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/Makefile Thu Dec 12 20:58:37 2002 -@@ -7,4 +7,10 @@ - ext3-objs := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o hash.o - -+export-objs += xattr.o -+ -+ifeq ($(CONFIG_EXT3_FS_XATTR),y) -+ext3-objs += xattr.o xattr_user.o -+endif -+ - include $(TOPDIR)/Rules.make -diff -Nru a/fs/ext3/file.c b/fs/ext3/file.c ---- a/fs/ext3/file.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/file.c Thu Dec 12 20:58:37 2002 -@@ -23,7 +23,7 @@ - #include - #include - #include --#include -+#include "xattr.h" - - /* - * Called when an inode is released. Note that this is different -@@ -98,5 +98,9 @@ - struct inode_operations ext3_file_inode_operations = { - .truncate = ext3_truncate, - .setattr = ext3_setattr, -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, - }; - -diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c ---- a/fs/ext3/ialloc.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/ialloc.c Thu Dec 12 20:58:37 2002 -@@ -25,6 +25,8 @@ - #include - #include - -+#include "xattr.h" -+ - /* - * ialloc.c contains the inodes allocation and deallocation routines - */ -@@ -118,6 +120,7 @@ - * as writing the quota to disk may need the lock as well. - */ - DQUOT_INIT(inode); -+ ext3_xattr_delete_inode(handle, inode); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); - -diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c ---- a/fs/ext3/inode.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/inode.c Thu Dec 12 20:58:37 2002 -@@ -42,6 +42,18 @@ - */ - #undef SEARCH_FROM_ZERO - -+/* -+ * Test whether an inode is a fast symlink. -+ */ -+static inline int ext3_inode_is_fast_symlink(struct inode *inode) -+{ -+ int ea_blocks = EXT3_I(inode)->i_file_acl ? -+ (inode->i_sb->s_blocksize >> 9) : 0; -+ -+ return (S_ISLNK(inode->i_mode) && -+ inode->i_blocks - ea_blocks == 0); -+} -+ - /* The ext3 forget function must perform a revoke if we are freeing data - * which has been journaled. Metadata (eg. indirect blocks) must be - * revoked in all cases. -@@ -51,7 +63,7 @@ - * still needs to be revoked. - */ - --static int ext3_forget(handle_t *handle, int is_metadata, -+int ext3_forget(handle_t *handle, int is_metadata, - struct inode *inode, struct buffer_head *bh, - int blocknr) - { -@@ -167,9 +179,7 @@ - { - handle_t *handle; - -- if (is_bad_inode(inode) || -- inode->i_ino == EXT3_ACL_IDX_INO || -- inode->i_ino == EXT3_ACL_DATA_INO) -+ if (is_bad_inode(inode)) - goto no_delete; - - lock_kernel(); -@@ -1979,6 +1989,8 @@ - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return; -+ if (ext3_inode_is_fast_symlink(inode)) -+ return; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - return; - -@@ -2130,8 +2142,6 @@ - struct ext3_group_desc * gdp; - - if ((inode->i_ino != EXT3_ROOT_INO && -- inode->i_ino != EXT3_ACL_IDX_INO && -- inode->i_ino != EXT3_ACL_DATA_INO && - inode->i_ino != EXT3_JOURNAL_INO && - inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) || - inode->i_ino > le32_to_cpu( -@@ -2263,10 +2273,7 @@ - - brelse (iloc.bh); - -- if (inode->i_ino == EXT3_ACL_IDX_INO || -- inode->i_ino == EXT3_ACL_DATA_INO) -- /* Nothing to do */ ; -- else if (S_ISREG(inode->i_mode)) { -+ if (S_ISREG(inode->i_mode)) { - inode->i_op = &ext3_file_inode_operations; - inode->i_fop = &ext3_file_operations; - if (ext3_should_writeback_data(inode)) -@@ -2277,18 +2284,20 @@ - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; - } else if (S_ISLNK(inode->i_mode)) { -- if (!inode->i_blocks) -+ if (ext3_inode_is_fast_symlink(inode)) - inode->i_op = &ext3_fast_symlink_inode_operations; - else { -- inode->i_op = &page_symlink_inode_operations; -+ inode->i_op = &ext3_symlink_inode_operations; - if (ext3_should_writeback_data(inode)) - inode->i_mapping->a_ops = &ext3_writeback_aops; - else - inode->i_mapping->a_ops = &ext3_aops; - } -- } else -+ } else { -+ inode->i_op = &ext3_special_inode_operations; - init_special_inode(inode, inode->i_mode, - le32_to_cpu(iloc.raw_inode->i_block[0])); -+ } - if (ei->i_flags & EXT3_SYNC_FL) - inode->i_flags |= S_SYNC; - if (ei->i_flags & EXT3_APPEND_FL) -diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c ---- a/fs/ext3/namei.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/namei.c Thu Dec 12 20:58:37 2002 -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include "xattr.h" - - - /* -@@ -1654,7 +1655,7 @@ - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - -- inode = ext3_new_inode (handle, dir, S_IFDIR); -+ inode = ext3_new_inode (handle, dir, S_IFDIR | mode); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; -@@ -1662,7 +1663,6 @@ - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; - inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; -- inode->i_blocks = 0; - dir_block = ext3_bread (handle, inode, 0, 1, &err); - if (!dir_block) { - inode->i_nlink--; /* is this nlink == 0? */ -@@ -1689,9 +1689,6 @@ - BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata"); - ext3_journal_dirty_metadata(handle, dir_block); - brelse (dir_block); -- inode->i_mode = S_IFDIR | mode; -- if (dir->i_mode & S_ISGID) -- inode->i_mode |= S_ISGID; - ext3_mark_inode_dirty(handle, inode); - err = ext3_add_entry (handle, dentry, inode); - if (err) { -@@ -2068,7 +2065,7 @@ - goto out_stop; - - if (l > sizeof (EXT3_I(inode)->i_data)) { -- inode->i_op = &page_symlink_inode_operations; -+ inode->i_op = &ext3_symlink_inode_operations; - if (ext3_should_writeback_data(inode)) - inode->i_mapping->a_ops = &ext3_writeback_aops; - else -@@ -2284,4 +2281,17 @@ - .rmdir = ext3_rmdir, - .mknod = ext3_mknod, - .rename = ext3_rename, -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, - }; -+ -+struct inode_operations ext3_special_inode_operations = { -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, -+}; -+ -+ -diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c ---- a/fs/ext3/super.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/super.c Thu Dec 12 20:58:37 2002 -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include "xattr.h" - - #ifdef CONFIG_JBD_DEBUG - static int ext3_ro_after; /* Make fs read-only after this many jiffies */ -@@ -405,6 +406,7 @@ - struct ext3_super_block *es = sbi->s_es; - int i; - -+ ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { - EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); -@@ -554,6 +556,7 @@ - int is_remount) - { - unsigned long *mount_options = &sbi->s_mount_opt; -+ - uid_t *resuid = &sbi->s_resuid; - gid_t *resgid = &sbi->s_resgid; - char * this_char; -@@ -566,6 +569,13 @@ - continue; - if ((value = strchr (this_char, '=')) != NULL) - *value++ = 0; -+#ifdef CONFIG_EXT3_FS_XATTR -+ if (!strcmp (this_char, "user_xattr")) -+ set_opt (*mount_options, XATTR_USER); -+ else if (!strcmp (this_char, "nouser_xattr")) -+ clear_opt (*mount_options, XATTR_USER); -+ else -+#endif - if (!strcmp (this_char, "bsddf")) - clear_opt (*mount_options, MINIX_DF); - else if (!strcmp (this_char, "nouid32")) { -@@ -982,6 +992,12 @@ - sbi->s_mount_opt = 0; - sbi->s_resuid = EXT3_DEF_RESUID; - sbi->s_resgid = EXT3_DEF_RESGID; -+ -+ /* Default extended attribute flags */ -+#ifdef CONFIG_EXT3_FS_XATTR -+ set_opt(sbi->s_mount_opt, XATTR_USER); -+#endif -+ - if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) - goto out_fail; - -@@ -1820,7 +1836,10 @@ - - static int __init init_ext3_fs(void) - { -- int err = init_inodecache(); -+ int err = init_ext3_xattr(); -+ if (err) -+ return err; -+ err = init_inodecache(); - if (err) - goto out1; - err = register_filesystem(&ext3_fs_type); -@@ -1830,6 +1849,7 @@ - out: - destroy_inodecache(); - out1: -+ exit_ext3_xattr(); - return err; - } - -@@ -1837,6 +1857,7 @@ - { - unregister_filesystem(&ext3_fs_type); - destroy_inodecache(); -+ exit_ext3_xattr(); - } - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); -diff -Nru a/fs/ext3/symlink.c b/fs/ext3/symlink.c ---- a/fs/ext3/symlink.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/symlink.c Thu Dec 12 20:58:37 2002 -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include "xattr.h" - - static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen) - { -@@ -33,7 +34,20 @@ - return vfs_follow_link(nd, (char*)ei->i_data); - } - -+struct inode_operations ext3_symlink_inode_operations = { -+ .readlink = page_readlink, -+ .follow_link = page_follow_link, -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, -+}; -+ - struct inode_operations ext3_fast_symlink_inode_operations = { -- .readlink = ext3_readlink, /* BKL not held. Don't need */ -+ .readlink = ext3_readlink, /* BKL not held. Don't need */ - .follow_link = ext3_follow_link, /* BKL not held. Don't need */ -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, - }; -diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/ext3/xattr.c Thu Dec 12 20:58:37 2002 -@@ -0,0 +1,1131 @@ -+/* -+ * 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 holdsinode->i_sem semaphore when any of the xattr inode -+ * operations are called, so we are guaranteed that only one -+ * processes accesses extended attributes of an inode at any time. -+ * -+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that -+ * only a single process is modifying an extended attribute block, even -+ * if the block is shared among inodes. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "xattr.h" -+ -+#define EXT3_EA_USER "user." -+ -+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data)) -+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr)) -+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1) -+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) -+ -+#ifdef EXT3_XATTR_DEBUG -+# define ea_idebug(inode, f...) do { \ -+ printk(KERN_DEBUG "inode %s:%ld: ", \ -+ kdevname(inode->i_dev), inode->i_ino); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+# define ea_bdebug(bh, f...) do { \ -+ printk(KERN_DEBUG "block %s:%ld: ", \ -+ kdevname(bh->b_dev), bh->b_blocknr); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+#else -+# define ea_idebug(f...) -+# define ea_bdebug(f...) -+#endif -+ -+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *, -+ struct ext3_xattr_header *); -+ -+static int ext3_xattr_cache_insert(struct buffer_head *); -+static struct buffer_head *ext3_xattr_cache_find(struct inode *, -+ struct ext3_xattr_header *); -+static void ext3_xattr_cache_remove(struct buffer_head *); -+static void ext3_xattr_rehash(struct ext3_xattr_header *, -+ struct ext3_xattr_entry *); -+ -+static struct mb_cache *ext3_xattr_cache; -+ -+/* -+ * If a file system does not share extended attributes among inodes, -+ * we should not need the ext3_xattr_sem semaphore. However, the -+ * filesystem may still contain shared blocks, so we always take -+ * the lock. -+ */ -+ -+static DECLARE_MUTEX(ext3_xattr_sem); -+static struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX]; -+static rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED; -+ -+int -+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler) -+{ -+ int error = -EINVAL; -+ -+ if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ if (!ext3_xattr_handlers[name_index-1]) { -+ ext3_xattr_handlers[name_index-1] = handler; -+ error = 0; -+ } -+ write_unlock(&ext3_handler_lock); -+ } -+ return error; -+} -+ -+void -+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler) -+{ -+ if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ ext3_xattr_handlers[name_index-1] = NULL; -+ write_unlock(&ext3_handler_lock); -+ } -+} -+ -+static inline const char * -+strcmp_prefix(const char *a, const char *a_prefix) -+{ -+ while (*a_prefix && *a == *a_prefix) { -+ a++; -+ a_prefix++; -+ } -+ return *a_prefix ? NULL : a; -+} -+ -+/* -+ * Decode the extended attribute name, and translate it into -+ * the name_index and name suffix. -+ */ -+static inline struct ext3_xattr_handler * -+ext3_xattr_resolve_name(const char **name) -+{ -+ struct ext3_xattr_handler *handler = NULL; -+ int i; -+ -+ if (!*name) -+ return NULL; -+ read_lock(&ext3_handler_lock); -+ for (i=0; 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 -+ */ -+ssize_t -+ext3_getxattr(struct dentry *dentry, const char *name, -+ void *buffer, size_t size) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -EOPNOTSUPP; -+ return handler->get(inode, name, buffer, size); -+} -+ -+/* -+ * Inode operation listxattr() -+ * -+ * dentry->d_inode->i_sem down -+ */ -+ssize_t -+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size) -+{ -+ return ext3_xattr_list(dentry->d_inode, buffer, size); -+} -+ -+/* -+ * Inode operation setxattr() -+ * -+ * dentry->d_inode->i_sem down -+ */ -+int -+ext3_setxattr(struct dentry *dentry, const char *name, -+ void *value, size_t size, int flags) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ if (size == 0) -+ value = ""; /* empty EA, do not remove */ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -EOPNOTSUPP; -+ return handler->set(inode, name, value, size, flags); -+} -+ -+/* -+ * Inode operation removexattr() -+ * -+ * dentry->d_inode->i_sem down -+ */ -+int -+ext3_removexattr(struct dentry *dentry, const char *name) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -EOPNOTSUPP; -+ return handler->set(inode, name, NULL, 0, XATTR_REPLACE); -+} -+ -+/* -+ * ext3_xattr_get() -+ * -+ * Copy an extended attribute into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_entry *entry; -+ unsigned int block, size; -+ char *end; -+ int name_len, error; -+ -+ ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", -+ name_index, name, buffer, (long)buffer_size); -+ -+ if (name == NULL) -+ return -EINVAL; -+ if (!EXT3_I(inode)->i_file_acl) -+ return -ENODATA; -+ block = EXT3_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(inode->i_sb, "ext3_xattr_get", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* find named attribute */ -+ name_len = strlen(name); -+ -+ error = -ERANGE; -+ if (name_len > 255) -+ goto cleanup; -+ entry = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (name_index == entry->e_name_index && -+ name_len == entry->e_name_len && -+ memcmp(name, entry->e_name, name_len) == 0) -+ goto found; -+ entry = next; -+ } -+ /* Check the remaining name entries */ -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ entry = next; -+ } -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ error = -ENODATA; -+ goto cleanup; -+found: -+ /* check the buffer size */ -+ if (entry->e_value_block != 0) -+ goto bad_block; -+ size = le32_to_cpu(entry->e_value_size); -+ if (size > inode->i_sb->s_blocksize || -+ le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize) -+ goto bad_block; -+ -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (buffer) { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ /* return value of attribute */ -+ memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs), -+ size); -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_list() -+ * -+ * Copy a list of attribute names into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_entry *entry; -+ unsigned int block, size = 0; -+ char *buf, *end; -+ int error; -+ -+ ea_idebug(inode, "buffer=%p, buffer_size=%ld", -+ buffer, (long)buffer_size); -+ -+ if (!EXT3_I(inode)->i_file_acl) -+ return 0; -+ block = EXT3_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(inode->i_sb, "ext3_xattr_list", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* compute the size required for the list of attribute names */ -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT3_XATTR_NEXT(entry)) { -+ struct ext3_xattr_handler *handler; -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ -+ handler = ext3_xattr_handler(entry->e_name_index); -+ if (handler) { -+ size += handler->list(NULL, inode, entry->e_name, -+ entry->e_name_len) + 1; -+ } -+ } -+ -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (!buffer) { -+ error = size; -+ goto cleanup; -+ } else { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ } -+ -+ /* list the attribute names */ -+ buf = buffer; -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT3_XATTR_NEXT(entry)) { -+ struct ext3_xattr_handler *handler; -+ -+ handler = ext3_xattr_handler(entry->e_name_index); -+ if (handler) { -+ buf += handler->list(buf, inode, entry->e_name, -+ entry->e_name_len); -+ *buf++ = '\0'; -+ } -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is -+ * not set, set it. -+ */ -+static void ext3_xattr_update_super_block(handle_t *handle, -+ struct super_block *sb) -+{ -+ if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) -+ return; -+ -+ lock_super(sb); -+ ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -+ EXT3_SB(sb)->s_es->s_feature_compat |= -+ cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR); -+ sb->s_dirt = 1; -+ ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -+ unlock_super(sb); -+} -+ -+/* -+ * ext3_xattr_set() -+ * -+ * Create, replace or remove an extended attribute for this inode. Buffer -+ * is NULL to remove an existing extended attribute, and non-NULL to -+ * either replace an existing extended attribute, or create a new extended -+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE -+ * specify that an extended attribute must exist and must not exist -+ * previous to the call, respectively. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+int -+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, const void *value, size_t value_len, int flags) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_header *header = NULL; -+ struct ext3_xattr_entry *here, *last; -+ unsigned int name_len; -+ int min_offs = sb->s_blocksize, not_found = 1, free, error; -+ char *end; -+ -+ /* -+ * header -- Points either into bh, or to a temporarily -+ * allocated buffer. -+ * here -- The named entry found, or the place for inserting, within -+ * the block pointed to by header. -+ * last -- Points right after the last named entry within the block -+ * pointed to by header. -+ * min_offs -- The offset of the first value (values are aligned -+ * towards the end of the block). -+ * end -- Points right after the block pointed to by header. -+ */ -+ -+ ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld", -+ name_index, name, value, (long)value_len); -+ -+ if (IS_RDONLY(inode)) -+ return -EROFS; -+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -+ return -EPERM; -+ if (value == NULL) -+ value_len = 0; -+ if (name == NULL) -+ return -EINVAL; -+ name_len = strlen(name); -+ if (name_len > 255 || value_len > sb->s_blocksize) -+ return -ERANGE; -+ down(&ext3_xattr_sem); -+ -+ if (EXT3_I(inode)->i_file_acl) { -+ /* The inode already has an extended attribute block. */ -+ int block = EXT3_I(inode)->i_file_acl; -+ -+ bh = sb_bread(sb, block); -+ error = -EIO; -+ if (!bh) -+ goto cleanup; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), -+ le32_to_cpu(HDR(bh)->h_refcount)); -+ header = HDR(bh); -+ end = bh->b_data + bh->b_size; -+ if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ header->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(sb, "ext3_xattr_set", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* Find the named attribute. */ -+ here = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(here)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!here->e_value_block && here->e_value_size) { -+ int offs = le16_to_cpu(here->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ not_found = name_index - here->e_name_index; -+ if (!not_found) -+ not_found = name_len - here->e_name_len; -+ if (!not_found) -+ not_found = memcmp(name, here->e_name,name_len); -+ if (not_found <= 0) -+ break; -+ here = next; -+ } -+ last = here; -+ /* We still need to compute min_offs and last. */ -+ while (!IS_LAST_ENTRY(last)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!last->e_value_block && last->e_value_size) { -+ int offs = le16_to_cpu(last->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ last = next; -+ } -+ -+ /* Check whether we have enough space left. */ -+ free = min_offs - ((char*)last - (char*)header) - sizeof(__u32); -+ } else { -+ /* We will use a new extended attribute block. */ -+ free = sb->s_blocksize - -+ sizeof(struct ext3_xattr_header) - sizeof(__u32); -+ here = last = NULL; /* avoid gcc uninitialized warning. */ -+ } -+ -+ if (not_found) { -+ /* Request to remove a nonexistent attribute? */ -+ error = -ENODATA; -+ if (flags & XATTR_REPLACE) -+ goto cleanup; -+ error = 0; -+ if (value == NULL) -+ goto cleanup; -+ else -+ free -= EXT3_XATTR_LEN(name_len); -+ } else { -+ /* Request to create an existing attribute? */ -+ error = -EEXIST; -+ if (flags & XATTR_CREATE) -+ goto cleanup; -+ if (!here->e_value_block && here->e_value_size) { -+ unsigned int size = le32_to_cpu(here->e_value_size); -+ -+ if (le16_to_cpu(here->e_value_offs) + size > -+ sb->s_blocksize || size > sb->s_blocksize) -+ goto bad_block; -+ free += EXT3_XATTR_SIZE(size); -+ } -+ } -+ free -= EXT3_XATTR_SIZE(value_len); -+ error = -ENOSPC; -+ if (free < 0) -+ goto cleanup; -+ -+ /* Here we know that we can set the new attribute. */ -+ -+ if (header) { -+ if (header->h_refcount == cpu_to_le32(1)) { -+ ea_bdebug(bh, "modifying in-place"); -+ ext3_xattr_cache_remove(bh); -+ error = ext3_journal_get_write_access(handle, bh); -+ if (error) -+ goto cleanup; -+ } else { -+ int offset; -+ -+ ea_bdebug(bh, "cloning"); -+ header = kmalloc(bh->b_size, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memcpy(header, HDR(bh), bh->b_size); -+ header->h_refcount = cpu_to_le32(1); -+ offset = (char *)header - bh->b_data; -+ here = ENTRY((char *)here + offset); -+ last = ENTRY((char *)last + offset); -+ } -+ } else { -+ /* Allocate a buffer where we construct the new block. */ -+ header = kmalloc(sb->s_blocksize, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memset(header, 0, sb->s_blocksize); -+ end = (char *)header + sb->s_blocksize; -+ header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC); -+ header->h_blocks = header->h_refcount = cpu_to_le32(1); -+ last = here = ENTRY(header+1); -+ } -+ -+ if (not_found) { -+ /* Insert the new name. */ -+ int size = EXT3_XATTR_LEN(name_len); -+ int rest = (char *)last - (char *)here; -+ memmove((char *)here + size, here, rest); -+ memset(here, 0, size); -+ here->e_name_index = name_index; -+ here->e_name_len = name_len; -+ memcpy(here->e_name, name, name_len); -+ } else { -+ /* Remove the old value. */ -+ if (!here->e_value_block && here->e_value_size) { -+ char *first_val = (char *)header + min_offs; -+ int offs = le16_to_cpu(here->e_value_offs); -+ char *val = (char *)header + offs; -+ size_t size = EXT3_XATTR_SIZE( -+ le32_to_cpu(here->e_value_size)); -+ memmove(first_val + size, first_val, val - first_val); -+ memset(first_val, 0, size); -+ here->e_value_offs = 0; -+ min_offs += size; -+ -+ /* Adjust all value offsets. */ -+ last = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(last)) { -+ int o = le16_to_cpu(last->e_value_offs); -+ if (!last->e_value_block && o < offs) -+ last->e_value_offs = -+ cpu_to_le16(o + size); -+ last = EXT3_XATTR_NEXT(last); -+ } -+ } -+ if (value == NULL) { -+ /* Remove this attribute. */ -+ if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) { -+ /* This block is now empty. */ -+ error = ext3_xattr_set2(handle, inode, bh,NULL); -+ goto cleanup; -+ } else { -+ /* Remove the old name. */ -+ int size = EXT3_XATTR_LEN(name_len); -+ last = ENTRY((char *)last - size); -+ memmove(here, (char*)here + size, -+ (char*)last - (char*)here); -+ memset(last, 0, size); -+ } -+ } -+ } -+ -+ if (value != NULL) { -+ /* Insert the new value. */ -+ here->e_value_size = cpu_to_le32(value_len); -+ if (value_len) { -+ size_t size = EXT3_XATTR_SIZE(value_len); -+ char *val = (char *)header + min_offs - size; -+ here->e_value_offs = -+ cpu_to_le16((char *)val - (char *)header); -+ memset(val + size - EXT3_XATTR_PAD, 0, -+ EXT3_XATTR_PAD); /* Clear the pad bytes. */ -+ memcpy(val, value, value_len); -+ } -+ } -+ ext3_xattr_rehash(header, here); -+ -+ error = ext3_xattr_set2(handle, inode, bh, header); -+ -+cleanup: -+ brelse(bh); -+ if (!(bh && header == HDR(bh))) -+ kfree(header); -+ up(&ext3_xattr_sem); -+ -+ return error; -+} -+ -+/* -+ * Second half of ext3_xattr_set(): Update the file system. -+ */ -+static int -+ext3_xattr_set2(handle_t *handle, struct inode *inode, -+ struct buffer_head *old_bh, struct ext3_xattr_header *header) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *new_bh = NULL; -+ int error; -+ -+ if (header) { -+ new_bh = ext3_xattr_cache_find(inode, header); -+ if (new_bh) { -+ /* -+ * We found an identical block in the cache. -+ * The old block will be released after updating -+ * the inode. -+ */ -+ ea_bdebug(old_bh, "reusing block %ld", -+ new_bh->b_blocknr); -+ -+ error = -EDQUOT; -+ if (DQUOT_ALLOC_BLOCK(inode, 1)) -+ goto cleanup; -+ -+ error = ext3_journal_get_write_access(handle, new_bh); -+ if (error) -+ goto cleanup; -+ HDR(new_bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(new_bh)->h_refcount) + 1); -+ ea_bdebug(new_bh, "refcount now=%d", -+ le32_to_cpu(HDR(new_bh)->h_refcount)); -+ } else if (old_bh && header == HDR(old_bh)) { -+ /* Keep this block. */ -+ new_bh = old_bh; -+ ext3_xattr_cache_insert(new_bh); -+ } else { -+ /* We need to allocate a new block */ -+ int block; -+ int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + -+ EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb); -+ -+ block = ext3_new_block(handle, inode, goal, 0, -+ 0, &error); -+ if (error) -+ goto cleanup; -+ ea_idebug(inode, "creating block %d", block); -+ -+ new_bh = sb_getblk(sb, block); -+ if (!new_bh) { -+getblk_failed: -+ ext3_free_blocks(handle, inode, block, 1); -+ error = -EIO; -+ goto cleanup; -+ } -+ lock_buffer(new_bh); -+ error = ext3_journal_get_create_access(handle, new_bh); -+ if (error) { -+ unlock_buffer(new_bh); -+ goto getblk_failed; -+ } -+ memcpy(new_bh->b_data, header, new_bh->b_size); -+ set_buffer_uptodate(new_bh); -+ unlock_buffer(new_bh); -+ ext3_xattr_cache_insert(new_bh); -+ -+ ext3_xattr_update_super_block(handle, sb); -+ } -+ error = ext3_journal_dirty_metadata(handle, new_bh); -+ if (error) -+ goto cleanup; -+ } -+ -+ /* Update the inode. */ -+ EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0; -+ inode->i_ctime = CURRENT_TIME; -+ ext3_mark_inode_dirty(handle, inode); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ -+ error = 0; -+ if (old_bh && old_bh != new_bh) { -+ /* -+ * If there was an old block, and we are not still using it, -+ * we now release the old block. -+ */ -+ unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount); -+ -+ error = ext3_journal_get_write_access(handle, old_bh); -+ if (error) -+ goto cleanup; -+ if (refcount == 1) { -+ /* Free the old block. */ -+ ea_bdebug(old_bh, "freeing"); -+ ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1); -+ -+ /* ext3_forget() calls bforget() for us, but we -+ let our caller release old_bh, so we need to -+ duplicate the handle before. */ -+ get_bh(old_bh); -+ ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr); -+ } else { -+ /* Decrement the refcount only. */ -+ refcount--; -+ HDR(old_bh)->h_refcount = cpu_to_le32(refcount); -+ DQUOT_FREE_BLOCK(inode, 1); -+ ext3_journal_dirty_metadata(handle, old_bh); -+ ea_bdebug(old_bh, "refcount now=%d", refcount); -+ } -+ } -+ -+cleanup: -+ if (old_bh != new_bh) -+ brelse(new_bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_delete_inode() -+ * -+ * Free extended attribute resources associated with this inode. This -+ * is called immediately before an inode is freed. -+ */ -+void -+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode) -+{ -+ struct buffer_head *bh; -+ unsigned int block = EXT3_I(inode)->i_file_acl; -+ -+ if (!block) -+ return; -+ down(&ext3_xattr_sem); -+ -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_delete_inode", -+ "inode %ld: block %d read error", inode->i_ino, block); -+ goto cleanup; -+ } -+ ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count))); -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+ ext3_error(inode->i_sb, "ext3_xattr_delete_inode", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ goto cleanup; -+ } -+ ext3_journal_get_write_access(handle, bh); -+ ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ if (HDR(bh)->h_refcount == cpu_to_le32(1)) { -+ ext3_xattr_cache_remove(bh); -+ ext3_free_blocks(handle, inode, block, 1); -+ ext3_forget(handle, 1, inode, bh, block); -+ bh = NULL; -+ } else { -+ HDR(bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ ext3_journal_dirty_metadata(handle, bh); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ DQUOT_FREE_BLOCK(inode, 1); -+ } -+ EXT3_I(inode)->i_file_acl = 0; -+ -+cleanup: -+ brelse(bh); -+ up(&ext3_xattr_sem); -+} -+ -+/* -+ * ext3_xattr_put_super() -+ * -+ * This is called when a file system is unmounted. -+ */ -+void -+ext3_xattr_put_super(struct super_block *sb) -+{ -+ mb_cache_shrink(ext3_xattr_cache, sb->s_bdev); -+} -+ -+/* -+ * ext3_xattr_cache_insert() -+ * -+ * Create a new entry in the extended attribute cache, and insert -+ * it unless such an entry is already in the cache. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+static int -+ext3_xattr_cache_insert(struct buffer_head *bh) -+{ -+ __u32 hash = le32_to_cpu(HDR(bh)->h_hash); -+ struct mb_cache_entry *ce; -+ int error; -+ -+ ce = mb_cache_entry_alloc(ext3_xattr_cache); -+ if (!ce) -+ return -ENOMEM; -+ error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash); -+ if (error) { -+ mb_cache_entry_free(ce); -+ if (error == -EBUSY) { -+ ea_bdebug(bh, "already in cache (%d cache entries)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ error = 0; -+ } -+ } else { -+ ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash, -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ mb_cache_entry_release(ce); -+ } -+ return error; -+} -+ -+/* -+ * ext3_xattr_cmp() -+ * -+ * Compare two extended attribute blocks for equality. -+ * -+ * Returns 0 if the blocks are equal, 1 if they differ, and -+ * a negative error number on errors. -+ */ -+static int -+ext3_xattr_cmp(struct ext3_xattr_header *header1, -+ struct ext3_xattr_header *header2) -+{ -+ struct ext3_xattr_entry *entry1, *entry2; -+ -+ entry1 = ENTRY(header1+1); -+ entry2 = ENTRY(header2+1); -+ while (!IS_LAST_ENTRY(entry1)) { -+ if (IS_LAST_ENTRY(entry2)) -+ return 1; -+ if (entry1->e_hash != entry2->e_hash || -+ entry1->e_name_len != entry2->e_name_len || -+ entry1->e_value_size != entry2->e_value_size || -+ memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len)) -+ return 1; -+ if (entry1->e_value_block != 0 || entry2->e_value_block != 0) -+ return -EIO; -+ if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), -+ (char *)header2 + le16_to_cpu(entry2->e_value_offs), -+ le32_to_cpu(entry1->e_value_size))) -+ return 1; -+ -+ entry1 = EXT3_XATTR_NEXT(entry1); -+ entry2 = EXT3_XATTR_NEXT(entry2); -+ } -+ if (!IS_LAST_ENTRY(entry2)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * ext3_xattr_cache_find() -+ * -+ * Find an identical extended attribute block. -+ * -+ * Returns a pointer to the block found, or NULL if such a block was -+ * not found or an error occurred. -+ */ -+static struct buffer_head * -+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header) -+{ -+ __u32 hash = le32_to_cpu(header->h_hash); -+ struct mb_cache_entry *ce; -+ -+ if (!header->h_hash) -+ return NULL; /* never share */ -+ ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); -+ ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_bdev, hash); -+ while (ce) { -+ struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block); -+ -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_cache_find", -+ "inode %ld: block %ld read error", -+ inode->i_ino, (unsigned long) ce->e_block); -+ } else if (le32_to_cpu(HDR(bh)->h_refcount) > -+ EXT3_XATTR_REFCOUNT_MAX) { -+ ea_idebug(inode, "block %ld refcount %d>%d", -+ (unsigned long) ce->e_block, -+ le32_to_cpu(HDR(bh)->h_refcount), -+ EXT3_XATTR_REFCOUNT_MAX); -+ } else if (!ext3_xattr_cmp(header, HDR(bh))) { -+ ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count))); -+ mb_cache_entry_release(ce); -+ return bh; -+ } -+ brelse(bh); -+ ce = mb_cache_entry_find_next(ce, 0, inode->i_bdev, hash); -+ } -+ return NULL; -+} -+ -+/* -+ * ext3_xattr_cache_remove() -+ * -+ * Remove the cache entry of a block from the cache. Called when a -+ * block becomes invalid. -+ */ -+static void -+ext3_xattr_cache_remove(struct buffer_head *bh) -+{ -+ struct mb_cache_entry *ce; -+ -+ ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev, -+ bh->b_blocknr); -+ if (ce) { -+ ea_bdebug(bh, "removing (%d cache entries remaining)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)-1); -+ mb_cache_entry_free(ce); -+ } else -+ ea_bdebug(bh, "no cache entry"); -+} -+ -+#define NAME_HASH_SHIFT 5 -+#define VALUE_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_hash_entry() -+ * -+ * Compute the hash of an extended attribute. -+ */ -+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ __u32 hash = 0; -+ char *name = entry->e_name; -+ int n; -+ -+ for (n=0; n < entry->e_name_len; n++) { -+ hash = (hash << NAME_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ -+ *name++; -+ } -+ -+ if (entry->e_value_block == 0 && entry->e_value_size != 0) { -+ __u32 *value = (__u32 *)((char *)header + -+ le16_to_cpu(entry->e_value_offs)); -+ for (n = (le32_to_cpu(entry->e_value_size) + -+ EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) { -+ hash = (hash << VALUE_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ -+ le32_to_cpu(*value++); -+ } -+ } -+ entry->e_hash = cpu_to_le32(hash); -+} -+ -+#undef NAME_HASH_SHIFT -+#undef VALUE_HASH_SHIFT -+ -+#define BLOCK_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_rehash() -+ * -+ * Re-compute the extended attribute hash value after an entry has changed. -+ */ -+static void ext3_xattr_rehash(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ struct ext3_xattr_entry *here; -+ __u32 hash = 0; -+ -+ ext3_xattr_hash_entry(header, entry); -+ here = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(here)) { -+ if (!here->e_hash) { -+ /* Block is not shared if an entry's hash value == 0 */ -+ hash = 0; -+ break; -+ } -+ hash = (hash << BLOCK_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^ -+ le32_to_cpu(here->e_hash); -+ here = EXT3_XATTR_NEXT(here); -+ } -+ header->h_hash = cpu_to_le32(hash); -+} -+ -+#undef BLOCK_HASH_SHIFT -+EXPORT_SYMBOL(ext3_xattr_get); -+EXPORT_SYMBOL(ext3_xattr_set); -+EXPORT_SYMBOL(ext3_bread); -+ -+int __init -+init_ext3_xattr(void) -+{ -+ int err; -+ -+ err = ext3_xattr_register(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler); -+ if (err) -+ return err; -+ ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL, -+ sizeof(struct mb_cache_entry) + -+ sizeof(struct mb_cache_entry_index), 1, 6); -+ if (!ext3_xattr_cache) { -+ ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+void -+exit_ext3_xattr(void) -+{ -+ if (ext3_xattr_cache) -+ mb_cache_destroy(ext3_xattr_cache); -+ ext3_xattr_cache = NULL; -+ ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler); -+} -+ -diff -Nru a/fs/ext3/xattr.h b/fs/ext3/xattr.h ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/ext3/xattr.h Thu Dec 12 20:58:37 2002 -@@ -0,0 +1,133 @@ -+/* -+ File: fs/ext3/xattr.h -+ -+ On-disk format of extended attributes for the ext3 filesystem. -+ -+ (C) 2001 Andreas Gruenbacher, -+*/ -+ -+#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 CONFIG_EXT3_FS_XATTR -+ -+struct ext3_xattr_handler { -+ char *prefix; -+ size_t (*list)(char *list, struct inode *inode, const char *name, -+ int name_len); -+ int (*get)(struct inode *inode, const char *name, void *buffer, -+ size_t size); -+ int (*set)(struct inode *inode, const char *name, const void *buffer, -+ size_t size, int flags); -+}; -+ -+extern int ext3_xattr_register(int, struct ext3_xattr_handler *); -+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *); -+ -+extern int ext3_setxattr(struct dentry *, const char *, void *, size_t, int); -+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t); -+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); -+extern int ext3_removexattr(struct dentry *, const char *); -+ -+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t); -+extern int ext3_xattr_list(struct inode *, char *, size_t); -+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int); -+ -+extern void ext3_xattr_delete_inode(handle_t *, struct inode *); -+extern void ext3_xattr_put_super(struct super_block *); -+ -+extern int init_ext3_xattr(void); -+extern void exit_ext3_xattr(void); -+ -+# else /* CONFIG_EXT3_FS_XATTR */ -+# define ext3_setxattr NULL -+# define ext3_getxattr NULL -+# define ext3_listxattr NULL -+# define ext3_removexattr NULL -+ -+static inline int -+ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t size, int flags) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int -+ext3_xattr_list(struct inode *inode, void *buffer, size_t size, int flags) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int -+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, const void *value, size_t size, int flags) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void -+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode) -+{ -+} -+ -+static inline void -+ext3_xattr_put_super(struct super_block *sb) -+{ -+} -+ -+static inline int -+init_ext3_xattr(void) -+{ -+ return 0; -+} -+ -+static inline void -+exit_ext3_xattr(void) -+{ -+} -+ -+# endif /* CONFIG_EXT3_FS_XATTR */ -+ -+extern struct ext3_xattr_handler ext3_xattr_user_handler; -diff -Nru a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/ext3/xattr_user.c Thu Dec 12 20:58:37 2002 -@@ -0,0 +1,99 @@ -+/* -+ * linux/fs/ext3/xattr_user.c -+ * Handler for extended user attributes. -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "xattr.h" -+ -+#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); -+ } -+ return prefix_len + name_len; -+} -+ -+static int -+ext3_xattr_user_get(struct inode *inode, const char *name, -+ void *buffer, size_t size) -+{ -+ int error; -+ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return -EOPNOTSUPP; -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+ error = ext3_permission_locked(inode, MAY_READ); -+#else -+ error = permission(inode, MAY_READ); -+#endif -+ if (error) -+ return error; -+ -+ return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name, -+ buffer, size); -+} -+ -+static int -+ext3_xattr_user_set(struct inode *inode, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ handle_t *handle; -+ int error; -+ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return -EOPNOTSUPP; -+ if ( !S_ISREG(inode->i_mode) && -+ (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) -+ return -EPERM; -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+ error = ext3_permission_locked(inode, MAY_WRITE); -+#else -+ error = permission(inode, MAY_WRITE); -+#endif -+ if (error) -+ return error; -+ -+ lock_kernel(); -+ handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name, -+ value, size, flags); -+ ext3_journal_stop(handle, inode); -+ unlock_kernel(); -+ -+ return error; -+} -+ -+struct ext3_xattr_handler ext3_xattr_user_handler = { -+ prefix: XATTR_USER_PREFIX, -+ list: ext3_xattr_user_list, -+ get: ext3_xattr_user_get, -+ set: ext3_xattr_user_set, -+}; -diff -Nru a/fs/mbcache.c b/fs/mbcache.c ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/mbcache.c Thu Dec 12 20:58:37 2002 -@@ -0,0 +1,702 @@ -+/* -+ * 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. -+ */ -+ -+#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)"); -+MODULE_LICENSE("GPL"); -+ -+EXPORT_SYMBOL(mb_cache_create); -+EXPORT_SYMBOL(mb_cache_shrink); -+EXPORT_SYMBOL(mb_cache_destroy); -+EXPORT_SYMBOL(mb_cache_entry_alloc); -+EXPORT_SYMBOL(mb_cache_entry_insert); -+EXPORT_SYMBOL(mb_cache_entry_release); -+EXPORT_SYMBOL(mb_cache_entry_takeout); -+EXPORT_SYMBOL(mb_cache_entry_free); -+EXPORT_SYMBOL(mb_cache_entry_dup); -+EXPORT_SYMBOL(mb_cache_entry_get); -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+EXPORT_SYMBOL(mb_cache_entry_find_first); -+EXPORT_SYMBOL(mb_cache_entry_find_next); -+#endif -+ -+ -+/* -+ * Global data: list of all mbcache's, lru list, and a spinlock for -+ * accessing cache data structures on SMP machines. (The lru list is -+ * global across all mbcaches.) -+ */ -+ -+static LIST_HEAD(mb_cache_list); -+static LIST_HEAD(mb_cache_lru_list); -+static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED; -+static struct shrinker *mb_shrinker; -+ -+static inline int -+mb_cache_indexes(struct mb_cache *cache) -+{ -+#ifdef MB_CACHE_INDEXES_COUNT -+ return MB_CACHE_INDEXES_COUNT; -+#else -+ return cache->c_indexes_count; -+#endif -+} -+ -+/* -+ * What the mbcache registers as to get shrunk dynamically. -+ */ -+ -+static int mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask); -+ -+static inline void -+__mb_cache_entry_takeout_lru(struct mb_cache_entry *ce) -+{ -+ if (!list_empty(&ce->e_lru_list)) -+ list_del_init(&ce->e_lru_list); -+} -+ -+ -+static inline void -+__mb_cache_entry_into_lru(struct mb_cache_entry *ce) -+{ -+ list_add(&ce->e_lru_list, &mb_cache_lru_list); -+} -+ -+ -+static inline int -+__mb_cache_entry_in_lru(struct mb_cache_entry *ce) -+{ -+ return (!list_empty(&ce->e_lru_list)); -+} -+ -+ -+/* -+ * Insert the cache entry into all hashes. -+ */ -+static inline void -+__mb_cache_entry_link(struct mb_cache_entry *ce) -+{ -+ struct mb_cache *cache = ce->e_cache; -+ unsigned int bucket; -+ int n; -+ -+ bucket = hash_long((unsigned long)ce->e_bdev + -+ (ce->e_block & 0xffffff), cache->c_bucket_bits); -+ list_add(&ce->e_block_list, &cache->c_block_hash[bucket]); -+ for (n=0; ne_indexes[n].o_key, -+ cache->c_bucket_bits); -+ list_add(&ce->e_indexes[n].o_list, -+ &cache->c_indexes_hash[n][bucket]); -+ } -+} -+ -+ -+/* -+ * Remove the cache entry from all hashes. -+ */ -+static inline void -+__mb_cache_entry_unlink(struct mb_cache_entry *ce) -+{ -+ int n; -+ -+ list_del_init(&ce->e_block_list); -+ for (n = 0; n < mb_cache_indexes(ce->e_cache); n++) -+ list_del(&ce->e_indexes[n].o_list); -+} -+ -+ -+static inline int -+__mb_cache_entry_is_linked(struct mb_cache_entry *ce) -+{ -+ return (!list_empty(&ce->e_block_list)); -+} -+ -+ -+static inline struct mb_cache_entry * -+__mb_cache_entry_read(struct mb_cache_entry *ce) -+{ -+ __mb_cache_entry_takeout_lru(ce); -+ atomic_inc(&ce->e_used); -+ return ce; -+} -+ -+ -+static inline void -+__mb_cache_entry_forget(struct mb_cache_entry *ce) -+{ -+ struct mb_cache *cache = ce->e_cache; -+ -+ mb_assert(atomic_read(&ce->e_used) == 0); -+ atomic_dec(&cache->c_entry_count); -+ if (cache->c_op.free) -+ cache->c_op.free(ce); -+ kmem_cache_free(cache->c_entry_cache, ce); -+} -+ -+ -+static inline void -+__mb_cache_entry_release_unlock(struct mb_cache_entry *ce) -+{ -+ if (atomic_dec_and_test(&ce->e_used)) { -+ if (!__mb_cache_entry_is_linked(ce)) -+ goto forget; -+ __mb_cache_entry_into_lru(ce); -+ } -+ spin_unlock(&mb_cache_spinlock); -+ return; -+forget: -+ spin_unlock(&mb_cache_spinlock); -+ __mb_cache_entry_forget(ce); -+} -+ -+ -+/* -+ * mb_cache_shrink_fn() memory pressure callback -+ * -+ * This function is called by the kernel memory management when memory -+ * gets low. -+ * -+ * @nr_to_scan: Number of objects to scan -+ * @gfp_mask: (ignored) -+ * -+ * Returns the number of objects which are present in the cache. -+ */ -+static int -+mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l; -+ int count = 0; -+ -+ spin_lock(&mb_cache_spinlock); -+ list_for_each_prev(l, &mb_cache_list) { -+ struct mb_cache *cache = -+ list_entry(l, struct mb_cache, c_cache_list); -+ mb_debug("cache %s (%d)", cache->c_name, -+ atomic_read(&cache->c_entry_count)); -+ count += atomic_read(&cache->c_entry_count); -+ } -+ mb_debug("trying to free %d entries", nr_to_scan); -+ if (nr_to_scan == 0) { -+ spin_unlock(&mb_cache_spinlock); -+ goto out; -+ } -+ while (nr_to_scan && !list_empty(&mb_cache_lru_list)) { -+ struct mb_cache_entry *ce = -+ list_entry(mb_cache_lru_list.prev, -+ struct mb_cache_entry, e_lru_list); -+ list_move(&ce->e_lru_list, &free_list); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ nr_to_scan--; -+ } -+ spin_unlock(&mb_cache_spinlock); -+ l = free_list.prev; -+ while (l != &free_list) { -+ struct mb_cache_entry *ce = list_entry(l, -+ struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ __mb_cache_entry_forget(ce); -+ count--; -+ } -+out: -+ mb_debug("%d remaining entries ", count); -+ return count; -+} -+ -+ -+/* -+ * mb_cache_create() create a new cache -+ * -+ * All entries in one cache are equal size. Cache entries may be from -+ * multiple devices. If this is the first mbcache created, registers -+ * the cache with kernel memory management. Returns NULL if no more -+ * memory was available. -+ * -+ * @name: name of the cache (informal) -+ * @cache_op: contains the callback called when freeing a cache entry -+ * @entry_size: The size of a cache entry, including -+ * struct mb_cache_entry -+ * @indexes_count: number of additional indexes in the cache. Must equal -+ * MB_CACHE_INDEXES_COUNT if the number of indexes is -+ * hardwired. -+ * @bucket_bits: log2(number of hash buckets) -+ */ -+struct mb_cache * -+mb_cache_create(const char *name, struct mb_cache_op *cache_op, -+ size_t entry_size, int indexes_count, int bucket_bits) -+{ -+ int m=0, n, bucket_count = 1 << bucket_bits; -+ struct mb_cache *cache = NULL; -+ -+ if(entry_size < sizeof(struct mb_cache_entry) + -+ indexes_count * sizeof(struct mb_cache_entry_index)) -+ return NULL; -+ -+ cache = kmalloc(sizeof(struct mb_cache) + -+ indexes_count * sizeof(struct list_head), GFP_KERNEL); -+ if (!cache) -+ goto fail; -+ cache->c_name = name; -+ if (cache_op) -+ cache->c_op.free = cache_op->free; -+ else -+ cache->c_op.free = NULL; -+ atomic_set(&cache->c_entry_count, 0); -+ cache->c_bucket_bits = bucket_bits; -+#ifdef MB_CACHE_INDEXES_COUNT -+ mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT); -+#else -+ cache->c_indexes_count = indexes_count; -+#endif -+ cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head), -+ GFP_KERNEL); -+ if (!cache->c_block_hash) -+ goto fail; -+ for (n=0; 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); -+ if (list_empty(&mb_cache_list)) { -+ if (mb_shrinker) { -+ printk(KERN_ERR "%s: already have a shrinker!\n", -+ __FUNCTION__); -+ remove_shrinker(mb_shrinker); -+ } -+ mb_shrinker = set_shrinker(DEFAULT_SEEKS, mb_cache_shrink_fn); -+ } -+ list_add(&cache->c_cache_list, &mb_cache_list); -+ spin_unlock(&mb_cache_spinlock); -+ return cache; -+ -+fail: -+ if (cache) { -+ while (--m >= 0) -+ kfree(cache->c_indexes_hash[m]); -+ if (cache->c_block_hash) -+ kfree(cache->c_block_hash); -+ kfree(cache); -+ } -+ return NULL; -+} -+ -+ -+/* -+ * mb_cache_shrink() -+ * -+ * Removes all cache entires of a device from the cache. All cache entries -+ * currently in use cannot be freed, and thus remain in the cache. All others -+ * are freed. -+ * -+ * @cache: which cache to shrink -+ * @bdev: which device's cache entries to shrink -+ */ -+void -+mb_cache_shrink(struct mb_cache *cache, struct block_device *bdev) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l; -+ -+ spin_lock(&mb_cache_spinlock); -+ l = mb_cache_lru_list.prev; -+ while (l != &mb_cache_lru_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ if (ce->e_bdev == bdev) { -+ list_move(&ce->e_lru_list, &free_list); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ } -+ } -+ spin_unlock(&mb_cache_spinlock); -+ l = free_list.prev; -+ while (l != &free_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ __mb_cache_entry_forget(ce); -+ } -+} -+ -+ -+/* -+ * mb_cache_destroy() -+ * -+ * Shrinks the cache to its minimum possible size (hopefully 0 entries), -+ * and then destroys it. If this was the last mbcache, un-registers the -+ * mbcache from kernel memory management. -+ */ -+void -+mb_cache_destroy(struct mb_cache *cache) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l; -+ int n; -+ -+ spin_lock(&mb_cache_spinlock); -+ l = mb_cache_lru_list.prev; -+ while (l != &mb_cache_lru_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ if (ce->e_cache == cache) { -+ list_move(&ce->e_lru_list, &free_list); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ } -+ } -+ list_del(&cache->c_cache_list); -+ if (list_empty(&mb_cache_list) && mb_shrinker) { -+ remove_shrinker(mb_shrinker); -+ mb_shrinker = 0; -+ } -+ spin_unlock(&mb_cache_spinlock); -+ -+ l = free_list.prev; -+ while (l != &free_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ __mb_cache_entry_forget(ce); -+ } -+ -+ if (atomic_read(&cache->c_entry_count) > 0) { -+ mb_error("cache %s: %d orphaned entries", -+ cache->c_name, -+ atomic_read(&cache->c_entry_count)); -+ } -+ -+ kmem_cache_destroy(cache->c_entry_cache); -+ -+ for (n=0; n < mb_cache_indexes(cache); n++) -+ kfree(cache->c_indexes_hash[n]); -+ kfree(cache->c_block_hash); -+ -+ kfree(cache); -+} -+ -+ -+/* -+ * mb_cache_entry_alloc() -+ * -+ * Allocates a new cache entry. The new entry will not be valid initially, -+ * and thus cannot be looked up yet. It should be filled with data, and -+ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL -+ * if no more memory was available. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_alloc(struct mb_cache *cache) -+{ -+ struct mb_cache_entry *ce; -+ -+ atomic_inc(&cache->c_entry_count); -+ ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL); -+ if (ce) { -+ INIT_LIST_HEAD(&ce->e_lru_list); -+ INIT_LIST_HEAD(&ce->e_block_list); -+ ce->e_cache = cache; -+ atomic_set(&ce->e_used, 1); -+ } -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_insert() -+ * -+ * Inserts an entry that was allocated using mb_cache_entry_alloc() into -+ * the cache. After this, the cache entry can be looked up, but is not yet -+ * in the lru list as the caller still holds a handle to it. Returns 0 on -+ * success, or -EBUSY if a cache entry for that device + inode exists -+ * already (this may happen after a failed lookup, but when another process -+ * has inserted the same cache entry in the meantime). -+ * -+ * @bdev: device the cache entry belongs to -+ * @block: block number -+ * @keys: array of additional keys. There must be indexes_count entries -+ * in the array (as specified when creating the cache). -+ */ -+int -+mb_cache_entry_insert(struct mb_cache_entry *ce, struct block_device *bdev, -+ sector_t block, unsigned int keys[]) -+{ -+ struct mb_cache *cache = ce->e_cache; -+ unsigned int bucket; -+ struct list_head *l; -+ int error = -EBUSY, n; -+ -+ bucket = hash_long((unsigned long)bdev + (block & 0xffffffff), -+ cache->c_bucket_bits); -+ spin_lock(&mb_cache_spinlock); -+ list_for_each_prev(l, &cache->c_block_hash[bucket]) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_block_list); -+ if (ce->e_bdev == bdev && ce->e_block == block) -+ goto out; -+ } -+ mb_assert(!__mb_cache_entry_is_linked(ce)); -+ ce->e_bdev = bdev; -+ ce->e_block = block; -+ for (n=0; ne_indexes[n].o_key = keys[n]; -+ __mb_cache_entry_link(ce); -+out: -+ spin_unlock(&mb_cache_spinlock); -+ return error; -+} -+ -+ -+/* -+ * mb_cache_entry_release() -+ * -+ * Release a handle to a cache entry. When the last handle to a cache entry -+ * is released it is either freed (if it is invalid) or otherwise inserted -+ * in to the lru list. -+ */ -+void -+mb_cache_entry_release(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ __mb_cache_entry_release_unlock(ce); -+} -+ -+ -+/* -+ * mb_cache_entry_takeout() -+ * -+ * Take a cache entry out of the cache, making it invalid. The entry can later -+ * be re-inserted using mb_cache_entry_insert(), or released using -+ * mb_cache_entry_release(). -+ */ -+void -+mb_cache_entry_takeout(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ mb_assert(!__mb_cache_entry_in_lru(ce)); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ spin_unlock(&mb_cache_spinlock); -+} -+ -+ -+/* -+ * mb_cache_entry_free() -+ * -+ * This is equivalent to the sequence mb_cache_entry_takeout() -- -+ * mb_cache_entry_release(). -+ */ -+void -+mb_cache_entry_free(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ mb_assert(!__mb_cache_entry_in_lru(ce)); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ __mb_cache_entry_release_unlock(ce); -+} -+ -+ -+/* -+ * mb_cache_entry_dup() -+ * -+ * Duplicate a handle to a cache entry (does not duplicate the cache entry -+ * itself). After the call, both the old and the new handle must be released. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_dup(struct mb_cache_entry *ce) -+{ -+ atomic_inc(&ce->e_used); -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_get() -+ * -+ * Get a cache entry by device / block number. (There can only be one entry -+ * in the cache per device and block.) Returns NULL if no such cache entry -+ * exists. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_get(struct mb_cache *cache, struct block_device *bdev, -+ sector_t block) -+{ -+ unsigned int bucket; -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ bucket = hash_long((unsigned long)bdev + (block & 0xffffffff), -+ cache->c_bucket_bits); -+ spin_lock(&mb_cache_spinlock); -+ list_for_each(l, &cache->c_block_hash[bucket]) { -+ ce = list_entry(l, struct mb_cache_entry, e_block_list); -+ if (ce->e_bdev == bdev && ce->e_block == block) { -+ ce = __mb_cache_entry_read(ce); -+ goto cleanup; -+ } -+ } -+ ce = NULL; -+ -+cleanup: -+ spin_unlock(&mb_cache_spinlock); -+ return ce; -+} -+ -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+ -+static struct mb_cache_entry * -+__mb_cache_entry_find(struct list_head *l, struct list_head *head, -+ int index, struct block_device *bdev, unsigned int key) -+{ -+ while (l != head) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, -+ e_indexes[index].o_list); -+ if (ce->e_bdev == bdev && -+ ce->e_indexes[index].o_key == key) { -+ ce = __mb_cache_entry_read(ce); -+ if (ce) -+ return ce; -+ } -+ l = l->next; -+ } -+ return NULL; -+} -+ -+ -+/* -+ * mb_cache_entry_find_first() -+ * -+ * Find the first cache entry on a given device with a certain key in -+ * an additional index. Additonal matches can be found with -+ * mb_cache_entry_find_next(). Returns NULL if no match was found. -+ * -+ * @cache: the cache to search -+ * @index: the number of the additonal index to search (0<=indexc_bucket_bits); -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ mb_assert(index < mb_cache_indexes(cache)); -+ spin_lock(&mb_cache_spinlock); -+ l = cache->c_indexes_hash[index][bucket].next; -+ ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket], -+ index, bdev, key); -+ spin_unlock(&mb_cache_spinlock); -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_find_next() -+ * -+ * Find the next cache entry on a given device with a certain key in an -+ * additional index. Returns NULL if no match could be found. The previous -+ * entry is atomatically released, so that mb_cache_entry_find_next() can -+ * be called like this: -+ * -+ * entry = mb_cache_entry_find_first(); -+ * while (entry) { -+ * ... -+ * entry = mb_cache_entry_find_next(entry, ...); -+ * } -+ * -+ * @prev: The previous match -+ * @index: the number of the additonal index to search (0<=indexe_cache; -+ unsigned int bucket = hash_long(key, cache->c_bucket_bits); -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ mb_assert(index < mb_cache_indexes(cache)); -+ spin_lock(&mb_cache_spinlock); -+ l = prev->e_indexes[index].o_list.next; -+ ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket], -+ index, bdev, key); -+ __mb_cache_entry_release_unlock(prev); -+ return ce; -+} -+ -+#endif /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */ -diff -Nru a/fs/namei.c b/fs/namei.c ---- a/fs/namei.c Thu Dec 12 20:58:37 2002 -+++ b/fs/namei.c Thu Dec 12 20:58:37 2002 -@@ -265,6 +265,9 @@ - - void path_release(struct nameidata *nd) - { -+ if (&nd->it && nd->dentry && nd->dentry->d_op && -+ nd->dentry->d_op->d_intent_release) -+ nd->dentry->d_op->d_intent_release(nd->dentry, &nd->it); - dput(nd->dentry); - mntput(nd->mnt); - } -@@ -273,10 +276,18 @@ - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -351,7 +362,7 @@ - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; -@@ -369,7 +380,10 @@ - struct dentry * dentry = d_alloc(parent, name); - result = ERR_PTR(-ENOMEM); - if (dentry) { -- result = dir->i_op->lookup(dir, dentry); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else -+ result = dir->i_op->lookup(dir, dentry); - if (result) - dput(dentry); - else { -@@ -391,6 +405,12 @@ - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ result = ERR_PTR(-ENOENT); -+ } - } - return result; - } -@@ -402,7 +422,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 = -ELOOP; - if (current->link_count >= 5) -@@ -419,7 +440,10 @@ - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -- err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -@@ -534,7 +558,7 @@ - unlock_nd(nd); - - need_lookup: -- dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE, &nd->it); - if (IS_ERR(dentry)) - goto fail; - mntget(mnt); -@@ -662,11 +686,11 @@ - if (!inode->i_op) - break; - -- if (inode->i_op->follow_link) { -+ if (inode->i_op->follow_link || inode->i_op->follow_link2) { - mntget(next.mnt); - dget_locked(next.dentry); - unlock_nd(nd); -- err = do_follow_link(next.dentry, nd); -+ err = do_follow_link(next.dentry, nd, &nd->it); - dput(next.dentry); - mntput(next.mnt); - if (err) -@@ -684,7 +708,7 @@ - nd->dentry = next.dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup2) - break; - continue; - /* here ends the main loop */ -@@ -717,11 +741,12 @@ - follow_mount(&next.mnt, &next.dentry); - inode = next.dentry->d_inode; - if ((lookup_flags & LOOKUP_FOLLOW) -- && inode && inode->i_op && inode->i_op->follow_link) { -+ && inode && inode->i_op && -+ (inode->i_op->follow_link || inode->i_op->follow_link2)) { - mntget(next.mnt); - dget_locked(next.dentry); - unlock_nd(nd); -- err = do_follow_link(next.dentry, nd); -+ err = do_follow_link(next.dentry, nd, &nd->it); - dput(next.dentry); - mntput(next.mnt); - if (err) -@@ -737,7 +762,8 @@ - break; - if (lookup_flags & LOOKUP_DIRECTORY) { - err = -ENOTDIR; -- if (!inode->i_op || !inode->i_op->lookup) -+ if (!inode->i_op || -+ (!inode->i_op->lookup && !inode->i_op->lookup2)) - break; - } - goto return_base; -@@ -886,7 +912,8 @@ - * needs parent already locked. Doesn't follow mounts. - * SMP-safe. - */ --struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+struct dentry * lookup_hash(struct qstr *name, struct dentry * base, -+ struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -909,13 +936,16 @@ - goto out; - } - -- dentry = cached_lookup(base, name, 0); -+ dentry = cached_lookup(base, name, 0, it); - if (!dentry) { - struct dentry *new = d_alloc(base, name); - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; -- dentry = inode->i_op->lookup(inode, new); -+ if (inode->i_op->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else -+ dentry = inode->i_op->lookup(inode, new); - if (!dentry) { - dentry = new; - security_ops->inode_post_lookup(inode, dentry); -@@ -927,7 +957,7 @@ - } - - /* SMP-safe */ --struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -+struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct lookup_intent *it) - { - unsigned long hash; - struct qstr this; -@@ -947,11 +977,16 @@ - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash(&this, base, it); - access: - return ERR_PTR(-EACCES); - } - -+struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -+{ -+ return lookup_one_len_it(name, base, len, NULL); -+} -+ - /* - * namei() - * -@@ -1268,7 +1303,7 @@ - - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - - do_last: - error = PTR_ERR(dentry); -@@ -1310,7 +1345,8 @@ - error = -ENOENT; - if (!dentry->d_inode) - goto exit_dput; -- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) -+ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || -+ dentry->d_inode->i_op->follow_link2)) - goto do_link; - - dput(nd->dentry); -@@ -1370,7 +1406,7 @@ - } - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - putname(nd->last.name); - goto do_last; - } -@@ -1384,7 +1420,7 @@ - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - if (IS_ERR(dentry)) - goto fail; - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1614,7 +1650,7 @@ - goto exit1; - } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, &nd.it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); -@@ -1675,7 +1711,7 @@ - if (nd.last_type != LAST_NORM) - goto exit1; - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, &nd.it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1949,7 +1985,8 @@ - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); -@@ -2020,7 +2057,7 @@ - - trap = lock_rename(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash(&oldnd.last, old_dir, &oldnd.it); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -2040,7 +2077,7 @@ - error = -EINVAL; - if (old_dentry == trap) - goto exit4; -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ new_dentry = lookup_hash(&newnd.last, new_dir, &newnd.it); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; -@@ -2050,7 +2087,7 @@ - goto exit5; - - error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ new_dir->d_inode, new_dentry, NULL); - exit5: - dput(new_dentry); - exit4: -@@ -2102,7 +2139,8 @@ - } - - 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; -@@ -2138,7 +2176,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 */ -@@ -2180,7 +2224,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); -diff -Nru a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c ---- a/fs/nfsd/vfs.c Thu Dec 12 20:58:37 2002 -+++ b/fs/nfsd/vfs.c Thu Dec 12 20:58:37 2002 -@@ -1292,7 +1292,7 @@ - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); -diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c ---- a/fs/sysfs/inode.c Thu Dec 12 20:58:37 2002 -+++ b/fs/sysfs/inode.c Thu Dec 12 20:58:37 2002 -@@ -471,7 +471,7 @@ - qstr.name = name; - qstr.len = strlen(name); - qstr.hash = full_name_hash(name,qstr.len); -- return lookup_hash(&qstr,parent); -+ return lookup_hash(&qstr,parent,NULL); - } - - /** -diff -Nru a/include/linux/dcache.h b/include/linux/dcache.h ---- a/include/linux/dcache.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/dcache.h Thu Dec 12 20:58:37 2002 -@@ -9,6 +9,24 @@ - #include - #include /* for BUG() */ - -+#define IT_OPEN (1) -+#define IT_CREAT (1<<1) -+#define IT_MKDIR (1<<2) -+#define IT_LINK (1<<3) -+#define IT_LINK2 (1<<4) -+#define IT_SYMLINK (1<<5) -+#define IT_UNLINK (1<<6) -+#define IT_RMDIR (1<<7) -+#define IT_RENAME (1<<8) -+#define IT_RENAME2 (1<<9) -+#define IT_READDIR (1<<10) -+#define IT_GETATTR (1<<11) -+#define IT_SETATTR (1<<12) -+#define IT_READLINK (1<<13) -+#define IT_MKNOD (1<<14) -+#define IT_LOOKUP (1<<15) -+ -+ - /* - * linux/include/linux/dcache.h - * -@@ -30,6 +48,8 @@ - unsigned int hash; - }; - -+#include -+ - struct dentry_stat_t { - int nr_dentry; - int nr_unused; -@@ -79,6 +99,7 @@ - struct list_head d_subdirs; /* our children */ - struct list_head d_alias; /* inode alias list */ - int d_mounted; -+ struct lookup_intent *d_it; - struct qstr d_name; - unsigned long d_time; /* used by d_revalidate */ - struct dentry_operations *d_op; -@@ -96,6 +117,8 @@ - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); -+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); - }; - - /* the dentry parameter passed to d_hash and d_compare is the parent -diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h ---- a/include/linux/ext3_fs.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/ext3_fs.h Thu Dec 12 20:58:37 2002 -@@ -64,8 +64,6 @@ - */ - #define EXT3_BAD_INO 1 /* Bad blocks inode */ - #define EXT3_ROOT_INO 2 /* Root inode */ --#define EXT3_ACL_IDX_INO 3 /* ACL inode */ --#define EXT3_ACL_DATA_INO 4 /* ACL inode */ - #define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ - #define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ - #define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ -@@ -95,7 +93,6 @@ - #else - # define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) - #endif --#define EXT3_ACLE_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry)) - #define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) - #ifdef __KERNEL__ - # define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -@@ -130,28 +127,6 @@ - #endif - - /* -- * ACL structures -- */ --struct ext3_acl_header /* Header of Access Control Lists */ --{ -- __u32 aclh_size; -- __u32 aclh_file_count; -- __u32 aclh_acle_count; -- __u32 aclh_first_acle; --}; -- --struct ext3_acl_entry /* Access Control List Entry */ --{ -- __u32 acle_size; -- __u16 acle_perms; /* Access permissions */ -- __u16 acle_type; /* Type of entry */ -- __u16 acle_tag; /* User or group identity */ -- __u16 acle_pad1; -- __u32 acle_next; /* Pointer on next entry for the */ -- /* same inode or on next free entry */ --}; -- --/* - * Structure of a blocks group descriptor - */ - struct ext3_group_desc -@@ -347,6 +322,7 @@ - #define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */ - #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ - #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ -+#define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -529,7 +505,7 @@ - #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ - #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ - --#define EXT3_FEATURE_COMPAT_SUPP 0 -+#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR - #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ - EXT3_FEATURE_INCOMPAT_RECOVER) - #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ -@@ -713,6 +689,7 @@ - - - /* inode.c */ -+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int); - extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); - extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); - -@@ -781,8 +758,10 @@ - - /* namei.c */ - extern struct inode_operations ext3_dir_inode_operations; -+extern struct inode_operations ext3_special_inode_operations; - - /* symlink.c */ -+extern struct inode_operations ext3_symlink_inode_operations; - extern struct inode_operations ext3_fast_symlink_inode_operations; - - -diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h ---- a/include/linux/ext3_jbd.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/ext3_jbd.h Thu Dec 12 20:58:37 2002 -@@ -30,13 +30,19 @@ - - #define EXT3_SINGLEDATA_TRANS_BLOCKS 8 - -+/* Extended attributes may touch two data buffers, two bitmap buffers, -+ * and two group and summaries. */ -+ -+#define EXT3_XATTR_TRANS_BLOCKS 8 -+ - /* Define the minimum size for a transaction which modifies data. This - * needs to take into account the fact that we may end up modifying two - * quota files too (one for the group, one for the user quota). The - * superblock only gets updated once, of course, so don't bother - * counting that again for the quota updates. */ - --#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2) -+#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \ -+ EXT3_XATTR_TRANS_BLOCKS - 2) - - extern int ext3_writepage_trans_blocks(struct inode *inode); - -diff -Nru a/include/linux/fs.h b/include/linux/fs.h ---- a/include/linux/fs.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/fs.h Thu Dec 12 20:58:37 2002 -@@ -700,7 +700,7 @@ - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct lookup_intent *it); - - /* - * File types -@@ -769,6 +769,8 @@ - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup2) (struct inode *,struct dentry *, -+ struct lookup_intent *); - int (*link) (struct dentry *,struct inode *,struct dentry *); - int (*unlink) (struct inode *,struct dentry *); - int (*symlink) (struct inode *,struct dentry *,const char *); -@@ -779,6 +781,7 @@ - struct inode *, struct dentry *); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); -+ int (*follow_link2) (struct dentry *, struct nameidata *, struct lookup_intent *it); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*setattr) (struct dentry *, struct iattr *); -@@ -995,6 +998,7 @@ - extern int unregister_filesystem(struct file_system_type *); - extern struct vfsmount *kern_mount(struct file_system_type *); - extern int may_umount(struct vfsmount *); -+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); - extern long do_mount(char *, char *, char *, unsigned long, void *); - - #define kern_umount mntput -@@ -1285,6 +1289,8 @@ - - extern int vfs_readlink(struct dentry *, char *, int, const char *); - extern int vfs_follow_link(struct nameidata *, const char *); -+int vfs_follow_link_it(struct nameidata *nd, const char *link, -+ struct lookup_intent *it); - extern int page_readlink(struct dentry *, char *, int); - extern int page_follow_link(struct dentry *, struct nameidata *); - extern int page_symlink(struct inode *inode, const char *symname, int len); -diff -Nru a/include/linux/lustre_version.h b/include/linux/lustre_version.h ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/include/linux/lustre_version.h Thu Dec 12 20:58:37 2002 -@@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 4 -diff -Nru a/include/linux/mbcache.h b/include/linux/mbcache.h ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/include/linux/mbcache.h Thu Dec 12 20:58:37 2002 -@@ -0,0 +1,72 @@ -+/* -+ 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 { -+ void (*free)(struct mb_cache_entry *); -+}; -+ -+struct mb_cache { -+ struct list_head c_cache_list; -+ const char *c_name; -+ struct mb_cache_op c_op; -+ atomic_t c_entry_count; -+ int c_bucket_bits; -+#ifndef MB_CACHE_INDEXES_COUNT -+ int c_indexes_count; -+#endif -+ kmem_cache_t *c_entry_cache; -+ struct list_head *c_block_hash; -+ struct list_head *c_indexes_hash[0]; -+}; -+ -+struct mb_cache_entry_index { -+ struct list_head o_list; -+ unsigned int o_key; -+}; -+ -+struct mb_cache_entry { -+ struct list_head e_lru_list; -+ struct mb_cache *e_cache; -+ atomic_t e_used; -+ struct block_device *e_bdev; -+ sector_t e_block; -+ struct list_head e_block_list; -+ struct mb_cache_entry_index e_indexes[0]; -+}; -+ -+/* Functions on caches */ -+ -+struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t, -+ int, int); -+void mb_cache_shrink(struct mb_cache *, struct block_device *); -+void mb_cache_destroy(struct mb_cache *); -+ -+/* Functions on cache entries */ -+ -+struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *); -+int mb_cache_entry_insert(struct mb_cache_entry *, struct block_device *, -+ sector_t, unsigned int[]); -+void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]); -+void mb_cache_entry_release(struct mb_cache_entry *); -+void mb_cache_entry_takeout(struct mb_cache_entry *); -+void mb_cache_entry_free(struct mb_cache_entry *); -+struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *); -+struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, -+ struct block_device *, -+ sector_t); -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int, -+ struct block_device *, -+ unsigned int); -+struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int, -+ struct block_device *, -+ unsigned int); -+#endif -diff -Nru a/include/linux/namei.h b/include/linux/namei.h ---- a/include/linux/namei.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/namei.h Thu Dec 12 20:58:37 2002 -@@ -5,6 +5,17 @@ - - struct vfsmount; - -+struct lookup_intent { -+ int it_op; -+ int it_mode; -+ int it_disposition; -+ int it_status; -+ struct iattr *it_iattr; -+ __u64 it_lock_handle[2]; -+ int it_lock_mode; -+ void *it_data; -+}; -+ - struct nameidata { - struct dentry *dentry; - struct vfsmount *mnt; -@@ -13,6 +24,7 @@ - int last_type; - struct dentry *old_dentry; - struct vfsmount *old_mnt; -+ struct lookup_intent it; - }; - - /* -@@ -46,7 +58,7 @@ - extern void path_release(struct nameidata *); - - extern struct dentry * lookup_one_len(const char *, struct dentry *, int); --extern struct dentry * lookup_hash(struct qstr *, struct dentry *); -+extern struct dentry * lookup_hash(struct qstr *, struct dentry *, struct lookup_intent *); - - extern int follow_down(struct vfsmount **, struct dentry **); - extern int follow_up(struct vfsmount **, struct dentry **); -diff -Nru a/include/linux/slab.h b/include/linux/slab.h ---- a/include/linux/slab.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/slab.h Thu Dec 12 20:58:37 2002 -@@ -56,6 +56,7 @@ - extern int kmem_cache_shrink(kmem_cache_t *); - extern void *kmem_cache_alloc(kmem_cache_t *, int); - extern void kmem_cache_free(kmem_cache_t *, void *); -+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); - extern unsigned int kmem_cache_size(kmem_cache_t *); - - extern void *kmalloc(size_t, int); -diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c ---- a/kernel/ksyms.c Thu Dec 12 20:58:37 2002 -+++ b/kernel/ksyms.c Thu Dec 12 20:58:37 2002 -@@ -286,6 +286,7 @@ - EXPORT_SYMBOL(mark_page_accessed); - 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); -@@ -365,6 +366,13 @@ - EXPORT_SYMBOL(tty_get_baud_rate); - EXPORT_SYMBOL(do_SAK); - -+/* lustre */ -+EXPORT_SYMBOL(panic_notifier_list); -+//EXPORT_SYMBOL(pagecache_lock_cacheline); -+EXPORT_SYMBOL(do_kern_mount); -+EXPORT_SYMBOL(exit_files); -+EXPORT_SYMBOL(kmem_cache_validate); -+ - /* filesystem registration */ - EXPORT_SYMBOL(register_filesystem); - EXPORT_SYMBOL(unregister_filesystem); -@@ -529,6 +537,7 @@ - EXPORT_SYMBOL(seq_lseek); - EXPORT_SYMBOL(single_open); - EXPORT_SYMBOL(single_release); -+EXPORT_SYMBOL(reparent_to_init); - - /* Program loader interfaces */ - EXPORT_SYMBOL(setup_arg_pages); -diff -Nru a/mm/slab.c b/mm/slab.c ---- a/mm/slab.c Thu Dec 12 20:58:37 2002 -+++ b/mm/slab.c Thu Dec 12 20:58:37 2002 -@@ -1236,6 +1236,59 @@ - * Called with the cache-lock held. - */ - -+extern struct page *check_get_page(unsigned long kaddr); -+struct page *page_mem_map(struct page *page); -+static int kmem_check_cache_obj (kmem_cache_t * cachep, -+ slab_t *slabp, void * objp) -+{ -+ int i; -+ unsigned int objnr; -+ -+#if DEBUG -+ if (cachep->flags & SLAB_RED_ZONE) { -+ objp -= BYTES_PER_WORD; -+ if ( *(unsigned long *)objp != RED_MAGIC2) -+ /* Either write before start, or a double free. */ -+ return 0; -+ if (*(unsigned long *)(objp+cachep->objsize - -+ BYTES_PER_WORD) != RED_MAGIC2) -+ /* Either write past end, or a double free. */ -+ return 0; -+ } -+#endif -+ -+ objnr = (objp-slabp->s_mem)/cachep->objsize; -+ if (objnr >= cachep->num) -+ return 0; -+ if (objp != slabp->s_mem + objnr*cachep->objsize) -+ return 0; -+ -+ /* Check slab's freelist to see if this obj is there. */ -+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { -+ if (i == objnr) -+ return 0; -+ } -+ return 1; -+} -+ -+ -+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) -+{ -+ struct page *page = check_get_page((unsigned long)objp); -+ -+ if (!page_mem_map(page)) -+ return 0; -+ -+ if (!PageSlab(page)) -+ return 0; -+ -+ /* XXX check for freed slab objects ? */ -+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) -+ return 0; -+ -+ return (cachep == GET_PAGE_CACHE(page)); -+} -+ - #if DEBUG - static int kmem_extra_free_checks (kmem_cache_t * cachep, - slab_t *slabp, void * objp) -diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c ---- a/net/unix/af_unix.c Thu Dec 12 20:58:37 2002 -+++ b/net/unix/af_unix.c Thu Dec 12 20:58:37 2002 -@@ -715,7 +715,7 @@ - /* - * Do the final lookup. - */ -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto out_mknod_unlock; diff --git a/lustre/kernel_patches/lustre-2.5-from811-812.patch b/lustre/kernel_patches/lustre-2.5-from811-812.patch deleted file mode 100644 index 3ee3169..0000000 --- a/lustre/kernel_patches/lustre-2.5-from811-812.patch +++ /dev/null @@ -1,189 +0,0 @@ -# This is a BitKeeper generated patch for the following project: -# Project Name: Linux kernel tree -# This patch format is intended for GNU patch command version 2.5 or higher. -# This patch includes the following deltas: -# ChangeSet 1.811 -> 1.812 -# kernel/ksyms.c 1.150 -> 1.151 -# include/linux/fs.h 1.176 -> 1.177 -# fs/namei.c 1.57 -> 1.58 -# fs/ext3/xattr.c 1.1 -> 1.2 -# (new) -> 1.1 include/linux/lustre_version.h -# -# The following is the BitKeeper ChangeSet Log -# -------------------------------------------- -# 02/12/11 root@kai.(none) 1.812 -# changed for lustre -# -------------------------------------------- -# -diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c ---- a/fs/ext3/xattr.c Thu Dec 12 20:58:52 2002 -+++ b/fs/ext3/xattr.c Thu Dec 12 20:58:52 2002 -@@ -58,6 +58,7 @@ - #include - #include - #include -+#include - #include - #include - #include "xattr.h" -@@ -1096,6 +1097,9 @@ - } - - #undef BLOCK_HASH_SHIFT -+EXPORT_SYMBOL(ext3_xattr_get); -+EXPORT_SYMBOL(ext3_xattr_set); -+EXPORT_SYMBOL(ext3_bread); - - int __init - init_ext3_xattr(void) -diff -Nru a/fs/namei.c b/fs/namei.c ---- a/fs/namei.c Thu Dec 12 20:58:52 2002 -+++ b/fs/namei.c Thu Dec 12 20:58:52 2002 -@@ -265,7 +265,7 @@ - - void path_release(struct nameidata *nd) - { -- if (nd->dentry && nd->dentry->d_op && -+ if (&nd->it && nd->dentry && nd->dentry->d_op && - nd->dentry->d_op->d_intent_release) - nd->dentry->d_op->d_intent_release(nd->dentry, &nd->it); - dput(nd->dentry); -@@ -422,7 +422,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 = -ELOOP; - if (current->link_count >= 5) -@@ -439,7 +440,10 @@ - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -- err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -@@ -682,11 +686,11 @@ - if (!inode->i_op) - break; - -- if (inode->i_op->follow_link) { -+ if (inode->i_op->follow_link || inode->i_op->follow_link2) { - mntget(next.mnt); - dget_locked(next.dentry); - unlock_nd(nd); -- err = do_follow_link(next.dentry, nd); -+ err = do_follow_link(next.dentry, nd, &nd->it); - dput(next.dentry); - mntput(next.mnt); - if (err) -@@ -737,11 +741,12 @@ - follow_mount(&next.mnt, &next.dentry); - inode = next.dentry->d_inode; - if ((lookup_flags & LOOKUP_FOLLOW) -- && inode && inode->i_op && inode->i_op->follow_link) { -+ && inode && inode->i_op && -+ (inode->i_op->follow_link || inode->i_op->follow_link2)) { - mntget(next.mnt); - dget_locked(next.dentry); - unlock_nd(nd); -- err = do_follow_link(next.dentry, nd); -+ err = do_follow_link(next.dentry, nd, &nd->it); - dput(next.dentry); - mntput(next.mnt); - if (err) -@@ -1340,7 +1345,8 @@ - error = -ENOENT; - if (!dentry->d_inode) - goto exit_dput; -- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) -+ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || -+ dentry->d_inode->i_op->follow_link2)) - goto do_link; - - dput(nd->dentry); -@@ -2133,7 +2139,8 @@ - } - - 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; -@@ -2169,7 +2176,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 */ -@@ -2211,7 +2224,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); -diff -Nru a/include/linux/fs.h b/include/linux/fs.h ---- a/include/linux/fs.h Thu Dec 12 20:58:52 2002 -+++ b/include/linux/fs.h Thu Dec 12 20:58:52 2002 -@@ -781,6 +781,7 @@ - struct inode *, struct dentry *); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); -+ int (*follow_link2) (struct dentry *, struct nameidata *, struct lookup_intent *it); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*setattr) (struct dentry *, struct iattr *); -@@ -1288,6 +1289,8 @@ - - extern int vfs_readlink(struct dentry *, char *, int, const char *); - extern int vfs_follow_link(struct nameidata *, const char *); -+int vfs_follow_link_it(struct nameidata *nd, const char *link, -+ struct lookup_intent *it); - extern int page_readlink(struct dentry *, char *, int); - extern int page_follow_link(struct dentry *, struct nameidata *); - extern int page_symlink(struct inode *inode, const char *symname, int len); -diff -Nru a/include/linux/lustre_version.h b/include/linux/lustre_version.h ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/include/linux/lustre_version.h Thu Dec 12 20:58:52 2002 -@@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 4 -diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c ---- a/kernel/ksyms.c Thu Dec 12 20:58:52 2002 -+++ b/kernel/ksyms.c Thu Dec 12 20:58:52 2002 -@@ -286,6 +286,7 @@ - EXPORT_SYMBOL(mark_page_accessed); - 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); -@@ -536,6 +537,7 @@ - EXPORT_SYMBOL(seq_lseek); - EXPORT_SYMBOL(single_open); - EXPORT_SYMBOL(single_release); -+EXPORT_SYMBOL(reparent_to_init); - - /* Program loader interfaces */ - EXPORT_SYMBOL(setup_arg_pages); diff --git a/lustre/kernel_patches/patches/lin-2.5.44.patch b/lustre/kernel_patches/patches/lin-2.5.44.patch deleted file mode 100644 index 07618d6..0000000 --- a/lustre/kernel_patches/patches/lin-2.5.44.patch +++ /dev/null @@ -1,3374 +0,0 @@ -# This is a BitKeeper generated patch for the following project: -# Project Name: Linux kernel tree -# This patch format is intended for GNU patch command version 2.5 or higher. -# This patch includes the following deltas: -# ChangeSet 1.809 -> 1.812 -# kernel/ksyms.c 1.149 -> 1.151 -# fs/ext3/Makefile 1.4 -> 1.5 -# include/linux/ext3_jbd.h 1.5 -> 1.6 -# fs/driverfs/inode.c 1.52 -> 1.53 -# include/linux/fs.h 1.175 -> 1.177 -# include/linux/namei.h 1.3 -> 1.4 -# fs/namei.c 1.56 -> 1.58 -# fs/nfsd/vfs.c 1.44 -> 1.45 -# arch/um/kernel/mem.c 1.5 -> 1.6 -# fs/ext3/ialloc.c 1.17 -> 1.18 -# fs/ext3/symlink.c 1.3 -> 1.4 -# fs/Makefile 1.42 -> 1.43 -# fs/ext3/namei.c 1.22 -> 1.23 -# include/linux/ext3_fs.h 1.11 -> 1.12 -# net/unix/af_unix.c 1.29 -> 1.30 -# fs/Config.in 1.39 -> 1.40 -# fs/ext3/inode.c 1.42 -> 1.43 -# fs/Config.help 1.21 -> 1.22 -# mm/slab.c 1.33 -> 1.34 -# fs/sysfs/inode.c 1.55 -> 1.56 -# fs/ext3/super.c 1.33 -> 1.34 -# fs/ext3/file.c 1.9 -> 1.10 -# include/linux/slab.h 1.13 -> 1.14 -# include/linux/dcache.h 1.19 -> 1.20 -# (new) -> 1.1 fs/ext3/xattr.h -# (new) -> 1.1 include/linux/mbcache.h -# (new) -> 1.1 include/linux/lustre_version.h -# (new) -> 1.2 fs/ext3/xattr.c -# (new) -> 1.1 fs/mbcache.c -# (new) -> 1.1 fs/ext3/xattr_user.c -# -# The following is the BitKeeper ChangeSet Log -# -------------------------------------------- -# 02/10/20 braam@clusterfs.com 1.810 -# xattrs for UML bk repository -# -------------------------------------------- -# 02/10/20 braam@clusterfs.com 1.811 -# Changes for Lustre -# -------------------------------------------- -# 02/12/11 root@kai.(none) 1.812 -# changed for lustre -# -------------------------------------------- -# -diff -Nru a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c ---- a/arch/um/kernel/mem.c Thu Dec 12 20:58:37 2002 -+++ b/arch/um/kernel/mem.c Thu Dec 12 20:58:37 2002 -@@ -656,6 +656,22 @@ - return(phys_mem_map(pte_val(pte))); - } - -+struct page *check_get_page(unsigned long kaddr) -+{ -+ struct page *page; -+ struct mem_region *mr; -+ unsigned long phys = __pa(kaddr); -+ unsigned int n = phys_region_index(phys); -+ -+ if(regions[n] == NULL) -+ return NULL; -+ -+ mr = regions[n]; -+ page = (struct page *) mr->mem_map; -+ return page + ((phys_addr(phys)) >> PAGE_SHIFT); -+} -+ -+ - struct mem_region *page_region(struct page *page, int *index_out) - { - int i; -@@ -743,7 +759,7 @@ - (addr <= region->start + region->len)) - return(mk_phys(addr - region->start, i)); - } -- panic("region_pa : no region for virtual address"); -+ //panic("region_pa : no region for virtual address"); - return(0); - } - -diff -Nru a/fs/Config.help b/fs/Config.help ---- a/fs/Config.help Thu Dec 12 20:58:37 2002 -+++ b/fs/Config.help Thu Dec 12 20:58:37 2002 -@@ -154,6 +154,13 @@ - of your root partition (the one containing the directory /) cannot - be compiled as a module, and so this may be dangerous. - -+CONFIG_EXT3_FS_XATTR -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page, or visit -+ for details). -+ -+ If unsure, say N. -+ - CONFIG_JBD - This is a generic journaling layer for block devices. It is - currently used by the ext3 file system, but it could also be used to -diff -Nru a/fs/Config.in b/fs/Config.in ---- a/fs/Config.in Thu Dec 12 20:58:37 2002 -+++ b/fs/Config.in Thu Dec 12 20:58:37 2002 -@@ -27,6 +27,7 @@ - dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL - - tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS -+dep_mbool ' Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS - # CONFIG_JBD could be its own option (even modular), but until there are - # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS - # dep_tristate ' Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS -@@ -180,6 +181,17 @@ - define_tristate CONFIG_ZISOFS_FS $CONFIG_ISO9660_FS - else - define_tristate CONFIG_ZISOFS_FS n -+fi -+ -+# Meta block cache for Extended Attributes (ext2/ext3) -+if [ "$CONFIG_EXT2_FS_XATTR" = "y" -o "$CONFIG_EXT3_FS_XATTR" = "y" ]; then -+ if [ "$CONFIG_EXT2_FS" = "y" -o "$CONFIG_EXT3_FS" = "y" ]; then -+ define_tristate CONFIG_FS_MBCACHE y -+ else -+ if [ "$CONFIG_EXT2_FS" = "m" -o "$CONFIG_EXT3_FS" = "m" ]; then -+ define_tristate CONFIG_FS_MBCACHE m -+ fi -+ fi - fi - - mainmenu_option next_comment -diff -Nru a/fs/Makefile b/fs/Makefile ---- a/fs/Makefile Thu Dec 12 20:58:37 2002 -+++ b/fs/Makefile Thu Dec 12 20:58:37 2002 -@@ -6,7 +6,7 @@ - # - - export-objs := open.o dcache.o buffer.o bio.o inode.o dquot.o mpage.o aio.o \ -- fcntl.o read_write.o dcookies.o -+ fcntl.o read_write.o dcookies.o mbcache.o - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ - bio.o super.o block_dev.o char_dev.o stat.o exec.o pipe.o \ -@@ -29,6 +29,8 @@ - obj-y += binfmt_script.o - - obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o -+ -+obj-$(CONFIG_FS_MBCACHE) += mbcache.o - - obj-$(CONFIG_QUOTA) += dquot.o - obj-$(CONFIG_QFMT_V1) += quota_v1.o -diff -Nru a/fs/driverfs/inode.c b/fs/driverfs/inode.c ---- a/fs/driverfs/inode.c Thu Dec 12 20:58:37 2002 -+++ b/fs/driverfs/inode.c Thu Dec 12 20:58:37 2002 -@@ -523,7 +523,7 @@ - qstr.name = name; - qstr.len = strlen(name); - qstr.hash = full_name_hash(name,qstr.len); -- return lookup_hash(&qstr,parent); -+ return lookup_hash(&qstr,parent, NULL); - } - - /** -diff -Nru a/fs/ext3/Makefile b/fs/ext3/Makefile ---- a/fs/ext3/Makefile Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/Makefile Thu Dec 12 20:58:37 2002 -@@ -7,4 +7,10 @@ - ext3-objs := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o hash.o - -+export-objs += xattr.o -+ -+ifeq ($(CONFIG_EXT3_FS_XATTR),y) -+ext3-objs += xattr.o xattr_user.o -+endif -+ - include $(TOPDIR)/Rules.make -diff -Nru a/fs/ext3/file.c b/fs/ext3/file.c ---- a/fs/ext3/file.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/file.c Thu Dec 12 20:58:37 2002 -@@ -23,7 +23,7 @@ - #include - #include - #include --#include -+#include "xattr.h" - - /* - * Called when an inode is released. Note that this is different -@@ -98,5 +98,9 @@ - struct inode_operations ext3_file_inode_operations = { - .truncate = ext3_truncate, - .setattr = ext3_setattr, -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, - }; - -diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c ---- a/fs/ext3/ialloc.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/ialloc.c Thu Dec 12 20:58:37 2002 -@@ -25,6 +25,8 @@ - #include - #include - -+#include "xattr.h" -+ - /* - * ialloc.c contains the inodes allocation and deallocation routines - */ -@@ -118,6 +120,7 @@ - * as writing the quota to disk may need the lock as well. - */ - DQUOT_INIT(inode); -+ ext3_xattr_delete_inode(handle, inode); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); - -diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c ---- a/fs/ext3/inode.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/inode.c Thu Dec 12 20:58:37 2002 -@@ -42,6 +42,18 @@ - */ - #undef SEARCH_FROM_ZERO - -+/* -+ * Test whether an inode is a fast symlink. -+ */ -+static inline int ext3_inode_is_fast_symlink(struct inode *inode) -+{ -+ int ea_blocks = EXT3_I(inode)->i_file_acl ? -+ (inode->i_sb->s_blocksize >> 9) : 0; -+ -+ return (S_ISLNK(inode->i_mode) && -+ inode->i_blocks - ea_blocks == 0); -+} -+ - /* The ext3 forget function must perform a revoke if we are freeing data - * which has been journaled. Metadata (eg. indirect blocks) must be - * revoked in all cases. -@@ -51,7 +63,7 @@ - * still needs to be revoked. - */ - --static int ext3_forget(handle_t *handle, int is_metadata, -+int ext3_forget(handle_t *handle, int is_metadata, - struct inode *inode, struct buffer_head *bh, - int blocknr) - { -@@ -167,9 +179,7 @@ - { - handle_t *handle; - -- if (is_bad_inode(inode) || -- inode->i_ino == EXT3_ACL_IDX_INO || -- inode->i_ino == EXT3_ACL_DATA_INO) -+ if (is_bad_inode(inode)) - goto no_delete; - - lock_kernel(); -@@ -1979,6 +1989,8 @@ - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return; -+ if (ext3_inode_is_fast_symlink(inode)) -+ return; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - return; - -@@ -2130,8 +2142,6 @@ - struct ext3_group_desc * gdp; - - if ((inode->i_ino != EXT3_ROOT_INO && -- inode->i_ino != EXT3_ACL_IDX_INO && -- inode->i_ino != EXT3_ACL_DATA_INO && - inode->i_ino != EXT3_JOURNAL_INO && - inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) || - inode->i_ino > le32_to_cpu( -@@ -2263,10 +2273,7 @@ - - brelse (iloc.bh); - -- if (inode->i_ino == EXT3_ACL_IDX_INO || -- inode->i_ino == EXT3_ACL_DATA_INO) -- /* Nothing to do */ ; -- else if (S_ISREG(inode->i_mode)) { -+ if (S_ISREG(inode->i_mode)) { - inode->i_op = &ext3_file_inode_operations; - inode->i_fop = &ext3_file_operations; - if (ext3_should_writeback_data(inode)) -@@ -2277,18 +2284,20 @@ - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; - } else if (S_ISLNK(inode->i_mode)) { -- if (!inode->i_blocks) -+ if (ext3_inode_is_fast_symlink(inode)) - inode->i_op = &ext3_fast_symlink_inode_operations; - else { -- inode->i_op = &page_symlink_inode_operations; -+ inode->i_op = &ext3_symlink_inode_operations; - if (ext3_should_writeback_data(inode)) - inode->i_mapping->a_ops = &ext3_writeback_aops; - else - inode->i_mapping->a_ops = &ext3_aops; - } -- } else -+ } else { -+ inode->i_op = &ext3_special_inode_operations; - init_special_inode(inode, inode->i_mode, - le32_to_cpu(iloc.raw_inode->i_block[0])); -+ } - if (ei->i_flags & EXT3_SYNC_FL) - inode->i_flags |= S_SYNC; - if (ei->i_flags & EXT3_APPEND_FL) -diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c ---- a/fs/ext3/namei.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/namei.c Thu Dec 12 20:58:37 2002 -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include "xattr.h" - - - /* -@@ -1654,7 +1655,7 @@ - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - -- inode = ext3_new_inode (handle, dir, S_IFDIR); -+ inode = ext3_new_inode (handle, dir, S_IFDIR | mode); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; -@@ -1662,7 +1663,6 @@ - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; - inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; -- inode->i_blocks = 0; - dir_block = ext3_bread (handle, inode, 0, 1, &err); - if (!dir_block) { - inode->i_nlink--; /* is this nlink == 0? */ -@@ -1689,9 +1689,6 @@ - BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata"); - ext3_journal_dirty_metadata(handle, dir_block); - brelse (dir_block); -- inode->i_mode = S_IFDIR | mode; -- if (dir->i_mode & S_ISGID) -- inode->i_mode |= S_ISGID; - ext3_mark_inode_dirty(handle, inode); - err = ext3_add_entry (handle, dentry, inode); - if (err) { -@@ -2068,7 +2065,7 @@ - goto out_stop; - - if (l > sizeof (EXT3_I(inode)->i_data)) { -- inode->i_op = &page_symlink_inode_operations; -+ inode->i_op = &ext3_symlink_inode_operations; - if (ext3_should_writeback_data(inode)) - inode->i_mapping->a_ops = &ext3_writeback_aops; - else -@@ -2284,4 +2281,17 @@ - .rmdir = ext3_rmdir, - .mknod = ext3_mknod, - .rename = ext3_rename, -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, - }; -+ -+struct inode_operations ext3_special_inode_operations = { -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, -+}; -+ -+ -diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c ---- a/fs/ext3/super.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/super.c Thu Dec 12 20:58:37 2002 -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include "xattr.h" - - #ifdef CONFIG_JBD_DEBUG - static int ext3_ro_after; /* Make fs read-only after this many jiffies */ -@@ -405,6 +406,7 @@ - struct ext3_super_block *es = sbi->s_es; - int i; - -+ ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { - EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); -@@ -554,6 +556,7 @@ - int is_remount) - { - unsigned long *mount_options = &sbi->s_mount_opt; -+ - uid_t *resuid = &sbi->s_resuid; - gid_t *resgid = &sbi->s_resgid; - char * this_char; -@@ -566,6 +569,13 @@ - continue; - if ((value = strchr (this_char, '=')) != NULL) - *value++ = 0; -+#ifdef CONFIG_EXT3_FS_XATTR -+ if (!strcmp (this_char, "user_xattr")) -+ set_opt (*mount_options, XATTR_USER); -+ else if (!strcmp (this_char, "nouser_xattr")) -+ clear_opt (*mount_options, XATTR_USER); -+ else -+#endif - if (!strcmp (this_char, "bsddf")) - clear_opt (*mount_options, MINIX_DF); - else if (!strcmp (this_char, "nouid32")) { -@@ -982,6 +992,12 @@ - sbi->s_mount_opt = 0; - sbi->s_resuid = EXT3_DEF_RESUID; - sbi->s_resgid = EXT3_DEF_RESGID; -+ -+ /* Default extended attribute flags */ -+#ifdef CONFIG_EXT3_FS_XATTR -+ set_opt(sbi->s_mount_opt, XATTR_USER); -+#endif -+ - if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) - goto out_fail; - -@@ -1820,7 +1836,10 @@ - - static int __init init_ext3_fs(void) - { -- int err = init_inodecache(); -+ int err = init_ext3_xattr(); -+ if (err) -+ return err; -+ err = init_inodecache(); - if (err) - goto out1; - err = register_filesystem(&ext3_fs_type); -@@ -1830,6 +1849,7 @@ - out: - destroy_inodecache(); - out1: -+ exit_ext3_xattr(); - return err; - } - -@@ -1837,6 +1857,7 @@ - { - unregister_filesystem(&ext3_fs_type); - destroy_inodecache(); -+ exit_ext3_xattr(); - } - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); -diff -Nru a/fs/ext3/symlink.c b/fs/ext3/symlink.c ---- a/fs/ext3/symlink.c Thu Dec 12 20:58:37 2002 -+++ b/fs/ext3/symlink.c Thu Dec 12 20:58:37 2002 -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include "xattr.h" - - static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen) - { -@@ -33,7 +34,20 @@ - return vfs_follow_link(nd, (char*)ei->i_data); - } - -+struct inode_operations ext3_symlink_inode_operations = { -+ .readlink = page_readlink, -+ .follow_link = page_follow_link, -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, -+}; -+ - struct inode_operations ext3_fast_symlink_inode_operations = { -- .readlink = ext3_readlink, /* BKL not held. Don't need */ -+ .readlink = ext3_readlink, /* BKL not held. Don't need */ - .follow_link = ext3_follow_link, /* BKL not held. Don't need */ -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, - }; -diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/ext3/xattr.c Thu Dec 12 20:58:37 2002 -@@ -0,0 +1,1131 @@ -+/* -+ * 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 holdsinode->i_sem semaphore when any of the xattr inode -+ * operations are called, so we are guaranteed that only one -+ * processes accesses extended attributes of an inode at any time. -+ * -+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that -+ * only a single process is modifying an extended attribute block, even -+ * if the block is shared among inodes. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "xattr.h" -+ -+#define EXT3_EA_USER "user." -+ -+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data)) -+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr)) -+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1) -+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) -+ -+#ifdef EXT3_XATTR_DEBUG -+# define ea_idebug(inode, f...) do { \ -+ printk(KERN_DEBUG "inode %s:%ld: ", \ -+ kdevname(inode->i_dev), inode->i_ino); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+# define ea_bdebug(bh, f...) do { \ -+ printk(KERN_DEBUG "block %s:%ld: ", \ -+ kdevname(bh->b_dev), bh->b_blocknr); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+#else -+# define ea_idebug(f...) -+# define ea_bdebug(f...) -+#endif -+ -+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *, -+ struct ext3_xattr_header *); -+ -+static int ext3_xattr_cache_insert(struct buffer_head *); -+static struct buffer_head *ext3_xattr_cache_find(struct inode *, -+ struct ext3_xattr_header *); -+static void ext3_xattr_cache_remove(struct buffer_head *); -+static void ext3_xattr_rehash(struct ext3_xattr_header *, -+ struct ext3_xattr_entry *); -+ -+static struct mb_cache *ext3_xattr_cache; -+ -+/* -+ * If a file system does not share extended attributes among inodes, -+ * we should not need the ext3_xattr_sem semaphore. However, the -+ * filesystem may still contain shared blocks, so we always take -+ * the lock. -+ */ -+ -+static DECLARE_MUTEX(ext3_xattr_sem); -+static struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX]; -+static rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED; -+ -+int -+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler) -+{ -+ int error = -EINVAL; -+ -+ if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ if (!ext3_xattr_handlers[name_index-1]) { -+ ext3_xattr_handlers[name_index-1] = handler; -+ error = 0; -+ } -+ write_unlock(&ext3_handler_lock); -+ } -+ return error; -+} -+ -+void -+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler) -+{ -+ if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ ext3_xattr_handlers[name_index-1] = NULL; -+ write_unlock(&ext3_handler_lock); -+ } -+} -+ -+static inline const char * -+strcmp_prefix(const char *a, const char *a_prefix) -+{ -+ while (*a_prefix && *a == *a_prefix) { -+ a++; -+ a_prefix++; -+ } -+ return *a_prefix ? NULL : a; -+} -+ -+/* -+ * Decode the extended attribute name, and translate it into -+ * the name_index and name suffix. -+ */ -+static inline struct ext3_xattr_handler * -+ext3_xattr_resolve_name(const char **name) -+{ -+ struct ext3_xattr_handler *handler = NULL; -+ int i; -+ -+ if (!*name) -+ return NULL; -+ read_lock(&ext3_handler_lock); -+ for (i=0; 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 -+ */ -+ssize_t -+ext3_getxattr(struct dentry *dentry, const char *name, -+ void *buffer, size_t size) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -EOPNOTSUPP; -+ return handler->get(inode, name, buffer, size); -+} -+ -+/* -+ * Inode operation listxattr() -+ * -+ * dentry->d_inode->i_sem down -+ */ -+ssize_t -+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size) -+{ -+ return ext3_xattr_list(dentry->d_inode, buffer, size); -+} -+ -+/* -+ * Inode operation setxattr() -+ * -+ * dentry->d_inode->i_sem down -+ */ -+int -+ext3_setxattr(struct dentry *dentry, const char *name, -+ void *value, size_t size, int flags) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ if (size == 0) -+ value = ""; /* empty EA, do not remove */ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -EOPNOTSUPP; -+ return handler->set(inode, name, value, size, flags); -+} -+ -+/* -+ * Inode operation removexattr() -+ * -+ * dentry->d_inode->i_sem down -+ */ -+int -+ext3_removexattr(struct dentry *dentry, const char *name) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -EOPNOTSUPP; -+ return handler->set(inode, name, NULL, 0, XATTR_REPLACE); -+} -+ -+/* -+ * ext3_xattr_get() -+ * -+ * Copy an extended attribute into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_entry *entry; -+ unsigned int block, size; -+ char *end; -+ int name_len, error; -+ -+ ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", -+ name_index, name, buffer, (long)buffer_size); -+ -+ if (name == NULL) -+ return -EINVAL; -+ if (!EXT3_I(inode)->i_file_acl) -+ return -ENODATA; -+ block = EXT3_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(inode->i_sb, "ext3_xattr_get", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* find named attribute */ -+ name_len = strlen(name); -+ -+ error = -ERANGE; -+ if (name_len > 255) -+ goto cleanup; -+ entry = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (name_index == entry->e_name_index && -+ name_len == entry->e_name_len && -+ memcmp(name, entry->e_name, name_len) == 0) -+ goto found; -+ entry = next; -+ } -+ /* Check the remaining name entries */ -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ entry = next; -+ } -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ error = -ENODATA; -+ goto cleanup; -+found: -+ /* check the buffer size */ -+ if (entry->e_value_block != 0) -+ goto bad_block; -+ size = le32_to_cpu(entry->e_value_size); -+ if (size > inode->i_sb->s_blocksize || -+ le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize) -+ goto bad_block; -+ -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (buffer) { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ /* return value of attribute */ -+ memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs), -+ size); -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_list() -+ * -+ * Copy a list of attribute names into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_entry *entry; -+ unsigned int block, size = 0; -+ char *buf, *end; -+ int error; -+ -+ ea_idebug(inode, "buffer=%p, buffer_size=%ld", -+ buffer, (long)buffer_size); -+ -+ if (!EXT3_I(inode)->i_file_acl) -+ return 0; -+ block = EXT3_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(inode->i_sb, "ext3_xattr_list", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* compute the size required for the list of attribute names */ -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT3_XATTR_NEXT(entry)) { -+ struct ext3_xattr_handler *handler; -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ -+ handler = ext3_xattr_handler(entry->e_name_index); -+ if (handler) { -+ size += handler->list(NULL, inode, entry->e_name, -+ entry->e_name_len) + 1; -+ } -+ } -+ -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (!buffer) { -+ error = size; -+ goto cleanup; -+ } else { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ } -+ -+ /* list the attribute names */ -+ buf = buffer; -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT3_XATTR_NEXT(entry)) { -+ struct ext3_xattr_handler *handler; -+ -+ handler = ext3_xattr_handler(entry->e_name_index); -+ if (handler) { -+ buf += handler->list(buf, inode, entry->e_name, -+ entry->e_name_len); -+ *buf++ = '\0'; -+ } -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is -+ * not set, set it. -+ */ -+static void ext3_xattr_update_super_block(handle_t *handle, -+ struct super_block *sb) -+{ -+ if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) -+ return; -+ -+ lock_super(sb); -+ ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -+ EXT3_SB(sb)->s_es->s_feature_compat |= -+ cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR); -+ sb->s_dirt = 1; -+ ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -+ unlock_super(sb); -+} -+ -+/* -+ * ext3_xattr_set() -+ * -+ * Create, replace or remove an extended attribute for this inode. Buffer -+ * is NULL to remove an existing extended attribute, and non-NULL to -+ * either replace an existing extended attribute, or create a new extended -+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE -+ * specify that an extended attribute must exist and must not exist -+ * previous to the call, respectively. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+int -+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, const void *value, size_t value_len, int flags) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_header *header = NULL; -+ struct ext3_xattr_entry *here, *last; -+ unsigned int name_len; -+ int min_offs = sb->s_blocksize, not_found = 1, free, error; -+ char *end; -+ -+ /* -+ * header -- Points either into bh, or to a temporarily -+ * allocated buffer. -+ * here -- The named entry found, or the place for inserting, within -+ * the block pointed to by header. -+ * last -- Points right after the last named entry within the block -+ * pointed to by header. -+ * min_offs -- The offset of the first value (values are aligned -+ * towards the end of the block). -+ * end -- Points right after the block pointed to by header. -+ */ -+ -+ ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld", -+ name_index, name, value, (long)value_len); -+ -+ if (IS_RDONLY(inode)) -+ return -EROFS; -+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -+ return -EPERM; -+ if (value == NULL) -+ value_len = 0; -+ if (name == NULL) -+ return -EINVAL; -+ name_len = strlen(name); -+ if (name_len > 255 || value_len > sb->s_blocksize) -+ return -ERANGE; -+ down(&ext3_xattr_sem); -+ -+ if (EXT3_I(inode)->i_file_acl) { -+ /* The inode already has an extended attribute block. */ -+ int block = EXT3_I(inode)->i_file_acl; -+ -+ bh = sb_bread(sb, block); -+ error = -EIO; -+ if (!bh) -+ goto cleanup; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), -+ le32_to_cpu(HDR(bh)->h_refcount)); -+ header = HDR(bh); -+ end = bh->b_data + bh->b_size; -+ if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ header->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(sb, "ext3_xattr_set", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* Find the named attribute. */ -+ here = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(here)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!here->e_value_block && here->e_value_size) { -+ int offs = le16_to_cpu(here->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ not_found = name_index - here->e_name_index; -+ if (!not_found) -+ not_found = name_len - here->e_name_len; -+ if (!not_found) -+ not_found = memcmp(name, here->e_name,name_len); -+ if (not_found <= 0) -+ break; -+ here = next; -+ } -+ last = here; -+ /* We still need to compute min_offs and last. */ -+ while (!IS_LAST_ENTRY(last)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!last->e_value_block && last->e_value_size) { -+ int offs = le16_to_cpu(last->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ last = next; -+ } -+ -+ /* Check whether we have enough space left. */ -+ free = min_offs - ((char*)last - (char*)header) - sizeof(__u32); -+ } else { -+ /* We will use a new extended attribute block. */ -+ free = sb->s_blocksize - -+ sizeof(struct ext3_xattr_header) - sizeof(__u32); -+ here = last = NULL; /* avoid gcc uninitialized warning. */ -+ } -+ -+ if (not_found) { -+ /* Request to remove a nonexistent attribute? */ -+ error = -ENODATA; -+ if (flags & XATTR_REPLACE) -+ goto cleanup; -+ error = 0; -+ if (value == NULL) -+ goto cleanup; -+ else -+ free -= EXT3_XATTR_LEN(name_len); -+ } else { -+ /* Request to create an existing attribute? */ -+ error = -EEXIST; -+ if (flags & XATTR_CREATE) -+ goto cleanup; -+ if (!here->e_value_block && here->e_value_size) { -+ unsigned int size = le32_to_cpu(here->e_value_size); -+ -+ if (le16_to_cpu(here->e_value_offs) + size > -+ sb->s_blocksize || size > sb->s_blocksize) -+ goto bad_block; -+ free += EXT3_XATTR_SIZE(size); -+ } -+ } -+ free -= EXT3_XATTR_SIZE(value_len); -+ error = -ENOSPC; -+ if (free < 0) -+ goto cleanup; -+ -+ /* Here we know that we can set the new attribute. */ -+ -+ if (header) { -+ if (header->h_refcount == cpu_to_le32(1)) { -+ ea_bdebug(bh, "modifying in-place"); -+ ext3_xattr_cache_remove(bh); -+ error = ext3_journal_get_write_access(handle, bh); -+ if (error) -+ goto cleanup; -+ } else { -+ int offset; -+ -+ ea_bdebug(bh, "cloning"); -+ header = kmalloc(bh->b_size, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memcpy(header, HDR(bh), bh->b_size); -+ header->h_refcount = cpu_to_le32(1); -+ offset = (char *)header - bh->b_data; -+ here = ENTRY((char *)here + offset); -+ last = ENTRY((char *)last + offset); -+ } -+ } else { -+ /* Allocate a buffer where we construct the new block. */ -+ header = kmalloc(sb->s_blocksize, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memset(header, 0, sb->s_blocksize); -+ end = (char *)header + sb->s_blocksize; -+ header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC); -+ header->h_blocks = header->h_refcount = cpu_to_le32(1); -+ last = here = ENTRY(header+1); -+ } -+ -+ if (not_found) { -+ /* Insert the new name. */ -+ int size = EXT3_XATTR_LEN(name_len); -+ int rest = (char *)last - (char *)here; -+ memmove((char *)here + size, here, rest); -+ memset(here, 0, size); -+ here->e_name_index = name_index; -+ here->e_name_len = name_len; -+ memcpy(here->e_name, name, name_len); -+ } else { -+ /* Remove the old value. */ -+ if (!here->e_value_block && here->e_value_size) { -+ char *first_val = (char *)header + min_offs; -+ int offs = le16_to_cpu(here->e_value_offs); -+ char *val = (char *)header + offs; -+ size_t size = EXT3_XATTR_SIZE( -+ le32_to_cpu(here->e_value_size)); -+ memmove(first_val + size, first_val, val - first_val); -+ memset(first_val, 0, size); -+ here->e_value_offs = 0; -+ min_offs += size; -+ -+ /* Adjust all value offsets. */ -+ last = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(last)) { -+ int o = le16_to_cpu(last->e_value_offs); -+ if (!last->e_value_block && o < offs) -+ last->e_value_offs = -+ cpu_to_le16(o + size); -+ last = EXT3_XATTR_NEXT(last); -+ } -+ } -+ if (value == NULL) { -+ /* Remove this attribute. */ -+ if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) { -+ /* This block is now empty. */ -+ error = ext3_xattr_set2(handle, inode, bh,NULL); -+ goto cleanup; -+ } else { -+ /* Remove the old name. */ -+ int size = EXT3_XATTR_LEN(name_len); -+ last = ENTRY((char *)last - size); -+ memmove(here, (char*)here + size, -+ (char*)last - (char*)here); -+ memset(last, 0, size); -+ } -+ } -+ } -+ -+ if (value != NULL) { -+ /* Insert the new value. */ -+ here->e_value_size = cpu_to_le32(value_len); -+ if (value_len) { -+ size_t size = EXT3_XATTR_SIZE(value_len); -+ char *val = (char *)header + min_offs - size; -+ here->e_value_offs = -+ cpu_to_le16((char *)val - (char *)header); -+ memset(val + size - EXT3_XATTR_PAD, 0, -+ EXT3_XATTR_PAD); /* Clear the pad bytes. */ -+ memcpy(val, value, value_len); -+ } -+ } -+ ext3_xattr_rehash(header, here); -+ -+ error = ext3_xattr_set2(handle, inode, bh, header); -+ -+cleanup: -+ brelse(bh); -+ if (!(bh && header == HDR(bh))) -+ kfree(header); -+ up(&ext3_xattr_sem); -+ -+ return error; -+} -+ -+/* -+ * Second half of ext3_xattr_set(): Update the file system. -+ */ -+static int -+ext3_xattr_set2(handle_t *handle, struct inode *inode, -+ struct buffer_head *old_bh, struct ext3_xattr_header *header) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *new_bh = NULL; -+ int error; -+ -+ if (header) { -+ new_bh = ext3_xattr_cache_find(inode, header); -+ if (new_bh) { -+ /* -+ * We found an identical block in the cache. -+ * The old block will be released after updating -+ * the inode. -+ */ -+ ea_bdebug(old_bh, "reusing block %ld", -+ new_bh->b_blocknr); -+ -+ error = -EDQUOT; -+ if (DQUOT_ALLOC_BLOCK(inode, 1)) -+ goto cleanup; -+ -+ error = ext3_journal_get_write_access(handle, new_bh); -+ if (error) -+ goto cleanup; -+ HDR(new_bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(new_bh)->h_refcount) + 1); -+ ea_bdebug(new_bh, "refcount now=%d", -+ le32_to_cpu(HDR(new_bh)->h_refcount)); -+ } else if (old_bh && header == HDR(old_bh)) { -+ /* Keep this block. */ -+ new_bh = old_bh; -+ ext3_xattr_cache_insert(new_bh); -+ } else { -+ /* We need to allocate a new block */ -+ int block; -+ int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + -+ EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb); -+ -+ block = ext3_new_block(handle, inode, goal, 0, -+ 0, &error); -+ if (error) -+ goto cleanup; -+ ea_idebug(inode, "creating block %d", block); -+ -+ new_bh = sb_getblk(sb, block); -+ if (!new_bh) { -+getblk_failed: -+ ext3_free_blocks(handle, inode, block, 1); -+ error = -EIO; -+ goto cleanup; -+ } -+ lock_buffer(new_bh); -+ error = ext3_journal_get_create_access(handle, new_bh); -+ if (error) { -+ unlock_buffer(new_bh); -+ goto getblk_failed; -+ } -+ memcpy(new_bh->b_data, header, new_bh->b_size); -+ set_buffer_uptodate(new_bh); -+ unlock_buffer(new_bh); -+ ext3_xattr_cache_insert(new_bh); -+ -+ ext3_xattr_update_super_block(handle, sb); -+ } -+ error = ext3_journal_dirty_metadata(handle, new_bh); -+ if (error) -+ goto cleanup; -+ } -+ -+ /* Update the inode. */ -+ EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0; -+ inode->i_ctime = CURRENT_TIME; -+ ext3_mark_inode_dirty(handle, inode); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ -+ error = 0; -+ if (old_bh && old_bh != new_bh) { -+ /* -+ * If there was an old block, and we are not still using it, -+ * we now release the old block. -+ */ -+ unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount); -+ -+ error = ext3_journal_get_write_access(handle, old_bh); -+ if (error) -+ goto cleanup; -+ if (refcount == 1) { -+ /* Free the old block. */ -+ ea_bdebug(old_bh, "freeing"); -+ ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1); -+ -+ /* ext3_forget() calls bforget() for us, but we -+ let our caller release old_bh, so we need to -+ duplicate the handle before. */ -+ get_bh(old_bh); -+ ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr); -+ } else { -+ /* Decrement the refcount only. */ -+ refcount--; -+ HDR(old_bh)->h_refcount = cpu_to_le32(refcount); -+ DQUOT_FREE_BLOCK(inode, 1); -+ ext3_journal_dirty_metadata(handle, old_bh); -+ ea_bdebug(old_bh, "refcount now=%d", refcount); -+ } -+ } -+ -+cleanup: -+ if (old_bh != new_bh) -+ brelse(new_bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_delete_inode() -+ * -+ * Free extended attribute resources associated with this inode. This -+ * is called immediately before an inode is freed. -+ */ -+void -+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode) -+{ -+ struct buffer_head *bh; -+ unsigned int block = EXT3_I(inode)->i_file_acl; -+ -+ if (!block) -+ return; -+ down(&ext3_xattr_sem); -+ -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_delete_inode", -+ "inode %ld: block %d read error", inode->i_ino, block); -+ goto cleanup; -+ } -+ ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count))); -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+ ext3_error(inode->i_sb, "ext3_xattr_delete_inode", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ goto cleanup; -+ } -+ ext3_journal_get_write_access(handle, bh); -+ ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ if (HDR(bh)->h_refcount == cpu_to_le32(1)) { -+ ext3_xattr_cache_remove(bh); -+ ext3_free_blocks(handle, inode, block, 1); -+ ext3_forget(handle, 1, inode, bh, block); -+ bh = NULL; -+ } else { -+ HDR(bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ ext3_journal_dirty_metadata(handle, bh); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ DQUOT_FREE_BLOCK(inode, 1); -+ } -+ EXT3_I(inode)->i_file_acl = 0; -+ -+cleanup: -+ brelse(bh); -+ up(&ext3_xattr_sem); -+} -+ -+/* -+ * ext3_xattr_put_super() -+ * -+ * This is called when a file system is unmounted. -+ */ -+void -+ext3_xattr_put_super(struct super_block *sb) -+{ -+ mb_cache_shrink(ext3_xattr_cache, sb->s_bdev); -+} -+ -+/* -+ * ext3_xattr_cache_insert() -+ * -+ * Create a new entry in the extended attribute cache, and insert -+ * it unless such an entry is already in the cache. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+static int -+ext3_xattr_cache_insert(struct buffer_head *bh) -+{ -+ __u32 hash = le32_to_cpu(HDR(bh)->h_hash); -+ struct mb_cache_entry *ce; -+ int error; -+ -+ ce = mb_cache_entry_alloc(ext3_xattr_cache); -+ if (!ce) -+ return -ENOMEM; -+ error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash); -+ if (error) { -+ mb_cache_entry_free(ce); -+ if (error == -EBUSY) { -+ ea_bdebug(bh, "already in cache (%d cache entries)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ error = 0; -+ } -+ } else { -+ ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash, -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ mb_cache_entry_release(ce); -+ } -+ return error; -+} -+ -+/* -+ * ext3_xattr_cmp() -+ * -+ * Compare two extended attribute blocks for equality. -+ * -+ * Returns 0 if the blocks are equal, 1 if they differ, and -+ * a negative error number on errors. -+ */ -+static int -+ext3_xattr_cmp(struct ext3_xattr_header *header1, -+ struct ext3_xattr_header *header2) -+{ -+ struct ext3_xattr_entry *entry1, *entry2; -+ -+ entry1 = ENTRY(header1+1); -+ entry2 = ENTRY(header2+1); -+ while (!IS_LAST_ENTRY(entry1)) { -+ if (IS_LAST_ENTRY(entry2)) -+ return 1; -+ if (entry1->e_hash != entry2->e_hash || -+ entry1->e_name_len != entry2->e_name_len || -+ entry1->e_value_size != entry2->e_value_size || -+ memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len)) -+ return 1; -+ if (entry1->e_value_block != 0 || entry2->e_value_block != 0) -+ return -EIO; -+ if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), -+ (char *)header2 + le16_to_cpu(entry2->e_value_offs), -+ le32_to_cpu(entry1->e_value_size))) -+ return 1; -+ -+ entry1 = EXT3_XATTR_NEXT(entry1); -+ entry2 = EXT3_XATTR_NEXT(entry2); -+ } -+ if (!IS_LAST_ENTRY(entry2)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * ext3_xattr_cache_find() -+ * -+ * Find an identical extended attribute block. -+ * -+ * Returns a pointer to the block found, or NULL if such a block was -+ * not found or an error occurred. -+ */ -+static struct buffer_head * -+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header) -+{ -+ __u32 hash = le32_to_cpu(header->h_hash); -+ struct mb_cache_entry *ce; -+ -+ if (!header->h_hash) -+ return NULL; /* never share */ -+ ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); -+ ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_bdev, hash); -+ while (ce) { -+ struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block); -+ -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_cache_find", -+ "inode %ld: block %ld read error", -+ inode->i_ino, (unsigned long) ce->e_block); -+ } else if (le32_to_cpu(HDR(bh)->h_refcount) > -+ EXT3_XATTR_REFCOUNT_MAX) { -+ ea_idebug(inode, "block %ld refcount %d>%d", -+ (unsigned long) ce->e_block, -+ le32_to_cpu(HDR(bh)->h_refcount), -+ EXT3_XATTR_REFCOUNT_MAX); -+ } else if (!ext3_xattr_cmp(header, HDR(bh))) { -+ ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count))); -+ mb_cache_entry_release(ce); -+ return bh; -+ } -+ brelse(bh); -+ ce = mb_cache_entry_find_next(ce, 0, inode->i_bdev, hash); -+ } -+ return NULL; -+} -+ -+/* -+ * ext3_xattr_cache_remove() -+ * -+ * Remove the cache entry of a block from the cache. Called when a -+ * block becomes invalid. -+ */ -+static void -+ext3_xattr_cache_remove(struct buffer_head *bh) -+{ -+ struct mb_cache_entry *ce; -+ -+ ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev, -+ bh->b_blocknr); -+ if (ce) { -+ ea_bdebug(bh, "removing (%d cache entries remaining)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)-1); -+ mb_cache_entry_free(ce); -+ } else -+ ea_bdebug(bh, "no cache entry"); -+} -+ -+#define NAME_HASH_SHIFT 5 -+#define VALUE_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_hash_entry() -+ * -+ * Compute the hash of an extended attribute. -+ */ -+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ __u32 hash = 0; -+ char *name = entry->e_name; -+ int n; -+ -+ for (n=0; n < entry->e_name_len; n++) { -+ hash = (hash << NAME_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ -+ *name++; -+ } -+ -+ if (entry->e_value_block == 0 && entry->e_value_size != 0) { -+ __u32 *value = (__u32 *)((char *)header + -+ le16_to_cpu(entry->e_value_offs)); -+ for (n = (le32_to_cpu(entry->e_value_size) + -+ EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) { -+ hash = (hash << VALUE_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ -+ le32_to_cpu(*value++); -+ } -+ } -+ entry->e_hash = cpu_to_le32(hash); -+} -+ -+#undef NAME_HASH_SHIFT -+#undef VALUE_HASH_SHIFT -+ -+#define BLOCK_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_rehash() -+ * -+ * Re-compute the extended attribute hash value after an entry has changed. -+ */ -+static void ext3_xattr_rehash(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ struct ext3_xattr_entry *here; -+ __u32 hash = 0; -+ -+ ext3_xattr_hash_entry(header, entry); -+ here = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(here)) { -+ if (!here->e_hash) { -+ /* Block is not shared if an entry's hash value == 0 */ -+ hash = 0; -+ break; -+ } -+ hash = (hash << BLOCK_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^ -+ le32_to_cpu(here->e_hash); -+ here = EXT3_XATTR_NEXT(here); -+ } -+ header->h_hash = cpu_to_le32(hash); -+} -+ -+#undef BLOCK_HASH_SHIFT -+EXPORT_SYMBOL(ext3_xattr_get); -+EXPORT_SYMBOL(ext3_xattr_set); -+EXPORT_SYMBOL(ext3_bread); -+ -+int __init -+init_ext3_xattr(void) -+{ -+ int err; -+ -+ err = ext3_xattr_register(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler); -+ if (err) -+ return err; -+ ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL, -+ sizeof(struct mb_cache_entry) + -+ sizeof(struct mb_cache_entry_index), 1, 6); -+ if (!ext3_xattr_cache) { -+ ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+void -+exit_ext3_xattr(void) -+{ -+ if (ext3_xattr_cache) -+ mb_cache_destroy(ext3_xattr_cache); -+ ext3_xattr_cache = NULL; -+ ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler); -+} -+ -diff -Nru a/fs/ext3/xattr.h b/fs/ext3/xattr.h ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/ext3/xattr.h Thu Dec 12 20:58:37 2002 -@@ -0,0 +1,133 @@ -+/* -+ File: fs/ext3/xattr.h -+ -+ On-disk format of extended attributes for the ext3 filesystem. -+ -+ (C) 2001 Andreas Gruenbacher, -+*/ -+ -+#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 CONFIG_EXT3_FS_XATTR -+ -+struct ext3_xattr_handler { -+ char *prefix; -+ size_t (*list)(char *list, struct inode *inode, const char *name, -+ int name_len); -+ int (*get)(struct inode *inode, const char *name, void *buffer, -+ size_t size); -+ int (*set)(struct inode *inode, const char *name, const void *buffer, -+ size_t size, int flags); -+}; -+ -+extern int ext3_xattr_register(int, struct ext3_xattr_handler *); -+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *); -+ -+extern int ext3_setxattr(struct dentry *, const char *, void *, size_t, int); -+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t); -+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); -+extern int ext3_removexattr(struct dentry *, const char *); -+ -+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t); -+extern int ext3_xattr_list(struct inode *, char *, size_t); -+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int); -+ -+extern void ext3_xattr_delete_inode(handle_t *, struct inode *); -+extern void ext3_xattr_put_super(struct super_block *); -+ -+extern int init_ext3_xattr(void); -+extern void exit_ext3_xattr(void); -+ -+# else /* CONFIG_EXT3_FS_XATTR */ -+# define ext3_setxattr NULL -+# define ext3_getxattr NULL -+# define ext3_listxattr NULL -+# define ext3_removexattr NULL -+ -+static inline int -+ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t size, int flags) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int -+ext3_xattr_list(struct inode *inode, void *buffer, size_t size, int flags) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int -+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, const void *value, size_t size, int flags) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void -+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode) -+{ -+} -+ -+static inline void -+ext3_xattr_put_super(struct super_block *sb) -+{ -+} -+ -+static inline int -+init_ext3_xattr(void) -+{ -+ return 0; -+} -+ -+static inline void -+exit_ext3_xattr(void) -+{ -+} -+ -+# endif /* CONFIG_EXT3_FS_XATTR */ -+ -+extern struct ext3_xattr_handler ext3_xattr_user_handler; -diff -Nru a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/ext3/xattr_user.c Thu Dec 12 20:58:37 2002 -@@ -0,0 +1,99 @@ -+/* -+ * linux/fs/ext3/xattr_user.c -+ * Handler for extended user attributes. -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "xattr.h" -+ -+#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); -+ } -+ return prefix_len + name_len; -+} -+ -+static int -+ext3_xattr_user_get(struct inode *inode, const char *name, -+ void *buffer, size_t size) -+{ -+ int error; -+ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return -EOPNOTSUPP; -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+ error = ext3_permission_locked(inode, MAY_READ); -+#else -+ error = permission(inode, MAY_READ); -+#endif -+ if (error) -+ return error; -+ -+ return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name, -+ buffer, size); -+} -+ -+static int -+ext3_xattr_user_set(struct inode *inode, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ handle_t *handle; -+ int error; -+ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return -EOPNOTSUPP; -+ if ( !S_ISREG(inode->i_mode) && -+ (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) -+ return -EPERM; -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+ error = ext3_permission_locked(inode, MAY_WRITE); -+#else -+ error = permission(inode, MAY_WRITE); -+#endif -+ if (error) -+ return error; -+ -+ lock_kernel(); -+ handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name, -+ value, size, flags); -+ ext3_journal_stop(handle, inode); -+ unlock_kernel(); -+ -+ return error; -+} -+ -+struct ext3_xattr_handler ext3_xattr_user_handler = { -+ prefix: XATTR_USER_PREFIX, -+ list: ext3_xattr_user_list, -+ get: ext3_xattr_user_get, -+ set: ext3_xattr_user_set, -+}; -diff -Nru a/fs/mbcache.c b/fs/mbcache.c ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/mbcache.c Thu Dec 12 20:58:37 2002 -@@ -0,0 +1,702 @@ -+/* -+ * 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. -+ */ -+ -+#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)"); -+MODULE_LICENSE("GPL"); -+ -+EXPORT_SYMBOL(mb_cache_create); -+EXPORT_SYMBOL(mb_cache_shrink); -+EXPORT_SYMBOL(mb_cache_destroy); -+EXPORT_SYMBOL(mb_cache_entry_alloc); -+EXPORT_SYMBOL(mb_cache_entry_insert); -+EXPORT_SYMBOL(mb_cache_entry_release); -+EXPORT_SYMBOL(mb_cache_entry_takeout); -+EXPORT_SYMBOL(mb_cache_entry_free); -+EXPORT_SYMBOL(mb_cache_entry_dup); -+EXPORT_SYMBOL(mb_cache_entry_get); -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+EXPORT_SYMBOL(mb_cache_entry_find_first); -+EXPORT_SYMBOL(mb_cache_entry_find_next); -+#endif -+ -+ -+/* -+ * Global data: list of all mbcache's, lru list, and a spinlock for -+ * accessing cache data structures on SMP machines. (The lru list is -+ * global across all mbcaches.) -+ */ -+ -+static LIST_HEAD(mb_cache_list); -+static LIST_HEAD(mb_cache_lru_list); -+static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED; -+static struct shrinker *mb_shrinker; -+ -+static inline int -+mb_cache_indexes(struct mb_cache *cache) -+{ -+#ifdef MB_CACHE_INDEXES_COUNT -+ return MB_CACHE_INDEXES_COUNT; -+#else -+ return cache->c_indexes_count; -+#endif -+} -+ -+/* -+ * What the mbcache registers as to get shrunk dynamically. -+ */ -+ -+static int mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask); -+ -+static inline void -+__mb_cache_entry_takeout_lru(struct mb_cache_entry *ce) -+{ -+ if (!list_empty(&ce->e_lru_list)) -+ list_del_init(&ce->e_lru_list); -+} -+ -+ -+static inline void -+__mb_cache_entry_into_lru(struct mb_cache_entry *ce) -+{ -+ list_add(&ce->e_lru_list, &mb_cache_lru_list); -+} -+ -+ -+static inline int -+__mb_cache_entry_in_lru(struct mb_cache_entry *ce) -+{ -+ return (!list_empty(&ce->e_lru_list)); -+} -+ -+ -+/* -+ * Insert the cache entry into all hashes. -+ */ -+static inline void -+__mb_cache_entry_link(struct mb_cache_entry *ce) -+{ -+ struct mb_cache *cache = ce->e_cache; -+ unsigned int bucket; -+ int n; -+ -+ bucket = hash_long((unsigned long)ce->e_bdev + -+ (ce->e_block & 0xffffff), cache->c_bucket_bits); -+ list_add(&ce->e_block_list, &cache->c_block_hash[bucket]); -+ for (n=0; ne_indexes[n].o_key, -+ cache->c_bucket_bits); -+ list_add(&ce->e_indexes[n].o_list, -+ &cache->c_indexes_hash[n][bucket]); -+ } -+} -+ -+ -+/* -+ * Remove the cache entry from all hashes. -+ */ -+static inline void -+__mb_cache_entry_unlink(struct mb_cache_entry *ce) -+{ -+ int n; -+ -+ list_del_init(&ce->e_block_list); -+ for (n = 0; n < mb_cache_indexes(ce->e_cache); n++) -+ list_del(&ce->e_indexes[n].o_list); -+} -+ -+ -+static inline int -+__mb_cache_entry_is_linked(struct mb_cache_entry *ce) -+{ -+ return (!list_empty(&ce->e_block_list)); -+} -+ -+ -+static inline struct mb_cache_entry * -+__mb_cache_entry_read(struct mb_cache_entry *ce) -+{ -+ __mb_cache_entry_takeout_lru(ce); -+ atomic_inc(&ce->e_used); -+ return ce; -+} -+ -+ -+static inline void -+__mb_cache_entry_forget(struct mb_cache_entry *ce) -+{ -+ struct mb_cache *cache = ce->e_cache; -+ -+ mb_assert(atomic_read(&ce->e_used) == 0); -+ atomic_dec(&cache->c_entry_count); -+ if (cache->c_op.free) -+ cache->c_op.free(ce); -+ kmem_cache_free(cache->c_entry_cache, ce); -+} -+ -+ -+static inline void -+__mb_cache_entry_release_unlock(struct mb_cache_entry *ce) -+{ -+ if (atomic_dec_and_test(&ce->e_used)) { -+ if (!__mb_cache_entry_is_linked(ce)) -+ goto forget; -+ __mb_cache_entry_into_lru(ce); -+ } -+ spin_unlock(&mb_cache_spinlock); -+ return; -+forget: -+ spin_unlock(&mb_cache_spinlock); -+ __mb_cache_entry_forget(ce); -+} -+ -+ -+/* -+ * mb_cache_shrink_fn() memory pressure callback -+ * -+ * This function is called by the kernel memory management when memory -+ * gets low. -+ * -+ * @nr_to_scan: Number of objects to scan -+ * @gfp_mask: (ignored) -+ * -+ * Returns the number of objects which are present in the cache. -+ */ -+static int -+mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l; -+ int count = 0; -+ -+ spin_lock(&mb_cache_spinlock); -+ list_for_each_prev(l, &mb_cache_list) { -+ struct mb_cache *cache = -+ list_entry(l, struct mb_cache, c_cache_list); -+ mb_debug("cache %s (%d)", cache->c_name, -+ atomic_read(&cache->c_entry_count)); -+ count += atomic_read(&cache->c_entry_count); -+ } -+ mb_debug("trying to free %d entries", nr_to_scan); -+ if (nr_to_scan == 0) { -+ spin_unlock(&mb_cache_spinlock); -+ goto out; -+ } -+ while (nr_to_scan && !list_empty(&mb_cache_lru_list)) { -+ struct mb_cache_entry *ce = -+ list_entry(mb_cache_lru_list.prev, -+ struct mb_cache_entry, e_lru_list); -+ list_move(&ce->e_lru_list, &free_list); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ nr_to_scan--; -+ } -+ spin_unlock(&mb_cache_spinlock); -+ l = free_list.prev; -+ while (l != &free_list) { -+ struct mb_cache_entry *ce = list_entry(l, -+ struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ __mb_cache_entry_forget(ce); -+ count--; -+ } -+out: -+ mb_debug("%d remaining entries ", count); -+ return count; -+} -+ -+ -+/* -+ * mb_cache_create() create a new cache -+ * -+ * All entries in one cache are equal size. Cache entries may be from -+ * multiple devices. If this is the first mbcache created, registers -+ * the cache with kernel memory management. Returns NULL if no more -+ * memory was available. -+ * -+ * @name: name of the cache (informal) -+ * @cache_op: contains the callback called when freeing a cache entry -+ * @entry_size: The size of a cache entry, including -+ * struct mb_cache_entry -+ * @indexes_count: number of additional indexes in the cache. Must equal -+ * MB_CACHE_INDEXES_COUNT if the number of indexes is -+ * hardwired. -+ * @bucket_bits: log2(number of hash buckets) -+ */ -+struct mb_cache * -+mb_cache_create(const char *name, struct mb_cache_op *cache_op, -+ size_t entry_size, int indexes_count, int bucket_bits) -+{ -+ int m=0, n, bucket_count = 1 << bucket_bits; -+ struct mb_cache *cache = NULL; -+ -+ if(entry_size < sizeof(struct mb_cache_entry) + -+ indexes_count * sizeof(struct mb_cache_entry_index)) -+ return NULL; -+ -+ cache = kmalloc(sizeof(struct mb_cache) + -+ indexes_count * sizeof(struct list_head), GFP_KERNEL); -+ if (!cache) -+ goto fail; -+ cache->c_name = name; -+ if (cache_op) -+ cache->c_op.free = cache_op->free; -+ else -+ cache->c_op.free = NULL; -+ atomic_set(&cache->c_entry_count, 0); -+ cache->c_bucket_bits = bucket_bits; -+#ifdef MB_CACHE_INDEXES_COUNT -+ mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT); -+#else -+ cache->c_indexes_count = indexes_count; -+#endif -+ cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head), -+ GFP_KERNEL); -+ if (!cache->c_block_hash) -+ goto fail; -+ for (n=0; 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); -+ if (list_empty(&mb_cache_list)) { -+ if (mb_shrinker) { -+ printk(KERN_ERR "%s: already have a shrinker!\n", -+ __FUNCTION__); -+ remove_shrinker(mb_shrinker); -+ } -+ mb_shrinker = set_shrinker(DEFAULT_SEEKS, mb_cache_shrink_fn); -+ } -+ list_add(&cache->c_cache_list, &mb_cache_list); -+ spin_unlock(&mb_cache_spinlock); -+ return cache; -+ -+fail: -+ if (cache) { -+ while (--m >= 0) -+ kfree(cache->c_indexes_hash[m]); -+ if (cache->c_block_hash) -+ kfree(cache->c_block_hash); -+ kfree(cache); -+ } -+ return NULL; -+} -+ -+ -+/* -+ * mb_cache_shrink() -+ * -+ * Removes all cache entires of a device from the cache. All cache entries -+ * currently in use cannot be freed, and thus remain in the cache. All others -+ * are freed. -+ * -+ * @cache: which cache to shrink -+ * @bdev: which device's cache entries to shrink -+ */ -+void -+mb_cache_shrink(struct mb_cache *cache, struct block_device *bdev) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l; -+ -+ spin_lock(&mb_cache_spinlock); -+ l = mb_cache_lru_list.prev; -+ while (l != &mb_cache_lru_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ if (ce->e_bdev == bdev) { -+ list_move(&ce->e_lru_list, &free_list); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ } -+ } -+ spin_unlock(&mb_cache_spinlock); -+ l = free_list.prev; -+ while (l != &free_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ __mb_cache_entry_forget(ce); -+ } -+} -+ -+ -+/* -+ * mb_cache_destroy() -+ * -+ * Shrinks the cache to its minimum possible size (hopefully 0 entries), -+ * and then destroys it. If this was the last mbcache, un-registers the -+ * mbcache from kernel memory management. -+ */ -+void -+mb_cache_destroy(struct mb_cache *cache) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l; -+ int n; -+ -+ spin_lock(&mb_cache_spinlock); -+ l = mb_cache_lru_list.prev; -+ while (l != &mb_cache_lru_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ if (ce->e_cache == cache) { -+ list_move(&ce->e_lru_list, &free_list); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ } -+ } -+ list_del(&cache->c_cache_list); -+ if (list_empty(&mb_cache_list) && mb_shrinker) { -+ remove_shrinker(mb_shrinker); -+ mb_shrinker = 0; -+ } -+ spin_unlock(&mb_cache_spinlock); -+ -+ l = free_list.prev; -+ while (l != &free_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ __mb_cache_entry_forget(ce); -+ } -+ -+ if (atomic_read(&cache->c_entry_count) > 0) { -+ mb_error("cache %s: %d orphaned entries", -+ cache->c_name, -+ atomic_read(&cache->c_entry_count)); -+ } -+ -+ kmem_cache_destroy(cache->c_entry_cache); -+ -+ for (n=0; n < mb_cache_indexes(cache); n++) -+ kfree(cache->c_indexes_hash[n]); -+ kfree(cache->c_block_hash); -+ -+ kfree(cache); -+} -+ -+ -+/* -+ * mb_cache_entry_alloc() -+ * -+ * Allocates a new cache entry. The new entry will not be valid initially, -+ * and thus cannot be looked up yet. It should be filled with data, and -+ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL -+ * if no more memory was available. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_alloc(struct mb_cache *cache) -+{ -+ struct mb_cache_entry *ce; -+ -+ atomic_inc(&cache->c_entry_count); -+ ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL); -+ if (ce) { -+ INIT_LIST_HEAD(&ce->e_lru_list); -+ INIT_LIST_HEAD(&ce->e_block_list); -+ ce->e_cache = cache; -+ atomic_set(&ce->e_used, 1); -+ } -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_insert() -+ * -+ * Inserts an entry that was allocated using mb_cache_entry_alloc() into -+ * the cache. After this, the cache entry can be looked up, but is not yet -+ * in the lru list as the caller still holds a handle to it. Returns 0 on -+ * success, or -EBUSY if a cache entry for that device + inode exists -+ * already (this may happen after a failed lookup, but when another process -+ * has inserted the same cache entry in the meantime). -+ * -+ * @bdev: device the cache entry belongs to -+ * @block: block number -+ * @keys: array of additional keys. There must be indexes_count entries -+ * in the array (as specified when creating the cache). -+ */ -+int -+mb_cache_entry_insert(struct mb_cache_entry *ce, struct block_device *bdev, -+ sector_t block, unsigned int keys[]) -+{ -+ struct mb_cache *cache = ce->e_cache; -+ unsigned int bucket; -+ struct list_head *l; -+ int error = -EBUSY, n; -+ -+ bucket = hash_long((unsigned long)bdev + (block & 0xffffffff), -+ cache->c_bucket_bits); -+ spin_lock(&mb_cache_spinlock); -+ list_for_each_prev(l, &cache->c_block_hash[bucket]) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_block_list); -+ if (ce->e_bdev == bdev && ce->e_block == block) -+ goto out; -+ } -+ mb_assert(!__mb_cache_entry_is_linked(ce)); -+ ce->e_bdev = bdev; -+ ce->e_block = block; -+ for (n=0; ne_indexes[n].o_key = keys[n]; -+ __mb_cache_entry_link(ce); -+out: -+ spin_unlock(&mb_cache_spinlock); -+ return error; -+} -+ -+ -+/* -+ * mb_cache_entry_release() -+ * -+ * Release a handle to a cache entry. When the last handle to a cache entry -+ * is released it is either freed (if it is invalid) or otherwise inserted -+ * in to the lru list. -+ */ -+void -+mb_cache_entry_release(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ __mb_cache_entry_release_unlock(ce); -+} -+ -+ -+/* -+ * mb_cache_entry_takeout() -+ * -+ * Take a cache entry out of the cache, making it invalid. The entry can later -+ * be re-inserted using mb_cache_entry_insert(), or released using -+ * mb_cache_entry_release(). -+ */ -+void -+mb_cache_entry_takeout(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ mb_assert(!__mb_cache_entry_in_lru(ce)); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ spin_unlock(&mb_cache_spinlock); -+} -+ -+ -+/* -+ * mb_cache_entry_free() -+ * -+ * This is equivalent to the sequence mb_cache_entry_takeout() -- -+ * mb_cache_entry_release(). -+ */ -+void -+mb_cache_entry_free(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ mb_assert(!__mb_cache_entry_in_lru(ce)); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ __mb_cache_entry_release_unlock(ce); -+} -+ -+ -+/* -+ * mb_cache_entry_dup() -+ * -+ * Duplicate a handle to a cache entry (does not duplicate the cache entry -+ * itself). After the call, both the old and the new handle must be released. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_dup(struct mb_cache_entry *ce) -+{ -+ atomic_inc(&ce->e_used); -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_get() -+ * -+ * Get a cache entry by device / block number. (There can only be one entry -+ * in the cache per device and block.) Returns NULL if no such cache entry -+ * exists. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_get(struct mb_cache *cache, struct block_device *bdev, -+ sector_t block) -+{ -+ unsigned int bucket; -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ bucket = hash_long((unsigned long)bdev + (block & 0xffffffff), -+ cache->c_bucket_bits); -+ spin_lock(&mb_cache_spinlock); -+ list_for_each(l, &cache->c_block_hash[bucket]) { -+ ce = list_entry(l, struct mb_cache_entry, e_block_list); -+ if (ce->e_bdev == bdev && ce->e_block == block) { -+ ce = __mb_cache_entry_read(ce); -+ goto cleanup; -+ } -+ } -+ ce = NULL; -+ -+cleanup: -+ spin_unlock(&mb_cache_spinlock); -+ return ce; -+} -+ -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+ -+static struct mb_cache_entry * -+__mb_cache_entry_find(struct list_head *l, struct list_head *head, -+ int index, struct block_device *bdev, unsigned int key) -+{ -+ while (l != head) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, -+ e_indexes[index].o_list); -+ if (ce->e_bdev == bdev && -+ ce->e_indexes[index].o_key == key) { -+ ce = __mb_cache_entry_read(ce); -+ if (ce) -+ return ce; -+ } -+ l = l->next; -+ } -+ return NULL; -+} -+ -+ -+/* -+ * mb_cache_entry_find_first() -+ * -+ * Find the first cache entry on a given device with a certain key in -+ * an additional index. Additonal matches can be found with -+ * mb_cache_entry_find_next(). Returns NULL if no match was found. -+ * -+ * @cache: the cache to search -+ * @index: the number of the additonal index to search (0<=indexc_bucket_bits); -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ mb_assert(index < mb_cache_indexes(cache)); -+ spin_lock(&mb_cache_spinlock); -+ l = cache->c_indexes_hash[index][bucket].next; -+ ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket], -+ index, bdev, key); -+ spin_unlock(&mb_cache_spinlock); -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_find_next() -+ * -+ * Find the next cache entry on a given device with a certain key in an -+ * additional index. Returns NULL if no match could be found. The previous -+ * entry is atomatically released, so that mb_cache_entry_find_next() can -+ * be called like this: -+ * -+ * entry = mb_cache_entry_find_first(); -+ * while (entry) { -+ * ... -+ * entry = mb_cache_entry_find_next(entry, ...); -+ * } -+ * -+ * @prev: The previous match -+ * @index: the number of the additonal index to search (0<=indexe_cache; -+ unsigned int bucket = hash_long(key, cache->c_bucket_bits); -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ mb_assert(index < mb_cache_indexes(cache)); -+ spin_lock(&mb_cache_spinlock); -+ l = prev->e_indexes[index].o_list.next; -+ ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket], -+ index, bdev, key); -+ __mb_cache_entry_release_unlock(prev); -+ return ce; -+} -+ -+#endif /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */ -diff -Nru a/fs/namei.c b/fs/namei.c ---- a/fs/namei.c Thu Dec 12 20:58:37 2002 -+++ b/fs/namei.c Thu Dec 12 20:58:37 2002 -@@ -265,6 +265,9 @@ - - void path_release(struct nameidata *nd) - { -+ if (&nd->it && nd->dentry && nd->dentry->d_op && -+ nd->dentry->d_op->d_intent_release) -+ nd->dentry->d_op->d_intent_release(nd->dentry, &nd->it); - dput(nd->dentry); - mntput(nd->mnt); - } -@@ -273,10 +276,18 @@ - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -351,7 +362,7 @@ - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; -@@ -369,7 +380,10 @@ - struct dentry * dentry = d_alloc(parent, name); - result = ERR_PTR(-ENOMEM); - if (dentry) { -- result = dir->i_op->lookup(dir, dentry); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else -+ result = dir->i_op->lookup(dir, dentry); - if (result) - dput(dentry); - else { -@@ -391,6 +405,12 @@ - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ result = ERR_PTR(-ENOENT); -+ } - } - return result; - } -@@ -402,7 +422,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 = -ELOOP; - if (current->link_count >= 5) -@@ -419,7 +440,10 @@ - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -- err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -@@ -534,7 +558,7 @@ - unlock_nd(nd); - - need_lookup: -- dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE, &nd->it); - if (IS_ERR(dentry)) - goto fail; - mntget(mnt); -@@ -662,11 +686,11 @@ - if (!inode->i_op) - break; - -- if (inode->i_op->follow_link) { -+ if (inode->i_op->follow_link || inode->i_op->follow_link2) { - mntget(next.mnt); - dget_locked(next.dentry); - unlock_nd(nd); -- err = do_follow_link(next.dentry, nd); -+ err = do_follow_link(next.dentry, nd, &nd->it); - dput(next.dentry); - mntput(next.mnt); - if (err) -@@ -684,7 +708,7 @@ - nd->dentry = next.dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup2) - break; - continue; - /* here ends the main loop */ -@@ -717,11 +741,12 @@ - follow_mount(&next.mnt, &next.dentry); - inode = next.dentry->d_inode; - if ((lookup_flags & LOOKUP_FOLLOW) -- && inode && inode->i_op && inode->i_op->follow_link) { -+ && inode && inode->i_op && -+ (inode->i_op->follow_link || inode->i_op->follow_link2)) { - mntget(next.mnt); - dget_locked(next.dentry); - unlock_nd(nd); -- err = do_follow_link(next.dentry, nd); -+ err = do_follow_link(next.dentry, nd, &nd->it); - dput(next.dentry); - mntput(next.mnt); - if (err) -@@ -737,7 +762,8 @@ - break; - if (lookup_flags & LOOKUP_DIRECTORY) { - err = -ENOTDIR; -- if (!inode->i_op || !inode->i_op->lookup) -+ if (!inode->i_op || -+ (!inode->i_op->lookup && !inode->i_op->lookup2)) - break; - } - goto return_base; -@@ -886,7 +912,8 @@ - * needs parent already locked. Doesn't follow mounts. - * SMP-safe. - */ --struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+struct dentry * lookup_hash(struct qstr *name, struct dentry * base, -+ struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -909,13 +936,16 @@ - goto out; - } - -- dentry = cached_lookup(base, name, 0); -+ dentry = cached_lookup(base, name, 0, it); - if (!dentry) { - struct dentry *new = d_alloc(base, name); - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; -- dentry = inode->i_op->lookup(inode, new); -+ if (inode->i_op->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else -+ dentry = inode->i_op->lookup(inode, new); - if (!dentry) { - dentry = new; - security_ops->inode_post_lookup(inode, dentry); -@@ -927,7 +957,7 @@ - } - - /* SMP-safe */ --struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -+struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct lookup_intent *it) - { - unsigned long hash; - struct qstr this; -@@ -947,11 +977,16 @@ - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash(&this, base, it); - access: - return ERR_PTR(-EACCES); - } - -+struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -+{ -+ return lookup_one_len_it(name, base, len, NULL); -+} -+ - /* - * namei() - * -@@ -1268,7 +1303,7 @@ - - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - - do_last: - error = PTR_ERR(dentry); -@@ -1310,7 +1345,8 @@ - error = -ENOENT; - if (!dentry->d_inode) - goto exit_dput; -- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) -+ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || -+ dentry->d_inode->i_op->follow_link2)) - goto do_link; - - dput(nd->dentry); -@@ -1370,7 +1406,7 @@ - } - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - putname(nd->last.name); - goto do_last; - } -@@ -1384,7 +1420,7 @@ - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - if (IS_ERR(dentry)) - goto fail; - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1614,7 +1650,7 @@ - goto exit1; - } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, &nd.it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); -@@ -1675,7 +1711,7 @@ - if (nd.last_type != LAST_NORM) - goto exit1; - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, &nd.it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1949,7 +1985,8 @@ - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); -@@ -2020,7 +2057,7 @@ - - trap = lock_rename(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash(&oldnd.last, old_dir, &oldnd.it); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -2040,7 +2077,7 @@ - error = -EINVAL; - if (old_dentry == trap) - goto exit4; -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ new_dentry = lookup_hash(&newnd.last, new_dir, &newnd.it); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; -@@ -2050,7 +2087,7 @@ - goto exit5; - - error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ new_dir->d_inode, new_dentry, NULL); - exit5: - dput(new_dentry); - exit4: -@@ -2102,7 +2139,8 @@ - } - - 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; -@@ -2138,7 +2176,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 */ -@@ -2180,7 +2224,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); -diff -Nru a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c ---- a/fs/nfsd/vfs.c Thu Dec 12 20:58:37 2002 -+++ b/fs/nfsd/vfs.c Thu Dec 12 20:58:37 2002 -@@ -1292,7 +1292,7 @@ - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); -diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c ---- a/fs/sysfs/inode.c Thu Dec 12 20:58:37 2002 -+++ b/fs/sysfs/inode.c Thu Dec 12 20:58:37 2002 -@@ -471,7 +471,7 @@ - qstr.name = name; - qstr.len = strlen(name); - qstr.hash = full_name_hash(name,qstr.len); -- return lookup_hash(&qstr,parent); -+ return lookup_hash(&qstr,parent,NULL); - } - - /** -diff -Nru a/include/linux/dcache.h b/include/linux/dcache.h ---- a/include/linux/dcache.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/dcache.h Thu Dec 12 20:58:37 2002 -@@ -9,6 +9,24 @@ - #include - #include /* for BUG() */ - -+#define IT_OPEN (1) -+#define IT_CREAT (1<<1) -+#define IT_MKDIR (1<<2) -+#define IT_LINK (1<<3) -+#define IT_LINK2 (1<<4) -+#define IT_SYMLINK (1<<5) -+#define IT_UNLINK (1<<6) -+#define IT_RMDIR (1<<7) -+#define IT_RENAME (1<<8) -+#define IT_RENAME2 (1<<9) -+#define IT_READDIR (1<<10) -+#define IT_GETATTR (1<<11) -+#define IT_SETATTR (1<<12) -+#define IT_READLINK (1<<13) -+#define IT_MKNOD (1<<14) -+#define IT_LOOKUP (1<<15) -+ -+ - /* - * linux/include/linux/dcache.h - * -@@ -30,6 +48,8 @@ - unsigned int hash; - }; - -+#include -+ - struct dentry_stat_t { - int nr_dentry; - int nr_unused; -@@ -79,6 +99,7 @@ - struct list_head d_subdirs; /* our children */ - struct list_head d_alias; /* inode alias list */ - int d_mounted; -+ struct lookup_intent *d_it; - struct qstr d_name; - unsigned long d_time; /* used by d_revalidate */ - struct dentry_operations *d_op; -@@ -96,6 +117,8 @@ - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); -+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); - }; - - /* the dentry parameter passed to d_hash and d_compare is the parent -diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h ---- a/include/linux/ext3_fs.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/ext3_fs.h Thu Dec 12 20:58:37 2002 -@@ -64,8 +64,6 @@ - */ - #define EXT3_BAD_INO 1 /* Bad blocks inode */ - #define EXT3_ROOT_INO 2 /* Root inode */ --#define EXT3_ACL_IDX_INO 3 /* ACL inode */ --#define EXT3_ACL_DATA_INO 4 /* ACL inode */ - #define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ - #define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ - #define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ -@@ -95,7 +93,6 @@ - #else - # define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) - #endif --#define EXT3_ACLE_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry)) - #define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) - #ifdef __KERNEL__ - # define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -@@ -130,28 +127,6 @@ - #endif - - /* -- * ACL structures -- */ --struct ext3_acl_header /* Header of Access Control Lists */ --{ -- __u32 aclh_size; -- __u32 aclh_file_count; -- __u32 aclh_acle_count; -- __u32 aclh_first_acle; --}; -- --struct ext3_acl_entry /* Access Control List Entry */ --{ -- __u32 acle_size; -- __u16 acle_perms; /* Access permissions */ -- __u16 acle_type; /* Type of entry */ -- __u16 acle_tag; /* User or group identity */ -- __u16 acle_pad1; -- __u32 acle_next; /* Pointer on next entry for the */ -- /* same inode or on next free entry */ --}; -- --/* - * Structure of a blocks group descriptor - */ - struct ext3_group_desc -@@ -347,6 +322,7 @@ - #define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */ - #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ - #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ -+#define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -529,7 +505,7 @@ - #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ - #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ - --#define EXT3_FEATURE_COMPAT_SUPP 0 -+#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR - #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ - EXT3_FEATURE_INCOMPAT_RECOVER) - #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ -@@ -713,6 +689,7 @@ - - - /* inode.c */ -+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int); - extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); - extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); - -@@ -781,8 +758,10 @@ - - /* namei.c */ - extern struct inode_operations ext3_dir_inode_operations; -+extern struct inode_operations ext3_special_inode_operations; - - /* symlink.c */ -+extern struct inode_operations ext3_symlink_inode_operations; - extern struct inode_operations ext3_fast_symlink_inode_operations; - - -diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h ---- a/include/linux/ext3_jbd.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/ext3_jbd.h Thu Dec 12 20:58:37 2002 -@@ -30,13 +30,19 @@ - - #define EXT3_SINGLEDATA_TRANS_BLOCKS 8 - -+/* Extended attributes may touch two data buffers, two bitmap buffers, -+ * and two group and summaries. */ -+ -+#define EXT3_XATTR_TRANS_BLOCKS 8 -+ - /* Define the minimum size for a transaction which modifies data. This - * needs to take into account the fact that we may end up modifying two - * quota files too (one for the group, one for the user quota). The - * superblock only gets updated once, of course, so don't bother - * counting that again for the quota updates. */ - --#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2) -+#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \ -+ EXT3_XATTR_TRANS_BLOCKS - 2) - - extern int ext3_writepage_trans_blocks(struct inode *inode); - -diff -Nru a/include/linux/fs.h b/include/linux/fs.h ---- a/include/linux/fs.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/fs.h Thu Dec 12 20:58:37 2002 -@@ -700,7 +700,7 @@ - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct lookup_intent *it); - - /* - * File types -@@ -769,6 +769,8 @@ - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup2) (struct inode *,struct dentry *, -+ struct lookup_intent *); - int (*link) (struct dentry *,struct inode *,struct dentry *); - int (*unlink) (struct inode *,struct dentry *); - int (*symlink) (struct inode *,struct dentry *,const char *); -@@ -779,6 +781,7 @@ - struct inode *, struct dentry *); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); -+ int (*follow_link2) (struct dentry *, struct nameidata *, struct lookup_intent *it); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*setattr) (struct dentry *, struct iattr *); -@@ -995,6 +998,7 @@ - extern int unregister_filesystem(struct file_system_type *); - extern struct vfsmount *kern_mount(struct file_system_type *); - extern int may_umount(struct vfsmount *); -+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); - extern long do_mount(char *, char *, char *, unsigned long, void *); - - #define kern_umount mntput -@@ -1285,6 +1289,8 @@ - - extern int vfs_readlink(struct dentry *, char *, int, const char *); - extern int vfs_follow_link(struct nameidata *, const char *); -+int vfs_follow_link_it(struct nameidata *nd, const char *link, -+ struct lookup_intent *it); - extern int page_readlink(struct dentry *, char *, int); - extern int page_follow_link(struct dentry *, struct nameidata *); - extern int page_symlink(struct inode *inode, const char *symname, int len); -diff -Nru a/include/linux/lustre_version.h b/include/linux/lustre_version.h ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/include/linux/lustre_version.h Thu Dec 12 20:58:37 2002 -@@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 4 -diff -Nru a/include/linux/mbcache.h b/include/linux/mbcache.h ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/include/linux/mbcache.h Thu Dec 12 20:58:37 2002 -@@ -0,0 +1,72 @@ -+/* -+ 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 { -+ void (*free)(struct mb_cache_entry *); -+}; -+ -+struct mb_cache { -+ struct list_head c_cache_list; -+ const char *c_name; -+ struct mb_cache_op c_op; -+ atomic_t c_entry_count; -+ int c_bucket_bits; -+#ifndef MB_CACHE_INDEXES_COUNT -+ int c_indexes_count; -+#endif -+ kmem_cache_t *c_entry_cache; -+ struct list_head *c_block_hash; -+ struct list_head *c_indexes_hash[0]; -+}; -+ -+struct mb_cache_entry_index { -+ struct list_head o_list; -+ unsigned int o_key; -+}; -+ -+struct mb_cache_entry { -+ struct list_head e_lru_list; -+ struct mb_cache *e_cache; -+ atomic_t e_used; -+ struct block_device *e_bdev; -+ sector_t e_block; -+ struct list_head e_block_list; -+ struct mb_cache_entry_index e_indexes[0]; -+}; -+ -+/* Functions on caches */ -+ -+struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t, -+ int, int); -+void mb_cache_shrink(struct mb_cache *, struct block_device *); -+void mb_cache_destroy(struct mb_cache *); -+ -+/* Functions on cache entries */ -+ -+struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *); -+int mb_cache_entry_insert(struct mb_cache_entry *, struct block_device *, -+ sector_t, unsigned int[]); -+void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]); -+void mb_cache_entry_release(struct mb_cache_entry *); -+void mb_cache_entry_takeout(struct mb_cache_entry *); -+void mb_cache_entry_free(struct mb_cache_entry *); -+struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *); -+struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, -+ struct block_device *, -+ sector_t); -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int, -+ struct block_device *, -+ unsigned int); -+struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int, -+ struct block_device *, -+ unsigned int); -+#endif -diff -Nru a/include/linux/namei.h b/include/linux/namei.h ---- a/include/linux/namei.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/namei.h Thu Dec 12 20:58:37 2002 -@@ -5,6 +5,17 @@ - - struct vfsmount; - -+struct lookup_intent { -+ int it_op; -+ int it_mode; -+ int it_disposition; -+ int it_status; -+ struct iattr *it_iattr; -+ __u64 it_lock_handle[2]; -+ int it_lock_mode; -+ void *it_data; -+}; -+ - struct nameidata { - struct dentry *dentry; - struct vfsmount *mnt; -@@ -13,6 +24,7 @@ - int last_type; - struct dentry *old_dentry; - struct vfsmount *old_mnt; -+ struct lookup_intent it; - }; - - /* -@@ -46,7 +58,7 @@ - extern void path_release(struct nameidata *); - - extern struct dentry * lookup_one_len(const char *, struct dentry *, int); --extern struct dentry * lookup_hash(struct qstr *, struct dentry *); -+extern struct dentry * lookup_hash(struct qstr *, struct dentry *, struct lookup_intent *); - - extern int follow_down(struct vfsmount **, struct dentry **); - extern int follow_up(struct vfsmount **, struct dentry **); -diff -Nru a/include/linux/slab.h b/include/linux/slab.h ---- a/include/linux/slab.h Thu Dec 12 20:58:37 2002 -+++ b/include/linux/slab.h Thu Dec 12 20:58:37 2002 -@@ -56,6 +56,7 @@ - extern int kmem_cache_shrink(kmem_cache_t *); - extern void *kmem_cache_alloc(kmem_cache_t *, int); - extern void kmem_cache_free(kmem_cache_t *, void *); -+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); - extern unsigned int kmem_cache_size(kmem_cache_t *); - - extern void *kmalloc(size_t, int); -diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c ---- a/kernel/ksyms.c Thu Dec 12 20:58:37 2002 -+++ b/kernel/ksyms.c Thu Dec 12 20:58:37 2002 -@@ -286,6 +286,7 @@ - EXPORT_SYMBOL(mark_page_accessed); - 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); -@@ -365,6 +366,13 @@ - EXPORT_SYMBOL(tty_get_baud_rate); - EXPORT_SYMBOL(do_SAK); - -+/* lustre */ -+EXPORT_SYMBOL(panic_notifier_list); -+//EXPORT_SYMBOL(pagecache_lock_cacheline); -+EXPORT_SYMBOL(do_kern_mount); -+EXPORT_SYMBOL(exit_files); -+EXPORT_SYMBOL(kmem_cache_validate); -+ - /* filesystem registration */ - EXPORT_SYMBOL(register_filesystem); - EXPORT_SYMBOL(unregister_filesystem); -@@ -529,6 +537,7 @@ - EXPORT_SYMBOL(seq_lseek); - EXPORT_SYMBOL(single_open); - EXPORT_SYMBOL(single_release); -+EXPORT_SYMBOL(reparent_to_init); - - /* Program loader interfaces */ - EXPORT_SYMBOL(setup_arg_pages); -diff -Nru a/mm/slab.c b/mm/slab.c ---- a/mm/slab.c Thu Dec 12 20:58:37 2002 -+++ b/mm/slab.c Thu Dec 12 20:58:37 2002 -@@ -1236,6 +1236,59 @@ - * Called with the cache-lock held. - */ - -+extern struct page *check_get_page(unsigned long kaddr); -+struct page *page_mem_map(struct page *page); -+static int kmem_check_cache_obj (kmem_cache_t * cachep, -+ slab_t *slabp, void * objp) -+{ -+ int i; -+ unsigned int objnr; -+ -+#if DEBUG -+ if (cachep->flags & SLAB_RED_ZONE) { -+ objp -= BYTES_PER_WORD; -+ if ( *(unsigned long *)objp != RED_MAGIC2) -+ /* Either write before start, or a double free. */ -+ return 0; -+ if (*(unsigned long *)(objp+cachep->objsize - -+ BYTES_PER_WORD) != RED_MAGIC2) -+ /* Either write past end, or a double free. */ -+ return 0; -+ } -+#endif -+ -+ objnr = (objp-slabp->s_mem)/cachep->objsize; -+ if (objnr >= cachep->num) -+ return 0; -+ if (objp != slabp->s_mem + objnr*cachep->objsize) -+ return 0; -+ -+ /* Check slab's freelist to see if this obj is there. */ -+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { -+ if (i == objnr) -+ return 0; -+ } -+ return 1; -+} -+ -+ -+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) -+{ -+ struct page *page = check_get_page((unsigned long)objp); -+ -+ if (!page_mem_map(page)) -+ return 0; -+ -+ if (!PageSlab(page)) -+ return 0; -+ -+ /* XXX check for freed slab objects ? */ -+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) -+ return 0; -+ -+ return (cachep == GET_PAGE_CACHE(page)); -+} -+ - #if DEBUG - static int kmem_extra_free_checks (kmem_cache_t * cachep, - slab_t *slabp, void * objp) -diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c ---- a/net/unix/af_unix.c Thu Dec 12 20:58:37 2002 -+++ b/net/unix/af_unix.c Thu Dec 12 20:58:37 2002 -@@ -715,7 +715,7 @@ - /* - * Do the final lookup. - */ -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto out_mknod_unlock; diff --git a/lustre/kernel_patches/patches/lustre-2.5.patch b/lustre/kernel_patches/patches/lustre-2.5.patch deleted file mode 100644 index 5e88d35..0000000 --- a/lustre/kernel_patches/patches/lustre-2.5.patch +++ /dev/null @@ -1,552 +0,0 @@ -# This is a BitKeeper generated patch for the following project: -# Project Name: Linux kernel tree -# This patch format is intended for GNU patch command version 2.5 or higher. -# This patch includes the following deltas: -# ChangeSet 1.810 -> 1.811 -# kernel/ksyms.c 1.149 -> 1.150 -# fs/driverfs/inode.c 1.52 -> 1.53 -# include/linux/fs.h 1.175 -> 1.176 -# include/linux/namei.h 1.3 -> 1.4 -# fs/namei.c 1.56 -> 1.57 -# fs/nfsd/vfs.c 1.44 -> 1.45 -# arch/um/kernel/mem.c 1.5 -> 1.6 -# net/unix/af_unix.c 1.29 -> 1.30 -# mm/slab.c 1.33 -> 1.34 -# fs/sysfs/inode.c 1.55 -> 1.56 -# include/linux/slab.h 1.13 -> 1.14 -# include/linux/dcache.h 1.19 -> 1.20 -# -# The following is the BitKeeper ChangeSet Log -# -------------------------------------------- -# 02/10/20 braam@clusterfs.com 1.811 -# Changes for Lustre -# -------------------------------------------- -# -diff -Nru a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c ---- a/arch/um/kernel/mem.c Sun Dec 8 02:49:38 2002 -+++ b/arch/um/kernel/mem.c Sun Dec 8 02:49:38 2002 -@@ -656,6 +656,22 @@ - return(phys_mem_map(pte_val(pte))); - } - -+struct page *check_get_page(unsigned long kaddr) -+{ -+ struct page *page; -+ struct mem_region *mr; -+ unsigned long phys = __pa(kaddr); -+ unsigned int n = phys_region_index(phys); -+ -+ if(regions[n] == NULL) -+ return NULL; -+ -+ mr = regions[n]; -+ page = (struct page *) mr->mem_map; -+ return page + ((phys_addr(phys)) >> PAGE_SHIFT); -+} -+ -+ - struct mem_region *page_region(struct page *page, int *index_out) - { - int i; -@@ -743,7 +759,7 @@ - (addr <= region->start + region->len)) - return(mk_phys(addr - region->start, i)); - } -- panic("region_pa : no region for virtual address"); -+ //panic("region_pa : no region for virtual address"); - return(0); - } - -diff -Nru a/fs/driverfs/inode.c b/fs/driverfs/inode.c ---- a/fs/driverfs/inode.c Sun Dec 8 02:49:38 2002 -+++ b/fs/driverfs/inode.c Sun Dec 8 02:49:38 2002 -@@ -523,7 +523,7 @@ - qstr.name = name; - qstr.len = strlen(name); - qstr.hash = full_name_hash(name,qstr.len); -- return lookup_hash(&qstr,parent); -+ return lookup_hash(&qstr,parent, NULL); - } - - /** -diff -Nru a/fs/namei.c b/fs/namei.c ---- a/fs/namei.c Sun Dec 8 02:49:38 2002 -+++ b/fs/namei.c Sun Dec 8 02:49:38 2002 -@@ -265,6 +265,9 @@ - - void path_release(struct nameidata *nd) - { -+ if (nd->dentry && nd->dentry->d_op && -+ nd->dentry->d_op->d_intent_release) -+ nd->dentry->d_op->d_intent_release(nd->dentry, &nd->it); - dput(nd->dentry); - mntput(nd->mnt); - } -@@ -273,10 +276,18 @@ - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -351,7 +362,7 @@ - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; -@@ -369,7 +380,10 @@ - struct dentry * dentry = d_alloc(parent, name); - result = ERR_PTR(-ENOMEM); - if (dentry) { -- result = dir->i_op->lookup(dir, dentry); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else -+ result = dir->i_op->lookup(dir, dentry); - if (result) - dput(dentry); - else { -@@ -391,6 +405,12 @@ - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ result = ERR_PTR(-ENOENT); -+ } - } - return result; - } -@@ -534,7 +554,7 @@ - unlock_nd(nd); - - need_lookup: -- dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE, &nd->it); - if (IS_ERR(dentry)) - goto fail; - mntget(mnt); -@@ -684,7 +704,7 @@ - nd->dentry = next.dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup2) - break; - continue; - /* here ends the main loop */ -@@ -737,7 +757,8 @@ - break; - if (lookup_flags & LOOKUP_DIRECTORY) { - err = -ENOTDIR; -- if (!inode->i_op || !inode->i_op->lookup) -+ if (!inode->i_op || -+ (!inode->i_op->lookup && !inode->i_op->lookup2)) - break; - } - goto return_base; -@@ -886,7 +907,8 @@ - * needs parent already locked. Doesn't follow mounts. - * SMP-safe. - */ --struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+struct dentry * lookup_hash(struct qstr *name, struct dentry * base, -+ struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -909,13 +931,16 @@ - goto out; - } - -- dentry = cached_lookup(base, name, 0); -+ dentry = cached_lookup(base, name, 0, it); - if (!dentry) { - struct dentry *new = d_alloc(base, name); - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; -- dentry = inode->i_op->lookup(inode, new); -+ if (inode->i_op->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else -+ dentry = inode->i_op->lookup(inode, new); - if (!dentry) { - dentry = new; - security_ops->inode_post_lookup(inode, dentry); -@@ -927,7 +952,7 @@ - } - - /* SMP-safe */ --struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -+struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct lookup_intent *it) - { - unsigned long hash; - struct qstr this; -@@ -947,11 +972,16 @@ - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash(&this, base, it); - access: - return ERR_PTR(-EACCES); - } - -+struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -+{ -+ return lookup_one_len_it(name, base, len, NULL); -+} -+ - /* - * namei() - * -@@ -1268,7 +1298,7 @@ - - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - - do_last: - error = PTR_ERR(dentry); -@@ -1370,7 +1400,7 @@ - } - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - putname(nd->last.name); - goto do_last; - } -@@ -1384,7 +1414,7 @@ - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - if (IS_ERR(dentry)) - goto fail; - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1614,7 +1644,7 @@ - goto exit1; - } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, &nd.it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); -@@ -1675,7 +1705,7 @@ - if (nd.last_type != LAST_NORM) - goto exit1; - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, &nd.it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1949,7 +1979,8 @@ - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); -@@ -2020,7 +2051,7 @@ - - trap = lock_rename(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash(&oldnd.last, old_dir, &oldnd.it); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -2040,7 +2071,7 @@ - error = -EINVAL; - if (old_dentry == trap) - goto exit4; -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ new_dentry = lookup_hash(&newnd.last, new_dir, &newnd.it); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; -@@ -2050,7 +2081,7 @@ - goto exit5; - - error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ new_dir->d_inode, new_dentry, NULL); - exit5: - dput(new_dentry); - exit4: -diff -Nru a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c ---- a/fs/nfsd/vfs.c Sun Dec 8 02:49:38 2002 -+++ b/fs/nfsd/vfs.c Sun Dec 8 02:49:38 2002 -@@ -1292,7 +1292,7 @@ - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); -diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c ---- a/fs/sysfs/inode.c Sun Dec 8 02:49:39 2002 -+++ b/fs/sysfs/inode.c Sun Dec 8 02:49:39 2002 -@@ -471,7 +471,7 @@ - qstr.name = name; - qstr.len = strlen(name); - qstr.hash = full_name_hash(name,qstr.len); -- return lookup_hash(&qstr,parent); -+ return lookup_hash(&qstr,parent,NULL); - } - - /** -diff -Nru a/include/linux/dcache.h b/include/linux/dcache.h ---- a/include/linux/dcache.h Sun Dec 8 02:49:39 2002 -+++ b/include/linux/dcache.h Sun Dec 8 02:49:39 2002 -@@ -9,6 +9,24 @@ - #include - #include /* for BUG() */ - -+#define IT_OPEN (1) -+#define IT_CREAT (1<<1) -+#define IT_MKDIR (1<<2) -+#define IT_LINK (1<<3) -+#define IT_LINK2 (1<<4) -+#define IT_SYMLINK (1<<5) -+#define IT_UNLINK (1<<6) -+#define IT_RMDIR (1<<7) -+#define IT_RENAME (1<<8) -+#define IT_RENAME2 (1<<9) -+#define IT_READDIR (1<<10) -+#define IT_GETATTR (1<<11) -+#define IT_SETATTR (1<<12) -+#define IT_READLINK (1<<13) -+#define IT_MKNOD (1<<14) -+#define IT_LOOKUP (1<<15) -+ -+ - /* - * linux/include/linux/dcache.h - * -@@ -30,6 +48,8 @@ - unsigned int hash; - }; - -+#include -+ - struct dentry_stat_t { - int nr_dentry; - int nr_unused; -@@ -79,6 +99,7 @@ - struct list_head d_subdirs; /* our children */ - struct list_head d_alias; /* inode alias list */ - int d_mounted; -+ struct lookup_intent *d_it; - struct qstr d_name; - unsigned long d_time; /* used by d_revalidate */ - struct dentry_operations *d_op; -@@ -96,6 +117,8 @@ - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); -+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); - }; - - /* the dentry parameter passed to d_hash and d_compare is the parent -diff -Nru a/include/linux/fs.h b/include/linux/fs.h ---- a/include/linux/fs.h Sun Dec 8 02:49:38 2002 -+++ b/include/linux/fs.h Sun Dec 8 02:49:38 2002 -@@ -700,7 +700,7 @@ - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct lookup_intent *it); - - /* - * File types -@@ -769,6 +769,8 @@ - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup2) (struct inode *,struct dentry *, -+ struct lookup_intent *); - int (*link) (struct dentry *,struct inode *,struct dentry *); - int (*unlink) (struct inode *,struct dentry *); - int (*symlink) (struct inode *,struct dentry *,const char *); -@@ -995,6 +997,7 @@ - extern int unregister_filesystem(struct file_system_type *); - extern struct vfsmount *kern_mount(struct file_system_type *); - extern int may_umount(struct vfsmount *); -+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); - extern long do_mount(char *, char *, char *, unsigned long, void *); - - #define kern_umount mntput -diff -Nru a/include/linux/namei.h b/include/linux/namei.h ---- a/include/linux/namei.h Sun Dec 8 02:49:38 2002 -+++ b/include/linux/namei.h Sun Dec 8 02:49:38 2002 -@@ -5,6 +5,17 @@ - - struct vfsmount; - -+struct lookup_intent { -+ int it_op; -+ int it_mode; -+ int it_disposition; -+ int it_status; -+ struct iattr *it_iattr; -+ __u64 it_lock_handle[2]; -+ int it_lock_mode; -+ void *it_data; -+}; -+ - struct nameidata { - struct dentry *dentry; - struct vfsmount *mnt; -@@ -13,6 +24,7 @@ - int last_type; - struct dentry *old_dentry; - struct vfsmount *old_mnt; -+ struct lookup_intent it; - }; - - /* -@@ -46,7 +58,7 @@ - extern void path_release(struct nameidata *); - - extern struct dentry * lookup_one_len(const char *, struct dentry *, int); --extern struct dentry * lookup_hash(struct qstr *, struct dentry *); -+extern struct dentry * lookup_hash(struct qstr *, struct dentry *, struct lookup_intent *); - - extern int follow_down(struct vfsmount **, struct dentry **); - extern int follow_up(struct vfsmount **, struct dentry **); -diff -Nru a/include/linux/slab.h b/include/linux/slab.h ---- a/include/linux/slab.h Sun Dec 8 02:49:39 2002 -+++ b/include/linux/slab.h Sun Dec 8 02:49:39 2002 -@@ -56,6 +56,7 @@ - extern int kmem_cache_shrink(kmem_cache_t *); - extern void *kmem_cache_alloc(kmem_cache_t *, int); - extern void kmem_cache_free(kmem_cache_t *, void *); -+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); - extern unsigned int kmem_cache_size(kmem_cache_t *); - - extern void *kmalloc(size_t, int); -diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c ---- a/kernel/ksyms.c Sun Dec 8 02:49:38 2002 -+++ b/kernel/ksyms.c Sun Dec 8 02:49:38 2002 -@@ -365,6 +365,13 @@ - EXPORT_SYMBOL(tty_get_baud_rate); - EXPORT_SYMBOL(do_SAK); - -+/* lustre */ -+EXPORT_SYMBOL(panic_notifier_list); -+//EXPORT_SYMBOL(pagecache_lock_cacheline); -+EXPORT_SYMBOL(do_kern_mount); -+EXPORT_SYMBOL(exit_files); -+EXPORT_SYMBOL(kmem_cache_validate); -+ - /* filesystem registration */ - EXPORT_SYMBOL(register_filesystem); - EXPORT_SYMBOL(unregister_filesystem); -diff -Nru a/mm/slab.c b/mm/slab.c ---- a/mm/slab.c Sun Dec 8 02:49:39 2002 -+++ b/mm/slab.c Sun Dec 8 02:49:39 2002 -@@ -1236,6 +1236,59 @@ - * Called with the cache-lock held. - */ - -+extern struct page *check_get_page(unsigned long kaddr); -+struct page *page_mem_map(struct page *page); -+static int kmem_check_cache_obj (kmem_cache_t * cachep, -+ slab_t *slabp, void * objp) -+{ -+ int i; -+ unsigned int objnr; -+ -+#if DEBUG -+ if (cachep->flags & SLAB_RED_ZONE) { -+ objp -= BYTES_PER_WORD; -+ if ( *(unsigned long *)objp != RED_MAGIC2) -+ /* Either write before start, or a double free. */ -+ return 0; -+ if (*(unsigned long *)(objp+cachep->objsize - -+ BYTES_PER_WORD) != RED_MAGIC2) -+ /* Either write past end, or a double free. */ -+ return 0; -+ } -+#endif -+ -+ objnr = (objp-slabp->s_mem)/cachep->objsize; -+ if (objnr >= cachep->num) -+ return 0; -+ if (objp != slabp->s_mem + objnr*cachep->objsize) -+ return 0; -+ -+ /* Check slab's freelist to see if this obj is there. */ -+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { -+ if (i == objnr) -+ return 0; -+ } -+ return 1; -+} -+ -+ -+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) -+{ -+ struct page *page = check_get_page((unsigned long)objp); -+ -+ if (!page_mem_map(page)) -+ return 0; -+ -+ if (!PageSlab(page)) -+ return 0; -+ -+ /* XXX check for freed slab objects ? */ -+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) -+ return 0; -+ -+ return (cachep == GET_PAGE_CACHE(page)); -+} -+ - #if DEBUG - static int kmem_extra_free_checks (kmem_cache_t * cachep, - slab_t *slabp, void * objp) -diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c ---- a/net/unix/af_unix.c Sun Dec 8 02:49:38 2002 -+++ b/net/unix/af_unix.c Sun Dec 8 02:49:38 2002 -@@ -715,7 +715,7 @@ - /* - * Do the final lookup. - */ -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto out_mknod_unlock; diff --git a/lustre/kernel_patches/patches/uml_check_get_page.patch b/lustre/kernel_patches/patches/uml_check_get_page.patch deleted file mode 100644 index fafdf90..0000000 --- a/lustre/kernel_patches/patches/uml_check_get_page.patch +++ /dev/null @@ -1,31 +0,0 @@ - - - - 0 files changed - ---- linux-2.4.18-17.8.0/arch/um/kernel/mem.c~uml_check_get_page 2002-12-06 14:52:30.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/arch/um/kernel/mem.c 2002-12-06 14:52:30.000000000 -0800 -@@ -529,6 +529,21 @@ struct page *pte_mem_map(pte_t pte) - return(phys_mem_map(pte_val(pte))); - } - -+struct page *check_get_page(unsigned long kaddr) -+{ -+ struct page *page; -+ struct mem_region *mr; -+ unsigned long phys = __pa(kaddr); -+ unsigned int n = phys_region_index(phys); -+ -+ if (regions[n] == NULL) -+ return NULL; -+ -+ mr = regions[n]; -+ page = (struct page *) mr->mem_map; -+ return page + ((phys_addr(phys)) >> PAGE_SHIFT); -+} -+ - struct mem_region *page_region(struct page *page, int *index_out) - { - int i; - -_ diff --git a/lustre/kernel_patches/patches/uml_no_panic.patch b/lustre/kernel_patches/patches/uml_no_panic.patch deleted file mode 100644 index b0c305b..0000000 --- a/lustre/kernel_patches/patches/uml_no_panic.patch +++ /dev/null @@ -1,31 +0,0 @@ - - - - 0 files changed - ---- linux-2.4.18-17.8.0/arch/um/kernel/mem.c~uml_no_panic 2002-12-06 14:52:30.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/arch/um/kernel/mem.c 2002-12-06 14:52:30.000000000 -0800 -@@ -559,7 +559,9 @@ struct mem_region *page_region(struct pa - return(region); - } - } -- panic("No region found for page"); -+// panic("No region found for page"); -+ printk(KERN_ERR "no region foudn for page %p\n, returning NULL\n", -+ page); - return(NULL); - } - -@@ -581,7 +583,9 @@ unsigned long region_pa(void *virt) - (addr <= region->start + region->len)) - return(mk_phys(addr - region->start, i)); - } -- panic("region_pa : no region for virtual address"); -+ //panic("region_pa : no region for virtual address"); -+ printk(KERN_ERR "no region for virtual address %lu, return pa 0\n", -+ addr); - return(0); - } - - -_ diff --git a/lustre/kernel_patches/pc/lin-2.5.44.pc b/lustre/kernel_patches/pc/lin-2.5.44.pc deleted file mode 100644 index c37c203..0000000 --- a/lustre/kernel_patches/pc/lin-2.5.44.pc +++ /dev/null @@ -1,30 +0,0 @@ -arch/um/kernel/mem.c -fs/Config.help -fs/Config.in -fs/driverfs/inode.c -fs/ext3/file.c -fs/ext3/ialloc.c -fs/ext3/inode.c -fs/ext3/Makefile -fs/ext3/namei.c -fs/ext3/super.c -fs/ext3/symlink.c -fs/ext3/xattr.c -fs/ext3/xattr.h -fs/ext3/xattr_user.c -fs/Makefile -fs/mbcache.c -fs/namei.c -fs/nfsd/vfs.c -fs/sysfs/inode.c -include/linux/dcache.h -include/linux/ext3_fs.h -include/linux/ext3_jbd.h -include/linux/fs.h -include/linux/lustre_version.h -include/linux/mbcache.h -include/linux/namei.h -include/linux/slab.h -kernel/ksyms.c -mm/slab.c -net/unix/af_unix.c diff --git a/lustre/kernel_patches/pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc b/lustre/kernel_patches/pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc deleted file mode 100644 index 44d4abf..0000000 --- a/lustre/kernel_patches/pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc +++ /dev/null @@ -1,23 +0,0 @@ -./include/linux/lustre_version.h -./arch/ia64/mm/init.c -./arch/i386/mm/init.c -./drivers/block/blkpg.c -./drivers/block/loop.c -./drivers/ide/ide-disk.c -./fs/ext3/Makefile -./fs/ext3/super.c -./fs/jbd/commit.c -./fs/jbd/journal.c -./fs/jbd/transaction.c -./include/linux/blkdev.h -./include/linux/slab.h -./include/linux/jbd.h -./kernel/ksyms.c -./include/linux/dcache.h -./include/linux/fs.h -./fs/dcache.c -./fs/nfsd/vfs.c -./fs/namei.c -./fs/open.c -./fs/stat.c -./mm/slab.c diff --git a/lustre/kernel_patches/pc/vanilla-2.4.18.pc b/lustre/kernel_patches/pc/vanilla-2.4.18.pc deleted file mode 100644 index c1ed719..0000000 --- a/lustre/kernel_patches/pc/vanilla-2.4.18.pc +++ /dev/null @@ -1,23 +0,0 @@ -include/linux/lustre_version.h -arch/ia64/mm/init.c -arch/i386/mm/init.c -drivers/block/blkpg.c -drivers/block/loop.c -drivers/ide/ide-disk.c -fs/ext3/Makefile -fs/ext3/super.c -fs/jbd/commit.c -fs/jbd/journal.c -fs/jbd/transaction.c -include/linux/blkdev.h -include/linux/slab.h -include/linux/jbd.h -kernel/ksyms.c -include/linux/dcache.h -include/linux/fs.h -fs/dcache.c -fs/nfsd/vfs.c -fs/namei.c -fs/open.c -fs/stat.c -mm/slab.c diff --git a/lustre/kernel_patches/pc/vanilla-2.4.19.pc b/lustre/kernel_patches/pc/vanilla-2.4.19.pc deleted file mode 100644 index c1ed719..0000000 --- a/lustre/kernel_patches/pc/vanilla-2.4.19.pc +++ /dev/null @@ -1,23 +0,0 @@ -include/linux/lustre_version.h -arch/ia64/mm/init.c -arch/i386/mm/init.c -drivers/block/blkpg.c -drivers/block/loop.c -drivers/ide/ide-disk.c -fs/ext3/Makefile -fs/ext3/super.c -fs/jbd/commit.c -fs/jbd/journal.c -fs/jbd/transaction.c -include/linux/blkdev.h -include/linux/slab.h -include/linux/jbd.h -kernel/ksyms.c -include/linux/dcache.h -include/linux/fs.h -fs/dcache.c -fs/nfsd/vfs.c -fs/namei.c -fs/open.c -fs/stat.c -mm/slab.c diff --git a/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc b/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc deleted file mode 100644 index 881576c..0000000 --- a/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc +++ /dev/null @@ -1,8 +0,0 @@ -fs/dcache.c -fs/namei.c -fs/nfsd/vfs.c -fs/open.c -fs/stat.c -include/linux/dcache.h -include/linux/fs.h -kernel/ksyms.c diff --git a/lustre/kernel_patches/pc/vfs_intent.pc b/lustre/kernel_patches/pc/vfs_intent.pc deleted file mode 100644 index 881576c..0000000 --- a/lustre/kernel_patches/pc/vfs_intent.pc +++ /dev/null @@ -1,8 +0,0 @@ -fs/dcache.c -fs/namei.c -fs/nfsd/vfs.c -fs/open.c -fs/stat.c -include/linux/dcache.h -include/linux/fs.h -kernel/ksyms.c diff --git a/lustre/kernel_patches/prepare_tree.sh b/lustre/kernel_patches/prepare_tree.sh deleted file mode 100755 index f512132..0000000 --- a/lustre/kernel_patches/prepare_tree.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/bash - -die() { - echo -e $* >&2 - echo aborting.. >&2 - exit 1 -} - -canon() { - cd $1 - CANON=$PWD - cd - -} - -canon $(dirname $0) -MYDIR=$CANON - -while [ ${#*} -gt 1 ]; do - case "$1" in - -t) - shift; - TREE=$1 - ;; - -s) - shift; - SERIES=$1 - ;; - *) - die "unknown argument $1" - break; - ;; - esac - shift; -done - -[ -z "$TREE" -o -z "$SERIES" ] && die "I need a tree and series:\n\t$0 -t kernel_dir -s series_name" -[ ! -d $TREE ] && die "kernel tree '$TREE' isn't a directory" -SERIES=$(basename $SERIES) -[ ! -f $MYDIR/series/$SERIES ] && die "no series file '$SERIES'" - -canon $TREE -TREE=$CANON - -# patch scripts wants a relative path from the linux tree to -# its patch pile :( - -MY=$(echo $MYDIR | sed -e 's_^/__') -TR=$(echo $TREE | sed -e 's_^/__') - -while true ; do - M=$(echo $MY | cut -d/ -f 1) - T=$(echo $TR | cut -d/ -f 1) - - if [ $M != $T ]; then - break; - fi - - MY=$(echo $MY | cut -d/ -f 2-) - TR=$(echo $TR | cut -d/ -f 2-) -done - -[ $MY == $MYDIR ] && die "bad! $MY == $MYDIR" - -REVERSE=$(revpath $TR)${MY} -ABSINO=$(stat $MYDIR | awk '($3 == "Inode:") {print $4}') -REVINO=`(cd $TREE ; stat $REVERSE | awk '($3 == "Inode:") {print $4}')` - -[ $ABSINO != $REVINO ] && die "inodes differ, my reverse path is bad?" - -echo export PATCHSCRIPTS=$REVERSE - -cd $TREE -ln -sf $REVERSE/series/$SERIES series - -PATH_ELEMENTS=$(echo $PATH | sed -e 's/:/ /g') - -NEW_PATH=$MYDIR/scripts - -for p in $PATH_ELEMENTS; do - if echo $p | grep kernel_patches/scripts > /dev/null 2>&1 ; then - continue; - fi - NEW_PATH="$NEW_PATH:$p" -done - -echo export PATH=$NEW_PATH - -echo "'$TREE' successfully setup" >&2 diff --git a/lustre/kernel_patches/scripts/apatch b/lustre/kernel_patches/scripts/apatch deleted file mode 100755 index 4b63598..0000000 --- a/lustre/kernel_patches/scripts/apatch +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - - -do_apply() -{ - FILES=$(cat $P/pc/$PATCH_NAME.pc) - for file in $FILES - do - copy_file_to_bup $file $PATCH_NAME - done - - silent=-s - if [ $opt_force != 0 ] - then - silent= - fi - - if patch -p1 $silent -i "$1" || [ $opt_force != 0 ] - then - true - else - echo SOMETHING WENT WRONG - exit 1 - fi -} - -add_to_db() -{ - basename "$1" >> "$DB" -} - -usage() -{ - echo "Usage: apatch patchname" - exit 1 -} - -opt_force=0 -PATCH_NAMES="" - -for i in $* -do - case "$i" in - -f) - opt_force=1;; - *) - PATCH_NAMES="$PATCH_NAMES $i" - esac -done - -if [ x"$PATCH_NAMES" == x ] -then - usage -fi - -apatch() -{ - PATCH_NAME=$(stripit $1) - - need_file_there $P/pc/$PATCH_NAME.pc - - if is_applied "$PATCH_NAME" - then - echo "$PATCH_NAME" is already applied - exit 1 - fi - - if [ $opt_force != 0 ] - then - echo FORCING PATCH - fi - - if [ $opt_force != 0 ] || can_apply $P/patches/"$PATCH_NAME".patch - then - do_apply $P/patches/"$PATCH_NAME".patch - add_to_db "$PATCH_NAME" - echo applied $PATCH_NAME - echo - else - echo "$PATCH_NAME" does not apply - exit 1 - fi -} - -for i in $PATCH_NAMES -do - if ! apatch $i - then - exit 1 - fi -done - diff --git a/lustre/kernel_patches/scripts/patchfns b/lustre/kernel_patches/scripts/patchfns deleted file mode 100644 index b6cc468..0000000 --- a/lustre/kernel_patches/scripts/patchfns +++ /dev/null @@ -1,239 +0,0 @@ -DB=applied-patches - -# -# Work out where the user's pc/, patch/ and txt/ directories live. -# -# If the user specified PATCHSCRIPTS in environment then use that (it's -# probably a relative path) -# -# If there is a directory ./patch-scripts then use that -# -# Otherwise use "." -# - -if [ x$PATCHSCRIPTS != x ] -then - P=$PATCHSCRIPTS -elif [ -d ./patch-scripts ] -then - P=./patch-scripts -elif [ -d ./patches ] -then - P=. -else - echo "could not locate your pc/ and patches/ directories" - exit 1 -fi - -top_patch() -{ - tail -1 $DB -} - -die() -{ - echo error: $* - exit 1 -} - -is_numeric() -{ - if echo $1 | egrep '^[0-9]*$' > /dev/null - then - return 0 - fi - return 1 -} - -is_applied_last() -{ - name="$(stripit $1)" - top_patch >$DB.1 - if grep "^$name$" "$DB.1" > /dev/null 2>&1 - then - rm $DB.1 - return 0 - else - rm $DB.1 - return 1 - fi -} - -is_applied() -{ - name=$(stripit "$1") - if grep "^$name$" "$DB" > /dev/null 2>&1 - then - return 0 - else - return 1 - fi -} - -can_apply() -{ - if patch -p1 --dry-run -i "$1" -f - then - return 0 - else - return 1 - fi -} - -can_remove() -{ - if patch -R -p1 --dry-run -i $P/patches/"$1".patch -f - then - return 0 - else - return 1 - fi -} - -remove_from_db() -{ - tmpfile=$(mktemp /tmp/p_XXXXXX) - name="$1" - sed -e "/^$name$/d" < "$DB" > $tmpfile - mv $tmpfile "$DB" -} - -stripit() -{ - ret=$(basename $1) - ret=$(echo $ret | sed -e 's/\.patch$//') - ret=$(echo $ret | sed -e 's/\.pc$//') - ret=$(echo $ret | sed -e 's/\.txt$//') - echo $ret -} - -top_is_current() -{ - patch_name=$(top_patch) - if [ x$patch_name == x ] - then - return 1 - else - patch_file=$P/patches/"$patch_name".patch - files=$(cat $P/pc/$patch_name.pc) - for file in $files - do - if [ $file -nt $patch_file ] - then - echo $file newer than $patch_file - return 0 - fi - done - fi - return 1 -} - -need_top_current() -{ - if top_is_current - then - echo "Error: Top patch is not up-to-date" - exit 1 - fi -} - -warn_top_current() -{ - if top_is_current - then - echo "Warning: Top patch is not up-to-date" - fi -} - -file_in_patch() -{ - file=$1 - patch=$2 - - if [ -e $P/pc/$patch.pc ] - then - if grep "^"$file"$" $P/pc/$patch.pc > /dev/null - then - return 0 - fi - fi - return 1 -} - -# copy_file_to_bup filename patchname -copy_file_to_bup() -{ - file=$1 - patch=$2 - bup="$file"~"$patch" - - if [ -e $bup ] - then - echo "Cannot install file $file in patch $patch: backup $bup exists" - exit 1 - fi - - if [ -e $file ] - then - cp $file "$file"~"$patch" - else - echo "file $file appears to be newly added" - fi -} - -install_file_in_patch() -{ - file=$1 - patch=$2 - - copy_file_to_bup $file $patch - echo $file >> $P/pc/$patch.pc -# touch $P/txt/$patch.txt -} - -need_file_there() -{ - if [ ! -e $1 ] - then - echo "File $1 does not exist" - exit 1 - fi -} - -desc() -{ - state=0 - while read x - do - if [ x"$x" = xDESC ] - then - state=1 - elif [ x"$x" = xEDESC ] - then - state=0 - elif [ $state = 1 ] - then - echo " $x" - fi - done -} - -body() -{ - file=$1 - - did_stuff=0 - while read x - do - if [ x"$x" = xEDESC ] - then - cat - did_stuff=1 - fi - done < $file - - if [ $did_stuff = 0 ] - then - cat $file - fi -} diff --git a/lustre/kernel_patches/scripts/poppatch b/lustre/kernel_patches/scripts/poppatch deleted file mode 100755 index 792cb9b..0000000 --- a/lustre/kernel_patches/scripts/poppatch +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: poppatch [npatches]" - exit 1 -} - -doit() -{ - echo $* 1>&2 - $* || { - echo oops - exit 1 - } -} - -if [ $# -gt 1 ] -then - usage -fi - -NR=1 -STOP_AT="" -if [ $# -eq 1 ] -then - if is_numeric $1 - then - NR=$1 - else - NR=1000 - STOP_AT=$(stripit $1) - fi -fi - -pop_one() -{ - TOP_PATCH=$(top_patch) - if [ x$TOP_PATCH == x ] - then - echo "no patches applied" - exit 0 - else - popped_patch="$(top_patch)" - if ! rpatch $(top_patch) - then - echo still at $(top_patch) - exit 1 - fi - echo - fi -} - -for i in $(seq 1 $NR) -do - pop_one - if [ x$STOP_AT != "x" ] - then - if [ $STOP_AT == $(toppatch) ] - then - exit 0 - fi - fi -done diff --git a/lustre/kernel_patches/scripts/pushpatch b/lustre/kernel_patches/scripts/pushpatch deleted file mode 100755 index 018716d..0000000 --- a/lustre/kernel_patches/scripts/pushpatch +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/sh - -# -# Add next patch in series -# - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: pushpatch [npatches]" - exit 1 -} - -opt_force=0 - -for i in $* -do - case "$i" in - -f) - opt_force=1;; - *) - if [ -n "$NR" -o -n "$STOP_AT" ] - then - usage - fi - if is_numeric $i - then - NR=$i - else - NR=1000 - STOP_AT=$(stripit $i) - fi;; - esac -done - -[ $opt_force = 1 ] && force="-f" - -SERIES=series - -if [ ! -e $SERIES ] -then - echo 'File "series" not found' - exit 1 -fi - -push_one() -{ - top=$(toppatch) - if [ x"$top" == x ] - then - todo=$(head -1 $SERIES) - else - last_in_series=$(stripit $(tail -1 $SERIES)) - if [ $last_in_series == $top ] - then - echo "Series fully applied. Ends at $top" - exit 0 - fi - todo=$(grep -C1 "^$top\.patch" $SERIES | tail -1) - if [ x$todo = x ] - then - todo=$(head -1 $SERIES) - fi - fi - - apatch $force $todo -} - -for i in $(seq 1 $NR) -do - push_one - if [ x$STOP_AT != "x" ] - then - if [ $STOP_AT == $(toppatch) ] - then - exit 0 - fi - fi -done diff --git a/lustre/kernel_patches/scripts/refpatch b/lustre/kernel_patches/scripts/refpatch deleted file mode 100755 index 88f3caf..0000000 --- a/lustre/kernel_patches/scripts/refpatch +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: refpatch" - exit 1 -} - -doit() -{ - echo $* 1>&2 - $* || { - echo oops - exit 1 - } -} - -if [ $# != 0 ] -then - usage -fi - -TOP_PATCH=$(top_patch) -mpatch $* $(top_patch) -echo "Refreshed $TOP_PATCH" diff --git a/lustre/kernel_patches/scripts/rpatch b/lustre/kernel_patches/scripts/rpatch deleted file mode 100755 index 42e1533..0000000 --- a/lustre/kernel_patches/scripts/rpatch +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -do_remove() -{ - if patch -R -p1 -s -i $P/patches/"$1".patch - then - true - else - echo SOMETHING WENT WRONG - exit 1 - fi -} - -kill_old_ones() -{ - FILES=$(cat $P/pc/$1.pc) - for file in $FILES - do - rm -f "$file"~"$1" - done -} - -usage() -{ - echo "Usage: rpatch patchname" - exit 1 -} - -if [ $# == 0 ] -then - usage -fi - -PATCH_NAME=$(stripit $1) - -warn_top_current - -if is_applied "$PATCH_NAME" -then - if can_remove "$PATCH_NAME" - then - do_remove "$PATCH_NAME" - kill_old_ones "$PATCH_NAME" - remove_from_db "$PATCH_NAME" - else - echo "$PATCH_NAME" does not remove cleanly - exit 1 - fi -else - echo "$PATCH_NAME" is not applied - exit 1 -fi - -top=$(top_patch) -if [ x"$top" == x ] -then - msg="no patches applied" -else - msg="now at $top" -fi - -echo Removed $PATCH_NAME, $msg - diff --git a/lustre/kernel_patches/series/chaos b/lustre/kernel_patches/series/chaos deleted file mode 100644 index b35612f..0000000 --- a/lustre/kernel_patches/series/chaos +++ /dev/null @@ -1,5 +0,0 @@ -dev_read_only.patch -exports.patch -kmem_cache_validate.patch -lustre_version.patch -vfs_intent.patch diff --git a/lustre/kernel_patches/series/hp-pnnl b/lustre/kernel_patches/series/hp-pnnl deleted file mode 100644 index d0171e0..0000000 --- a/lustre/kernel_patches/series/hp-pnnl +++ /dev/null @@ -1 +0,0 @@ -patch-2.4.18-hp1_pnnl18.2.8qsnet diff --git a/lustre/kernel_patches/series/lin-2.5.44 b/lustre/kernel_patches/series/lin-2.5.44 deleted file mode 100644 index 1bc028b..0000000 --- a/lustre/kernel_patches/series/lin-2.5.44 +++ /dev/null @@ -1 +0,0 @@ -lin-2.5.44.patch diff --git a/lustre/kernel_patches/series/rh-2.4.18-18 b/lustre/kernel_patches/series/rh-2.4.18-18 deleted file mode 100644 index ec72618..0000000 --- a/lustre/kernel_patches/series/rh-2.4.18-18 +++ /dev/null @@ -1,8 +0,0 @@ -dev_read_only.patch -exports.patch -kmem_cache_validate.patch -lustre_version.patch -uml_check_get_page.patch -uml_no_panic.patch -vfs_intent-2.4.18-18.patch -uml_compile_fixes.patch diff --git a/lustre/kernel_patches/series/vanilla-2.4.18 b/lustre/kernel_patches/series/vanilla-2.4.18 deleted file mode 100644 index 314a8c3..0000000 --- a/lustre/kernel_patches/series/vanilla-2.4.18 +++ /dev/null @@ -1 +0,0 @@ -vanilla-2.4.18 diff --git a/lustre/kernel_patches/series/vanilla-2.4.19 b/lustre/kernel_patches/series/vanilla-2.4.19 deleted file mode 100644 index f868802..0000000 --- a/lustre/kernel_patches/series/vanilla-2.4.19 +++ /dev/null @@ -1 +0,0 @@ -vanilla-2.4.19 diff --git a/lustre/kernel_patches/txt/lin-2.5.44.txt b/lustre/kernel_patches/txt/lin-2.5.44.txt deleted file mode 100644 index bcfe8c3..0000000 --- a/lustre/kernel_patches/txt/lin-2.5.44.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -patches for making kernel 2.5.44 ready for mounting Lustre. -EDESC diff --git a/lustre/kernel_patches/txt/vfs_intent.txt b/lustre/kernel_patches/txt/vfs_intent.txt deleted file mode 100644 index 010cdb7..0000000 --- a/lustre/kernel_patches/txt/vfs_intent.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -(undescribed patch) -EDESC diff --git a/lustre/kernel_patches/which_patch b/lustre/kernel_patches/which_patch deleted file mode 100644 index 1f5c168..0000000 --- a/lustre/kernel_patches/which_patch +++ /dev/null @@ -1,5 +0,0 @@ -series/rh-8.0: - redhat 2.4.18-14 - redhat 2.4.18-17 -series/rh-2.4.18-18 - redhat 2.4.18-18 diff --git a/lustre/lib/debug.c b/lustre/lib/debug.c deleted file mode 100644 index c3a2721..0000000 --- a/lustre/lib/debug.c +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Helper routines for dumping data structs for debugging. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copryright (C) 2002 Cluster File Systems, Inc. - * - */ - -#define DEBUG_SUBSYSTEM D_OTHER - -#include -#include - -int dump_ioo(struct obd_ioobj *ioo) -{ - CERROR("obd_ioobj: ioo_id=%Ld, ioo_gr=%Ld, ioo_type=%d, ioo_bufct=%d\n", - ioo->ioo_id, ioo->ioo_gr, ioo->ioo_type, ioo->ioo_bufcnt); - return -EINVAL; -} - -int dump_lniobuf(struct niobuf_local *nb) -{ - CERROR("niobuf_local: addr=%p, offset=%Ld, len=%d, xid=%d, page=%p\n", - nb->addr, nb->offset, nb->len, nb->xid, nb->page); - CERROR("nb->page: index = %ld\n", nb->page ? nb->page->index : -1); - - return -EINVAL; -} - -int dump_rniobuf(struct niobuf_remote *nb) -{ - CERROR("niobuf_remote: offset=%Ld, len=%d, flags=%x, xid=%d\n", - nb->offset, nb->len, nb->flags, nb->xid); - - return -EINVAL; -} - -int dump_obdo(struct obdo *oa) -{ - CERROR("obdo: o_valid = %08x\n", oa->o_valid); - if (oa->o_valid & OBD_MD_FLID) - CERROR("obdo: o_id = %Ld\n", oa->o_id); - if (oa->o_valid & OBD_MD_FLATIME) - CERROR("obdo: o_atime = %Ld\n", oa->o_atime); - if (oa->o_valid & OBD_MD_FLMTIME) - CERROR("obdo: o_mtime = %Ld\n", oa->o_mtime); - if (oa->o_valid & OBD_MD_FLCTIME) - CERROR("obdo: o_ctime = %Ld\n", oa->o_ctime); - if (oa->o_valid & OBD_MD_FLSIZE) - CERROR("obdo: o_size = %Ld\n", oa->o_size); - if (oa->o_valid & OBD_MD_FLBLOCKS) /* allocation of space */ - CERROR("obdo: o_blocks = %Ld\n", oa->o_blocks); - if (oa->o_valid & OBD_MD_FLBLKSZ) - CERROR("obdo: o_blksize = %d\n", oa->o_blksize); - if (oa->o_valid & OBD_MD_FLMODE) - CERROR("obdo: o_mode = %o\n", oa->o_mode); - if (oa->o_valid & OBD_MD_FLUID) - CERROR("obdo: o_uid = %d\n", oa->o_uid); - if (oa->o_valid & OBD_MD_FLGID) - CERROR("obdo: o_gid = %d\n", oa->o_gid); - if (oa->o_valid & OBD_MD_FLFLAGS) - CERROR("obdo: o_flags = %x\n", oa->o_flags); - if (oa->o_valid & OBD_MD_FLNLINK) - CERROR("obdo: o_nlink = %d\n", oa->o_nlink); - if (oa->o_valid & OBD_MD_FLGENER) - CERROR("obdo: o_generation = %d\n", oa->o_generation); - - return -EINVAL; -} - -/* XXX assumes only a single page in request */ -int dump_req(struct ptlrpc_request *req) -{ - struct ost_body *body = lustre_msg_buf(req->rq_reqmsg, 0); - struct obd_ioobj *ioo = lustre_msg_buf(req->rq_reqmsg, 1); - //struct niobuf *nb = lustre_msg_buf(req->rq_reqmsg, 2); - - CERROR("ost_body: connid = %d, data = %d\n", body->connid, body->data); - dump_obdo(&body->oa); - //dump_niobuf(nb); - dump_ioo(ioo); - - return -EINVAL; -} - diff --git a/lustre/lib/ll_pack.c b/lustre/lib/ll_pack.c deleted file mode 100644 index 44152f2..0000000 --- a/lustre/lib/ll_pack.c +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * (Un)packing of OST/MDS requests - * - */ - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include - -void obd_statfs_pack(struct obd_statfs *osfs, struct statfs *sfs) -{ - if (osfs == NULL || sfs == NULL) - LBUG(); - - osfs->os_type = HTON__u64(sfs->f_type); - osfs->os_blocks = HTON__u64(sfs->f_blocks); - osfs->os_bfree = HTON__u64(sfs->f_bfree); - osfs->os_bavail = HTON__u64(sfs->f_bavail); - osfs->os_files = HTON__u64(sfs->f_files); - osfs->os_ffree = HTON__u64(sfs->f_ffree); - osfs->os_bsize = HTON__u32(sfs->f_bsize); - osfs->os_namelen = HTON__u32(sfs->f_namelen); -} - -void obd_statfs_unpack(struct obd_statfs *osfs, struct statfs *sfs) -{ - if (osfs == NULL || sfs == NULL) - LBUG(); - - sfs->f_type = NTOH__u64(osfs->os_type); - sfs->f_blocks = NTOH__u64(osfs->os_blocks); - sfs->f_bfree = NTOH__u64(osfs->os_bfree); - sfs->f_bavail = NTOH__u64(osfs->os_bavail); - sfs->f_files = NTOH__u64(osfs->os_files); - sfs->f_ffree = NTOH__u64(osfs->os_ffree); - sfs->f_bsize = NTOH__u32(osfs->os_bsize); - sfs->f_namelen = NTOH__u32(osfs->os_namelen); -} - diff --git a/lustre/lib/lov_pack.c b/lustre/lib/lov_pack.c deleted file mode 100644 index d8b9b3e..0000000 --- a/lustre/lib/lov_pack.c +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * (Un)packing of OST/MDS requests - * - */ - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include - -void lov_packdesc(struct lov_desc *ld) -{ - ld->ld_tgt_count = HTON__u32(ld->ld_tgt_count); - ld->ld_default_stripe_count = HTON__u32(ld->ld_default_stripe_count); - ld->ld_default_stripe_size = HTON__u32(ld->ld_default_stripe_size); - ld->ld_pattern = HTON__u32(ld->ld_pattern); -} - -void lov_unpackdesc(struct lov_desc *ld) -{ - ld->ld_tgt_count = NTOH__u32(ld->ld_tgt_count); - ld->ld_default_stripe_count = HTON__u32(ld->ld_default_stripe_count); - ld->ld_default_stripe_size = HTON__u32(ld->ld_default_stripe_size); - ld->ld_pattern = HTON__u32(ld->ld_pattern); -} diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c deleted file mode 100644 index 923f87b..0000000 --- a/lustre/llite/dcache.c +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copyright (C) 2001, Cluster File Systems, Inc. - * - */ - -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include - -extern struct address_space_operations ll_aops; - -void ll_intent_release(struct dentry *de) -{ - struct ldlm_lock *lock; - struct lustre_handle *handle; - ENTRY; - - if (de->d_it == NULL) { - EXIT; - return; - } - - handle = (struct lustre_handle *)de->d_it->it_lock_handle; - lock = lustre_handle2object(handle); - CDEBUG(D_INFO, "calling ldlm_lock_decref(%p, %d)\n", lock, - de->d_it->it_lock_mode); - ldlm_lock_decref(lock, de->d_it->it_lock_mode); - EXIT; -} - -int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it) -{ - ENTRY; - - RETURN(0); -} - - -struct dentry_operations ll_d_ops = { - d_revalidate2: ll_revalidate2, - d_intent_release: ll_intent_release -}; diff --git a/lustre/llite/iod.c b/lustre/llite/iod.c deleted file mode 100644 index 0e403ce..0000000 --- a/lustre/llite/iod.c +++ /dev/null @@ -1,502 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_LLITE -#include - -/* wakeup every 30s */ -#define LIOD_WAKEUP_CYCLE (30) - -/* FIXME tempororily copy from mm_inline.h */ -static inline void __add_page_to_inactive_clean_list(struct page * page) -{ - struct zone_struct * zone = page_zone(page); - DEBUG_LRU_PAGE(page); - SetPageInactiveClean(page); - list_add(&page->lru, &zone->inactive_clean_list); - zone->inactive_clean_pages++; -// nr_inactive_clean_pages++; -} - -static inline void __del_page_from_active_list(struct page * page) -{ - struct zone_struct * zone = page_zone(page); - list_del(&page->lru); - ClearPageActive(page); -// nr_active_pages--; - zone->active_pages--; - DEBUG_LRU_PAGE(page); -} - -static inline void __del_page_from_inactive_dirty_list(struct page * page) -{ - struct zone_struct * zone = page_zone(page); - list_del(&page->lru); - ClearPageInactiveDirty(page); -// nr_inactive_dirty_pages--; - zone->inactive_dirty_pages--; - DEBUG_LRU_PAGE(page); -} - -/* move page into inactive_clean list. - * - * caller need to make sure that this page is not used - * by anyothers - */ -void refile_clean_page(struct page *page) -{ - LASSERT(PageLocked(page)); - LASSERT(!PageDirty(page)); - - ClearPageReferenced(page); - page->age = 0; - - spin_lock(&pagemap_lru_lock); - if (PageActive(page)) { - __del_page_from_active_list(page); - __add_page_to_inactive_clean_list(page); - } else if (PageInactiveClean(page)) { - __del_page_from_inactive_dirty_list(page); - __add_page_to_inactive_clean_list(page); - } - spin_unlock(&pagemap_lru_lock); -} - - -/* return value: - * -1: no need to flush - * 0: need async flush - * 1: need sync flush - * - * Note: here we are more sensitive than kswapd, hope we could - * do more flush work by ourselves, not resort to kswapd - */ -static inline int balance_dirty_state(void) -{ - if (free_high(ALL_ZONES) > 0) { - printk("memory low, sync flush\n"); - return 1; - } - if (free_plenty(ALL_ZONES) > 0) { - printk("memory high, async flush\n"); - return 0; - } - else - return -1; -} - -extern spinlock_t inode_lock; - -static int flush_some_pages(struct super_block *sb); - -/* the main liod loop */ -static int liod_main(void *arg) -{ - struct super_block *sb = (struct super_block *)arg; - struct ll_io_daemon *iod = &ll_s2sbi(sb)->ll_iod; - - ENTRY; - - lock_kernel(); - daemonize(); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - spin_lock_irq(¤t->sigmask_lock); - sigfillset(¤t->blocked); - our_recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); -#else - sigfillset(¤t->blocked); - our_recalc_sigpending(current); -#endif - - sprintf(current->comm, "liod"); - unlock_kernel(); - - /* declare we are ready */ - set_bit(LIOD_FLAG_ALIVE, &iod->io_flag); - wake_up(&iod->io_waitq); - - CDEBUG(D_CACHE, "liod(%d) started\n", current->pid); - while (1) { - int flushed; - int t; - int times; - - /* check the stop command */ - if (test_bit(LIOD_FLAG_STOP, &iod->io_flag)) { - /* at umount time, should not be anyone - * trying to flushing pages */ - LASSERT(!waitqueue_active(&iod->io_sem.wait)); - break; - } - - t = interruptible_sleep_on_timeout(&iod->io_sleepq, - LIOD_WAKEUP_CYCLE*HZ); - CDEBUG(D_NET, "liod(%d) active due to %s\n", current->pid, - (t ? "wakeup" : "timeout")); - - printk("liod(%d) active due to %s\n", current->pid, - (t ? "wakeup" : "timeout")); - - times=0; - down(&iod->io_sem); - do { - flushed = flush_some_pages(sb); - conditional_schedule(); - printk("iod: loop %d times\n", ++times); - } while (flushed && (balance_dirty_state() >= 0)); - up(&iod->io_sem); - } - - clear_bit(LIOD_FLAG_ALIVE, &iod->io_flag); - wake_up(&iod->io_waitq); - - CDEBUG(D_NET, "liod(%d) exit\n", current->pid); - RETURN(0); -} - -int liod_start(struct super_block *sb) -{ - struct ll_io_daemon *iod = &ll_s2sbi(sb)->ll_iod; - int rc; - - /* initialize */ - iod->io_flag = 0; - init_waitqueue_head(&iod->io_sleepq); - init_waitqueue_head(&iod->io_waitq); - init_MUTEX(&iod->io_sem); - - rc = kernel_thread(liod_main, (void *) sb, - CLONE_VM | CLONE_FS | CLONE_FILES); - - if (rc < 0) { - CERROR("fail to start liod, error %d\n", rc); - return rc; - } - - /* wait liod start */ - wait_event(iod->io_waitq, test_bit(LIOD_FLAG_ALIVE, &iod->io_flag)); - - return 0; -} - -static inline void liod_wakeup(struct ll_io_daemon *iod) -{ - wake_up(&iod->io_sleepq); -} - -static inline void select_one_page(struct brw_page *pg, - struct inode *inode, - struct page *page) -{ - obd_off off; - - pg->pg = page; - pg->off = ((obd_off)page->index) << PAGE_SHIFT; - pg->flag = OBD_BRW_CREATE; - - off = ((obd_off)(page->index + 1)) << PAGE_SHIFT; - if (off > inode->i_size) - pg->count = inode->i_size & ~PAGE_MASK; - else - pg->count = PAGE_SIZE; -} - -/* select candidate dirty pages within an inode - * return: - * - npgs contains number of pages selected - * - 0: all pages in dirty list are searched - * 1: probably still have dirty pages - * - * don't sleep in this functions - * */ -static int select_inode_pages(struct inode *inode, struct brw_page *pgs, int *npgs) -{ - int nrmax = *npgs, nr = 0; - struct address_space *mapping = inode->i_mapping; - struct page *page; - struct list_head *list, *end; - - LASSERT(nrmax <= LIOD_FLUSH_NR); - - *npgs = 0; - - spin_lock(&pagecache_lock); - - /* if no dirty pages, just return */ - if (list_empty(&mapping->dirty_pages)) { - spin_unlock(&pagecache_lock); - return 0; - } - - list = mapping->dirty_pages.prev; - end = &mapping->dirty_pages; - while (nr < nrmax) { - /* no more dirty pages on this inode */ - if (list == end) - break; - - page = list_entry(list, struct page, list); - list = list->prev; - - /* flush pages only if we could gain the lock */ - if (!TryLockPage(page)) { - /* remove from dirty list */ - list_del(&page->list); - - if (PageDirty(page)) { - page_cache_get(page); - /* add to locked list */ - list_add(&page->list, &mapping->locked_pages); - - select_one_page(&pgs[nr++], inode, page); - - if (nr >= nrmax) - break; - } else { - /* it's quite possible. add to clean list */ - list_add(&page->list, &mapping->clean_pages); - UnlockPage(page); - } - } else { - if (list == &mapping->dirty_pages) - break; - - /* move to tail */ - list_del(&page->list); - list_add(&page->list, &mapping->dirty_pages); - if (end == &mapping->dirty_pages) - end = &page->list; - } - } - spin_unlock(&pagecache_lock); - - *npgs = nr; - - if (list == end) - return 0; - else - return 1; -} - -static int bulk_flush_pages( - struct inode *inode, - int npgs, - struct brw_page *pgs, - struct obd_brw_set *set) -{ - struct page *page; - int rc; - - set->brw_callback = ll_brw_sync_wait; - rc = obd_brw(OBD_BRW_WRITE, ll_i2obdconn(inode), - ll_i2info(inode)->lli_smd, npgs, pgs, set); - if (rc) { - CERROR("error from obd_brw: rc = %d\n", rc); - } else { - rc = ll_brw_sync_wait(set, CB_PHASE_START); - if (rc) - CERROR("error from callback: rc = %d\n", rc); - } - - rc = 0; - - while (--npgs >= 0) { - page = pgs[npgs].pg; - - LASSERT(PageLocked(page)); - - if (!rc) { - ClearPageDirty(page); - - /* move pages to clean list */ - spin_lock(&pagecache_lock); - list_del(&page->list); - list_add(&page->list, &inode->i_mapping->clean_pages); - spin_unlock(&pagecache_lock); - - refile_clean_page(page); - rc++; - } else { - SetPageDirty(page); - - /* add back to dirty list */ - spin_lock(&pagecache_lock); - list_del(&page->list); - list_add(&page->list, &inode->i_mapping->dirty_pages); - spin_unlock(&pagecache_lock); - } - UnlockPage(page); - - page_cache_release(page); - } - - spin_lock(&pagecache_lock); - if (list_empty(&inode->i_mapping->dirty_pages)) - inode->i_state &= ~I_DIRTY_PAGES; - spin_unlock(&pagecache_lock); - - return rc; -} - -/* syncronously flush certain amount of dirty pages right away - * don't simply call fdatasync(), we need a more efficient way - * to do flush in bunch mode. - * - * return the number of pages were flushed - * - * caller should gain the sbi->io_sem lock - * - * FIXME now we simply flush pages on at most one inode, probably - * need add multiple inode flush later. - */ -static int flush_some_pages(struct super_block *sb) -{ - struct ll_io_daemon *iod; - struct brw_page *pgs; - struct obd_brw_set *set; - struct list_head *list, *end; - struct inode *inode; - int npgs; - - iod = &ll_s2sbi(sb)->ll_iod; - set = &iod->io_set; - pgs = iod->io_pgs; - - /* init set */ - init_waitqueue_head(&set->brw_waitq); - INIT_LIST_HEAD(&set->brw_desc_head); - atomic_set(&set->brw_refcount, 0); - - { - int n = 0; - list = sb->s_dirty.prev; - while (list != &sb->s_dirty) { - n++; - list = list->prev; - } - printk("dirty inode length %d\n", n); - } - - /* FIXME simutanously gain inode_lock and pagecache_lock could - * cause busy spin forever? Check this */ - spin_lock(&inode_lock); - - /* sync dirty inodes from tail, since we try to sync - * from the oldest one */ - npgs = 0; - list = sb->s_dirty.prev; - end = &sb->s_dirty; - while (1) { - int ret; - - /* no dirty inodes left */ - if (list == end) - break; - - inode = list_entry(list, struct inode, i_list); - list = list->next; - - /* if inode is locked, it should be have been moved away - * from dirty list */ - if (inode->i_state & I_LOCK) - LBUG(); - - npgs = LIOD_FLUSH_NR; - ret = select_inode_pages(inode, pgs, &npgs); - - /* quit if found some pages */ - if (npgs) { - /* if all pages are searched on this inode, - * we could move it to the list end */ - if (!ret) { - list_del(&inode->i_list); - list_add(&inode->i_list, &sb->s_dirty); - } - break; - } else { - /* no page found, move inode to the end of list */ - if (list == &sb->s_dirty) - break; - - list_del(&inode->i_list); - list_add(&inode->i_list, &sb->s_dirty); - if (end == &sb->s_dirty) - end = &inode->i_list; - } - } - spin_unlock(&inode_lock); - - if (npgs) - printk("got %d pages of inode %lu to flush\n", - npgs, inode->i_ino); - else - printk("didn't found dirty pages\n"); - - if (!npgs) - return 0; - - if (!inode) - LBUG(); - - CDEBUG(D_CACHE, "got %d pages of inode %lu to flush\n", - npgs, inode->i_ino); - - return bulk_flush_pages(inode, npgs, pgs, set); -} - -void ll_balance_dirty_pages(struct super_block *sb) -{ - int flush; - struct ll_sb_info *sbi = ll_s2sbi(sb); - - flush = balance_dirty_state(); - if (flush < 0) - return; - - if (flush > 0) { - int n = 0, flush; - - if (!down_trylock(&sbi->ll_iod.io_sem)) { - do { - flush = flush_some_pages(sb); - printk("ll_balance_dirty: loop %d times\n", ++n); - } while (flush && (balance_dirty_state() > 0)); - - up(&sbi->ll_iod.io_sem); - } - } - - /* FIXME we need a way to wake up liods on *all* llite fs */ - liod_wakeup(&sbi->ll_iod); -} - -void liod_stop(struct super_block *sb) -{ - struct ll_io_daemon *iod = &ll_s2sbi(sb)->ll_iod; - - if (!test_bit(LIOD_FLAG_ALIVE, &iod->io_flag)) { - CERROR("liod died unexpectedly!\n"); - return; - } - - /* send the kill command */ - set_bit(LIOD_FLAG_STOP, &iod->io_flag); - - /* if wakeup daemon */ - wake_up(&iod->io_sleepq); - - /* wait liod exit */ - wait_event(iod->io_waitq, !test_bit(LIOD_FLAG_ALIVE, &iod->io_flag)); - - return; -} diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c deleted file mode 100644 index 428bd43..0000000 --- a/lustre/llite/lproc_llite.c +++ /dev/null @@ -1,176 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include - - - -int rd_path(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - return 0; - -} -int rd_fstype(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct super_block *sb=(struct super_block*)data; - - len+=snprintf(page, count, "%s\n", sb->s_type->name); - return len; -} -int rd_blksize(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct super_block *sb=(struct super_block*)data; - struct statfs mystats; - (sb->s_op->statfs)(sb, &mystats); - len+=snprintf(page, count, LPU64"\n", (__u64)(mystats.f_bsize)); - return len; - -} -int rd_blktotal(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct super_block *sb=(struct super_block*)data; - struct statfs mystats; - (sb->s_op->statfs)(sb, &mystats); - len+=snprintf(page, count, LPU64"\n", (__u64)(mystats.f_blocks)); - return len; - -} - -int rd_blkfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct super_block *sb=(struct super_block*)data; - struct statfs mystats; - (sb->s_op->statfs)(sb, &mystats); - len+=snprintf(page, count, LPU64"\n", (__u64)(mystats.f_bfree)); - return len; - - -} - -int rd_kbfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct super_block *sb=(struct super_block*)data; - struct statfs mystats; - long blk_size=0; - - (sb->s_op->statfs)(sb, &mystats); - blk_size=mystats.f_bsize; - - len+=snprintf(page, count, LPU64"\n", - (__u64)((mystats.f_bfree)/(blk_size*1024))); - return len; - -} - -int rd_filestotal(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - int len=0; - struct super_block *sb=(struct super_block*)data; - - struct statfs mystats; - - - (sb->s_op->statfs)(sb, &mystats); - - len+=snprintf(page, count, LPU64"\n", (__u64)(mystats.f_files)); - return len; -} - -int rd_filesfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - int len=0; - struct super_block *sb=(struct super_block*)data; - - struct statfs mystats; - - - (sb->s_op->statfs)(sb, &mystats); - - len+=snprintf(page, count, LPU64"\n", (__u64)(mystats.f_ffree)); - return len; -} - -int rd_filegroups(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} -int rd_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct super_block *sb=(struct super_block*)data; - struct ll_sb_info *sbi=ll_s2sbi(sb); - len+=snprintf(page, count, "%s\n", sbi->ll_sb_uuid); - return len; - -} -int rd_dev_name(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct obd_device* dev=(struct obd_device*)data; - len+=snprintf(page, count, "%s\n", dev->obd_name); - return len; -} - -int rd_dev_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct obd_device* dev=(struct obd_device*)data; - len+=snprintf(page, count, "%s\n", dev->obd_uuid); - return len; -} - - -lprocfs_vars_t status_var_nm_1[]={ - {"status/uuid", rd_uuid, 0}, - {"status/mntpt_path", rd_path, 0}, - {"status/fs_type", rd_fstype, 0}, - {"status/blocksize",rd_blksize, 0}, - {"status/blockstotal",rd_blktotal, 0}, - {"status/blocksfree",rd_blkfree, 0}, - {"status/kbytesfree", rd_kbfree, 0}, - {"status/filestotal", rd_filestotal, 0}, - {"status/filesfree", rd_filesfree, 0}, - {"status/filegroups", rd_filegroups, 0}, - {0} -}; diff --git a/lustre/llite/recover.c b/lustre/llite/recover.c deleted file mode 100644 index 115e229..0000000 --- a/lustre/llite/recover.c +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Lustre Light Super operations - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copryright (C) 1996 Peter J. Braam - * Copryright (C) 1999 Stelias Computing Inc. - * Copryright (C) 1999 Seagate Technology Inc. - * Copryright (C) 2001 Mountain View Data, Inc. - * Copryright (C) 2002 Cluster File Systems, Inc. - * - */ - -#include -#include - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include - -void ll_recover(struct ptlrpc_client *cli) -{ - struct ptlrpc_request *req; - struct list_head *tmp, *pos; - ENTRY; - - spin_lock(&cli->cli_lock); - /* first shot at this: resend the request */ - list_for_each_safe(tmp, pos, &cli->cli_sent_head) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - CDEBUG(D_INODE, "replaying request %p\n", req); - list_del(&req->rq_list); - ptlrpc_resend_req(req); - } - - recovd_cli_fixed(cli); - spin_unlock(&cli->cli_lock); - - EXIT; -} diff --git a/lustre/lov/lov_pack.c b/lustre/lov/lov_pack.c deleted file mode 100644 index d28a6c9..0000000 --- a/lustre/lov/lov_pack.c +++ /dev/null @@ -1,176 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * (Un)packing of OST/MDS requests - * - */ - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include -#include - -/* lov_packdesc() is in mds/mds_lov.c */ - -void lov_unpackdesc(struct lov_desc *ld) -{ - ld->ld_tgt_count = NTOH__u32(ld->ld_tgt_count); - ld->ld_default_stripe_count = HTON__u32(ld->ld_default_stripe_count); - ld->ld_default_stripe_size = HTON__u32(ld->ld_default_stripe_size); - ld->ld_pattern = HTON__u32(ld->ld_pattern); -} - -/* Pack LOV object metadata for shipment to the MDS. - * - * XXX In the future, this will be enhanced to get the EA size from the - * underlying OSC device(s) to get their EA sizes so we can stack - * LOVs properly. For now lov_mds_md_size() just assumes one obd_id - * per stripe. - */ -int lov_packmd(struct lustre_handle *conn, struct lov_mds_md **lmmp, - struct lov_stripe_md *lsm) -{ - struct obd_device *obd = class_conn2obd(conn); - struct lov_obd *lov = &obd->u.lov; - struct lov_oinfo *loi; - struct lov_mds_md *lmm; - int ost_count = lov->desc.ld_tgt_count; - int stripe_count = ost_count; - int lmm_size; - int i; - ENTRY; - - if (lsm) - stripe_count = lsm->lsm_stripe_count; - - /* XXX LOV STACKING call into osc for sizes */ - lmm_size = lov_mds_md_size(ost_count); - - if (!lmmp) - RETURN(lmm_size); - - if (*lmmp && !lsm) { - /* endianness */ - ost_count = ((*lmmp)->lmm_ost_count); - OBD_FREE(*lmmp, lov_mds_md_size(ost_count)); - *lmmp = NULL; - RETURN(0); - } - - if (!*lmmp) { - OBD_ALLOC(*lmmp, lmm_size); - if (!*lmmp) - RETURN(-ENOMEM); - } - - lmm = *lmmp; - - lmm->lmm_stripe_count = (stripe_count); - if (!lsm) - RETURN(lmm_size); - /* XXX endianness */ - lmm->lmm_magic = (lsm->lsm_magic); - lmm->lmm_object_id = (lsm->lsm_object_id); - lmm->lmm_stripe_size = (lsm->lsm_stripe_size); - lmm->lmm_stripe_pattern = (lsm->lsm_stripe_pattern); - lmm->lmm_stripe_offset = (lsm->lsm_stripe_offset); - lmm->lmm_ost_count = (lov->desc.ld_tgt_count); - - /* Only fill in the object ids which we are actually using. - * Assumes lmm_objects is otherwise zero-filled. */ - for (i = 0, loi = lsm->lsm_oinfo; i < stripe_count; i++, loi++) - /* XXX call down to osc_packmd() to do the packing */ - lmm->lmm_objects[loi->loi_ost_idx].l_object_id = (loi->loi_id); - - RETURN(lmm_size); -} - -int lov_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp, - struct lov_mds_md *lmm) -{ - struct obd_device *obd = class_conn2obd(conn); - struct lov_obd *lov = &obd->u.lov; - struct lov_stripe_md *lsm; - struct lov_oinfo *loi; - int ost_count = lov->desc.ld_active_tgt_count; - int ost_offset = 0; - int stripe_count = 0; - int lsm_size; - int i; - ENTRY; - - if (lmm) - /* endianness */ - stripe_count = (lmm->lmm_stripe_count); - - if (!stripe_count) - stripe_count = lov->desc.ld_default_stripe_count; - if (!stripe_count || stripe_count > ost_count) - stripe_count = ost_count; - - /* XXX LOV STACKING call into osc for sizes */ - lsm_size = lov_stripe_md_size(stripe_count); - - if (!lsmp) - RETURN(lsm_size); - - if (*lsmp && !lmm) { - stripe_count = (*lsmp)->lsm_stripe_count; - OBD_FREE(*lsmp, lov_stripe_md_size(stripe_count)); - *lsmp = NULL; - RETURN(0); - } - - if (!*lsmp) { - OBD_ALLOC(*lsmp, lsm_size); - if (!*lsmp) - RETURN(-ENOMEM); - } - - lsm = *lsmp; - - lsm->lsm_stripe_count = stripe_count; - if (!lmm) - RETURN(lsm_size); - - /* XXX endianness */ - ost_offset = lsm->lsm_stripe_offset = (lmm->lmm_stripe_offset); - lsm->lsm_magic = (lmm->lmm_magic); - lsm->lsm_object_id = (lmm->lmm_object_id); - lsm->lsm_stripe_size = (lmm->lmm_stripe_size); - lsm->lsm_stripe_pattern = (lmm->lmm_stripe_pattern); - - for (i = 0, loi = lsm->lsm_oinfo; i < ost_count; i++, ost_offset++) { - ost_offset %= ost_count; - - if (!lmm->lmm_objects[ost_offset].l_object_id) - continue; - - LASSERT(loi - lsm->lsm_oinfo < stripe_count); - /* XXX LOV STACKING call down to osc_unpackmd() */ - loi->loi_id = (lmm->lmm_objects[ost_offset].l_object_id); - loi->loi_ost_idx = ost_offset; - loi++; - } - - RETURN(lsm_size); -} diff --git a/lustre/lov/lproc_lov.c b/lustre/lov/lproc_lov.c deleted file mode 100644 index 8198dc6..0000000 --- a/lustre/lov/lproc_lov.c +++ /dev/null @@ -1,211 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#include - -/* - * Common STATUS namespace - */ - -int rd_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct obd_device* dev=(struct obd_device*)data; - len+=snprintf(page, count, "%s\n", dev->obd_uuid); - return len; - - -} -int rd_stripesize(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* dev=(struct obd_device*)data; - int len=0; - struct lov_obd* lov=&dev->u.lov; - len+=snprintf(page, count, LPU64"\n", - (__u64)(lov->desc.ld_default_stripe_size)); - - return len; -} - -int rd_stripeoffset(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* dev=(struct obd_device*)data; - int len=0; - struct lov_obd* lov=&dev->u.lov; - len+=snprintf(page, count, LPU64"\n", - lov->desc.ld_default_stripe_offset); - return len; - -} - -int rd_stripetype(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* dev=(struct obd_device*)data; - int len=0; - struct lov_obd* lov=&dev->u.lov; - len+=snprintf(page, count, LPU64"\n", - (__u64)(lov->desc.ld_pattern)); - return len; - -} -int rd_stripecount(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* dev=(struct obd_device*)data; - int len=0; - struct lov_obd* lov=&dev->u.lov; - len+=snprintf(page, count, LPU64"\n", - (__u64)(lov->desc.ld_default_stripe_count)); - return len; - -} -int rd_numobd(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* dev=(struct obd_device*)data; - int len=0; - struct lov_obd* lov=&dev->u.lov; - len+=snprintf(page, count, LPU64"\n", - (__u64)(lov->desc.ld_tgt_count)); - return len; - -} - -int rd_activeobd(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* dev=(struct obd_device*)data; - int len=0; - struct lov_obd* lov=&dev->u.lov; - len+=snprintf(page, count, LPU64"\n", - (__u64)(lov->desc.ld_active_tgt_count)); - return len; - -} - -int rd_blksize(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - - -int rd_blktotal(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_blkfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_kbfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_numobjects(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_objfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_objgroups(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_target(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* dev=(struct obd_device*)data; - int len=0, i=0; - struct lov_obd* lov=&dev->u.lov; - struct lov_tgt_desc* tgts=lov->tgts; - while(idesc.ld_tgt_count){ - len+=snprintf(page, count, "%d: %s\n", i, tgts->uuid); - i++; - tgts++; - } - - return len; -} -int rd_mdc(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* dev=(struct obd_device*)data; - int len=0; - struct lov_obd* lov=&dev->u.lov; - len+=snprintf(page, count, "%s\n", lov->mdcobd->obd_uuid); - return len; -} - -lprocfs_vars_t status_var_nm_1[]={ - {"status/uuid", rd_uuid, 0}, - {"status/stripesize",rd_stripesize, 0}, - {"status/stripeoffset",rd_stripeoffset, 0}, - {"status/stripecount",rd_stripecount, 0}, - {"status/stripetype", rd_stripetype, 0}, - {"status/numobd",rd_numobd, 0}, - {"status/activeobd", rd_activeobd, 0}, - {"status/objects", rd_numobjects, 0}, - {"status/objectsfree", rd_objfree, 0}, - {"status/objectgroups", rd_objgroups, 0}, - {"status/blocksize", rd_blksize, 0}, - {"status/blockstotal", rd_blktotal, 0}, - {"status/kbytesfree", rd_kbfree, 0}, - {"status/blocksfree", rd_blkfree, 0}, - {"status/target_obd", rd_target, 0}, - {"status/target_mdc", rd_mdc, 0}, - - {0} -}; -int rd_numdevices(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_type* class=(struct obd_type*)data; - int len=0; - len+=snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -lprocfs_vars_t status_class_var[]={ - {"status/num_devices", rd_numdevices, 0}, - {0} -}; diff --git a/lustre/mdc/lproc_mdc.c b/lustre/mdc/lproc_mdc.c deleted file mode 100644 index 54d1d4c..0000000 --- a/lustre/mdc/lproc_mdc.c +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#include - - -int rd_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - struct obd_device* temp=(struct obd_device*)data; - int len=0; - len+=snprintf(page, count, "%s\n",temp->obd_uuid); - return len; - - -} -int rd_blksize(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - return 0; - -} -int rd_kbtotal(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_kbfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - - -int rd_files(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_filesfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_filegroups(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} -int rd_conn_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct client_obd* cli=&temp->u.cli; - struct obd_import* imp=&cli->cl_import; - int len=0; - len+=snprintf(page, count, "%s\n",imp->imp_connection->c_remote_uuid); - return len; -} - -int rd_server_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct client_obd* cli=&temp->u.cli; - int len=0; - len+=snprintf(page, count, "%s\n",cli->cl_target_uuid); - return len; -} - -int rd_server_name(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; - -} - -lprocfs_vars_t status_var_nm_1[]={ - {"status/uuid", rd_uuid, 0}, - {"status/blocksize",rd_blksize, 0}, - {"status/kbytestotal",rd_kbtotal, 0}, - {"status/kbytesfree", rd_kbfree, 0}, - {"status/files", rd_files, 0}, - {"status/filesfree", rd_filesfree, 0}, - {"status/filegroups", rd_filegroups, 0}, - {"status/server_uuid", rd_server_uuid, 0}, - {"status/conn_uuid", rd_conn_uuid, 0}, - {0} -}; -int rd_numdevices(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_type* class=(struct obd_type*)data; - int len=0; - len+=snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -lprocfs_vars_t status_class_var[]={ - {"status/num_devices", rd_numdevices, 0}, - {0} -}; diff --git a/lustre/mds/lproc_mds.c b/lustre/mds/lproc_mds.c deleted file mode 100644 index a65816f..0000000 --- a/lustre/mds/lproc_mds.c +++ /dev/null @@ -1,187 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#include - - -int rd_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - int len=0; - len+=snprintf(page, count, "%s\n", temp->obd_uuid); - return len; -} -int rd_blksize(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct mds_obd *mds=&temp->u.mds; - struct statfs mystats; - int rc, len=0; - - rc = vfs_statfs(mds->mds_sb, &mystats); - if (rc) { - CERROR("mds: statfs failed: rc %d\n", rc); - return 0; - } - len+=snprintf(page, count, LPU64"\n", (__u64)(mystats.f_bsize)); - return len; - -} -int rd_blktotal(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct mds_obd *mds=&temp->u.mds; - struct statfs mystats; - int rc, len=0; - - rc = vfs_statfs(mds->mds_sb, &mystats); - if (rc) { - CERROR("mds: statfs failed: rc %d\n", rc); - return 0; - } - len+=snprintf(page, count, LPU64"\n", (__u64)(mystats.f_blocks)); - return len; - -} - -int rd_blkfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct mds_obd *mds=&temp->u.mds; - struct statfs mystats; - int rc, len=0; - - rc = vfs_statfs(mds->mds_sb, &mystats); - if (rc) { - CERROR("mds: statfs failed: rc %d\n", rc); - return 0; - } - len+=snprintf(page, count, LPU64"\n", (__u64)(mystats.f_bfree)); - return len; - -} - -int rd_kbfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct mds_obd *mds=&temp->u.mds; - struct statfs mystats; - int rc, blk_size, len=0; - - rc = vfs_statfs(mds->mds_sb, &mystats); - if (rc) { - CERROR("mds: statfs failed: rc %d\n", rc); - return 0; - } - blk_size=mystats.f_bsize; - len+=snprintf(page, count, LPU64"\n", - (__u64)((mystats.f_bfree)/(blk_size*1024))); - return len; - -} - -int rd_fstype(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct mds_obd *mds=&temp->u.mds; - int len=0; - len+=snprintf(page, count, "%s\n", mds->mds_fstype); - return len; - -} - -int rd_ffiles(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct mds_obd *mds=&temp->u.mds; - struct statfs mystats; - int rc, len=0; - - rc = vfs_statfs(mds->mds_sb, &mystats); - if (rc) { - CERROR("mds: statfs failed: rc %d\n", rc); - return 0; - } - - len+=snprintf(page, count, LPU64"\n", (__u64)(mystats.f_files)); - return len; - - -} - -int rd_inodesfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct mds_obd *mds=&temp->u.mds; - struct statfs mystats; - int rc, len=0; - - rc = vfs_statfs(mds->mds_sb, &mystats); - if (rc) { - CERROR("mds: statfs failed: rc %d\n", rc); - return 0; - } - - len+=snprintf(page, count, LPU64"\n", (__u64)(mystats.f_ffree)); - return len; -} - -int rd_filesets(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} -lprocfs_vars_t status_var_nm_1[]={ - {"status/uuid", rd_uuid, 0}, - {"status/f_blocksize",rd_blksize, 0}, - {"status/f_blockstotal",rd_blktotal, 0}, - {"status/f_blocksfree",rd_blkfree, 0}, - {"status/f_kbytesfree", rd_kbfree, 0}, - {"status/f_fstype", rd_fstype, 0}, - {"status/f_files", rd_ffiles, 0}, - {"status/f_inodesfree", rd_inodesfree, 0}, - {"status/f_filesets", rd_filesets, 0}, - {0} -}; -int rd_numdevices(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_type* class=(struct obd_type*)data; - int len=0; - len+=snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -lprocfs_vars_t status_class_var[]={ - {"status/num_devices", rd_numdevices, 0}, - {0} -}; diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c deleted file mode 100644 index 8efca61..0000000 --- a/lustre/mds/mds_fs.c +++ /dev/null @@ -1,463 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * linux/mds/mds_fs.c - * - * Lustre Metadata Server (MDS) filesystem interface code - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * by Andreas Dilger - * - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_MDS - -#include -#include -#include - -LIST_HEAD(mds_fs_types); - -struct mds_fs_type { - struct list_head mft_list; - struct mds_fs_operations *mft_ops; - char *mft_name; -}; - -/* This will be a hash table at some point. */ -static int mds_init_client_data(struct mds_obd *mds) -{ - INIT_LIST_HEAD(&mds->mds_client_info); - return 0; -} - -#define MDS_MAX_CLIENTS 1024 -#define MDS_MAX_CLIENT_WORDS (MDS_MAX_CLIENTS / sizeof(unsigned long)) - -static unsigned long last_rcvd_slots[MDS_MAX_CLIENT_WORDS]; - -/* Add client data to the MDS. The in-memory storage will be a hash at some - * point. We use a bitmap to locate a free space in the last_rcvd file if - * cl_off is -1 (i.e. a new client). Otherwise, we have just read the data - * from the last_rcvd file and we know its offset. - */ -int mds_client_add(struct mds_obd *mds, struct mds_client_data *mcd, int cl_off) -{ - struct mds_client_info *mci; - - OBD_ALLOC(mci, sizeof(*mci)); - if (!mci) { - CERROR("no memory for MDS client info\n"); - RETURN(-ENOMEM); - } - INIT_LIST_HEAD(&mci->mci_open_head); - - CDEBUG(D_INFO, "client at offset %d with UUID '%s' added\n", - cl_off, mcd->mcd_uuid); - - if (cl_off == -1) { - unsigned long *word; - int bit; - - repeat: - word = last_rcvd_slots; - while(*word == ~0UL) - ++word; - if (word - last_rcvd_slots >= MDS_MAX_CLIENT_WORDS) { - CERROR("no room in client MDS bitmap - fix code\n"); - return -ENOMEM; - } - bit = ffz(*word); - if (test_and_set_bit(bit, word)) { - CERROR("found bit %d set for word %d - fix code\n", - bit, word - last_rcvd_slots); - goto repeat; - } - cl_off = word - last_rcvd_slots + bit; - } else { - if (test_and_set_bit(cl_off, last_rcvd_slots)) { - CERROR("bit %d already set in bitmap - bad bad\n", - cl_off); - LBUG(); - } - } - - mci->mci_mcd = mcd; - mci->mci_off = cl_off; - - /* For now we just put the clients in a list, not a hashed list */ - list_add_tail(&mci->mci_list, &mds->mds_client_info); - - mds->mds_client_count++; - - return 0; -} - -void mds_client_del(struct mds_obd *mds, struct mds_client_info *mci) -{ - unsigned long *word; - int bit; - - word = last_rcvd_slots + mci->mci_off / sizeof(unsigned long); - bit = mci->mci_off % sizeof(unsigned long); - - if (!test_and_clear_bit(bit, word)) { - CERROR("bit %d already clear in word %d - bad bad\n", - bit, word - last_rcvd_slots); - LBUG(); - } - - --mds->mds_client_count; - list_del(&mci->mci_list); - OBD_FREE(mci->mci_mcd, sizeof(*mci->mci_mcd)); - OBD_FREE(mci, sizeof (*mci)); -} - -static int mds_client_free_all(struct mds_obd *mds) -{ - struct list_head *p, *n; - - list_for_each_safe(p, n, &mds->mds_client_info) { - struct mds_client_info *mci; - - mci = list_entry(p, struct mds_client_info, mci_list); - mds_client_del(mds, mci); - } - - return 0; -} - -static int mds_server_free_data(struct mds_obd *mds) -{ - OBD_FREE(mds->mds_server_data, sizeof(*mds->mds_server_data)); - mds->mds_server_data = NULL; - - return 0; -} - -#define LAST_RCVD "last_rcvd" - -static int mds_read_last_rcvd(struct mds_obd *mds, struct file *f) -{ - struct mds_server_data *msd; - struct mds_client_data *mcd = NULL; - loff_t fsize = f->f_dentry->d_inode->i_size; - loff_t off = 0; - int cl_off; - __u64 last_rcvd = 0; - __u64 last_mount; - int rc = 0; - - OBD_ALLOC(msd, sizeof(*msd)); - if (!msd) - RETURN(-ENOMEM); - rc = lustre_fread(f, (char *)msd, sizeof(*msd), &off); - - mds->mds_server_data = msd; - if (rc == 0) { - CERROR("empty MDS %s, new MDS?\n", LAST_RCVD); - RETURN(0); - } else if (rc != sizeof(*msd)) { - CERROR("error reading MDS %s: rc = %d\n", LAST_RCVD, rc); - if (rc > 0) { - rc = -EIO; - } - GOTO(err_msd, rc); - } - - /* - * When we do a clean MDS shutdown, we save the last_rcvd into - * the header. If we find clients with higher last_rcvd values - * then those clients may need recovery done. - */ - last_rcvd = le64_to_cpu(msd->msd_last_rcvd); - mds->mds_last_rcvd = last_rcvd; - CDEBUG(D_INODE, "got %Lu for server last_rcvd value\n", - (unsigned long long)last_rcvd); - - last_mount = le64_to_cpu(msd->msd_mount_count); - mds->mds_mount_count = last_mount; - CDEBUG(D_INODE, "got %Lu for server last_mount value\n", - (unsigned long long)last_mount); - - for (off = MDS_LR_CLIENT, cl_off = 0, rc = sizeof(*mcd); - off <= fsize - sizeof(*mcd) && rc == sizeof(*mcd); - off = MDS_LR_CLIENT + ++cl_off * MDS_LR_SIZE) { - if (!mcd) - OBD_ALLOC(mcd, sizeof(*mcd)); - if (!mcd) - GOTO(err_msd, rc = -ENOMEM); - - rc = lustre_fread(f, (char *)mcd, sizeof(*mcd), &off); - if (rc != sizeof(*mcd)) { - CERROR("error reading MDS %s offset %d: rc = %d\n", - LAST_RCVD, cl_off, rc); - if (rc > 0) - rc = -EIO; - break; - } - - last_rcvd = le64_to_cpu(mcd->mcd_last_rcvd); - last_mount = le64_to_cpu(mcd->mcd_mount_count); - - if (last_rcvd && - last_mount - mcd->mcd_mount_count < MDS_MOUNT_RECOV) { - rc = mds_client_add(mds, mcd, cl_off); - if (rc) { - rc = 0; - break; - } - mcd = NULL; - } else { - CDEBUG(D_INFO, - "client at offset %d with UUID '%s' ignored\n", - cl_off, mcd->mcd_uuid); - } - - if (last_rcvd > mds->mds_last_rcvd) { - CDEBUG(D_OTHER, - "client at offset %d has last_rcvd = %Lu\n", - cl_off, (unsigned long long)last_rcvd); - mds->mds_last_rcvd = last_rcvd; - } - } - CDEBUG(D_INODE, "got %Lu for highest last_rcvd value, %d clients\n", - (unsigned long long)mds->mds_last_rcvd, mds->mds_client_count); - - /* After recovery, there can be no local uncommitted transactions */ - mds->mds_last_committed = mds->mds_last_rcvd; - - return 0; - -err_msd: - mds_server_free_data(mds); - return rc; -} - -static int mds_fs_prep(struct mds_obd *mds) -{ - struct obd_run_ctxt saved; - struct dentry *dentry; - struct file *f; - int rc; - - push_ctxt(&saved, &mds->mds_ctxt); - dentry = simple_mkdir(current->fs->pwd, "ROOT", 0755); - if (IS_ERR(dentry)) { - rc = PTR_ERR(dentry); - CERROR("cannot create ROOT directory: rc = %d\n", rc); - GOTO(err_pop, rc); - } - /* XXX probably want to hold on to this later... */ - dput(dentry); - f = filp_open("ROOT", O_RDONLY, 0); - if (IS_ERR(f)) { - rc = PTR_ERR(f); - CERROR("cannot open ROOT: rc = %d\n", rc); - LBUG(); - GOTO(err_pop, rc); - } - - mds->mds_rootfid.id = f->f_dentry->d_inode->i_ino; - mds->mds_rootfid.generation = f->f_dentry->d_inode->i_generation; - mds->mds_rootfid.f_type = S_IFDIR; - - rc = filp_close(f, 0); - if (rc) { - CERROR("cannot close ROOT: rc = %d\n", rc); - LBUG(); - } - - dentry = simple_mkdir(current->fs->pwd, "FH", 0700); - if (IS_ERR(dentry)) { - rc = PTR_ERR(dentry); - CERROR("cannot create FH directory: rc = %d\n", rc); - GOTO(err_pop, rc); - } - /* XXX probably want to hold on to this later... */ - dput(dentry); - - rc = mds_init_client_data(mds); - if (rc) - GOTO(err_pop, rc); - - f = filp_open(LAST_RCVD, O_RDWR | O_CREAT, 0644); - if (IS_ERR(f)) { - rc = PTR_ERR(f); - CERROR("cannot open/create %s file: rc = %d\n", LAST_RCVD, rc); - GOTO(err_pop, rc = PTR_ERR(f)); - } - if (!S_ISREG(f->f_dentry->d_inode->i_mode)) { - CERROR("%s is not a regular file!: mode = %o\n", LAST_RCVD, - f->f_dentry->d_inode->i_mode); - GOTO(err_pop, rc = -ENOENT); - } - - rc = mds_fs_journal_data(mds, f); - if (rc) { - CERROR("cannot journal data on %s: rc = %d\n", LAST_RCVD, rc); - GOTO(err_filp, rc); - } - - rc = mds_read_last_rcvd(mds, f); - if (rc) { - CERROR("cannot read %s: rc = %d\n", LAST_RCVD, rc); - GOTO(err_client, rc); - } - mds->mds_rcvd_filp = f; - pop_ctxt(&saved); - - RETURN(0); - -err_client: - mds_client_free_all(mds); -err_filp: - if (filp_close(f, 0)) - CERROR("can't close %s after error\n", LAST_RCVD); -err_pop: - pop_ctxt(&saved); - - return rc; -} - -static struct mds_fs_operations *mds_search_fs_type(const char *name) -{ - struct list_head *p; - struct mds_fs_type *type; - - /* lock mds_fs_types list */ - list_for_each(p, &mds_fs_types) { - type = list_entry(p, struct mds_fs_type, mft_list); - if (!strcmp(type->mft_name, name)) { - /* unlock mds_fs_types list */ - return type->mft_ops; - } - } - /* unlock mds_fs_types list */ - return NULL; -} - -int mds_register_fs_type(struct mds_fs_operations *ops, const char *name) -{ - struct mds_fs_operations *found; - struct mds_fs_type *type; - - if ((found = mds_search_fs_type(name))) { - if (found != ops) { - CERROR("different operations for type %s\n", name); - RETURN(-EEXIST); - } - return 0; - } - OBD_ALLOC(type, sizeof(*type)); - if (!type) - RETURN(-ENOMEM); - - INIT_LIST_HEAD(&type->mft_list); - type->mft_ops = ops; - type->mft_name = strdup(name); - if (!type->mft_name) { - OBD_FREE(type, sizeof(*type)); - RETURN(-ENOMEM); - } - MOD_INC_USE_COUNT; - list_add(&type->mft_list, &mds_fs_types); - - return 0; -} - -void mds_unregister_fs_type(const char *name) -{ - struct list_head *p; - - /* lock mds_fs_types list */ - list_for_each(p, &mds_fs_types) { - struct mds_fs_type *type; - - type = list_entry(p, struct mds_fs_type, mft_list); - if (!strcmp(type->mft_name, name)) { - list_del(p); - kfree(type->mft_name); - OBD_FREE(type, sizeof(*type)); - MOD_DEC_USE_COUNT; - break; - } - } - /* unlock mds_fs_types list */ -} - -int mds_fs_setup(struct mds_obd *mds, struct vfsmount *mnt) -{ - struct mds_fs_operations *fs_ops; - int rc; - - if (!(fs_ops = mds_search_fs_type(mds->mds_fstype))) { - char name[32]; - - snprintf(name, sizeof(name) - 1, "mds_%s", mds->mds_fstype); - name[sizeof(name) - 1] = '\0'; - - if ((rc = request_module(name))) { - fs_ops = mds_search_fs_type(mds->mds_fstype); - CDEBUG(D_INFO, "Loaded module '%s'\n", name); - if (!fs_ops) - rc = -ENOENT; - } - - if (rc) { - CERROR("Can't find MDS fs interface '%s'\n", name); - RETURN(rc); - } - } - - mds->mds_fsops = fs_ops; - mds->mds_vfsmnt = mnt; - mds->mds_ctxt.pwdmnt = mnt; - mds->mds_ctxt.pwd = mnt->mnt_root; - mds->mds_ctxt.fs = KERNEL_DS; - - /* - * Replace the client filesystem delete_inode method with our own, - * so that we can clear the object ID before the inode is deleted. - * The fs_delete_inode method will call cl_delete_inode for us. - * We need to do this for the MDS superblock only, hence we install - * a modified copy of the original superblock method table. - * - * We still assume that there is only a single MDS client filesystem - * type, as we don't have access to the mds struct in delete_inode - * and store the client delete_inode method in a global table. This - * will only become a problem if/when multiple MDSs are running on a - * single host with different underlying filesystems. - */ - OBD_ALLOC(mds->mds_sop, sizeof(*mds->mds_sop)); - if (!mds->mds_sop) - RETURN(-ENOMEM); - - memcpy(mds->mds_sop, mds->mds_sb->s_op, sizeof(*mds->mds_sop)); - mds->mds_fsops->cl_delete_inode = mds->mds_sop->delete_inode; - mds->mds_sop->delete_inode = mds->mds_fsops->fs_delete_inode; - mds->mds_sb->s_op = mds->mds_sop; - - rc = mds_fs_prep(mds); - - if (rc) - OBD_FREE(mds->mds_sop, sizeof(*mds->mds_sop)); - - return rc; -} - -void mds_fs_cleanup(struct mds_obd *mds) -{ - mds_client_free_all(mds); - mds_server_free_data(mds); - - OBD_FREE(mds->mds_sop, sizeof(*mds->mds_sop)); -} - -EXPORT_SYMBOL(mds_register_fs_type); -EXPORT_SYMBOL(mds_unregister_fs_type); diff --git a/lustre/obdclass/fsfilt.c b/lustre/obdclass/fsfilt.c deleted file mode 100644 index 97a84df..0000000 --- a/lustre/obdclass/fsfilt.c +++ /dev/null @@ -1,110 +0,0 @@ -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_FILTER - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -LIST_HEAD(fsfilt_types); - -static struct fsfilt_operations *fsfilt_search_type(const char *type) -{ - struct fsfilt_operations *found; - struct list_head *p; - - list_for_each(p, &fsfilt_types) { - found = list_entry(p, struct fsfilt_operations, fs_list); - if (!strcmp(found->fs_type, type)) { - return found; - } - } - return NULL; -} - -int fsfilt_register_ops(struct fsfilt_operations *fs_ops) -{ - struct fsfilt_operations *found; - - /* lock fsfilt_types list */ - if ((found = fsfilt_search_type(fs_ops->fs_type))) { - if (found != fs_ops) { - CERROR("different operations for type %s\n", - fs_ops->fs_type); - /* unlock fsfilt_types list */ - RETURN(-EEXIST); - } - } else { - MOD_INC_USE_COUNT; - list_add(&fs_ops->fs_list, &fsfilt_types); - } - - /* unlock fsfilt_types list */ - return 0; -} - -void fsfilt_unregister_ops(struct fsfilt_operations *fs_ops) -{ - struct list_head *p; - - /* lock fsfilt_types list */ - list_for_each(p, &fsfilt_types) { - struct fsfilt_operations *found; - - found = list_entry(p, typeof(*found), fs_list); - if (found == fs_ops) { - list_del(p); - MOD_DEC_USE_COUNT; - break; - } - } - /* unlock fsfilt_types list */ -} - -struct fsfilt_operations *fsfilt_get_ops(char *type) -{ - struct fsfilt_operations *fs_ops; - - /* lock fsfilt_types list */ - if (!(fs_ops = fsfilt_search_type(type))) { - char name[32]; - int rc; - - snprintf(name, sizeof(name) - 1, "fsfilt_%s", type); - name[sizeof(name) - 1] = '\0'; - - if ((rc = request_module(name))) { - fs_ops = fsfilt_search_type(type); - CDEBUG(D_INFO, "Loaded module '%s'\n", name); - if (!fs_ops) - rc = -ENOENT; - } - - if (rc) { - CERROR("Can't find fsfilt_%s interface\n", name); - RETURN(ERR_PTR(rc)); - /* unlock fsfilt_types list */ - } - } - __MOD_INC_USE_COUNT(fs_ops->fs_owner); - /* unlock fsfilt_types list */ - - return fs_ops; -} - -void fsfilt_put_ops(struct fsfilt_operations *fs_ops) -{ - __MOD_DEC_USE_COUNT(fs_ops->fs_owner); -} - - -EXPORT_SYMBOL(fsfilt_register_ops); -EXPORT_SYMBOL(fsfilt_unregister_ops); -EXPORT_SYMBOL(fsfilt_get_ops); -EXPORT_SYMBOL(fsfilt_put_ops); diff --git a/lustre/obdclass/fsfilt_ext3.c b/lustre/obdclass/fsfilt_ext3.c deleted file mode 100644 index 3878315..0000000 --- a/lustre/obdclass/fsfilt_ext3.c +++ /dev/null @@ -1,327 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/lib/fsfilt_ext3.c - * Lustre filesystem abstraction routines - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Andreas Dilger - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define DEBUG_SUBSYSTEM S_FILTER - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static kmem_cache_t *fcb_cache; -static int fcb_cache_count; - -struct fsfilt_cb_data { - struct journal_callback cb_jcb; /* data private to jbd */ - fsfilt_cb_t cb_func; /* MDS/OBD completion function */ - struct obd_device *cb_obd; /* MDS/OBD completion device */ - __u64 cb_last_rcvd; /* MDS/OST last committed operation */ -}; - -#define EXT3_XATTR_INDEX_LUSTRE 5 -#define XATTR_LUSTRE_MDS_OBJID "system.lustre_mds_objid" - -/* - * We don't currently need any additional blocks for rmdir and - * unlink transactions because we are storing the OST oa_id inside - * the inode (which we will be changing anyways as part of this - * transaction). - */ -static void *fsfilt_ext3_start(struct inode *inode, int op) -{ - /* For updates to the last recieved file */ - int nblocks = EXT3_DATA_TRANS_BLOCKS; - void *handle; - - switch(op) { - case FSFILT_OP_RMDIR: - case FSFILT_OP_UNLINK: - nblocks += EXT3_DELETE_TRANS_BLOCKS; - break; - case FSFILT_OP_RENAME: - /* We may be modifying two directories */ - nblocks += EXT3_DATA_TRANS_BLOCKS; - case FSFILT_OP_SYMLINK: - /* Possible new block + block bitmap + GDT for long symlink */ - nblocks += 3; - case FSFILT_OP_CREATE: - case FSFILT_OP_MKDIR: - case FSFILT_OP_MKNOD: - /* New inode + block bitmap + GDT for new file */ - nblocks += 3; - case FSFILT_OP_LINK: - /* Change parent directory */ - nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS+EXT3_DATA_TRANS_BLOCKS; - break; - case FSFILT_OP_SETATTR: - /* Setattr on inode */ - nblocks += 1; - break; - default: CERROR("unknown transaction start op %d\n", op); - LBUG(); - } - - lock_kernel(); - handle = journal_start(EXT3_JOURNAL(inode), nblocks); - unlock_kernel(); - - return handle; -} - -static int fsfilt_ext3_commit(struct inode *inode, void *handle) -{ - int rc; - - lock_kernel(); - rc = journal_stop((handle_t *)handle); - unlock_kernel(); - - return rc; -} - -static int fsfilt_ext3_setattr(struct dentry *dentry, void *handle, - struct iattr *iattr) -{ - struct inode *inode = dentry->d_inode; - int rc; - - lock_kernel(); - if (inode->i_op->setattr) - rc = inode->i_op->setattr(dentry, iattr); - else - rc = inode_setattr(inode, iattr); - - unlock_kernel(); - - return rc; -} - -static int fsfilt_ext3_set_md(struct inode *inode, void *handle, - void *lmm, int lmm_size) -{ - int rc; - - down(&inode->i_sem); - lock_kernel(); - rc = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_LUSTRE, - XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size, 0); - unlock_kernel(); - up(&inode->i_sem); - - if (rc) { - CERROR("error adding MD data to inode %lu: rc = %d\n", - inode->i_ino, rc); - if (rc != -ENOSPC) LBUG(); - } - return rc; -} - -static int fsfilt_ext3_get_md(struct inode *inode, void *lmm, int size) -{ - int rc; - - down(&inode->i_sem); - lock_kernel(); - rc = ext3_xattr_get(inode, EXT3_XATTR_INDEX_LUSTRE, - XATTR_LUSTRE_MDS_OBJID, lmm, size); - unlock_kernel(); - up(&inode->i_sem); - - /* This gives us the MD size */ - if (lmm == NULL) - return (rc == -ENODATA) ? 0 : rc; - - if (rc < 0) { - CDEBUG(D_INFO, "error getting EA %s from inode %lu: " - "rc = %d\n", XATTR_LUSTRE_MDS_OBJID, inode->i_ino, rc); - memset(lmm, 0, size); - return (rc == -ENODATA) ? 0 : rc; - } - - return rc; -} - -static ssize_t fsfilt_ext3_readpage(struct file *file, char *buf, size_t count, - loff_t *offset) -{ - struct inode *inode = file->f_dentry->d_inode; - int rc = 0; - - if (S_ISREG(inode->i_mode)) - rc = file->f_op->read(file, buf, count, offset); - else { - struct buffer_head *bh; - - /* FIXME: this assumes the blocksize == count, but the calling - * function will detect this as an error for now */ - bh = ext3_bread(NULL, inode, - *offset >> inode->i_sb->s_blocksize_bits, - 0, &rc); - - if (bh) { - memcpy(buf, bh->b_data, inode->i_blksize); - brelse(bh); - rc = inode->i_blksize; - } - } - - return rc; -} - -static void fsfilt_ext3_cb_func(struct journal_callback *jcb, int error) -{ - struct fsfilt_cb_data *fcb = (struct fsfilt_cb_data *)jcb; - - fcb->cb_func(fcb->cb_obd, fcb->cb_last_rcvd, error); - - kmem_cache_free(fcb_cache, fcb); - --fcb_cache_count; -} - -static int fsfilt_ext3_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func) -{ -#ifdef HAVE_JOURNAL_CALLBACK_STATUS - struct fsfilt_cb_data *fcb; - - fcb = kmem_cache_alloc(fcb_cache, GFP_NOFS); - if (!fcb) - RETURN(-ENOMEM); - - ++fcb_cache_count; - fcb->cb_func = cb_func; - fcb->cb_obd = obd; - fcb->cb_last_rcvd = last_rcvd; - - CDEBUG(D_EXT2, "set callback for last_rcvd: "LPD64"\n", last_rcvd); - lock_kernel(); - /* Note that an "incompatible pointer" warning here is OK for now */ - journal_callback_set(handle, fsfilt_ext3_cb_func, - (struct journal_callback *)fcb); - unlock_kernel(); -#else -#warning "no journal callback kernel patch, faking it..." - static long next = 0; - - if (time_after(jiffies, next)) { - CERROR("no journal callback kernel patch, faking it...\n"); - next = jiffies + 300 * HZ; - } - - cb_func(obd, last_rcvd, 0); -#endif - - return 0; -} - -static int fsfilt_ext3_journal_data(struct file *filp) -{ - struct inode *inode = filp->f_dentry->d_inode; - - EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL; - - return 0; -} - -/* - * We need to hack the return value for the free inode counts because - * the current EA code requires one filesystem block per inode with EAs, - * so it is possible to run out of blocks before we run out of inodes. - * - * This can be removed when the ext3 EA code is fixed. - */ -static int fsfilt_ext3_statfs(struct super_block *sb, struct statfs *sfs) -{ - int rc = vfs_statfs(sb, sfs); - - if (!rc && sfs->f_bfree < sfs->f_ffree) - sfs->f_ffree = sfs->f_bfree; - - return rc; -} - -static struct fsfilt_operations fsfilt_ext3_ops = { - fs_type: "ext3", - fs_owner: THIS_MODULE, - fs_start: fsfilt_ext3_start, - fs_commit: fsfilt_ext3_commit, - fs_setattr: fsfilt_ext3_setattr, - fs_set_md: fsfilt_ext3_set_md, - fs_get_md: fsfilt_ext3_get_md, - fs_readpage: fsfilt_ext3_readpage, - fs_journal_data: fsfilt_ext3_journal_data, - fs_set_last_rcvd: fsfilt_ext3_set_last_rcvd, - fs_statfs: fsfilt_ext3_statfs, -}; - -static int __init fsfilt_ext3_init(void) -{ - int rc; - - //rc = ext3_xattr_register(); - fcb_cache = kmem_cache_create("fsfilt_ext3_fcb", - sizeof(struct fsfilt_cb_data), 0, - 0, NULL, NULL); - if (!fcb_cache) { - CERROR("error allocating fsfilt journal callback cache\n"); - GOTO(out, rc = -ENOMEM); - } - - rc = fsfilt_register_ops(&fsfilt_ext3_fs_ops); - - if (rc) - kmem_cache_destroy(fcb_cache); -out: - return rc; -} - -static void __exit fsfilt_ext3_exit(void) -{ - int rc; - - fsfilt_unregister_ops(&fsfilt_ext3_fs_ops); - rc = kmem_cache_destroy(fcb_cache); - - if (rc || fcb_cache_count) { - CERROR("can't free fsfilt callback cache: count %d, rc = %d\n", - fcb_cache_count, rc); - } - - //rc = ext3_xattr_unregister(); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre ext3 Filesystem Helper v0.1"); -MODULE_LICENSE("GPL"); - -module_init(fsfilt_ext3_init); -module_exit(fsfilt_ext3_exit); diff --git a/lustre/obdclass/fsfilt_extN.c b/lustre/obdclass/fsfilt_extN.c deleted file mode 100644 index 9b5a1f9..0000000 --- a/lustre/obdclass/fsfilt_extN.c +++ /dev/null @@ -1,449 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/lib/fsfilt_extN.c - * Lustre filesystem abstraction routines - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Andreas Dilger - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define DEBUG_SUBSYSTEM S_FILTER - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static kmem_cache_t *fcb_cache; -static int fcb_cache_count; - -struct fsfilt_cb_data { - struct journal_callback cb_jcb; /* data private to jbd */ - fsfilt_cb_t cb_func; /* MDS/OBD completion function */ - struct obd_device *cb_obd; /* MDS/OBD completion device */ - __u64 cb_last_rcvd; /* MDS/OST last committed operation */ -}; - -#define EXTN_XATTR_INDEX_LUSTRE 5 -#define XATTR_LUSTRE_MDS_OBJID "system.lustre_mds_objid" - -/* - * We don't currently need any additional blocks for rmdir and - * unlink transactions because we are storing the OST oa_id inside - * the inode (which we will be changing anyways as part of this - * transaction). - */ -static void *fsfilt_extN_start(struct inode *inode, int op) -{ - /* For updates to the last recieved file */ - int nblocks = EXTN_DATA_TRANS_BLOCKS; - void *handle; - - switch(op) { - case FSFILT_OP_RMDIR: - case FSFILT_OP_UNLINK: - nblocks += EXTN_DELETE_TRANS_BLOCKS; - break; - case FSFILT_OP_RENAME: - /* modify additional directory */ - nblocks += EXTN_DATA_TRANS_BLOCKS; - /* no break */ - case FSFILT_OP_SYMLINK: - /* additional block + block bitmap + GDT for long symlink */ - nblocks += 3; - /* no break */ - case FSFILT_OP_CREATE: - case FSFILT_OP_MKDIR: - case FSFILT_OP_MKNOD: - /* modify one inode + block bitmap + GDT */ - nblocks += 3; - /* no break */ - case FSFILT_OP_LINK: - /* modify parent directory */ - nblocks += EXTN_INDEX_EXTRA_TRANS_BLOCKS+EXTN_DATA_TRANS_BLOCKS; - break; - case FSFILT_OP_SETATTR: - /* Setattr on inode */ - nblocks += 1; - break; - default: CERROR("unknown transaction start op %d\n", op); - LBUG(); - } - - LASSERT(!current->journal_info); - lock_kernel(); - handle = journal_start(EXTN_JOURNAL(inode), nblocks); - unlock_kernel(); - - return handle; -} - -/* - * Calculate the number of buffer credits needed to write multiple pages in - * a single extN transaction. No, this shouldn't be here, but as yet extN - * doesn't have a nice API for calculating this sort of thing in advance. - * - * See comment above extN_writepage_trans_blocks for details. We assume - * no data journaling is being done, but it does allow for all of the pages - * being non-contiguous. If we are guaranteed contiguous pages we could - * reduce the number of (d)indirect blocks a lot. - * - * With N blocks per page and P pages, for each inode we have at most: - * N*P indirect - * min(N*P, blocksize/4 + 1) dindirect blocks - * niocount tindirect - * - * For the entire filesystem, we have at most: - * min(sum(nindir + P), ngroups) bitmap blocks (from the above) - * min(sum(nindir + P), gdblocks) group descriptor blocks (from the above) - * objcount inode blocks - * 1 superblock - * 2 * EXTN_SINGLEDATA_TRANS_BLOCKS for the quota files - */ -static int fsfilt_extN_credits_needed(int objcount, struct fsfilt_objinfo *fso) -{ - struct super_block *sb = fso->fso_dentry->d_inode->i_sb; - int blockpp = 1 << (PAGE_CACHE_SHIFT - sb->s_blocksize_bits); - int addrpp = EXTN_ADDR_PER_BLOCK(sb) * blockpp; - int nbitmaps = 0; - int ngdblocks = 0; - int needed = objcount + 1; - int i; - - for (i = 0; i < objcount; i++, fso++) { - int nblocks = fso->fso_bufcnt * blockpp; - int ndindirect = min(nblocks, addrpp + 1); - int nindir = nblocks + ndindirect + 1; - - nbitmaps += nindir + nblocks; - ngdblocks += nindir + nblocks; - - needed += nindir; - } - - /* Assumes extN and extN have same sb_info layout at the start. */ - if (nbitmaps > EXTN_SB(sb)->s_groups_count) - nbitmaps = EXTN_SB(sb)->s_groups_count; - if (ngdblocks > EXTN_SB(sb)->s_gdb_count) - ngdblocks = EXTN_SB(sb)->s_gdb_count; - - needed += nbitmaps + ngdblocks; - -#ifdef CONFIG_QUOTA - /* We assume that there will be 1 bit set in s_dquot.flags for each - * quota file that is active. This is at least true for now. - */ - needed += hweight32(sb_any_quota_enabled(sb)) * - EXTN_SINGLEDATA_TRANS_BLOCKS; -#endif - - return needed; -} - -/* We have to start a huge journal transaction here to hold all of the - * metadata for the pages being written here. This is necessitated by - * the fact that we do lots of prepare_write operations before we do - * any of the matching commit_write operations, so even if we split - * up to use "smaller" transactions none of them could complete until - * all of them were opened. By having a single journal transaction, - * we eliminate duplicate reservations for common blocks like the - * superblock and group descriptors or bitmaps. - * - * We will start the transaction here, but each prepare_write will - * add a refcount to the transaction, and each commit_write will - * remove a refcount. The transaction will be closed when all of - * the pages have been written. - */ -static void *fsfilt_extN_brw_start(int objcount, struct fsfilt_objinfo *fso, - int niocount, struct niobuf_remote *nb) -{ - journal_t *journal; - handle_t *handle; - int needed; - ENTRY; - - LASSERT(!current->journal_info); - journal = EXTN_SB(fso->fso_dentry->d_inode->i_sb)->s_journal; - needed = fsfilt_extN_credits_needed(objcount, fso); - - /* The number of blocks we could _possibly_ dirty can very large. - * We reduce our request if it is absurd (and we couldn't get that - * many credits for a single handle anyways). - * - * At some point we have to limit the size of I/Os sent at one time, - * increase the size of the journal, or we have to calculate the - * actual journal requirements more carefully by checking all of - * the blocks instead of being maximally pessimistic. It remains to - * be seen if this is a real problem or not. - */ - if (needed > journal->j_max_transaction_buffers) { - CERROR("want too many journal credits (%d) using %d instead\n", - needed, journal->j_max_transaction_buffers); - needed = journal->j_max_transaction_buffers; - } - - lock_kernel(); - handle = journal_start(journal, needed); - unlock_kernel(); - if (IS_ERR(handle)) - CERROR("can't get handle for %d credits: rc = %ld\n", needed, - PTR_ERR(handle)); - - RETURN(handle); -} - -static int fsfilt_extN_commit(struct inode *inode, void *handle) -{ - int rc; - - lock_kernel(); - rc = journal_stop((handle_t *)handle); - unlock_kernel(); - - return rc; -} - -static int fsfilt_extN_setattr(struct dentry *dentry, void *handle, - struct iattr *iattr) -{ - struct inode *inode = dentry->d_inode; - int rc; - - lock_kernel(); - if (inode->i_op->setattr) - rc = inode->i_op->setattr(dentry, iattr); - else - rc = inode_setattr(inode, iattr); - - unlock_kernel(); - - return rc; -} - -static int fsfilt_extN_set_md(struct inode *inode, void *handle, - void *lmm, int lmm_size) -{ - int rc; - - down(&inode->i_sem); - lock_kernel(); - rc = extN_xattr_set(handle, inode, EXTN_XATTR_INDEX_LUSTRE, - XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size, 0); - unlock_kernel(); - up(&inode->i_sem); - - if (rc) { - CERROR("error adding MD data to inode %lu: rc = %d\n", - inode->i_ino, rc); - if (rc != -ENOSPC) LBUG(); - } - return rc; -} - -static int fsfilt_extN_get_md(struct inode *inode, void *lmm, int size) -{ - int rc; - - down(&inode->i_sem); - lock_kernel(); - rc = extN_xattr_get(inode, EXTN_XATTR_INDEX_LUSTRE, - XATTR_LUSTRE_MDS_OBJID, lmm, size); - unlock_kernel(); - up(&inode->i_sem); - - /* This gives us the MD size */ - if (lmm == NULL) - return (rc == -ENODATA) ? 0 : rc; - - if (rc < 0) { - CDEBUG(D_INFO, "error getting EA %s from inode %lu: " - "rc = %d\n", XATTR_LUSTRE_MDS_OBJID, inode->i_ino, rc); - memset(lmm, 0, size); - return (rc == -ENODATA) ? 0 : rc; - } - - return rc; -} - -static ssize_t fsfilt_extN_readpage(struct file *file, char *buf, size_t count, - loff_t *offset) -{ - struct inode *inode = file->f_dentry->d_inode; - int rc = 0; - - if (S_ISREG(inode->i_mode)) - rc = file->f_op->read(file, buf, count, offset); - else { - struct buffer_head *bh; - - /* FIXME: this assumes the blocksize == count, but the calling - * function will detect this as an error for now */ - bh = extN_bread(NULL, inode, - *offset >> inode->i_sb->s_blocksize_bits, - 0, &rc); - - if (bh) { - memcpy(buf, bh->b_data, inode->i_blksize); - brelse(bh); - rc = inode->i_blksize; - } - } - - return rc; -} - -static void fsfilt_extN_cb_func(struct journal_callback *jcb, int error) -{ - struct fsfilt_cb_data *fcb = (struct fsfilt_cb_data *)jcb; - - fcb->cb_func(fcb->cb_obd, fcb->cb_last_rcvd, error); - - kmem_cache_free(fcb_cache, fcb); - --fcb_cache_count; -} - -static int fsfilt_extN_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func) -{ -#ifdef HAVE_JOURNAL_CALLBACK_STATUS - struct fsfilt_cb_data *fcb; - - fcb = kmem_cache_alloc(fcb_cache, GFP_NOFS); - if (!fcb) - RETURN(-ENOMEM); - - ++fcb_cache_count; - fcb->cb_func = cb_func; - fcb->cb_obd = obd; - fcb->cb_last_rcvd = last_rcvd; - - CDEBUG(D_EXT2, "set callback for last_rcvd: "LPD64"\n", last_rcvd); - lock_kernel(); - /* Note that an "incompatible pointer" warning here is OK for now */ - journal_callback_set(handle, fsfilt_extN_cb_func, - (struct journal_callback *)fcb); - unlock_kernel(); -#else -#warning "no journal callback kernel patch, faking it..." - static long next = 0; - - if (time_after(jiffies, next)) { - CERROR("no journal callback kernel patch, faking it...\n"); - next = jiffies + 300 * HZ; - } - - cb_func(obd, last_rcvd, 0); -#endif - - return 0; -} - -static int fsfilt_extN_journal_data(struct file *filp) -{ - struct inode *inode = filp->f_dentry->d_inode; - - EXTN_I(inode)->i_flags |= EXTN_JOURNAL_DATA_FL; - - return 0; -} - -/* - * We need to hack the return value for the free inode counts because - * the current EA code requires one filesystem block per inode with EAs, - * so it is possible to run out of blocks before we run out of inodes. - * - * This can be removed when the extN EA code is fixed. - */ -static int fsfilt_extN_statfs(struct super_block *sb, struct obd_statfs *osfs) -{ - struct statfs sfs; - int rc = vfs_statfs(sb, &sfs); - - if (!rc && sfs.f_bfree < sfs.f_ffree) - sfs.f_ffree = sfs.f_bfree; - - statfs_pack(osfs, &sfs); - return rc; -} - -static struct fsfilt_operations fsfilt_extN_ops = { - fs_type: "extN", - fs_owner: THIS_MODULE, - fs_start: fsfilt_extN_start, - fs_brw_start: fsfilt_extN_brw_start, - fs_commit: fsfilt_extN_commit, - fs_setattr: fsfilt_extN_setattr, - fs_set_md: fsfilt_extN_set_md, - fs_get_md: fsfilt_extN_get_md, - fs_readpage: fsfilt_extN_readpage, - fs_journal_data: fsfilt_extN_journal_data, - fs_set_last_rcvd: fsfilt_extN_set_last_rcvd, - fs_statfs: fsfilt_extN_statfs, -}; - -static int __init fsfilt_extN_init(void) -{ - int rc; - - //rc = extN_xattr_register(); - fcb_cache = kmem_cache_create("fsfilt_extN_fcb", - sizeof(struct fsfilt_cb_data), 0, - 0, NULL, NULL); - if (!fcb_cache) { - CERROR("error allocating fsfilt journal callback cache\n"); - GOTO(out, rc = -ENOMEM); - } - - rc = fsfilt_register_ops(&fsfilt_extN_ops); - - if (rc) - kmem_cache_destroy(fcb_cache); -out: - return rc; -} - -static void __exit fsfilt_extN_exit(void) -{ - int rc; - - fsfilt_unregister_ops(&fsfilt_extN_ops); - rc = kmem_cache_destroy(fcb_cache); - - if (rc || fcb_cache_count) { - CERROR("can't free fsfilt callback cache: count %d, rc = %d\n", - fcb_cache_count, rc); - } - - //rc = extN_xattr_unregister(); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre extN Filesystem Helper v0.1"); -MODULE_LICENSE("GPL"); - -module_init(fsfilt_extN_init); -module_exit(fsfilt_extN_exit); diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c deleted file mode 100644 index ea2b9c4..0000000 --- a/lustre/obdclass/lprocfs_status.c +++ /dev/null @@ -1,360 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#define EXPORT_SYMTAB -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_CLASS -#define MAX_STRING_SIZE 100 - -#include -#include - -#ifdef LPROC_SNMP - -#define DEFAULT_MODE 0444 -/* - * Tokenizer array. Change this array to include special - * characters for string tokenizing - */ -char tok[] = {'/', (char)0}; - - - -/* - * Externs - */ -extern struct proc_dir_entry proc_root; /* Defined in proc/root.c */ - -/* - * Globals - */ -struct proc_dir_entry *proc_lustre_root = 0; -struct proc_dir_entry *proc_lustre_dev_root = 0; -struct proc_dir_entry *proc_lustre_fs_root=0; - -struct proc_dir_entry* lprocfs_mkdir(const char* dname, - struct proc_dir_entry *parent) -{ - struct proc_dir_entry *child_dir_entry; - - child_dir_entry = proc_mkdir(dname, parent); - - if (!child_dir_entry) - CERROR("lustre: failed to create /proc entry %s\n", dname); - - return child_dir_entry; -} -struct proc_dir_entry* lprocfs_srch(struct proc_dir_entry* head, - const char* name) -{ - struct proc_dir_entry* temp; - - if (!head) - return 0; - temp = head->subdir; - while (temp != NULL) { - if (!strcmp(temp->name, name)) - return temp; - temp = temp->next; - } - - return 0; -} - - -void lprocfs_remove_all(struct proc_dir_entry* root) -{ - - struct proc_dir_entry *temp=root; - struct proc_dir_entry* rm_entry; - - while(1){ - - while(temp->subdir){ - temp=temp->subdir; - } - rm_entry=temp; - temp=temp->parent; - remove_proc_entry(rm_entry->name, rm_entry->parent); - if(temp==root->parent) break; - - } - - -} - -struct proc_dir_entry* lprocfs_new_dir(struct proc_dir_entry* root, - const char* string, - const char* tok) -{ - struct proc_dir_entry* new_root = 0; - struct proc_dir_entry* temp_entry = 0; - - char temp_string[MAX_STRING_SIZE]; - char* my_str; - char* mover_str; - - /* - * Remove trailing escaping character - */ - memset(temp_string, 0, MAX_STRING_SIZE); - if (strlen(string) >= MAX_STRING_SIZE) { - CDEBUG(D_OTHER, "Directory namespace too long"); - return 0; - } - - strcpy(temp_string, string); - temp_string[strlen(string) + 1] = '\0'; - - new_root=root; - mover_str=temp_string; - while ((my_str = strsep(&mover_str, tok))) { - if(!*my_str) - continue; - CDEBUG(D_OTHER, "SEARCH= %s\t, ROOT=%s\n", my_str, - new_root->name); - temp_entry = lprocfs_srch(new_root, my_str); - if (temp_entry == 0) { - CDEBUG(D_OTHER, "Adding: %s\n", my_str); - temp_entry = lprocfs_mkdir(my_str, new_root); - if (temp_entry == 0) { - CDEBUG(D_OTHER, - "! Did not create new dir %s !!\n", - my_str); - return 0; - } - } - new_root = temp_entry; - } - - return new_root; -} - -int lprocfs_new_vars(struct proc_dir_entry* root, - lprocfs_vars_t* list, - const char* tok, - void* data) -{ - struct proc_dir_entry* temp_root=0; - struct proc_dir_entry* new_leaf=0; - struct proc_dir_entry* new_parent=0; - char temp_string[MAX_STRING_SIZE]; - - if(!list) - return 0; - - while(list->name){ - temp_root=lprocfs_new_dir(root, list->name, tok); - - if(!temp_root){ - CDEBUG(D_OTHER, "!LProcFS: Mods: No root!"); - return -EINVAL; - } - /* Convert the last element into a leaf-node */ - memset(temp_string, 0, MAX_STRING_SIZE); - strcpy(temp_string, temp_root->name); - temp_string[strlen(temp_root->name) + 1] = '\0'; - new_parent=temp_root->parent; - if (new_parent != 0){ - remove_proc_entry(temp_root->name, new_parent); - } else { - remove_proc_entry(temp_root->name, NULL); - } - new_leaf = create_proc_entry(temp_string, DEFAULT_MODE, - new_parent); - new_leaf->read_proc = list->read_fptr; - new_leaf->write_proc = list->write_fptr; - new_leaf->data=data; - list++; - } - return 0; - -} - -/* - * API implementations - */ - -int lprocfs_add_vars(struct proc_dir_entry* root, - lprocfs_vars_t* var, - void* data) -{ - - return lprocfs_new_vars(root, var, - (const char*) tok, data); - - -} - -int lprocfs_reg_obd(struct obd_device* device, - lprocfs_vars_t* list, - void* data) -{ - - int retval = 0; - struct proc_dir_entry* this_dev_root=0; - - /* Obtain this device root */ - this_dev_root = lprocfs_mkdir(device->obd_name, - device->obd_type->typ_procroot); - - device->obd_proc_entry=this_dev_root; - retval=lprocfs_add_vars(this_dev_root, list, - data); - - return retval; -} - -int lprocfs_dereg_obd(struct obd_device* device) -{ - - CDEBUG(D_OTHER, "LPROCFS removing device = %s\n", device->obd_name); - - if (!device) { - CDEBUG(D_OTHER, "! LProcfs: Null pointer !\n"); - return 0; - } - - lprocfs_remove_all(device->obd_proc_entry); - - if (device->counters) - OBD_FREE(device->counters, device->cntr_mem_size); - - return 0; -} - -struct proc_dir_entry* lprocfs_reg_mnt(char* mnt_name) -{ - return lprocfs_mkdir(mnt_name, proc_lustre_fs_root); - -} - -int lprocfs_dereg_mnt(struct proc_dir_entry* root) -{ - lprocfs_remove_all(root); - return 0; - -} - -int lprocfs_reg_class(struct obd_type* type, - lprocfs_vars_t* list, - void* data) -{ - struct proc_dir_entry* root; - int retval; - - root=lprocfs_mkdir(type->typ_name, proc_lustre_dev_root); - - type->typ_procroot=root; - - retval=lprocfs_add_vars(root, list, data); - - return retval; -} - -int lprocfs_dereg_class(struct obd_type* class) -{ - if(!class){ - CDEBUG(D_OTHER, "Non-existent class", - class->typ_name); - return 0; - } - - lprocfs_remove_all(class->typ_procroot); - - CDEBUG(D_OTHER, "LPROCFS removed = %s\n", class->typ_name); - - return 0; - -} -int lprocfs_reg_main() -{ - proc_lustre_root = lprocfs_mkdir("lustre", &proc_root); - if (!proc_lustre_root) { - CERROR(" !! Cannot create /proc/lustre !! \n"); - return -EINVAL; - } - - proc_lustre_dev_root =lprocfs_mkdir("devices", proc_lustre_root); - - if (!proc_lustre_dev_root) { - CERROR(" !! Cannot create /proc/lustre/devices !! \n"); - return -EINVAL; - } - proc_lustre_fs_root=lprocfs_mkdir("mnt_pnt", proc_lustre_root); - - if (!proc_lustre_fs_root) { - CERROR(" !! Cannot create /proc/lustre/mnt_pnt !! \n"); - return -EINVAL; - } - - return 0; - -} - -int lprocfs_dereg_main() -{ - lprocfs_remove_all(proc_lustre_root); - proc_lustre_root=0; - proc_lustre_dev_root=0; - proc_lustre_fs_root=0; - return 0; - -} - - -/* - * Needs to go... - */ - -int lprocfs_ll_rd(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - __u64 *temp = (__u64 *)data; - int len; - - len = snprintf(page, count, LPU64"\n", *temp); - - return len; -} - -#endif /* LPROC_SNMP */ - - -EXPORT_SYMBOL(lprocfs_reg_obd); -EXPORT_SYMBOL(lprocfs_dereg_obd); -EXPORT_SYMBOL(lprocfs_reg_main); -EXPORT_SYMBOL(lprocfs_dereg_main); -EXPORT_SYMBOL(lprocfs_reg_mnt); -EXPORT_SYMBOL(lprocfs_dereg_mnt); -EXPORT_SYMBOL(lprocfs_add_vars); -EXPORT_SYMBOL(lprocfs_reg_class); -EXPORT_SYMBOL(lprocfs_dereg_class); -EXPORT_SYMBOL(lprocfs_ll_rd); - - diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c deleted file mode 100644 index 524e779..0000000 --- a/lustre/obdecho/echo_client.c +++ /dev/null @@ -1,262 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2001, 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_ECHO - -#include -#include -#include -#include -#include - -static int echo_iocontrol(long cmd, struct lustre_handle *obdconn, int len, - void *karg, void *uarg) -{ - struct obd_device *obd = class_conn2obd(obdconn); - struct echo_client_obd *ec = &obd->u.echo_client; - struct obd_ioctl_data *data = karg; - int rw = OBD_BRW_READ, rc = 0; - ENTRY; - - if (obd == NULL) { - CERROR("ioctl: No device\n"); - GOTO(out, rc = -EINVAL); - } - - switch (cmd) { - case OBD_IOC_CREATE: { - struct lov_stripe_md *lsm = NULL; -#warning FIXME: save lsm into file handle for other ops, release on close - rc = obd_create(&ec->conn, &data->ioc_obdo1, &lsm); - GOTO(out, rc); - } - - case OBD_IOC_GETATTR: - rc = obd_getattr(&ec->conn, &data->ioc_obdo1, NULL); - GOTO(out, rc); - - case OBD_IOC_SETATTR: - rc = obd_setattr(&ec->conn, &data->ioc_obdo1, NULL); - GOTO(out, rc); - - case OBD_IOC_DESTROY: { - //void *ea; - rc = obd_destroy(&ec->conn, &data->ioc_obdo1, NULL); - GOTO(out, rc); - } - - case OBD_IOC_OPEN: { - struct lov_stripe_md *lsm = NULL; // XXX fill in from create - - rc = obd_open(&ec->conn, &data->ioc_obdo1, lsm); - GOTO(out, rc); - } - - case OBD_IOC_CLOSE: { - struct lov_stripe_md *lsm = NULL; // XXX fill in from create - - rc = obd_close(&ec->conn, &data->ioc_obdo1, lsm); - GOTO(out, rc); - } - - case OBD_IOC_BRW_WRITE: - rw = OBD_BRW_WRITE; - case OBD_IOC_BRW_READ: { - struct lov_stripe_md tmp_lsm; // XXX fill in from create - struct lov_stripe_md *lsm = &tmp_lsm; // XXX fill in from create - struct obd_brw_set *set; - obd_count pages = 0; - struct brw_page *pga, *pgp; - __u64 id = data->ioc_obdo1.o_id; - int gfp_mask = (id & 1) ? GFP_HIGHUSER : GFP_KERNEL; - int verify = (id != 0); - __u64 off; - int j; - - set = obd_brw_set_new(); - if (set == NULL) - GOTO(out, rc = -ENOMEM); - - pages = data->ioc_count / PAGE_SIZE; - off = data->ioc_offset; - - CDEBUG(D_INODE, "BRW %s with %d pages @ "LPX64"\n", - rw == OBD_BRW_READ ? "read" : "write", pages, off); - OBD_ALLOC(pga, pages * sizeof(*pga)); - if (!pga) { - CERROR("no memory for %d BRW per-page data\n", pages); - GOTO(brw_free, rc = -ENOMEM); - } - - memset(lsm, 0, sizeof(*lsm)); // XXX don't do this later - lsm->lsm_object_id = id; // ensure id == lsm->lsm_object_id - - for (j = 0, pgp = pga; j < pages; j++, off += PAGE_SIZE, pgp++){ - pgp->pg = alloc_pages(gfp_mask, 0); - if (!pgp->pg) { - CERROR("no memory for brw pages\n"); - GOTO(brw_cleanup, rc = -ENOMEM); - } - pgp->count = PAGE_SIZE; - pgp->off = off; - pgp->flag = 0; - - if (verify) { - void *addr = kmap(pgp->pg); - - if (rw == OBD_BRW_WRITE) - page_debug_setup(addr, pgp->count, - pgp->off, id); - else - page_debug_setup(addr, pgp->count, - 0xdeadbeef00c0ffee, - 0xdeadbeef00c0ffee); - kunmap(pgp->pg); - } - } - - set->brw_callback = ll_brw_sync_wait; - rc = obd_brw(rw, &ec->conn, lsm, j, pga, set); - if (rc) - CERROR("test_brw: error from obd_brw: rc = %d\n", rc); - else { - rc = ll_brw_sync_wait(set, CB_PHASE_START); - if (rc) - CERROR("test_brw: error from callback: rc = " - "%d\n", rc); - } - EXIT; - brw_cleanup: - for (j = 0, pgp = pga; j < pages; j++, pgp++) { - if (pgp->pg == NULL) - continue; - - if (verify && !rc) { - void *addr = kmap(pgp->pg); - - rc = page_debug_check("test_brw", addr, - PAGE_SIZE, pgp->off, id); - kunmap(pgp->pg); - } - __free_pages(pgp->pg, 0); - } - brw_free: - obd_brw_set_free(set); - OBD_FREE(pga, pages * sizeof(*pga)); - GOTO(out, rc); - } - default: - return -ENOTTY; - } - - out: - RETURN(rc); -} - -static int echo_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct obd_ioctl_data* data = buf; - struct echo_client_obd *ec = &obddev->u.echo_client; - struct obd_device *tgt; - int rc; - ENTRY; - - if (data->ioc_inllen1 < 1) { - CERROR("requires a TARGET OBD UUID\n"); - RETURN(-EINVAL); - } - if (data->ioc_inllen1 > 37) { - CERROR("OBD UUID must be less than 38 characters\n"); - RETURN(-EINVAL); - } - - MOD_INC_USE_COUNT; - tgt = class_uuid2obd(data->ioc_inlbuf1); - if (!tgt || !(tgt->obd_flags & OBD_ATTACHED) || - !(tgt->obd_flags & OBD_SET_UP)) { - CERROR("device not attached or not set up (%d)\n", - data->ioc_dev); - GOTO(error_dec, rc = -EINVAL); - } - - rc = obd_connect(&ec->conn, tgt, NULL, NULL, NULL); - if (rc) { - CERROR("fail to connect to device %d\n", data->ioc_dev); - GOTO(error_dec, rc = -EINVAL); - } - RETURN(rc); -error_dec: - MOD_DEC_USE_COUNT; - RETURN(rc); -} - -static int echo_cleanup(struct obd_device * obddev) -{ - struct echo_client_obd *ec = &obddev->u.echo_client; - int rc; - ENTRY; - - if (!list_empty(&obddev->obd_exports)) { - CERROR("still has clients!\n"); - RETURN(-EBUSY); - } - - rc = obd_disconnect(&ec->conn); - if (rc) { - CERROR("fail to disconnect device: %d\n", rc); - RETURN(-EINVAL); - } - - MOD_DEC_USE_COUNT; - RETURN(0); -} - -static int echo_connect(struct lustre_handle *conn, struct obd_device *src, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - return class_connect(conn, src, cluuid); -} - -static struct obd_ops echo_obd_ops = { - o_setup: echo_setup, - o_cleanup: echo_cleanup, - o_iocontrol: echo_iocontrol, - o_connect: echo_connect, - o_disconnect: class_disconnect -}; - -int echo_client_init(void) -{ - extern struct lprocfs_vars status_class_var[]; - - return class_register_type(&echo_obd_ops, status_class_var, - OBD_ECHO_CLIENT_DEVICENAME); -} - -void echo_client_cleanup(void) -{ - class_unregister_type(OBD_ECHO_CLIENT_DEVICENAME); -} diff --git a/lustre/obdecho/lproc_echo.c b/lustre/obdecho/lproc_echo.c deleted file mode 100644 index 4592f6b..0000000 --- a/lustre/obdecho/lproc_echo.c +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_ECHO - -#include -#include - - -int rd_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct obd_device* dev=(struct obd_device*)data; - len+=snprintf(page, count, "%s\n", dev->obd_uuid); - return len; - -} - -int rd_fstype(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct obd_device* dev=(struct obd_device*)data; - len+=snprintf(page, count, "%s\n", dev->u.echo.eo_fstype); - return len; - -} - - -lprocfs_vars_t status_var_nm_1[]={ - {"status/uuid", rd_uuid, 0}, - {"status/fstype", rd_fstype, 0}, - {0} -}; - -int rd_numdevices(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_type* class=(struct obd_type*)data; - int len=0; - len+=snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -lprocfs_vars_t status_class_var[]={ - {"status/num_devices", rd_numdevices, 0}, - {0} -}; diff --git a/lustre/obdfilter/lproc_obdfilter.c b/lustre/obdfilter/lproc_obdfilter.c deleted file mode 100644 index ab37589..0000000 --- a/lustre/obdfilter/lproc_obdfilter.c +++ /dev/null @@ -1,151 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#include - - -int rd_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct obd_device* dev=(struct obd_device*)data; - len+=snprintf(page, count, "%s\n", dev->obd_uuid); - return len; - - - -} -int rd_blksize(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct statfs mystats; - - int len=0; - - vfs_statfs(temp->u.filter.fo_sb, &mystats); - - len+=snprintf(page, count, "%ld\n", mystats.f_bsize); - return len; - - -} -int rd_kbtotal(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct statfs mystats; - int len=0; - __u64 result; - - vfs_statfs(temp->u.filter.fo_sb, &mystats); - - result=((__u64)(mystats.f_blocks*mystats.f_bsize))>>10; - - len+=snprintf(page, count, LPU64"\n", result); - - return len; -} - -int rd_kbfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct statfs mystats; - - int len=0; - __u64 result; - - vfs_statfs(temp->u.filter.fo_sb, &mystats); - result=((__u64)(mystats.f_bfree*mystats.f_bsize))>>10; - - len+=snprintf(page, count, LPU64"\n", result); - return len; -} - -int rd_fstype(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - struct obd_device* temp=(struct obd_device*)data; - int len=0; - - len+=snprintf(page, count, "%s\n", temp->u.filter.fo_fstype); - return len; - -} -int rd_files(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - struct obd_device* temp=(struct obd_device*)data; - struct statfs mystats; - - int len=0; - - vfs_statfs(temp->u.filter.fo_sb, &mystats); - - len+=snprintf(page, count, "%ld\n", mystats.f_files); - return len; -} - -int rd_filesfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct statfs mystats; - - int len=0; - - vfs_statfs(temp->u.filter.fo_sb, &mystats); - - len+=snprintf(page, count, "%ld\n", mystats.f_ffree); - return len; - - -} - -lprocfs_vars_t status_var_nm_1[]={ - {"status/uuid", rd_uuid, 0}, - {"status/blocksize",rd_blksize, 0}, - {"status/kbytestotal",rd_kbtotal, 0}, - {"status/kbytesfree", rd_kbfree, 0}, - {"status/files", rd_files, 0}, - {"status/filesfree", rd_filesfree, 0}, - {"status/fstype", rd_fstype, 0}, - {0} -}; -int rd_numdevices(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_type* class=(struct obd_type*)data; - int len=0; - len+=snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -lprocfs_vars_t status_class_var[]={ - {"status/num_devices", rd_numdevices, 0}, - {0} -}; diff --git a/lustre/osc/lproc_osc.c b/lustre/osc/lproc_osc.c deleted file mode 100644 index 0ee8873..0000000 --- a/lustre/osc/lproc_osc.c +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#include - -int rd_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - struct obd_device* dev=(struct obd_device*)data; - len+=snprintf(page, count, "%s\n", dev->obd_uuid); - return len; - -} -int rd_blksize(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} -int rd_blktotal(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_blkfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_kbfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_numobjects(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_objfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int rd_objgroups(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} -int rd_server_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - struct obd_device* temp=(struct obd_device*)data; - struct client_obd* cli=&temp->u.cli; - int len=0; - len+=snprintf(page, count, "%s\n",cli->cl_target_uuid); - return len; - - -} -int rd_conn_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct client_obd* cli=&temp->u.cli; - struct obd_import* imp=&cli->cl_import; - int len=0; - len+=snprintf(page, count, "%s\n",\ - imp->imp_connection->c_remote_uuid); - return len; - -} - -lprocfs_vars_t status_var_nm_1[]={ - {"status/uuid", rd_uuid, 0}, - {"status/f_blocksize",rd_blksize, 0}, - {"status/f_blockstotal",rd_blktotal, 0}, - {"status/f_blocksfree",rd_blkfree, 0}, - {"status/f_kbytesfree", rd_kbfree, 0}, - {"status/f_objects", rd_numobjects, 0}, - {"status/f_objectsfree", rd_objfree, 0}, - {"status/f_objectgroups", rd_objgroups, 0}, - {"status/ost_server_uuid", rd_server_uuid, 0}, - {"status/ost_conn_uuid", rd_conn_uuid, 0}, - {0} -}; -int rd_numdevices(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_type* class=(struct obd_type*)data; - int len=0; - len+=snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -lprocfs_vars_t status_class_var[]={ - {"status/num_devices", rd_numdevices, 0}, - {0} -}; diff --git a/lustre/ost/lproc_ost.c b/lustre/ost/lproc_ost.c deleted file mode 100644 index 8878ad0..0000000 --- a/lustre/ost/lproc_ost.c +++ /dev/null @@ -1,174 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_OST - -#include -#include - - -int rd_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - struct obd_device* temp=(struct obd_device*)data; - int len=0; - len+=snprintf(page, count, "%s\n", temp->obd_uuid); - return len; - - -} -int rd_blksize(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - struct obd_device* temp=(struct obd_device*)data; - struct ost_obd *ost=&temp->u.ost; - struct lustre_handle *conn=&ost->ost_conn; - struct obd_statfs mystats; - int len=0; - - obd_statfs(conn, &mystats); - len+=snprintf(page, count, "%d\n", mystats.os_bsize); - return len; - -} -int rd_kbtotal(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device* temp=(struct obd_device*)data; - struct ost_obd *ost=&temp->u.ost; - struct lustre_handle *conn=&ost->ost_conn; - struct obd_statfs mystats; - int len=0; - __u32 blk_size; - __u64 result; - - - obd_statfs(conn, &mystats); - - blk_size=mystats.os_bsize; - blk_size>>=10; - - result=mystats.os_blocks; - - while(blk_size>>=1){ - result<<=1; - } - - len+=snprintf(page, count, LPU64"\n", result); - return len; - - -} - - -int rd_kbfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - struct obd_device* temp=(struct obd_device*)data; - struct ost_obd *ost=&temp->u.ost; - struct lustre_handle *conn=&ost->ost_conn; - struct obd_statfs mystats; - int len=0; - __u32 blk_size; - __u64 result; - - obd_statfs(conn, &mystats); - - blk_size=mystats.os_bsize; - blk_size>>=10; - - result=mystats.os_bfree; - - while(blk_size>>=1){ - result<<=1; - } - - len+=snprintf(page, count, LPU64"\n", result); - return len; - -} - -int rd_files(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - struct obd_device* temp=(struct obd_device*)data; - struct ost_obd *ost=&temp->u.ost; - struct lustre_handle *conn=&ost->ost_conn; - struct obd_statfs mystats; - int len=0; - - obd_statfs(conn, &mystats); - - len+=snprintf(page, count, LPU64"\n",mystats.os_files); - return len; - -} - -int rd_filesfree(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - - struct obd_device* temp=(struct obd_device*)data; - struct ost_obd *ost=&temp->u.ost; - struct lustre_handle *conn=&ost->ost_conn; - struct obd_statfs mystats; - int len=0; - - obd_statfs(conn, &mystats); - len+=snprintf(page, count, LPU64"\n", mystats.os_ffree); - return len; - -} - -int rd_objgroups(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -lprocfs_vars_t status_var_nm_1[]={ - {"status/uuid", rd_uuid, 0}, - {"status/blocksize",rd_blksize, 0}, - {"status/kbytesfree", rd_kbfree, 0}, - {"status/kbytestotal", rd_kbtotal, 0}, - {"status/files", rd_files, 0}, - {"status/filesfree", rd_filesfree, 0}, - {"status/objectgroups", rd_objgroups, 0}, - {0} -}; - -int rd_numdevices(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_type* class=(struct obd_type*)data; - int len=0; - len+=snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -lprocfs_vars_t status_class_var[]={ - {"status/num_devices", rd_numdevices, 0}, - {0} -}; diff --git a/lustre/patches/patch-2.4.18-chaos11 b/lustre/patches/patch-2.4.18-chaos11 deleted file mode 100644 index dd15a36..0000000 --- a/lustre/patches/patch-2.4.18-chaos11 +++ /dev/null @@ -1,1498 +0,0 @@ ---- linux-2.4.18-chaos5-pristine/drivers/block/blkpg.c Sat Jun 29 23:07:36 2002 -+++ linux-2.4.18-chaos5/drivers/block/blkpg.c Sat Jun 29 23:09:04 2002 -@@ -295,3 +295,38 @@ - } - - EXPORT_SYMBOL(blk_ioctl); -+ -+#define NUM_DEV_NO_WRITE 16 -+static int dev_no_write[NUM_DEV_NO_WRITE]; -+ -+/* -+ * Debug code for turning block devices "read-only" (will discard writes -+ * silently). This is for filesystem crash/recovery testing. -+ */ -+void dev_set_rdonly(kdev_t dev, int no_write) -+{ -+ if (dev) { -+ printk(KERN_WARNING "Turning device %s read-only\n", -+ bdevname(dev)); -+ dev_no_write[no_write] = 0xdead0000 + dev; -+ } -+} -+ -+int dev_check_rdonly(kdev_t dev) { -+ int i; -+ -+ for (i = 0; i < NUM_DEV_NO_WRITE; i++) { -+ if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 && -+ dev == (dev_no_write[i] & 0xffff)) -+ return 1; -+ } -+ return 0; -+} -+ -+void dev_clear_rdonly(int no_write) { -+ dev_no_write[no_write] = 0; -+} -+ -+EXPORT_SYMBOL(dev_set_rdonly); -+EXPORT_SYMBOL(dev_check_rdonly); -+EXPORT_SYMBOL(dev_clear_rdonly); ---- linux-2.4.18-chaos5-pristine/drivers/block/loop.c Sat Jun 29 23:07:36 2002 -+++ linux-2.4.18-chaos5/drivers/block/loop.c Sat Jun 29 23:09:04 2002 -@@ -503,6 +503,11 @@ - spin_unlock_irq(&lo->lo_lock); - - if (rw == WRITE) { -+#ifdef CONFIG_DEV_RDONLY -+ if (dev_check_rdonly(rbh->b_rdev)) -+ goto err; -+#endif -+ - if (lo->lo_flags & LO_FLAGS_READ_ONLY) - goto err; - } else if (rw == READA) { ---- linux-2.4.18-chaos5-pristine/drivers/ide/ide-disk.c Sat Jun 29 23:07:36 2002 -+++ linux-2.4.18-chaos5/drivers/ide/ide-disk.c Sat Jun 29 23:09:04 2002 -@@ -557,6 +557,12 @@ - */ - static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) - { -+#ifdef CONFIG_DEV_RDONLY -+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { -+ ide_end_request(1, HWGROUP(drive)); -+ return ide_stopped; -+ } -+#endif - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl,IDE_CONTROL_REG); - ---- linux-2.4.18-chaos5-pristine/fs/ext3/Makefile Sat Jun 29 23:07:56 2002 -+++ linux-2.4.18-chaos5/fs/ext3/Makefile Sat Jun 29 23:09:04 2002 -@@ -9,6 +9,8 @@ - - O_TARGET := ext3.o - -+export-objs := super.o -+ - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o - obj-m := $(O_TARGET) ---- linux-2.4.18-chaos5-pristine/fs/ext3/super.c Sat Jun 29 23:07:56 2002 -+++ linux-2.4.18-chaos5/fs/ext3/super.c Sat Jun 29 23:09:04 2002 -@@ -1746,7 +1746,7 @@ - unregister_filesystem(&ext3_fs_type); - } - --EXPORT_NO_SYMBOLS; -+EXPORT_SYMBOL(ext3_bread); - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); - MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); ---- linux-2.4.18-chaos5-pristine/fs/jbd/commit.c Sat Jun 29 23:07:56 2002 -+++ linux-2.4.18-chaos5/fs/jbd/commit.c Sat Jun 29 23:09:04 2002 -@@ -482,7 +482,7 @@ - transaction's t_log_list queue, and metadata buffers are on - the t_iobuf_list queue. - -- Wait for the transactions in reverse order. That way we are -+ Wait for the buffers in reverse order. That way we are - less likely to be woken up until all IOs have completed, and - so we incur less scheduling load. - */ -@@ -575,8 +575,10 @@ - - jbd_debug(3, "JBD: commit phase 6\n"); - -- if (is_journal_aborted(journal)) -+ if (is_journal_aborted(journal)) { -+ unlock_journal(journal); - goto skip_commit; -+ } - - /* Done it all: now write the commit record. We should have - * cleaned up our previous buffers by now, so if we are in abort -@@ -586,9 +588,10 @@ - descriptor = journal_get_descriptor_buffer(journal); - if (!descriptor) { - __journal_abort_hard(journal); -+ unlock_journal(journal); - goto skip_commit; - } -- -+ - /* AKPM: buglet - add `i' to tmp! */ - for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) { - journal_header_t *tmp = -@@ -609,7 +612,6 @@ - put_bh(bh); /* One for getblk() */ - journal_unlock_journal_head(descriptor); - } -- lock_journal(journal); - - /* End of a transaction! Finally, we can do checkpoint - processing: any buffers committed as a result of this -@@ -618,6 +620,25 @@ - - skip_commit: - -+ /* Call any callbacks that had been registered for handles in this -+ * transaction. It is up to the callback to free any allocated -+ * memory. -+ */ -+ if (!list_empty(&commit_transaction->t_jcb)) { -+ struct list_head *p, *n; -+ int error = is_journal_aborted(journal); -+ -+ list_for_each_safe(p, n, &commit_transaction->t_jcb) { -+ struct journal_callback *jcb; -+ -+ jcb = list_entry(p, struct journal_callback, jcb_list); -+ list_del(p); -+ jcb->jcb_func(jcb, error); -+ } -+ } -+ -+ lock_journal(journal); -+ - jbd_debug(3, "JBD: commit phase 7\n"); - - J_ASSERT(commit_transaction->t_sync_datalist == NULL); ---- linux-2.4.18-chaos5-pristine/fs/jbd/journal.c Sat Jun 29 23:07:56 2002 -+++ linux-2.4.18-chaos5/fs/jbd/journal.c Sat Jun 29 23:09:04 2002 -@@ -58,6 +58,7 @@ - #endif - EXPORT_SYMBOL(journal_flush); - EXPORT_SYMBOL(journal_revoke); -+EXPORT_SYMBOL(journal_callback_set); - - EXPORT_SYMBOL(journal_init_dev); - EXPORT_SYMBOL(journal_init_inode); ---- linux-2.4.18-chaos5-pristine/fs/jbd/transaction.c Sat Jun 29 23:07:56 2002 -+++ linux-2.4.18-chaos5/fs/jbd/transaction.c Sat Jun 29 23:09:04 2002 -@@ -57,6 +57,7 @@ - transaction->t_state = T_RUNNING; - transaction->t_tid = journal->j_transaction_sequence++; - transaction->t_expires = jiffies + journal->j_commit_interval; -+ INIT_LIST_HEAD(&transaction->t_jcb); - - /* Set up the commit timer for the new transaction. */ - J_ASSERT (!journal->j_commit_timer_active); -@@ -201,6 +202,20 @@ - return 0; - } - -+/* Allocate a new handle. This should probably be in a slab... */ -+static handle_t *get_handle(int nblocks) -+{ -+ handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ if (!handle) -+ return NULL; -+ memset(handle, 0, sizeof (handle_t)); -+ handle->h_buffer_credits = nblocks; -+ handle->h_ref = 1; -+ INIT_LIST_HEAD(&handle->h_jcb); -+ -+ return handle; -+} -+ - /* - * Obtain a new handle. - * -@@ -227,14 +242,11 @@ - handle->h_ref++; - return handle; - } -- -- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ -+ handle = get_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); -- memset (handle, 0, sizeof (handle_t)); - -- handle->h_buffer_credits = nblocks; -- handle->h_ref = 1; - current->journal_info = handle; - - err = start_this_handle(journal, handle); -@@ -333,14 +345,11 @@ - - if (is_journal_aborted(journal)) - return ERR_PTR(-EIO); -- -- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ -+ handle = get_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); -- memset (handle, 0, sizeof (handle_t)); - -- handle->h_buffer_credits = nblocks; -- handle->h_ref = 1; - current->journal_info = handle; - - err = try_start_this_handle(journal, handle); -@@ -1319,6 +1328,29 @@ - #endif - - /* -+ * Register a callback function for this handle. The function will be -+ * called when the transaction that this handle is part of has been -+ * committed to disk with the original callback data struct and the -+ * error status of the journal as parameters. There is no guarantee of -+ * ordering between handles within a single transaction, nor between -+ * callbacks registered on the same handle. -+ * -+ * The caller is responsible for allocating the journal_callback struct. -+ * This is to allow the caller to add as much extra data to the callback -+ * as needed, but reduce the overhead of multiple allocations. The caller -+ * allocated struct must start with a struct journal_callback at offset 0, -+ * and has the caller-specific data afterwards. -+ */ -+void journal_callback_set(handle_t *handle, void (*func)(void *, int), -+ void *cb_data) -+{ -+ struct journal_callback *jcb = cb_data; -+ -+ list_add(&jcb->jcb_list, &handle->h_jcb); -+ jcb->jcb_func = func; -+} -+ -+/* - * All done for a particular handle. - * - * There is not much action needed here. We just return any remaining -@@ -1383,7 +1415,10 @@ - wake_up(&journal->j_wait_transaction_locked); - } - -- /* -+ /* Move callbacks from the handle to the transaction. */ -+ list_splice(&handle->h_jcb, &transaction->t_jcb); -+ -+ /* - * If the handle is marked SYNC, we need to set another commit - * going! We also want to force a commit if the current - * transaction is occupying too much of the log, or if the ---- linux-2.4.18-chaos5-pristine/include/linux/blkdev.h Sat Jun 29 23:07:57 2002 -+++ linux-2.4.18-chaos5/include/linux/blkdev.h Mon Jul 1 08:51:17 2002 -@@ -276,4 +276,9 @@ - } - return retval; - } -+ -+#define CONFIG_DEV_RDONLY -+void dev_set_rdonly(kdev_t, int); -+int dev_check_rdonly(kdev_t); -+void dev_clear_rdonly(int); - #endif ---- linux-2.4.18-chaos5-pristine/include/linux/jbd.h Sat Jun 29 23:07:57 2002 -+++ linux-2.4.18-chaos5/include/linux/jbd.h Mon Jul 1 08:51:19 2002 -@@ -257,6 +257,13 @@ - return bh->b_private; - } - -+#define HAVE_JOURNAL_CALLBACK_STATUS -+struct journal_callback { -+ struct list_head jcb_list; -+ void (*jcb_func)(void *cb_data, int error); -+ /* user data goes here */ -+}; -+ - struct jbd_revoke_table_s; - - /* The handle_t type represents a single atomic update being performed -@@ -287,6 +294,12 @@ - operations */ - int h_err; - -+ /* List of application registered callbacks for this handle. -+ * The function(s) will be called after the transaction that -+ * this handle is part of has been committed to disk. -+ */ -+ struct list_head h_jcb; -+ - /* Flags */ - unsigned int h_sync: 1; /* sync-on-close */ - unsigned int h_jdata: 1; /* force data journaling */ -@@ -406,6 +419,10 @@ - - /* How many handles used this transaction? */ - int t_handle_count; -+ -+ /* List of registered callback functions for this transaction. -+ * Called when the transaction is committed. */ -+ struct list_head t_jcb; - }; - - -@@ -654,6 +671,8 @@ - extern int journal_try_to_free_buffers(journal_t *, struct page *, int); - extern int journal_stop(handle_t *); - extern int journal_flush (journal_t *); -+extern void journal_callback_set(handle_t *handle, void (*fn)(void *, int), -+ void *cb_data); - - extern void journal_lock_updates (journal_t *); - extern void journal_unlock_updates (journal_t *); ---- linux-2.4.18-chaos5-pristine/kernel/ksyms.c Sat Jun 29 23:07:57 2002 -+++ linux-2.4.18-chaos5/kernel/ksyms.c Sat Jun 29 23:09:04 2002 -@@ -306,6 +306,13 @@ - EXPORT_SYMBOL(lock_may_write); - EXPORT_SYMBOL(dcache_readdir); - -+/* lustre */ -+EXPORT_SYMBOL(panic_notifier_list); -+EXPORT_SYMBOL(pagecache_lock_cacheline); -+EXPORT_SYMBOL(kmem_cache_validate); -+EXPORT_SYMBOL(do_kern_mount); -+ -+ - /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ - EXPORT_SYMBOL(default_llseek); - EXPORT_SYMBOL(dentry_open); ---- linux-2.4.18-chaos5-pristine/include/linux/dcache.h Sat Jun 29 23:07:57 2002 -+++ linux-2.4.18-chaos5/include/linux/dcache.h Mon Jul 1 08:51:12 2002 -@@ -6,6 +6,33 @@ - #include - #include - -+#define IT_OPEN (1) -+#define IT_CREAT (1<<1) -+#define IT_MKDIR (1<<2) -+#define IT_LINK (1<<3) -+#define IT_SYMLINK (1<<4) -+#define IT_UNLINK (1<<5) -+#define IT_RMDIR (1<<6) -+#define IT_RENAME (1<<7) -+#define IT_RENAME2 (1<<8) -+#define IT_READDIR (1<<9) -+#define IT_GETATTR (1<<10) -+#define IT_SETATTR (1<<11) -+#define IT_READLINK (1<<12) -+#define IT_MKNOD (1<<13) -+#define IT_LOOKUP (1<<14) -+ -+struct lookup_intent { -+ int it_op; -+ int it_mode; -+ int it_disposition; -+ int it_status; -+ struct iattr *it_iattr; -+ __u64 it_lock_handle[2]; -+ int it_lock_mode; -+ void *it_data; -+}; -+ - /* - * linux/include/linux/dcache.h - * -@@ -78,6 +105,7 @@ - unsigned long d_time; /* used by d_revalidate */ - struct dentry_operations *d_op; - struct super_block * d_sb; /* The root of the dentry tree */ -+ struct lookup_intent *d_it; - unsigned long d_vfs_flags; - void * d_fsdata; /* fs-specific data */ - void * d_extra_attributes; /* TUX-specific data */ -@@ -91,6 +119,8 @@ - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); -+ void (*d_intent_release)(struct dentry *); - }; - - /* the dentry parameter passed to d_hash and d_compare is the parent ---- linux-2.4.18-chaos5-pristine/include/linux/fs.h Sat Jun 29 23:07:57 2002 -+++ linux-2.4.18-chaos5/include/linux/fs.h Mon Jul 1 08:51:12 2002 -@@ -572,6 +572,7 @@ - - /* needed for tty driver, and maybe others */ - void *private_data; -+ struct lookup_intent *f_intent; - - /* preallocated helper kiobuf to speedup O_DIRECT */ - struct kiobuf *f_iobuf; -@@ -829,7 +830,9 @@ - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it); - - /* - * File types -@@ -890,6 +893,7 @@ - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); - int (*link) (struct dentry *,struct inode *,struct dentry *); - int (*unlink) (struct inode *,struct dentry *); - int (*symlink) (struct inode *,struct dentry *,const char *); -@@ -1036,6 +1040,7 @@ - extern struct vfsmount *kern_mount(struct file_system_type *); - extern int may_umount(struct vfsmount *); - extern long do_mount(char *, char *, char *, unsigned long, void *); -+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); - extern void umount_tree(struct vfsmount *); - - #define kern_umount mntput -@@ -1370,6 +1375,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 *)); -@@ -1381,6 +1387,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 iput(struct inode *); - extern void force_delete(struct inode *); ---- linux-2.4.18-chaos5-pristine/fs/dcache.c Mon Feb 25 12:38:08 2002 -+++ linux-2.4.18-chaos5/fs/dcache.c Wed Jul 31 11:44:36 2002 -@@ -617,6 +617,7 @@ - dentry->d_op = NULL; - dentry->d_fsdata = NULL; - dentry->d_mounted = 0; -+ dentry->d_it = NULL; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); ---- linux-2.4.18-chaos5-pristine/fs/nfsd/vfs.c Sat Jun 29 23:07:56 2002 -+++ linux-2.4.18-chaos5/fs/nfsd/vfs.c Sat Jun 29 23:09:04 2002 -@@ -1298,7 +1298,7 @@ - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); - unlock_kernel(); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); ---- linux-2.4.18-chaos5-pristine/fs/namei.c Sat Jun 29 23:07:56 2002 -+++ linux-2.4.18-chaos5/fs/namei.c Tue Jul 2 16:06:05 2002 -@@ -94,6 +94,14 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct dentry *de) -+{ -+ if (de->d_op && de->d_op->d_intent_release) -+ de->d_op->d_intent_release(de); -+ de->d_it = NULL; -+} -+ -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -260,10 +268,19 @@ - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -281,7 +297,8 @@ - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; -@@ -300,6 +316,9 @@ - result = ERR_PTR(-ENOMEM); - if (dentry) { - lock_kernel(); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -322,6 +341,13 @@ - result = ERR_PTR(-ENOENT); - } - } -+ else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ result = ERR_PTR(-ENOENT); -+ } -+ } - return result; - } - -@@ -447,7 +472,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; -@@ -524,12 +549,12 @@ - break; - } - /* This does the actual lookups.. */ -- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, it); - if (!dentry) { - err = -EWOULDBLOCKIO; - if (atomic) - break; -- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, it); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -563,7 +588,7 @@ - nd->dentry = dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup2) - break; - continue; - /* here ends the main loop */ -@@ -590,12 +615,12 @@ - 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; -@@ -619,7 +644,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->lookup2)) - break; - } - goto return_base; -@@ -651,6 +677,7 @@ - } - } - return_base: -+ nd->dentry->d_it = it; - return 0; - out_dput: - dput(dentry); -@@ -658,15 +685,29 @@ - } - path_release(nd); - return_err: -+ if (!err) -+ nd->dentry->d_it = it; - 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 */ - /* returns 1 if everything is done */ - static int __emul_lookup_dentry(const char *name, struct nameidata *nd) -@@ -749,6 +790,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; -@@ -777,7 +829,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; -@@ -800,13 +853,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->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -818,6 +874,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) - { -@@ -839,7 +901,7 @@ - } - 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 +932,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. -@@ -1008,7 +1086,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; -@@ -1022,16 +1101,19 @@ - * 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; -+ dentry->d_it = it; - goto ok; - } - - /* - * Create - we need to know the parent. - */ -+ if (it) -+ it->it_op |= IT_CREAT; - error = path_lookup(pathname, LOOKUP_PARENT, nd); - if (error) - return error; -@@ -1047,7 +1129,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); -@@ -1056,6 +1138,7 @@ - goto exit; - } - -+ dentry->d_it = it; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - error = vfs_create(dir->d_inode, dentry, -@@ -1172,9 +1255,11 @@ - if (flag & FMODE_WRITE) - DQUOT_INIT(inode); - -+ intent_release(dentry); - return 0; - - exit_dput: -+ intent_release(dentry); - dput(dentry); - exit: - path_release(nd); -@@ -1217,13 +1302,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, NULL); - 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; - -@@ -1231,7 +1323,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) -@@ -1277,6 +1369,7 @@ - char * tmp; - struct dentry * dentry; - struct nameidata nd; -+ struct lookup_intent it = { IT_MKNOD , mode }; - - if (S_ISDIR(mode)) - return -EPERM; -@@ -1287,11 +1380,12 @@ - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(dentry); - - mode &= ~current->fs->umask; - if (!IS_ERR(dentry)) { -+ dentry->d_it = ⁢ - switch (mode & S_IFMT) { - case 0: case S_IFREG: - error = vfs_create(nd.dentry->d_inode,dentry,mode); -@@ -1305,6 +1399,7 @@ - default: - error = -EINVAL; - } -+ intent_release(dentry); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1345,6 +1440,7 @@ - { - int error = 0; - char * tmp; -+ struct lookup_intent it = { IT_MKDIR, mode }; - - tmp = getname(pathname); - error = PTR_ERR(tmp); -@@ -1355,11 +1451,13 @@ - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 1); -+ dentry = lookup_create(&nd, 1, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { -+ dentry->d_it = ⁢ - error = vfs_mkdir(nd.dentry->d_inode, dentry, - mode & ~current->fs->umask); -+ intent_release(dentry); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1439,6 +1537,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { IT_RMDIR, 0 }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1460,10 +1559,12 @@ - goto exit1; - } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { -+ dentry->d_it = ⁢ - error = vfs_rmdir(nd.dentry->d_inode, dentry); -+ intent_release(dentry); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1507,6 +1608,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { IT_UNLINK, 0 }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1519,14 +1621,16 @@ - if (nd.last_type != LAST_NORM) - goto exit1; - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { -+ dentry->d_it = ⁢ - /* Why not before? Because we want correct error value */ - if (nd.last.name[nd.last.len]) - goto slashes; - error = vfs_unlink(nd.dentry->d_inode, dentry); - exit2: -+ intent_release(dentry); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1573,6 +1677,7 @@ - int error = 0; - char * from; - char * to; -+ struct lookup_intent it = { IT_SYMLINK, 0 }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1586,11 +1691,13 @@ - error = path_lookup(to, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { -+ dentry->d_it = ⁢ - error = vfs_symlink(nd.dentry->d_inode, dentry, from); -- dput(dentry); -+ intent_release(dentry); -+ dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); - path_release(&nd); -@@ -1654,6 +1761,7 @@ - { - int error; - char * to; -+ struct lookup_intent it = { IT_LINK, 0 }; - - to = getname(newname); - error = PTR_ERR(to); -@@ -1670,10 +1778,12 @@ - error = -EXDEV; - if (old_nd.mnt != nd.mnt) - goto out_release; -- new_dentry = lookup_create(&nd, 0); -+ new_dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(new_dentry); - if (!IS_ERR(new_dentry)) { -+ new_dentry->d_it = ⁢ - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); -+ intent_release(new_dentry); - dput(new_dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1714,7 +1824,8 @@ - * locking]. - */ - int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - struct inode *target; -@@ -1768,10 +1879,12 @@ - } else - double_down(&old_dir->i_zombie, - &new_dir->i_zombie); -+ new_dentry->d_it = it; - if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry); - if (target) { - if (!error) - target->i_flags |= S_DEAD; -@@ -1793,7 +1906,8 @@ - } - - int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - -@@ -1820,10 +1934,12 @@ - DQUOT_INIT(old_dir); - DQUOT_INIT(new_dir); - double_down(&old_dir->i_zombie, &new_dir->i_zombie); -+ new_dentry->d_it = it; - if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry); - double_up(&old_dir->i_zombie, &new_dir->i_zombie); - if (error) - return error; -@@ -1835,13 +1951,14 @@ - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - if (S_ISDIR(old_dentry->d_inode->i_mode)) -- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); - else -- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); - if (!error) { - if (old_dir == new_dir) - inode_dir_notify(old_dir, DN_RENAME); -@@ -1858,6 +1975,7 @@ - int error = 0; - struct dentry * old_dir, * new_dir; - struct dentry * old_dentry, *new_dentry; -+ struct lookup_intent it = {IT_RENAME, 0}; - struct nameidata oldnd, newnd; - - error = path_lookup(oldname, LOOKUP_PARENT, &oldnd); -@@ -1883,7 +2001,7 @@ - - double_lock(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -1899,14 +2019,15 @@ - if (newnd.last.name[newnd.last.len]) - goto exit4; - } -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ it.it_op = IT_RENAME2; -+ new_dentry = lookup_hash_it(&newnd.last, new_dir, &it); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; - - lock_kernel(); - error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ new_dir->d_inode, new_dentry, &it); - unlock_kernel(); - - dput(new_dentry); ---- linux-2.4.18-chaos5-pristine/fs/open.c Sat Jun 29 23:07:56 2002 -+++ linux-2.4.18-chaos5/fs/open.c Sat Jun 29 23:09:04 2002 -@@ -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); -+extern void intent_release(struct dentry *de); - - int vfs_statfs(struct super_block *sb, struct statfs *buf) - { -@@ -118,14 +120,19 @@ - struct nameidata nd; - struct inode * inode; - int error; -+ struct lookup_intent it; -+ -+ it.it_op = IT_SETATTR; -+ - - error = -EINVAL; - if (length < 0) /* sorry, but loff_t says... */ - goto out; - -- error = user_path_walk(path, &nd); -+ error = user_path_walk_it(path, &nd, &it); - if (error) - goto out; -+ nd.dentry->d_it = ⁢ - inode = nd.dentry->d_inode; - - /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ -@@ -168,6 +175,7 @@ - put_write_access(inode); - - dput_and_out: -+ intent_release(nd.dentry); - path_release(&nd); - out: - return error; -@@ -259,10 +267,14 @@ - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; -+ struct lookup_intent it; - -- error = user_path_walk(filename, &nd); -+ it.it_op = IT_SETATTR; -+ -+ error = user_path_walk_it(filename, &nd, &it); - if (error) - goto out; -+ nd.dentry->d_it = ⁢ - inode = nd.dentry->d_inode; - - error = -EROFS; -@@ -286,6 +298,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry); - path_release(&nd); - out: - return error; -@@ -303,11 +316,15 @@ - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; -+ struct lookup_intent it; -+ -+ it.it_op = IT_SETATTR; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - - if (error) - goto out; -+ nd.dentry->d_it = ⁢ - inode = nd.dentry->d_inode; - - error = -EROFS; -@@ -330,6 +347,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry); - path_release(&nd); - out: - return error; -@@ -346,6 +364,9 @@ - int old_fsuid, old_fsgid; - kernel_cap_t old_cap; - int res; -+ struct lookup_intent it; -+ -+ it.it_op = IT_GETATTR; - - if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ - return -EINVAL; -@@ -363,13 +384,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(nd.dentry); - path_release(&nd); - } - -@@ -384,11 +406,13 @@ - { - int error; - struct nameidata nd; -- -- error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); -+ struct lookup_intent it = {IT_GETATTR}; -+ -+ error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it); - if (error) - goto out; - -+ nd.dentry->d_it = ⁢ - error = permission(nd.dentry->d_inode,MAY_EXEC); - if (error) - goto dput_and_out; -@@ -396,6 +420,7 @@ - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(nd.dentry); - path_release(&nd); - out: - return error; -@@ -435,12 +460,14 @@ - { - int error; - struct nameidata nd; -+ struct lookup_intent it = {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; - -+ nd.dentry->d_it = ⁢ - error = permission(nd.dentry->d_inode,MAY_EXEC); - if (error) - goto dput_and_out; -@@ -453,6 +480,7 @@ - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(nd.dentry); - path_release(&nd); - out: - return error; -@@ -497,12 +525,15 @@ - struct inode * inode; - int error; - struct iattr newattrs; -+ struct lookup_intent it; - -- error = user_path_walk(filename, &nd); -+ it.it_op = IT_SETATTR; -+ error = user_path_walk_it(filename, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; - -+ nd.dentry->d_it = ⁢ - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; -@@ -518,6 +549,7 @@ - error = notify_change(nd.dentry, &newattrs); - - dput_and_out: -+ intent_release(nd.dentry); - path_release(&nd); - out: - return error; -@@ -587,10 +619,15 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it; -+ -+ it.it_op = IT_SETATTR; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { -+ nd.dentry->d_it = ⁢ - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry); - path_release(&nd); - } - return error; -@@ -600,10 +637,15 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it; - -- error = user_path_walk_link(filename, &nd); -+ it.it_op = IT_SETATTR; -+ -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { -+ nd.dentry->d_it = ⁢ - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry); - path_release(&nd); - } - return error; -@@ -637,10 +679,15 @@ - * for the internal routines (ie open_namei()/follow_link() etc). 00 is - * used by symlinks. - */ -+extern int open_namei_it(const char *filename, int namei_flags, int mode, -+ struct nameidata *nd, struct lookup_intent *it); -+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it); -+ - struct file *filp_open(const char * filename, int flags, int mode) - { - int namei_flags, error; - struct nameidata nd; -+ struct lookup_intent it = {IT_OPEN, 0}; - - namei_flags = flags; - if ((namei_flags+1) & O_ACCMODE) -@@ -648,14 +695,14 @@ - if (namei_flags & O_TRUNC) - namei_flags |= 2; - -- error = open_namei(filename, namei_flags, mode, &nd); -+ error = open_namei_it(filename, namei_flags, mode, &nd, &it); - if (!error) -- return dentry_open(nd.dentry, nd.mnt, flags); -+ return dentry_open_it(nd.dentry, nd.mnt, flags, &it); - - return ERR_PTR(error); - } - --struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it) - { - struct file * f; - struct inode *inode; -@@ -712,11 +759,19 @@ - cleanup_file: - put_filp(f); - cleanup_dentry: -+ intent_release(dentry); - dput(dentry); - mntput(mnt); - return ERR_PTR(error); - } - -+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+{ -+ return dentry_open_it(dentry, mnt, flags, NULL); -+ -+} -+ -+ - /* - * Find an empty file descriptor entry, and mark it busy. - */ ---- linux-2.4.18-chaos5-pristine/fs/stat.c Sat Jun 29 23:07:56 2002 -+++ linux-2.4.18-chaos5/fs/stat.c Mon Jul 1 08:54:45 2002 -@@ -13,6 +13,8 @@ - - #include - -+ -+extern void intent_release(struct dentry *de); - /* - * Revalidate the inode. This is required for proper NFS attribute caching. - */ -@@ -104,10 +106,12 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { IT_GETATTR}; - -- error = user_path_walk(name, &nd); -+ error = user_path_walk_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry); - path_release(&nd); - } - return error; -@@ -117,10 +121,13 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { IT_GETATTR}; -+ - -- error = user_path_walk_link(name, &nd); -+ error = user_path_walk_link_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry); - path_release(&nd); - } - return error; ---- linux-2.4.18-chaos5-pristine/mm/slab.c Sat Jun 29 23:07:57 2002 -+++ linux-2.4.18-chaos5/mm/slab.c Sat Jun 29 23:09:04 2002 -@@ -1207,6 +1207,58 @@ - * Called with the cache-lock held. - */ - -+extern struct page *check_get_page(unsigned long kaddr); -+struct page *page_mem_map(struct page *page); -+static int kmem_check_cache_obj (kmem_cache_t * cachep, -+ slab_t *slabp, void * objp) -+{ -+ int i; -+ unsigned int objnr; -+#if DEBUG -+ if (cachep->flags & SLAB_RED_ZONE) { -+ objp -= BYTES_PER_WORD; -+ if ( *(unsigned long *)objp != RED_MAGIC2) -+ /* Either write before start, or a double free. */ -+ return 0; -+ if (*(unsigned long *)(objp+cachep->objsize - -+ BYTES_PER_WORD) != RED_MAGIC2) -+ /* Either write past end, or a double free. */ -+ return 0; -+ } -+#endif -+ -+ objnr = (objp-slabp->s_mem)/cachep->objsize; -+ if (objnr >= cachep->num) -+ return 0; -+ if (objp != slabp->s_mem + objnr*cachep->objsize) -+ return 0; -+ -+ /* Check slab's freelist to see if this obj is there. */ -+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { -+ if (i == objnr) -+ return 0; -+ } -+ return 1; -+} -+ -+ -+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) -+{ -+ struct page *page = check_get_page((unsigned long)objp); -+ -+ if (!VALID_PAGE(page)) -+ return 0; -+ -+ if (!PageSlab(page)) -+ return 0; -+ -+ /* XXX check for freed slab objects ? */ -+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) -+ return 0; -+ -+ return (cachep == GET_PAGE_CACHE(page)); -+} -+ - #if DEBUG - static int kmem_extra_free_checks (kmem_cache_t * cachep, - slab_t *slabp, void * objp) ---- linux-2.4.18-chaos5-pristine/arch/i386/mm/init.c Sat Jun 29 23:07:34 2002 -+++ linux-2.4.18-chaos5/arch/i386/mm/init.c Sat Jun 29 23:09:04 2002 -@@ -43,6 +43,14 @@ - static unsigned long totalram_pages; - static unsigned long totalhigh_pages; - -+ -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid enough? -+ return virt_to_page(kaddr); -+} -+ -+ - int do_check_pgt_cache(int low, int high) - { - int freed = 0; ---- linux-2.4.18-chaos5-pristine/include/linux/slab.h Sat Jun 29 23:07:57 2002 -+++ linux-2.4.18-chaos5/include/linux/slab.h Mon Jul 1 08:51:12 2002 -@@ -57,6 +57,7 @@ - extern int kmem_cache_shrink(kmem_cache_t *); - extern void *kmem_cache_alloc(kmem_cache_t *, int); - extern void kmem_cache_free(kmem_cache_t *, void *); -+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); - - extern void *kmalloc(size_t, int); - extern void kfree(const void *); ---- linux-2.4.18-chaos5-pristine/scripts/mkspec Sat Jun 29 23:07:58 2002 -+++ linux-2.4.18-chaos5/scripts/mkspec Sat Jun 29 23:09:04 2002 -@@ -64,6 +64,7 @@ - fi - # Back on track, again - echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" -+echo 'cp vmlinux $RPM_BUILD_ROOT'"/boot/vmlinux-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" - echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" - echo "" - echo "%clean" diff --git a/lustre/patches/patch-2.4.18-hp1_pnnl18.2.8qsnet b/lustre/patches/patch-2.4.18-hp1_pnnl18.2.8qsnet deleted file mode 100644 index 4c99e3c..0000000 --- a/lustre/patches/patch-2.4.18-hp1_pnnl18.2.8qsnet +++ /dev/null @@ -1,1673 +0,0 @@ ---- linux-pristine/./include/linux/lustre_version.h Wed Dec 31 19:00:00 1969 -+++ linux/./include/linux/lustre_version.h Tue Nov 26 07:02:14 2002 -@@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 4 ---- linux-pristine/./arch/ia64/mm/init.c Thu Dec 5 10:47:25 2002 -+++ linux/./arch/ia64/mm/init.c Fri Nov 29 18:06:20 2002 -@@ -44,6 +44,12 @@ - - static struct page *vmem_map; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int - do_check_pgt_cache (int low, int high) - { ---- linux-pristine/./arch/i386/mm/init.c Thu Dec 5 10:47:24 2002 -+++ linux/./arch/i386/mm/init.c Fri Nov 29 18:06:20 2002 -@@ -43,6 +43,12 @@ - static unsigned long totalram_pages; - static unsigned long totalhigh_pages; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int do_check_pgt_cache(int low, int high) - { - int freed = 0; ---- linux-pristine/./drivers/block/blkpg.c Thu Dec 5 10:47:36 2002 -+++ linux/./drivers/block/blkpg.c Fri Nov 29 18:08:05 2002 -@@ -308,6 +308,41 @@ - - 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-pristine/./drivers/block/loop.c Thu Dec 5 10:47:37 2002 -+++ linux/./drivers/block/loop.c Fri Nov 29 18:06:20 2002 -@@ -471,6 +471,11 @@ - spin_unlock_irq(&lo->lo_lock); - - if (rw == WRITE) { -+#ifdef CONFIG_DEV_RDONLY -+ if (dev_check_rdonly(rbh->b_rdev)) -+ goto err; -+#endif -+ - if (lo->lo_flags & LO_FLAGS_READ_ONLY) - goto err; - } else if (rw == READA) { ---- linux-pristine/./drivers/ide/ide-disk.c Thu Dec 5 10:47:59 2002 -+++ linux/./drivers/ide/ide-disk.c Fri Nov 29 18:06:20 2002 -@@ -367,6 +367,12 @@ - */ - static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) - { -+#ifdef CONFIG_DEV_RDONLY -+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { -+ ide_end_request(1, HWGROUP(drive)); -+ return ide_stopped; -+ } -+#endif - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl,IDE_CONTROL_REG); - OUT_BYTE(0x00, IDE_FEATURE_REG); ---- linux-pristine/./fs/ext3/Makefile Thu Dec 5 10:49:13 2002 -+++ linux/./fs/ext3/Makefile Fri Nov 29 18:06:20 2002 -@@ -9,6 +9,8 @@ - - O_TARGET := ext3.o - -+export-objs := super.o -+ - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o - obj-m := $(O_TARGET) ---- linux-pristine/./fs/ext3/super.c Thu Dec 5 10:49:13 2002 -+++ linux/./fs/ext3/super.c Fri Nov 29 18:06:20 2002 -@@ -1744,7 +1744,7 @@ - unregister_filesystem(&ext3_fs_type); - } - --EXPORT_NO_SYMBOLS; -+EXPORT_SYMBOL(ext3_bread); - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); - MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); ---- linux-pristine/./fs/jbd/commit.c Thu Dec 5 10:49:15 2002 -+++ linux/./fs/jbd/commit.c Fri Nov 29 18:06:20 2002 -@@ -475,7 +475,7 @@ - transaction's t_log_list queue, and metadata buffers are on - the t_iobuf_list queue. - -- Wait for the transactions in reverse order. That way we are -+ Wait for the buffers in reverse order. That way we are - less likely to be woken up until all IOs have completed, and - so we incur less scheduling load. - */ -@@ -566,8 +566,10 @@ - - jbd_debug(3, "JBD: commit phase 6\n"); - -- if (is_journal_aborted(journal)) -+ if (is_journal_aborted(journal)) { -+ unlock_journal(journal); - goto skip_commit; -+ } - - /* Done it all: now write the commit record. We should have - * cleaned up our previous buffers by now, so if we are in abort -@@ -577,6 +579,7 @@ - descriptor = journal_get_descriptor_buffer(journal); - if (!descriptor) { - __journal_abort_hard(journal); -+ unlock_journal(journal); - goto skip_commit; - } - -@@ -600,7 +603,6 @@ - put_bh(bh); /* One for getblk() */ - journal_unlock_journal_head(descriptor); - } -- lock_journal(journal); - - /* End of a transaction! Finally, we can do checkpoint - processing: any buffers committed as a result of this -@@ -609,6 +611,25 @@ - - skip_commit: - -+ /* Call any callbacks that had been registered for handles in this -+ * transaction. It is up to the callback to free any allocated -+ * memory. -+ */ -+ if (!list_empty(&commit_transaction->t_jcb)) { -+ struct list_head *p, *n; -+ int error = is_journal_aborted(journal); -+ -+ list_for_each_safe(p, n, &commit_transaction->t_jcb) { -+ struct journal_callback *jcb; -+ -+ jcb = list_entry(p, struct journal_callback, jcb_list); -+ list_del(p); -+ jcb->jcb_func(jcb, error); -+ } -+ } -+ -+ lock_journal(journal); -+ - jbd_debug(3, "JBD: commit phase 7\n"); - - J_ASSERT(commit_transaction->t_sync_datalist == NULL); ---- linux-pristine/./fs/jbd/journal.c Thu Dec 5 10:49:15 2002 -+++ linux/./fs/jbd/journal.c Fri Nov 29 18:06:20 2002 -@@ -58,6 +58,7 @@ - #endif - EXPORT_SYMBOL(journal_flush); - EXPORT_SYMBOL(journal_revoke); -+EXPORT_SYMBOL(journal_callback_set); - - EXPORT_SYMBOL(journal_init_dev); - EXPORT_SYMBOL(journal_init_inode); ---- linux-pristine/./fs/jbd/transaction.c Thu Dec 5 10:49:15 2002 -+++ linux/./fs/jbd/transaction.c Fri Nov 29 18:06:20 2002 -@@ -57,6 +57,7 @@ - transaction->t_state = T_RUNNING; - transaction->t_tid = journal->j_transaction_sequence++; - transaction->t_expires = jiffies + journal->j_commit_interval; -+ INIT_LIST_HEAD(&transaction->t_jcb); - - /* Set up the commit timer for the new transaction. */ - J_ASSERT (!journal->j_commit_timer_active); -@@ -201,6 +202,20 @@ - return 0; - } - -+/* Allocate a new handle. This should probably be in a slab... */ -+static handle_t *new_handle(int nblocks) -+{ -+ handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ if (!handle) -+ return NULL; -+ memset(handle, 0, sizeof (handle_t)); -+ handle->h_buffer_credits = nblocks; -+ handle->h_ref = 1; -+ INIT_LIST_HEAD(&handle->h_jcb); -+ -+ return handle; -+} -+ - /* - * Obtain a new handle. - * -@@ -227,14 +242,11 @@ - handle->h_ref++; - return handle; - } -- -- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ -+ handle = new_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); -- memset (handle, 0, sizeof (handle_t)); - -- handle->h_buffer_credits = nblocks; -- handle->h_ref = 1; - current->journal_info = handle; - - err = start_this_handle(journal, handle); -@@ -333,14 +345,11 @@ - - if (is_journal_aborted(journal)) - return ERR_PTR(-EIO); -- -- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ -+ handle = new_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); -- memset (handle, 0, sizeof (handle_t)); - -- handle->h_buffer_credits = nblocks; -- handle->h_ref = 1; - current->journal_info = handle; - - err = try_start_this_handle(journal, handle); -@@ -1328,6 +1337,28 @@ - #endif - - /* -+ * Register a callback function for this handle. The function will be -+ * called when the transaction that this handle is part of has been -+ * committed to disk with the original callback data struct and the -+ * error status of the journal as parameters. There is no guarantee of -+ * ordering between handles within a single transaction, nor between -+ * callbacks registered on the same handle. -+ * -+ * The caller is responsible for allocating the journal_callback struct. -+ * This is to allow the caller to add as much extra data to the callback -+ * as needed, but reduce the overhead of multiple allocations. The caller -+ * allocated struct must start with a struct journal_callback at offset 0, -+ * and has the caller-specific data afterwards. -+ */ -+void journal_callback_set(handle_t *handle, -+ void (*func)(struct journal_callback *jcb, int error), -+ struct journal_callback *jcb) -+{ -+ list_add(&jcb->jcb_list, &handle->h_jcb); -+ jcb->jcb_func = func; -+} -+ -+/* - * All done for a particular handle. - * - * There is not much action needed here. We just return any remaining -@@ -1393,7 +1424,10 @@ - wake_up(&journal->j_wait_transaction_locked); - } - -- /* -+ /* Move callbacks from the handle to the transaction. */ -+ list_splice(&handle->h_jcb, &transaction->t_jcb); -+ -+ /* - * If the handle is marked SYNC, we need to set another commit - * going! We also want to force a commit if the current - * transaction is occupying too much of the log, or if the ---- linux-pristine/./include/linux/blkdev.h Thu Dec 5 10:49:41 2002 -+++ linux/./include/linux/blkdev.h Fri Nov 29 18:30:34 2002 -@@ -228,4 +228,8 @@ - return retval; - } - -+#define CONFIG_DEV_RDONLY -+void dev_set_rdonly(kdev_t, int); -+int dev_check_rdonly(kdev_t); -+void dev_clear_rdonly(int); - #endif ---- linux-pristine/./include/linux/slab.h Thu Dec 5 10:49:53 2002 -+++ linux/./include/linux/slab.h Fri Nov 29 18:30:15 2002 -@@ -58,6 +58,7 @@ - extern void *kmem_cache_alloc(kmem_cache_t *, int); - extern void *kmem_cache_zalloc(kmem_cache_t *, int); - extern void kmem_cache_free(kmem_cache_t *, void *); -+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); - - extern void *kmalloc(size_t, int); - extern void kfree(const void *); ---- linux-pristine/./include/linux/jbd.h Thu Dec 5 10:49:43 2002 -+++ linux/./include/linux/jbd.h Fri Nov 29 18:50:01 2002 -@@ -249,6 +249,13 @@ - return bh->b_private; - } - -+#define HAVE_JOURNAL_CALLBACK_STATUS -+struct journal_callback { -+ struct list_head jcb_list; -+ void (*jcb_func)(struct journal_callback *jcb, int error); -+ /* user data goes here */ -+}; -+ - struct jbd_revoke_table_s; - - /* The handle_t type represents a single atomic update being performed -@@ -279,6 +286,12 @@ - operations */ - int h_err; - -+ /* List of application registered callbacks for this handle. -+ * The function(s) will be called after the transaction that -+ * this handle is part of has been committed to disk. -+ */ -+ struct list_head h_jcb; -+ - /* Flags */ - unsigned int h_sync: 1; /* sync-on-close */ - unsigned int h_jdata: 1; /* force data journaling */ -@@ -398,6 +411,10 @@ - - /* How many handles used this transaction? */ - int t_handle_count; -+ -+ /* List of registered callback functions for this transaction. -+ * Called when the transaction is committed. */ -+ struct list_head t_jcb; - }; - - -@@ -646,6 +663,9 @@ - extern int journal_try_to_free_buffers(journal_t *, struct page *, int); - extern int journal_stop(handle_t *); - extern int journal_flush (journal_t *); -+extern void journal_callback_set(handle_t *handle, -+ void (*fn)(struct journal_callback *,int), -+ struct journal_callback *jcb); - - extern void journal_lock_updates (journal_t *); - extern void journal_unlock_updates (journal_t *); ---- linux-pristine/./kernel/ksyms.c Thu Dec 5 10:50:01 2002 -+++ linux/./kernel/ksyms.c Fri Nov 29 18:37:23 2002 -@@ -271,6 +271,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); -@@ -285,6 +286,11 @@ - EXPORT_SYMBOL(nr_free_pages); - EXPORT_SYMBOL(page_cache_size); - -+/* lustre */ -+EXPORT_SYMBOL(pagecache_lock); -+EXPORT_SYMBOL(do_kern_mount); -+EXPORT_SYMBOL(kmem_cache_validate); -+ - /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ - EXPORT_SYMBOL(default_llseek); - EXPORT_SYMBOL(dentry_open); ---- linux-pristine/./include/linux/dcache.h Thu Dec 5 10:49:42 2002 -+++ linux/./include/linux/dcache.h Fri Nov 29 18:30:11 2002 -@@ -6,6 +6,34 @@ - #include - #include - -+#define IT_OPEN (1) -+#define IT_CREAT (1<<1) -+#define IT_MKDIR (1<<2) -+#define IT_LINK (1<<3) -+#define IT_LINK2 (1<<4) -+#define IT_SYMLINK (1<<5) -+#define IT_UNLINK (1<<6) -+#define IT_RMDIR (1<<7) -+#define IT_RENAME (1<<8) -+#define IT_RENAME2 (1<<9) -+#define IT_READDIR (1<<10) -+#define IT_GETATTR (1<<11) -+#define IT_SETATTR (1<<12) -+#define IT_READLINK (1<<13) -+#define IT_MKNOD (1<<14) -+#define IT_LOOKUP (1<<15) -+ -+struct lookup_intent { -+ int it_op; -+ int it_mode; -+ int it_disposition; -+ int it_status; -+ struct iattr *it_iattr; -+ __u64 it_lock_handle[2]; -+ int it_lock_mode; -+ void *it_data; -+}; -+ - /* - * linux/include/linux/dcache.h - * -@@ -78,6 +106,7 @@ - unsigned long d_time; /* used by d_revalidate */ - struct dentry_operations *d_op; - struct super_block * d_sb; /* The root of the dentry tree */ -+ struct lookup_intent *d_it; - unsigned long d_vfs_flags; - void * d_fsdata; /* fs-specific data */ - unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */ -@@ -90,6 +119,8 @@ - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); -+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); - }; - - /* the dentry parameter passed to d_hash and d_compare is the parent ---- linux-pristine/./include/linux/fs.h Thu Dec 5 10:49:42 2002 -+++ linux/./include/linux/fs.h Fri Nov 29 18:30:15 2002 -@@ -588,6 +588,7 @@ - - /* needed for tty driver, and maybe others */ - void *private_data; -+ struct lookup_intent *f_intent; - - /* preallocated helper kiobuf to speedup O_DIRECT */ - struct kiobuf *f_iobuf; -@@ -849,7 +850,9 @@ - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it); - - /* - * File types -@@ -911,6 +914,7 @@ - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); - int (*link) (struct dentry *,struct inode *,struct dentry *); - int (*unlink) (struct inode *,struct dentry *); - int (*symlink) (struct inode *,struct dentry *,const char *); -@@ -921,6 +925,8 @@ - struct inode *, struct dentry *); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); -+ int (*follow_link2) (struct dentry *, struct nameidata *, -+ struct lookup_intent *it); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*revalidate) (struct dentry *); -@@ -1063,7 +1069,7 @@ - extern struct vfsmount *kern_mount(struct file_system_type *); - extern int may_umount(struct vfsmount *); - extern long do_mount(char *, char *, char *, unsigned long, void *); -- -+struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data); - #define kern_umount mntput - - extern int vfs_statfs(struct super_block *, struct statfs *); -@@ -1387,6 +1393,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(link_path_walk(const char *, struct nameidata *)); -@@ -1397,6 +1404,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 iput(struct inode *); - extern void force_delete(struct inode *); -@@ -1508,6 +1517,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; ---- linux-pristine/./fs/dcache.c Thu Dec 5 10:49:13 2002 -+++ linux/./fs/dcache.c Fri Nov 29 18:06:20 2002 -@@ -617,6 +617,7 @@ - dentry->d_op = NULL; - dentry->d_fsdata = NULL; - dentry->d_mounted = 0; -+ dentry->d_it = NULL; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); ---- linux-pristine/./fs/nfsd/vfs.c Thu Dec 5 10:49:18 2002 -+++ linux/./fs/nfsd/vfs.c Fri Nov 29 18:06:20 2002 -@@ -1285,7 +1285,7 @@ - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); ---- linux-pristine/./fs/namei.c Thu Dec 5 10:49:16 2002 -+++ linux/./fs/namei.c Fri Nov 29 18:11:18 2002 -@@ -94,6 +94,12 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct dentry *de, struct lookup_intent *it) -+{ -+ if (it && de->d_op && de->d_op->d_intent_release) -+ de->d_op->d_intent_release(de, it); -+} -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -260,10 +266,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_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -281,7 +296,8 @@ - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; -@@ -300,6 +316,9 @@ - result = ERR_PTR(-ENOMEM); - if (dentry) { - lock_kernel(); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -321,6 +340,12 @@ - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ result = ERR_PTR(-ENOENT); -+ } - } - return result; - } -@@ -332,7 +357,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 >= 5) -@@ -346,10 +372,14 @@ - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -- err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -+ intent_release(dentry, it); - path_release(nd); - return -ELOOP; - } -@@ -445,7 +475,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; -@@ -518,9 +549,9 @@ - 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; -@@ -537,8 +568,8 @@ - if (!inode->i_op) - goto out_dput; - -- if (inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ if (inode->i_op->follow_link || inode->i_op->follow_link2) { -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -554,7 +585,7 @@ - nd->dentry = dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup2) - break; - continue; - /* here ends the main loop */ -@@ -581,9 +612,9 @@ - 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; -@@ -591,9 +622,9 @@ - while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry)) - ; - inode = dentry->d_inode; -- if ((lookup_flags & LOOKUP_FOLLOW) -- && inode && inode->i_op && inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && -+ (inode->i_op->follow_link || inode->i_op->follow_link2)) { -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -607,7 +638,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->lookup2)) - break; - } - goto return_base; -@@ -636,10 +668,21 @@ - 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,7 +785,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; -@@ -765,13 +809,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->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -783,6 +830,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) - { -@@ -804,7 +857,7 @@ - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash_it(&this, base, NULL); - access: - return ERR_PTR(-EACCES); - } -@@ -836,6 +889,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. -@@ -970,7 +1040,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; -@@ -985,7 +1056,7 @@ - */ - if (!(flag & O_CREAT)) { - if (path_init(pathname, lookup_flags(flag), nd)) -- error = path_walk(pathname, nd); -+ error = path_walk_it(pathname, nd, it); - if (error) - return error; - dentry = nd->dentry; -@@ -995,6 +1066,10 @@ - /* - * Create - we need to know the parent. - */ -+ if (it) { -+ it->it_mode = mode; -+ it->it_op |= IT_CREAT; -+ } - if (path_init(pathname, LOOKUP_PARENT, nd)) - error = path_walk(pathname, nd); - if (error) -@@ -1011,7 +1086,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); -@@ -1020,6 +1095,7 @@ - goto exit; - } - -+ it->it_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - if (!IS_POSIX_ACL(dir->d_inode)) -@@ -1054,7 +1130,8 @@ - error = -ENOENT; - if (!dentry->d_inode) - goto exit_dput; -- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) -+ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || -+ dentry->d_inode->i_op->follow_link2)) - goto do_link; - - dput(nd->dentry); -@@ -1140,8 +1217,10 @@ - return 0; - - exit_dput: -+ intent_release(dentry, it); - dput(dentry); - exit: -+ intent_release(nd->dentry, it); - path_release(nd); - return error; - -@@ -1160,7 +1239,12 @@ - * are done. Procfs-like symlinks just set LAST_BIND. - */ - UPDATE_ATIME(dentry->d_inode); -- error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ error = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) -+ intent_release(dentry, it); - dput(dentry); - if (error) - return error; -@@ -1182,13 +1266,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; - -@@ -1196,7 +1287,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) -@@ -1242,6 +1333,7 @@ - char * tmp; - struct dentry * dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode }; - - if (S_ISDIR(mode)) - return -EPERM; -@@ -1253,7 +1345,7 @@ - error = path_walk(tmp, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(dentry); - - if (!IS_POSIX_ACL(nd.dentry->d_inode)) -@@ -1272,6 +1364,7 @@ - default: - error = -EINVAL; - } -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1312,6 +1405,7 @@ - { - int error = 0; - char * tmp; -+ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; - - tmp = getname(pathname); - error = PTR_ERR(tmp); -@@ -1323,12 +1417,13 @@ - error = path_walk(tmp, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 1); -+ dentry = lookup_create(&nd, 1, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - if (!IS_POSIX_ACL(nd.dentry->d_inode)) - mode &= ~current->fs->umask; - error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1410,6 +1505,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_RMDIR }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1432,10 +1528,11 @@ - goto exit1; - } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1479,6 +1576,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_UNLINK }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1492,7 +1590,7 @@ - if (nd.last_type != LAST_NORM) - goto exit1; - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1500,6 +1598,7 @@ - goto slashes; - error = vfs_unlink(nd.dentry->d_inode, dentry); - exit2: -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1546,6 +1645,7 @@ - int error = 0; - char * from; - char * to; -+ struct lookup_intent it = { .it_op = IT_SYMLINK }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1560,10 +1660,12 @@ - error = path_walk(to, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ it.it_data = from; -+ dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_symlink(nd.dentry->d_inode, dentry, from); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1629,6 +1731,7 @@ - int error; - char * from; - char * to; -+ struct lookup_intent it = { .it_op = IT_LINK }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1641,7 +1744,7 @@ - - error = 0; - if (path_init(from, LOOKUP_POSITIVE, &old_nd)) -- error = path_walk(from, &old_nd); -+ error = path_walk_it(from, &old_nd, &it); - if (error) - goto exit; - if (path_init(to, LOOKUP_PARENT, &nd)) -@@ -1651,10 +1754,12 @@ - error = -EXDEV; - if (old_nd.mnt != nd.mnt) - goto out_release; -- new_dentry = lookup_create(&nd, 0); -+ it.it_op = IT_LINK2; -+ new_dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(new_dentry); - if (!IS_ERR(new_dentry)) { - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); -+ intent_release(new_dentry, &it); - dput(new_dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1697,7 +1802,8 @@ - * locking]. - */ - int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - struct inode *target; -@@ -1757,6 +1863,7 @@ - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - if (target) { - if (!error) - target->i_flags |= S_DEAD; -@@ -1778,7 +1885,8 @@ - } - - int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - -@@ -1809,6 +1917,7 @@ - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - double_up(&old_dir->i_zombie, &new_dir->i_zombie); - if (error) - return error; -@@ -1820,13 +1929,14 @@ - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - if (S_ISDIR(old_dentry->d_inode->i_mode)) -- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); - else -- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); - if (!error) { - if (old_dir == new_dir) - inode_dir_notify(old_dir, DN_RENAME); -@@ -1843,6 +1953,7 @@ - int error = 0; - struct dentry * old_dir, * new_dir; - struct dentry * old_dentry, *new_dentry; -+ struct lookup_intent it = { .it_op = IT_RENAME }; - struct nameidata oldnd, newnd; - - if (path_init(oldname, LOOKUP_PARENT, &oldnd)) -@@ -1871,7 +1982,7 @@ - - double_lock(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -1887,18 +1998,21 @@ - if (newnd.last.name[newnd.last.len]) - goto exit4; - } -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ it.it_op = IT_RENAME2; -+ new_dentry = lookup_hash_it(&newnd.last, new_dir, &it); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; - - lock_kernel(); - error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ new_dir->d_inode, new_dentry, &it); - unlock_kernel(); - -+ intent_release(new_dentry, &it); - dput(new_dentry); - exit4: -+ intent_release(old_dentry, &it); - dput(old_dentry); - exit3: - double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); -@@ -1947,7 +2061,8 @@ - } - - 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; -@@ -1960,7 +2075,7 @@ - /* 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; -@@ -1982,7 +2097,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 */ -@@ -2024,7 +2145,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); ---- linux-pristine/./fs/open.c Thu Dec 5 10:49:20 2002 -+++ linux/./fs/open.c Fri Nov 29 18:06:21 2002 -@@ -19,6 +19,9 @@ - #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); -+extern void intent_release(struct dentry *de, struct lookup_intent *it); - - int vfs_statfs(struct super_block *sb, struct statfs *buf) - { -@@ -94,12 +97,13 @@ - struct nameidata nd; - struct inode * inode; - int error; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - - error = -EINVAL; - if (length < 0) /* sorry, but loff_t says... */ - goto out; - -- error = user_path_walk(path, &nd); -+ error = user_path_walk_it(path, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -144,6 +148,7 @@ - put_write_access(inode); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -235,8 +240,9 @@ - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -262,6 +268,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -279,8 +286,9 @@ - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - - if (error) - goto out; -@@ -307,6 +315,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -323,6 +332,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; -@@ -340,13 +350,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(nd.dentry, &it); - path_release(&nd); - } - -@@ -362,6 +373,7 @@ - int error; - struct nameidata nd; - char *name; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - name = getname(filename); - error = PTR_ERR(name); -@@ -370,7 +382,7 @@ - - error = 0; - if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd)) -- error = path_walk(name, &nd); -+ error = path_walk_it(name, &nd, &it); - putname(name); - if (error) - goto out; -@@ -382,6 +394,7 @@ - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -422,6 +435,7 @@ - int error; - struct nameidata nd; - char *name; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - name = getname(filename); - error = PTR_ERR(name); -@@ -430,7 +444,7 @@ - - path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW | - LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); -- error = path_walk(name, &nd); -+ error = path_walk_it(name, &nd, &it); - putname(name); - if (error) - goto out; -@@ -447,6 +461,7 @@ - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -491,8 +506,9 @@ - struct inode * inode; - int error; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -512,6 +528,7 @@ - error = notify_change(nd.dentry, &newattrs); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -581,10 +598,12 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -594,10 +613,12 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -631,10 +652,16 @@ - * for the internal routines (ie open_namei()/follow_link() etc). 00 is - * used by symlinks. - */ -+extern int open_namei_it(const char *filename, int namei_flags, int mode, -+ struct nameidata *nd, struct lookup_intent *it); -+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it); -+ - struct file *filp_open(const char * filename, int flags, int mode) - { - int namei_flags, error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_OPEN }; - - namei_flags = flags; - if ((namei_flags+1) & O_ACCMODE) -@@ -642,14 +669,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; -@@ -692,6 +720,7 @@ - } - f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); - -+ intent_release(dentry, it); - return f; - - cleanup_all: -@@ -706,11 +735,17 @@ - cleanup_file: - put_filp(f); - cleanup_dentry: -+ intent_release(dentry, it); - dput(dentry); - mntput(mnt); - return ERR_PTR(error); - } - -+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+{ -+ return dentry_open_it(dentry, mnt, flags, NULL); -+} -+ - /* - * Find an empty file descriptor entry, and mark it busy. - */ ---- linux-pristine/./fs/stat.c Thu Dec 5 10:49:22 2002 -+++ linux/./fs/stat.c Fri Nov 29 18:06:21 2002 -@@ -13,6 +13,7 @@ - - #include - -+extern void intent_release(struct dentry *de, struct lookup_intent *it); - /* - * Revalidate the inode. This is required for proper NFS attribute caching. - */ -@@ -135,13 +136,15 @@ - asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -151,13 +154,15 @@ - asmlinkage long sys_newstat(char * filename, struct stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -172,13 +177,15 @@ - asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -189,13 +196,15 @@ - asmlinkage long sys_newlstat(char * filename, struct stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -247,20 +256,21 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_READLINK }; - - if (bufsiz <= 0) - return -EINVAL; - -- error = user_path_walk_link(path, &nd); -+ error = user_path_walk_link_it(path, &nd, &it); - if (!error) { - struct inode * inode = nd.dentry->d_inode; -- - error = -EINVAL; - if (inode->i_op && inode->i_op->readlink && - !(error = do_revalidate(nd.dentry))) { - UPDATE_ATIME(inode); - error = inode->i_op->readlink(nd.dentry, buf, bufsiz); - } -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -333,12 +343,14 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -348,12 +360,14 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; ---- linux-pristine/./mm/slab.c Thu Dec 5 10:50:02 2002 -+++ linux/./mm/slab.c Fri Nov 29 18:06:21 2002 -@@ -1187,6 +1187,59 @@ - * Called with the cache-lock held. - */ - -+extern struct page *check_get_page(unsigned long kaddr); -+struct page *page_mem_map(struct page *page); -+static int kmem_check_cache_obj (kmem_cache_t * cachep, -+ slab_t *slabp, void * objp) -+{ -+ int i; -+ unsigned int objnr; -+ -+#if DEBUG -+ if (cachep->flags & SLAB_RED_ZONE) { -+ objp -= BYTES_PER_WORD; -+ if ( *(unsigned long *)objp != RED_MAGIC2) -+ /* Either write before start, or a double free. */ -+ return 0; -+ if (*(unsigned long *)(objp+cachep->objsize - -+ BYTES_PER_WORD) != RED_MAGIC2) -+ /* Either write past end, or a double free. */ -+ return 0; -+ } -+#endif -+ -+ objnr = (objp-slabp->s_mem)/cachep->objsize; -+ if (objnr >= cachep->num) -+ return 0; -+ if (objp != slabp->s_mem + objnr*cachep->objsize) -+ return 0; -+ -+ /* Check slab's freelist to see if this obj is there. */ -+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { -+ if (i == objnr) -+ return 0; -+ } -+ return 1; -+} -+ -+ -+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) -+{ -+ struct page *page = check_get_page((unsigned long)objp); -+ -+ if (!VALID_PAGE(page)) -+ return 0; -+ -+ if (!PageSlab(page)) -+ return 0; -+ -+ /* XXX check for freed slab objects ? */ -+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) -+ return 0; -+ -+ return (cachep == GET_PAGE_CACHE(page)); -+} -+ - #if DEBUG - static int kmem_extra_free_checks (kmem_cache_t * cachep, - slab_t *slabp, void * objp) diff --git a/lustre/patches/patch-2.4.9-chaos14 b/lustre/patches/patch-2.4.9-chaos14 deleted file mode 100644 index 24b5628..0000000 --- a/lustre/patches/patch-2.4.9-chaos14 +++ /dev/null @@ -1,331 +0,0 @@ -diff -ru ../kernel-2.4.9/drivers/block/blkpg.c ../kernel-2.4.9-lustre/drivers/block/blkpg.c ---- ../kernel-2.4.9/drivers/block/blkpg.c Wed Oct 31 17:50:05 2001 -+++ ../kernel-2.4.9-lustre/drivers/block/blkpg.c Mon May 13 14:35:35 2002 -@@ -326,7 +326,43 @@ - - 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() - * - * Description: This function will read any inaccessible blocks at the end -diff -ru ../kernel-2.4.9/drivers/block/loop.c ../kernel-2.4.9-lustre/drivers/block/loop.c ---- ../kernel-2.4.9/drivers/block/loop.c Wed Oct 31 17:50:05 2001 -+++ ../kernel-2.4.9-lustre/drivers/block/loop.c Mon May 13 14:23:05 2002 -@@ -482,6 +482,11 @@ - spin_unlock_irq(&lo->lo_lock); - - if (rw == WRITE) { -+#ifdef CONFIG_DEV_RDONLY -+ if (dev_check_rdonly(rbh->b_rdev)) -+ goto err; -+#endif -+ - if (lo->lo_flags & LO_FLAGS_READ_ONLY) - goto err; - } else if (rw == READA) { -diff -ru ../kernel-2.4.9/drivers/ide/ide-disk.c ../kernel-2.4.9-lustre/drivers/ide/ide-disk.c ---- ../kernel-2.4.9/drivers/ide/ide-disk.c Wed Oct 31 17:50:21 2001 -+++ ../kernel-2.4.9-lustre/drivers/ide/ide-disk.c Mon May 13 14:23:05 2002 -@@ -374,6 +374,12 @@ - */ - static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) - { -+#ifdef CONFIG_DEV_RDONLY -+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { -+ ide_end_request(1, HWGROUP(drive)); -+ return ide_stopped; -+ } -+#endif - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl,IDE_CONTROL_REG); - OUT_BYTE(0x00, IDE_FEATURE_REG); -diff -ru ../kernel-2.4.9/fs/jbd/commit.c ../kernel-2.4.9-lustre/fs/jbd/commit.c ---- ../kernel-2.4.9/fs/jbd/commit.c Wed Oct 31 17:51:37 2001 -+++ ../kernel-2.4.9-lustre/fs/jbd/commit.c Mon May 13 14:23:05 2002 -@@ -462,7 +462,7 @@ - transaction's t_log_list queue, and metadata buffers are on - the t_iobuf_list queue. - -- Wait for the transactions in reverse order. That way we are -+ Wait for the buffers in reverse order. That way we are - less likely to be woken up until all IOs have completed, and - so we incur less scheduling load. - */ -@@ -566,8 +566,10 @@ - - jbd_debug(3, "JBD: commit phase 6\n"); - -- if (is_journal_aborted(journal)) -+ if (is_journal_aborted(journal)) { -+ unlock_journal(journal); - goto skip_commit; -+ } - - /* Done it all: now write the commit record. We should have - * cleaned up our previous buffers by now, so if we are in abort -@@ -577,9 +579,10 @@ - descriptor = journal_get_descriptor_buffer(journal); - if (!descriptor) { - __journal_abort_hard(journal); -+ unlock_journal(journal); - goto skip_commit; - } -- -+ - /* AKPM: buglet - add `i' to tmp! */ - for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) { - journal_header_t *tmp = -@@ -600,7 +603,6 @@ - put_bh(bh); /* One for getblk() */ - journal_unlock_journal_head(descriptor); - } -- lock_journal(journal); - - /* End of a transaction! Finally, we can do checkpoint - processing: any buffers committed as a result of this -@@ -609,6 +611,25 @@ - - skip_commit: - -+ /* Call any callbacks that had been registered for handles in this -+ * transaction. It is up to the callback to free any allocated -+ * memory. -+ */ -+ if (!list_empty(&commit_transaction->t_jcb)) { -+ struct list_head *p, *n; -+ int error = is_journal_aborted(journal); -+ -+ list_for_each_safe(p, n, &commit_transaction->t_jcb) { -+ struct journal_callback *jcb; -+ -+ jcb = list_entry(p, struct journal_callback, jcb_list); -+ list_del(p); -+ jcb->jcb_func(jcb, error); -+ } -+ } -+ -+ lock_journal(journal); -+ - jbd_debug(3, "JBD: commit phase 7\n"); - - J_ASSERT(commit_transaction->t_sync_datalist == NULL); -diff -ru ../kernel-2.4.9/fs/jbd/journal.c ../kernel-2.4.9-lustre/fs/jbd/journal.c ---- ../kernel-2.4.9/fs/jbd/journal.c Wed Oct 31 17:51:37 2001 -+++ ../kernel-2.4.9-lustre/fs/jbd/journal.c Mon May 13 14:23:05 2002 -@@ -56,6 +56,7 @@ - #endif - EXPORT_SYMBOL(journal_flush); - EXPORT_SYMBOL(journal_revoke); -+EXPORT_SYMBOL(journal_callback_set); - - EXPORT_SYMBOL(journal_init_dev); - EXPORT_SYMBOL(journal_init_inode); -diff -ru ../kernel-2.4.9/fs/jbd/transaction.c ../kernel-2.4.9-lustre/fs/jbd/transaction.c ---- ../kernel-2.4.9/fs/jbd/transaction.c Sat Jan 26 01:42:21 2002 -+++ ../kernel-2.4.9-lustre/fs/jbd/transaction.c Mon May 13 14:23:05 2002 -@@ -59,6 +59,7 @@ - transaction->t_state = T_RUNNING; - transaction->t_tid = journal->j_transaction_sequence++; - transaction->t_expires = jiffies + journal->j_commit_interval; -+ INIT_LIST_HEAD(&transaction->t_jcb); - - /* Set up the commit timer for the new transaction. */ - J_ASSERT (!journal->j_commit_timer_active); -@@ -202,6 +203,20 @@ - return 0; - } - -+/* Allocate a new handle. This should probably be in a slab... */ -+static handle_t *get_handle(int nblocks) -+{ -+ handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ if (!handle) -+ return NULL; -+ memset(handle, 0, sizeof (handle_t)); -+ handle->h_buffer_credits = nblocks; -+ handle->h_ref = 1; -+ INIT_LIST_HEAD(&handle->h_jcb); -+ -+ return handle; -+} -+ - /* - * Obtain a new handle. - * -@@ -228,14 +243,11 @@ - handle->h_ref++; - return handle; - } -- -- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ -+ handle = get_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); -- memset (handle, 0, sizeof (handle_t)); - -- handle->h_buffer_credits = nblocks; -- handle->h_ref = 1; - current->journal_info = handle; - - err = start_this_handle(journal, handle); -@@ -334,14 +346,11 @@ - - if (is_journal_aborted(journal)) - return ERR_PTR(-EIO); -- -- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ -+ handle = get_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); -- memset (handle, 0, sizeof (handle_t)); - -- handle->h_buffer_credits = nblocks; -- handle->h_ref = 1; - current->journal_info = handle; - - err = try_start_this_handle(journal, handle); -@@ -1328,6 +1337,29 @@ - #endif - - /* -+ * Register a callback function for this handle. The function will be -+ * called when the transaction that this handle is part of has been -+ * committed to disk with the original callback data struct and the -+ * error status of the journal as parameters. There is no guarantee of -+ * ordering between handles within a single transaction, nor between -+ * callbacks registered on the same handle. -+ * -+ * The caller is responsible for allocating the journal_callback struct. -+ * This is to allow the caller to add as much extra data to the callback -+ * as needed, but reduce the overhead of multiple allocations. The caller -+ * allocated struct must start with a struct journal_callback at offset 0, -+ * and has the caller-specific data afterwards. -+ */ -+void journal_callback_set(handle_t *handle, void (*func)(void *, int), -+ void *cb_data) -+{ -+ struct journal_callback *jcb = cb_data; -+ -+ list_add(&jcb->jcb_list, &handle->h_jcb); -+ jcb->jcb_func = func; -+} -+ -+/* - * All done for a particular handle. - * - * There is not much action needed here. We just return any remaining -@@ -1409,7 +1439,10 @@ - wake_up(&journal->j_wait_transaction_locked); - } - -- /* -+ /* Move callbacks from the handle to the transaction. */ -+ list_splice(&handle->h_jcb, &transaction->t_jcb); -+ -+ /* - * If the handle is marked SYNC, we need to set another commit - * going! We also want to force a commit if the current - * transaction is occupying too much of the log, or if the -diff -ru ../kernel-2.4.9/include/linux/blkdev.h ../kernel-2.4.9-lustre/include/linux/blkdev.h ---- ../kernel-2.4.9/include/linux/blkdev.h Thu May 9 12:59:13 2002 -+++ ../kernel-2.4.9-lustre/include/linux/blkdev.h Mon May 13 14:23:05 2002 -@@ -257,5 +257,9 @@ - #define blk_started_io(nsects) \ - atomic_add(nsects, &queued_sectors); - -+#define CONFIG_DEV_RDONLY -+void dev_set_rdonly(kdev_t, int); -+int dev_check_rdonly(kdev_t); -+void dev_clear_rdonly(int); - #endif - -diff -ru ../kernel-2.4.9/include/linux/jbd.h ../kernel-2.4.9-lustre/include/linux/jbd.h ---- ../kernel-2.4.9/include/linux/jbd.h Thu May 9 12:59:02 2002 -+++ ../kernel-2.4.9-lustre/include/linux/jbd.h Mon May 13 14:23:05 2002 -@@ -251,6 +251,13 @@ - return bh->b_private; - } - -+#define HAVE_JOURNAL_CALLBACK_STATUS -+struct journal_callback { -+ struct list_head jcb_list; -+ void (*jcb_func)(void *cb_data, int error); -+ /* user data goes here */ -+}; -+ - struct jbd_revoke_table_s; - - /* The handle_t type represents a single atomic update being performed -@@ -281,6 +288,12 @@ - operations */ - int h_err; - -+ /* List of application registered callbacks for this handle. -+ * The function(s) will be called after the transaction that -+ * this handle is part of has been committed to disk. -+ */ -+ struct list_head h_jcb; -+ - /* Flags */ - unsigned int h_sync: 1; /* sync-on-close */ - unsigned int h_jdata: 1; /* force data journaling */ -@@ -400,6 +413,10 @@ - - /* How many handles used this transaction? */ - int t_handle_count; -+ -+ /* List of registered callback functions for this transaction. -+ * Called when the transaction is committed. */ -+ struct list_head t_jcb; - }; - - -@@ -647,6 +664,8 @@ - extern int journal_try_to_free_buffers(journal_t *, struct page *, int); - extern int journal_stop(handle_t *); - extern int journal_flush (journal_t *); -+extern void journal_callback_set(handle_t *handle, void (*func)(void *), -+ void *cb_data); - - extern void journal_lock_updates (journal_t *); - extern void journal_unlock_updates (journal_t *); diff --git a/lustre/ptlrpc/connmgr.c b/lustre/ptlrpc/connmgr.c deleted file mode 100644 index c93c17d..0000000 --- a/lustre/ptlrpc/connmgr.c +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * obd/rpc/recovd.c - * - * Lustre High Availability Daemon - * - * Copyright (C) 2001, 2002 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * by Peter Braam - * - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_RPC - -#include -#include -#include - -static int connmgr_unpack_body(struct ptlrpc_request *req) -{ - struct connmgr_body *b = lustre_msg_buf(req->rq_repmsg, 0); - if (b == NULL) { - LBUG(); - RETURN(-EINVAL); - } - - b->generation = NTOH__u32(b->generation); - - return 0; -} - -int connmgr_connect(struct recovd_obd *recovd, struct ptlrpc_connection *conn) -{ - struct ptlrpc_request *req; - struct ptlrpc_client *cl; - struct connmgr_body *body; - int rc, size = sizeof(*body); - ENTRY; - - if (!recovd) { - CERROR("no manager\n"); - LBUG(); - } - cl = recovd->recovd_client; - - req = ptlrpc_prep_req(cl, conn, CONNMGR_CONNECT, 1, &size, NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - body->generation = HTON__u32(conn->c_generation); - body->conn = (__u64)(unsigned long)conn; - body->conn_token = conn->c_token; - strncpy(body->conn_uuid, conn->c_local_uuid, sizeof(body->conn_uuid)); - - req->rq_replen = lustre_msg_size(1, &size); - - rc = ptlrpc_queue_wait(req); - rc = ptlrpc_check_status(req, rc); - if (!rc) { - rc = connmgr_unpack_body(req); - if (rc) - GOTO(out_free, rc); - body = lustre_msg_buf(req->rq_repmsg, 0); - CDEBUG(D_NET, "remote generation: %o\n", body->generation); - conn->c_level = LUSTRE_CONN_CON; - conn->c_remote_conn = body->conn; - conn->c_remote_token = body->conn_token; - strncpy(conn->c_remote_uuid, body->conn_uuid, - sizeof(conn->c_remote_uuid)); - } - - EXIT; - out_free: - ptlrpc_free_req(req); - out: - return rc; -} - -static int connmgr_handle_connect(struct ptlrpc_request *req) -{ - struct connmgr_body *body; - int rc, size = sizeof(*body); - ENTRY; - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) { - CERROR("connmgr: out of memory\n"); - req->rq_status = -ENOMEM; - RETURN(0); - } - - body = lustre_msg_buf(req->rq_reqmsg, 0); - connmgr_unpack_body(req); - - req->rq_connection->c_remote_conn = body->conn; - req->rq_connection->c_remote_token = body->conn_token; - strncpy(req->rq_connection->c_remote_uuid, body->conn_uuid, - sizeof(req->rq_connection->c_remote_uuid)); - - CERROR("incoming generation %d\n", body->generation); - body = lustre_msg_buf(req->rq_repmsg, 0); - body->generation = 4711; - body->conn = (__u64)(unsigned long)req->rq_connection; - body->conn_token = req->rq_connection->c_token; - - req->rq_connection->c_level = LUSTRE_CONN_CON; - RETURN(0); -} - -int connmgr_handle(struct obd_device *dev, struct ptlrpc_service *svc, - struct ptlrpc_request *req) -{ - int rc; - ENTRY; - - rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); - if (rc) { - CERROR("Invalid request\n"); - GOTO(out, rc); - } - - if (req->rq_reqmsg->type != NTOH__u32(PTL_RPC_MSG_REQUEST)) { - CERROR("wrong packet type sent %d\n", - req->rq_reqmsg->type); - GOTO(out, rc = -EINVAL); - } - - switch (req->rq_reqmsg->opc) { - case CONNMGR_CONNECT: - CDEBUG(D_INODE, "connmgr connect\n"); - rc = connmgr_handle_connect(req); - break; - - default: - rc = ptlrpc_error(svc, req); - RETURN(rc); - } - - EXIT; -out: - if (rc) { - ptlrpc_error(svc, req); - } else { - CDEBUG(D_NET, "sending reply\n"); - ptlrpc_reply(svc, req); - } - - return 0; -} diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c deleted file mode 100644 index 48a8401..0000000 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#include - -int rd_uuid(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len=0; - len+=snprintf(page, count, "%s\n", - ((struct obd_device*)data)->obd_uuid); - return len; - -} - -lprocfs_vars_t status_var_nm_1[]={ - {"status/uuid", rd_uuid, 0}, - {0} -}; -int rd_numdevices(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_type* class=(struct obd_type*)data; - int len=0; - len+=snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -lprocfs_vars_t status_class_var[]={ - {"status/num_devices", rd_numdevices, 0}, - {0} -}; diff --git a/lustre/scripts/lustre b/lustre/scripts/lustre deleted file mode 100755 index 6a1ff0a..0000000 --- a/lustre/scripts/lustre +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash -# -# lustre This shell script takes care of starting and stopping Lustre -# -# chkconfig: 345 99 1 -# description: Lustre Lite network File System. \ -# This starts both Lustre client and server functions. -# processname: obdctl -# config: /etc/lustre/lustre.cfg -# pidfile: /var/run/lustre.pid - -SERVICE=lustre -LOCK=/var/lock/subsys/$SERVICE - -# Source function library. -if [ -f /etc/init.d/functions ] ; then - . /etc/init.d/functions -fi - -# Source networking configuration. -if [ -f /etc/sysconfig/network ] ; then - . /etc/sysconfig/network -fi - -# Check that networking is up. -[ "${NETWORKING}" = "no" ] && exit 0 - -[ -f /usr/sbin/obdctl ] || exit 0 - -start() { - echo -n $"Starting $SERVICE: " - /usr/sbin/llrsetup.sh - RETVAL=$? - echo $SERVICE - [ $RETVAL = 0 ] && touch $LOCK -} - -stop() { - echo -n $"Shutting down $SERVICE: " - /usr/sbin/llcleanup.sh - echo $SERVICE - rm -f $LOCK -} - -restart() { - stop - start -} - -# See how we were called. -case "$1" in - start) - start - ;; - stop) - stop - ;; - restart) - restart - ;; - status) - status $SERVICE - ;; - *) - echo $"Usage: $SERVICE {start|stop|restart|status}" - exit 1 -esac - -exit $RETVAL - diff --git a/lustre/scripts/nodelustre b/lustre/scripts/nodelustre deleted file mode 100755 index b5e6540..0000000 --- a/lustre/scripts/nodelustre +++ /dev/null @@ -1,46 +0,0 @@ -#! /bin/sh -# nodelustre - Start and stop Lustre on MCR nodes -# Copyright (C) 2002 Cluster File Systems, Inc. -# Gord Eagle , 2002-09-10 - -# Set this to the shared config file. -MASTER_CONFIG=http://emcri/lustre.xml -CONFIG=/etc/lustre/lustre.xml -COMPUTE_NODE=client - -LCONF=/usr/local/cfs/lustre/utils/lconf -WGET=wget - -case "$1" in -start | stop) - # Fetch the config file. We can't use --output-document because it - # makes Wget ignore timestamping. - if test -n "$MASTER_CONFIG"; then - (cd `echo "$CONFIG" | sed 's%/[^/]*$%%'` && \ - $WGET --timestamping "$MASTER_CONFIG") || exit $? - fi - - # Map all client nodes to the COMPUTE_NODE virtual node. - if test -n "$COMPUTE_NODE" && nodeattr compute; then - node=" --node $COMPUTE_NODE" - else - node= - fi - - # If we're stopping, do the lconf cleanup. - if test "$1" = stop; then - cleanup=' --cleanup' - else - cleanup= - fi - - $LCONF$cleanup$node "$CONFIG" - ;; - -*) - echo "$0 {start|stop}" 1>&2 - exit 1 - ;; -esac - -exit 0 diff --git a/lustre/scripts/version_tag.pl b/lustre/scripts/version_tag.pl deleted file mode 100644 index f74ac27..0000000 --- a/lustre/scripts/version_tag.pl +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/perl -$pristine=1; -if($ARGV[0]){chdir($ARGV[0]);} -get_linuxdir(); -get_tag(); -get_latest_mtime(); -generate_ver(); - -sub get_tag -{ - $tag=open(TAG,"CVS/Tag"); - if(!$tag){ - $tag="HEAD"; - } else { - $tag=; - $tag=~/.(.*)$/; - $tag=$1; - close(TAG); - } -} -sub get_latest_mtime -{ - use Time::Local; - %months=("Jan"=>1,"Feb"=>2,"Mar"=>3,"Apr"=>4,"May"=>5, - "Jun"=>6,"Jul"=>7,"Aug"=>8,"Sep"=>9,"Oct"=>10, - "Nov"=>11,"Dec"=>12); - - $last_mtime=0; - @entries=`find . -name Entries`; - foreach $entry(@entries){ - open(ENTRY,$entry); - while() { - $line=$_; - @temp_file_entry=split("/",$line); - $time_entry=$temp_file_entry[3]; - $file=$temp_file_entry[1]; - - $cur_dir=$entry; - $cur_dir=~s/\/CVS\/Entries$//g; - chomp($cur_dir); - ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, - $atime,$mtime,$ctime,$blksize,$blocks) - = stat($cur_dir."/".$file); - $local_date=gmtime($mtime); - if(! ($local_date =~ /$time_entry/) && - !($temp_file_entry[0] =~ /D/) && - !($file =~ /lustre\.spec\.in/)) { - #print "$file\n"; - $pristine=0; - } - - if($time_entry && - $file =~ m/\.c$|\.h$|\.am$|\.in$/ && - !($file =~ /lustre\.spec\.in/)){ - - @time=split(" ",$time_entry); - ($hours,$min,$sec)=split(":",$time[3]); - ($mday, $mon, $year)=($time[2],$time[1], - $time[4]); - $secs=0; - $mon=$months{$mon}; - if($mon>0 && $mon<13){ - $secs=timelocal($sec,$min,$hours,$mday, - $mon,$year); - } - if($secs>$last_mtime){ - $last_mtime=$secs; - $show_last=$hours.$min.$sec. - $year.$mon.$mday; - } - - } - } - close(ENTRY); - } -} - -sub get_linuxdir -{ - open(CONFIG,"config.status") or die "Run ./configure first \n"; - while($line=){ - $line =~ /(.*)\%\@LINUX\@\%(.*)\%g/; - if($2){$linuxdir=$2;last;} - } - close(CONFIG); - open(VER,"$linuxdir/include/linux/version.h") - or die "Run make dep on $linuxdir \n"; - while($line=){ - $line =~ /#define UTS_RELEASE "(.*)"/; - if($1){ $kernver=$1; last;} - } - chomp($kernver); - $linuxdir=~s/\//\./g; - close(VER); -} - -sub generate_ver -{ - print "#define BUILD_VERSION \""; - if($pristine){ - print "$tag-$show_last-PRISTINE-$linuxdir-$kernver\"\n"; - }else{ - print "$tag-$show_last-CHANGED-$linuxdir-$kernver\"\n"; - } -} diff --git a/lustre/tests/ba-echo.sh b/lustre/tests/ba-echo.sh deleted file mode 100644 index d971016..0000000 --- a/lustre/tests/ba-echo.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -config=${1:-ba-echo.xml} - -LMC="save_cmd" -LMC_REAL="../../lustre/utils/lmc -m $config" - -PORT=988 -TCPBUF=1048576 -OST=ba-ost-1 -CLIENT=client - -UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt} - -h2ip () { - echo "${1}" -} -BATCH=/tmp/lmc-batch.$$ -save_cmd() { - echo "$@" >> $BATCH -} - -[ -f $config ] && rm $config - -# Client node -${LMC} --node $CLIENT --tcpbuf $TCPBUF --net '*' tcp $PORT - -OBD_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST` -[ "$OBD_UUID" ] && OBD_UUID="--obduuid=$OBD_UUID" || echo "$OST: no UUID" - -# server node -${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp $PORT -${LMC} --node $OST --obdtype=obdecho $OBD_UUID --ost - -# osc on client -${LMC} --node $CLIENT --osc OSC_$OST - -$LMC_REAL --batch $BATCH -rm -f $BATCH diff --git a/lustre/tests/ba-mount.sh b/lustre/tests/ba-mount.sh deleted file mode 100644 index 2a2ff3d..0000000 --- a/lustre/tests/ba-mount.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -# There are configurations for three machines in this config file: the OST, -# the MDS/client, other clients -# -# To start your cluster using the ba-mount.xml file that this produces, first -# run: -# > lconf ba-mount.xml -# on the MDS/client, and then run: -# > lconf --node client ba-mount.xml -# on any other clients. - -config=${1:-ba-mount.xml} - -LMC_REAL="${LMC:-../utils/lmc} -m config" -LMC="save_cmd" - -PORT=988 -TCPBUF=1048576 -OST=ba-ost-1 -MDS=mds-hostname - -UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt} - -h2ip () { - echo "${1}" -} -BATCH=/tmp/lmc-batch.$$ -save_cmd() { - echo "$@" >> $BATCH -} - -[ -f $config ] && rm $config - -# MDS/client node -${LMC} --node $MDS --tcpbuf $TCPBUF --net '*' tcp $PORT -${LMC} --node $MDS --mds mds1 /tmp/mds1 50000 - -OBD_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST` -[ "$OBD_UUID" ] && OBD_UUID="--obduuid=$OBD_UUID" || echo "$OST: no UUID" - -# server node -${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp $PORT -${LMC} --node $OST $OBD_UUID --ost bluearc - -# mount point on the MDS/client -${LMC} --node $MDS --mtpt /mnt/lustre mds1 OSC_$OST - -# other clients -${LMC} --node client --tcpbuf $TCPBUF --net '*' tcp $PORT -${LMC} --node client --mtpt /mnt/lustre mds1 OSC_$OST - -$LMC_REAL --batch $BATCH -rm -f $BATCH diff --git a/lustre/tests/checkstat.c b/lustre/tests/checkstat.c deleted file mode 100644 index f09fde9..0000000 --- a/lustre/tests/checkstat.c +++ /dev/null @@ -1,314 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void -usage (char *argv0, int help) -{ - char *progname = strrchr(argv0, '/'); - - if (progname == NULL) - progname = argv0; - - fprintf (help ? stdout : stderr, - "Usage: %s [flags] file[s]\n", - progname); - - if (!help) - { - fprintf (stderr, " or try '-h' for help\n"); - exit (1); - } - - printf ("Check given files have...\n"); - printf (" -p permission file must have required permissions\n"); - printf (" -t dir|file|link file must be of the specified type\n"); - printf (" -l link_name file must be a link to the given name\n"); - printf (" -s size file must have the given size\n"); - printf (" -u user file must be owned by given user\n"); - printf (" -g group file must be owned by given group\n"); - printf (" -f follow symlinks\n"); - printf (" -a file must be absent\n"); - printf (" -v increase verbosity\n"); - printf (" -h print help\n"); - printf (" Exit status is 0 on success, 1 on failure\n"); -} - -int -main (int argc, char **argv) -{ - int c; - struct stat64 buf; - int perms = -1; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - char *type = NULL; - long absent = 0; - char *checklink = NULL; - int verbose = 0; - long long size = -1; - int follow = 0; - char *term; - - while ((c = getopt (argc, argv, "p:t:l:s:u:g:avfh")) != -1) - switch (c) - { - case 'p': - perms = (int)strtol (optarg, &term, 0); - if (term == optarg) - { - fprintf (stderr, "Can't parse permission %s\n", optarg); - return (1); - } - break; - - case 'l': - checklink = optarg; - break; - - case 's': - size = strtoll (optarg, &term, 0); - if (term == optarg) - { - fprintf (stderr, "Can't parse size %s\n", optarg); - return (1); - } - break; - - case 'u': - if (*optarg == '#') - { - uid = (uid_t)strtol (optarg + 1, &term, 0); - if (term == optarg + 1) - { - fprintf (stderr, "Can't parse numeric uid %s\n", optarg); - return (1); - } - } else { - struct passwd *pw = getpwnam (optarg); - - if (pw == NULL) - { - fprintf (stderr, "Can't find user %s\n", optarg); - return (1); - } - uid = pw->pw_uid; - } - break; - - case 'g': - if (*optarg == '#') - { - gid = (gid_t)strtol (optarg + 1, &term, 0); - if (term == optarg + 1) - { - fprintf (stderr, "Can't parse numeric gid %s\n", optarg); - return (1); - } - } else { - struct group *gr = getgrnam (optarg); - - if (gr == NULL) - { - fprintf (stderr, "Can't find group %s\n", optarg); - return (1); - } - uid = gr->gr_gid; - } - break; - - case 't': - type = optarg; - break; - - case 'a': - absent = 1; - break; - - case 'v': - verbose++; - break; - - case 'f': - follow++; - break; - - case 'h': - usage (argv[0], 1); - return (0); - - default: - usage (argv[0], 0); - } - - if (optind == argc) - usage (argv[0], 0); - - do - { - char *fname = argv[optind]; - int rc = follow ? stat64 (fname, &buf) : lstat64 (fname, &buf); - - if (rc != 0) - { - if (!(absent && errno == ENOENT)) - { - if (verbose) - printf ("Can't %sstat %s: %s\n", - follow ? "" : "l", - fname, strerror (errno)); - return (1); - } - - if (verbose) - printf ("%s: absent OK\n", fname); - continue; - } - - if (absent) - { - if (verbose) - printf ("%s exists\n", fname); - return (1); - } - - if (type != NULL) - { - if (!strcmp (type, "d") || - !strcmp (type, "dir")) - { - if (!S_ISDIR (buf.st_mode)) - { - if (verbose) - printf ("%s is not a directory\n", - fname); - return (1); - } - } - else if (!strcmp (type, "f") || - !strcmp (type, "file")) - { - if (!S_ISREG (buf.st_mode)) - { - if (verbose) - printf ("%s is not a regular file\n", - fname); - return (1); - } - } - else if (!strcmp (type, "l") || - !strcmp (type, "link")) - { - if (!S_ISLNK (buf.st_mode)) - { - if (verbose) - printf ("%s is not a link\n", - fname); - return (1); - } - } - else - { - fprintf (stderr, "Can't parse file type %s\n", type); - return (1); - } - - if (verbose) - printf ("%s has type %s OK\n", fname, type); - } - - if (perms != -1) - { - if ((buf.st_mode & ~S_IFMT) != perms) - { - if (verbose) - printf ("%s has perms 0%o, not 0%o\n", - fname, (buf.st_mode & ~S_IFMT), perms); - return (1); - } - - if (verbose) - printf ("%s has perms 0%o OK\n", - fname, perms); - } - - if (size != -1) - { - if (buf.st_size != size) - { - if (verbose) - printf ("%s has size %Ld, not %Ld\n", - fname, (long long)buf.st_size, size); - return (1); - } - - if (verbose) - printf ("%s has size %Ld OK\n", fname, size); - } - - if (checklink != NULL) - { - static char lname[4<<10]; - - rc = readlink (fname, lname, sizeof (lname) - 1); - - if (rc < 0) - { - if (verbose) - printf ("%s: can't read link: %s\n", - fname, strerror (errno)); - return (1); - } - - lname[rc] = 0; - if (strcmp (checklink, lname)) - { - if (verbose) - printf ("%s is a link to %s and not %s\n", - fname, lname, checklink); - return (1); - } - - if (verbose) - printf ("%s links to %s OK\n", fname, checklink); - } - - if (uid != (uid_t)-1) - { - if (buf.st_uid != uid) - { - if (verbose) - printf ("%s is owned by user #%ld and not #%ld\n", - fname, (long)buf.st_uid, (long)uid); - return (1); - } - - if (verbose) - printf ("%s is owned by user #%ld OK\n", - fname, (long)uid); - } - - if (gid != (gid_t)-1) - { - if (buf.st_gid != gid) - { - if (verbose) - printf ("%s is owned by group #%ld and not #%ld\n", - fname, (long)buf.st_gid, (long)gid); - return (1); - } - - if (verbose) - printf ("%s is owned by group #%ld OK\n", - fname, (long)gid); - } - } while (++optind < argc); - - return (0); -} diff --git a/lustre/tests/client-mount.cfg b/lustre/tests/client-mount.cfg deleted file mode 100644 index 6f2addb..0000000 --- a/lustre/tests/client-mount.cfg +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# Config file for mounting a client Lustre filesystem -SETUP_MDC=y -SETUP_OSC=y -OSCMT=/mnt/lustre -SETUP_MOUNT=y diff --git a/lustre/tests/cobd.sh b/lustre/tests/cobd.sh deleted file mode 100755 index 3f6521a..0000000 --- a/lustre/tests/cobd.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - - -config=${1:-$(basename $0 .sh)}.xml - -LMC=${LMC:-../utils/lmc -m $config} -TMP=${TMP:-/tmp} - -MDSDEV=$TMP/mds1 -MDSSIZE=50000 - -OSTDEV=$TMP/ost1 -OSTSIZE=200000 - -kver=`uname -r | cut -d "." -f 1,2` - -case $kver in - 2.4) FSTYPE="--fstype=extN" ;; - 2.5) FSTYPE="--fstype=ext3" ;; - *) echo "Kernel version $kver not supported" - exit 1 - ;; -esac - -rm -f $config -# create nodes -${LMC} --add node --node localhost || exit 10 -${LMC} --add net --node localhost --nid localhost --nettype tcp || exit 11 - -# configure mds server -${LMC} --add mds --node localhost --mds mds1 --dev $MDSDEV --size $MDSSIZE || exit 20 - -# configure ost -${LMC} --add ost --node localhost --obd obd1 --obdtype obdecho || exit 30 -# configure ost -${LMC} --add ost --node localhost --obd obd2 --obdtype obdecho || exit 30 - -${LMC} --add cobd --node localhost --real_obd obd1 --cache_obd obd2 - -# create client config -# ${LMC} -m $config --add mtpt --node localhost --path /mnt/lustre --mds mds1 --obd obd1 || exit 40 diff --git a/lustre/tests/createmany.c b/lustre/tests/createmany.c deleted file mode 100644 index 27ba3f7..0000000 --- a/lustre/tests/createmany.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char ** argv) -{ - int i, rc, count; - char filename[4096]; - - if (argc < 3) { - printf("Usage %s filenamebase count\n", argv[0]); - return 1; - } - - if (strlen(argv[1]) > 4080) { - printf("name too long\n"); - return 1; - } - - count = strtoul(argv[2], NULL, 0); - - - for (i=0 ; i < count ; i++) { - sprintf(filename, "%s-%d", argv[1], i); - rc = mknod(filename, S_IFREG| 0444, 0); - if (rc) { - printf("mknod(%s) error: %s\n", - filename, strerror(errno)); - break; - } - } - return rc; -} diff --git a/lustre/tests/directio.c b/lustre/tests/directio.c deleted file mode 100644 index e495517..0000000 --- a/lustre/tests/directio.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -// not correctly in the headers yet!! -#ifndef O_DIRECT -#define O_DIRECT 040000 /* direct disk access hint */ -#endif - -#define BLOCKSIZE 4096 - -int main(int argc, char **argv) -{ - int fd; - char *buf; - int pages; - int rc; - - if (argc != 3) { - printf("Usage: %s file nr_pages\n", argv[0]); - return 1; - } - - pages = strtoul(argv[2], 0, 0); - printf("directio on %s for %d pages \n", argv[1], pages); - - buf = mmap(0, pages * BLOCKSIZE, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON, 0, 0); - if (!buf) { - printf("No memory %s\n", strerror(errno)); - return 1; - } - - fd = open(argv[1], O_DIRECT | O_RDWR | O_CREAT); - if (fd == -1) { - printf("Cannot open %s: %s\n", argv[1], strerror(errno)); - return 1; - } - - rc = read(fd, buf, pages * BLOCKSIZE); - if (rc != pages * BLOCKSIZE) { - printf("Read error: %s, rc %d\n", strerror(errno), rc); - return 1; - } - - if ( lseek(fd, 0, SEEK_SET) != 0 ) { - printf("Cannot seek %s\n", strerror(errno)); - return 1; - } - - rc = write(fd, buf, pages * BLOCKSIZE); - if (rc != pages * BLOCKSIZE) { - printf("Write error %s\n", strerror(errno)); - return 1; - } - - return 0; -} diff --git a/lustre/tests/elan-client.cfg b/lustre/tests/elan-client.cfg deleted file mode 100644 index 1978c12..0000000 --- a/lustre/tests/elan-client.cfg +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -# Config file for setting up a remote server with a real OST -NETWORK=elan -LOCALHOST=5 -SERVER=4 - -[ -z "$RSH" ] && RSH=ssh -RSH_MDS="$RSH dev$SERVER" -RSH_OST="$RSH dev$SERVER" -RSH_OSC=eval diff --git a/lustre/tests/elan-server.cfg b/lustre/tests/elan-server.cfg deleted file mode 100644 index 7520840..0000000 --- a/lustre/tests/elan-server.cfg +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# Config file for setting up a remote server with a real OST -NETWORK=elan -LOCALHOST=4 -SERVER=4 diff --git a/lustre/tests/llcleanup.sh b/lustre/tests/llcleanup.sh deleted file mode 100755 index 4cf2879..0000000 --- a/lustre/tests/llcleanup.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -SRCDIR="`dirname $0`" -. $SRCDIR/common.sh - -setup_opts "$@" - -$DBGCTL get_debug > /tmp/debug.1 -cleanup_client -$DBGCTL get_debug > /tmp/debug.2 -cleanup_server - -$DBGCTL get_debug > /tmp/debug.3 -cleanup_lustre -$DBGCTL get_debug > /tmp/debug.4 -cleanup_portals diff --git a/lustre/tests/llmount2-hack.sh b/lustre/tests/llmount2-hack.sh deleted file mode 100644 index 495626c..0000000 --- a/lustre/tests/llmount2-hack.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -# suggested boilerplate for test script - -LCONF=${LCONF:-../utils/lconf} -NAME=${NAME:-local2-hack} - -config=$NAME.xml - -${LCONF} --reformat --gdb $config || exit 2 - -../utils/lctl < - - - - - - - - - - - - - localhost - 988 - - - - extN - /tmp/mds1 - yes - - - - - extN - /tmp/ost1 - yes - - - - - - - - - - - - - /mnt/lustre1 - - diff --git a/lustre/tests/mds-failover.xml b/lustre/tests/mds-failover.xml deleted file mode 100644 index 135288d..0000000 --- a/lustre/tests/mds-failover.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - uml1 - 666 - - - - - - - - - - - - - uml2 - 666 - - - - - - - - - - - - - - - - - - - - - - - - - - extN - /tmp/mds - yes - - - - - - extN - /tmp/mds - yes - - - - - - - - - - - - - - extN - /tmp/obd1 - yes - - - - extN - /tmp/obd2 - yes - - - - /mnt/lustre - - - - - - diff --git a/lustre/tests/mds.cfg b/lustre/tests/mds.cfg deleted file mode 100644 index 7807b33..0000000 --- a/lustre/tests/mds.cfg +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# Config file for setting up a metadata server -MDSFS=ext3 -MDSDEV=/tmp/mds -MDSSIZE=10000 -SETUP_MDS=y diff --git a/lustre/tests/mkdirmany.c b/lustre/tests/mkdirmany.c deleted file mode 100755 index ce2e5d4..0000000 --- a/lustre/tests/mkdirmany.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char ** argv) -{ - int i, rc, count; - char dirname[4096]; - - if (argc < 3) { - printf("Usage %s dirnamebase count\n", argv[0]); - return 1; - } - - if (strlen(argv[1]) > 4080) { - printf("name too long\n"); - return 1; - } - - count = strtoul(argv[2], NULL, 0); - - - for (i=0 ; i < count ; i++) { - sprintf(dirname, "%s-%d", argv[1], i); - rc = mkdir(dirname, 0755); - if (rc) { - printf("mkdir(%s) error: %s\n", - dirname, strerror(errno)); - break; - } - } - return rc; -} diff --git a/lustre/tests/mount2.sh b/lustre/tests/mount2.sh deleted file mode 100644 index 7c25103..0000000 --- a/lustre/tests/mount2.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -config=${1:-mount2.xml} - -LMC=${LMC:-../utils/lmc} -TMP=${TMP:-/tmp} - -MDSDEV=$TMP/mds1 -MDSSIZE=50000 - -OSTDEV=$TMP/ost1 -OSTSIZE=100000 - -kver=`uname -r | cut -d "." -f 1,2` - -case $kver in - 2.4) FSTYPE="--fstype=extN" ;; - 2.5) FSTYPE="--fstype=ext3" ;; - *) echo "Kernel version $kver not supported" - exit 1 - ;; -esac - -# create nodes -${LMC} -o $config --node localhost --net localhost tcp || exit 1 - -# configure mds server -${LMC} -m $config --format --node localhost $FSTYPE --mds mds1 $MDSDEV $MDSSIZE || exit 2 - -# configure ost -${LMC} -m $config --format --node localhost $FSTYPE --ost $OSTDEV $OSTSIZE || exit 3 - -# create client config -${LMC} -m $config --node localhost --mtpt /mnt/lustre mds1 OSC_localhost || exit 4 -${LMC} -m $config --node localhost --mtpt /mnt/lustre2 mds1 OSC_localhost || exit 4 diff --git a/lustre/tests/mount2fs.sh b/lustre/tests/mount2fs.sh deleted file mode 100644 index 9e766cb..0000000 --- a/lustre/tests/mount2fs.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -# -# Test case for 2 different filesystems mounted on the same client. -# Uses 3 umls - -config=${1-mds-bug.xml} -LMC=${LMC-../utils/lmc} -TMP=${TMP:-/tmp} - -MDSDEV=$TMP/mds1 -MDSDEV2=$TMP/mds2 -MDSSIZE=50000 - -OSTDEV1=$TMP/ost1 -OSTDEV2=$TMP/ost2 -OSTSIZE=100000 - -MDSNODE=uml1 -OSTNODE=uml2 -CLIENT=uml3 - -# create nodes -${LMC} -o $config --node $MDSNODE --net $MDSNODE tcp || exit 1 -${LMC} -m $config --node $OSTNODE --net $OSTNODE tcp || exit 2 -${LMC} -m $config --node $CLIENT --net $CLIENT tcp || exit 3 - -# configure mds server -${LMC} -m $config --format --node $MDSNODE --mds mds1 $MDSDEV $MDSSIZE ||exit 10 -${LMC} -m $config --format --node $MDSNODE --mds mds2 $MDSDEV2 $MDSSIZE ||exit 10 - -# configure ost -${LMC} -m $config --lov lov1 mds1 65536 0 0 || exit 20 -${LMC} -m $config --lov lov2 mds2 65536 0 0 || exit 20 -${LMC} -m $config --node $OSTNODE --lov lov1 --ost $OSTDEV1 $OSTSIZE || exit 21 -${LMC} -m $config --node $OSTNODE --lov lov2 --ost $OSTDEV2 $OSTSIZE || exit 22 - -# create client config -${LMC} -m $config --node $CLIENT --mtpt /mnt/lustre mds1 lov1 || exit 30 -${LMC} -m $config --node $CLIENT --mtpt /mnt/lustre2 mds2 lov2 || exit 30 - - - - diff --git a/lustre/tests/multifstat.c b/lustre/tests/multifstat.c deleted file mode 100644 index fa510bc..0000000 --- a/lustre/tests/multifstat.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - int fd1, fd2; - struct stat st1, st2; - - if (argc != 3) { - printf("Usage %s file1 file2\n", argv[0]); - return 1; - } - - - fd1 = open(argv[1], O_CREAT| O_RDWR, 0666); - if (fd1 == -1) { - printf("Error opening %s: %s\n", argv[1], strerror(errno)); - return errno; - } - - fd2 = open(argv[2], O_RDONLY); - if (fd2 == -1) { - printf("Error opening %s: %s\n", argv[2], strerror(errno)); - return errno; - } - - sleep(1); - - if ( write(fd1, "hello", strlen("hello")) != strlen("hello")) { - printf("Error writing: %s\n", strerror(errno)); - return errno; - } - - if ( fstat(fd1, &st1) ) { - printf("Error statting %s: %s\n", argv[1], strerror(errno)); - return errno; - } - - if ( fstat(fd2, &st2) ) { - printf("Error statting %s: %s\n", argv[2], strerror(errno)); - return errno; - } - - if ( st1.st_size != st2.st_size ) { - printf("Sizes don't match %ld, %ld\n", - st1.st_size, st2.st_size); - return 1; - } - - if ( st1.st_mtime != st2.st_mtime ) { - printf("Mtimes don't match %ld, %ld\n", - st1.st_mtime, st2.st_mtime); - return 1; - } - - return 0; -} diff --git a/lustre/tests/net-client.cfg b/lustre/tests/net-client.cfg deleted file mode 100644 index e25c19f..0000000 --- a/lustre/tests/net-client.cfg +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# Config file for setting up a remote server with a real OST -NETWORK=tcp -LOCALHOST=dev5 -SERVER=dev4 -PORT=1234 - -[ -z "$RSH" ] && RSH=ssh -SERVER_DNS=dev4 -MDS_RSH="$RSH $SERVER_DNS" -OST_RSH="$RSH $SERVER_DNS" diff --git a/lustre/tests/net-local.cfg b/lustre/tests/net-local.cfg deleted file mode 100644 index 0670b7e..0000000 --- a/lustre/tests/net-local.cfg +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# Config file for running tests on a single host over loopback TCP -NETWORK=tcp -LOCALHOST=localhost -SERVER=localhost -PORT=2432 diff --git a/lustre/tests/net-server.cfg b/lustre/tests/net-server.cfg deleted file mode 100644 index f173f21..0000000 --- a/lustre/tests/net-server.cfg +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# Config file for setting up a remote server with a real OST -NETWORK=tcp -LOCALHOST=dev4 -SERVER=dev4 -PORT=2432 diff --git a/lustre/tests/openunlink.c b/lustre/tests/openunlink.c deleted file mode 100644 index d0ae419..0000000 --- a/lustre/tests/openunlink.c +++ /dev/null @@ -1,122 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define T1 "write before unlink\n" -#define T2 "write after unlink\n" -char buf[128]; - -int main(int argc, char **argv) -{ - int fd, rc; - - if (argc != 2) { - fprintf(stderr, "usage: %s filename\n", argv[0]); - exit(1); - } else { - fprintf(stderr, "congratulations - program starting\n"); - } - - fprintf(stderr, "opening\n"); - fd = open(argv[1], O_RDWR | O_TRUNC | O_CREAT, 0644); - if (fd == -1) { - fprintf(stderr, "open (before) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "writing\n"); - rc = write(fd, T1, strlen(T1) + 1); - if (rc != strlen(T1) + 1) { - fprintf(stderr, "write (before) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "closing\n"); - rc = close(fd); - if (rc ) { - fprintf(stderr, "close (before) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "opening again\n"); - fd = open(argv[1], O_RDWR ); - if (fd == -1) { - fprintf(stderr, "open (before) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "unlinking\n"); - rc = unlink(argv[1]); - if (rc ) { - fprintf(stderr, "open %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "reading\n"); - rc = read(fd, buf, strlen(T1) + 1); - if (rc != strlen(T1) + 1) { - fprintf(stderr, "read -after %s rc %d\n", strerror(errno), rc); - exit(1); - } - - fprintf(stderr, "comparing data\n"); - if (memcmp(buf, T1, strlen(T1) + 1) ) { - fprintf(stderr, "FAILURE: read wrong data after unlink\n"); - exit(1); - } - - fprintf(stderr, "truncating\n"); - rc = ftruncate(fd, 0); - if (rc ) { - fprintf(stderr, "truncate -after unl %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "seeking\n"); - rc = lseek(fd, 0, SEEK_SET); - if (rc != 0 ) { - fprintf(stderr, "seek (before write) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "writing again\n"); - rc = write(fd, T2, strlen(T2) + 1); - if (rc != strlen(T2) + 1) { - fprintf(stderr, "write (before) %s (rc %d)\n", strerror(errno), rc); - exit(1); - } - - fprintf(stderr, "seeking\n"); - rc = lseek(fd, 0, SEEK_SET); - if (rc != 0 ) { - fprintf(stderr, "seek (before read) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "reading again\n"); - rc = read(fd, buf, strlen(T2) + 1); - if (rc != strlen(T2) + 1) { - fprintf(stderr, "read (after trunc) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "comparing data again\n"); - if (memcmp(buf, T2, strlen(T2) + 1) ) { - fprintf(stderr, "FAILURE: read wrong data after trunc\n"); - exit(1); - } - - fprintf(stderr, "closing again\n"); - rc = close(fd); - if (rc ) { - fprintf(stderr, "close (before) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "SUCCESS - goto beer\n"); - return 0; -} diff --git a/lustre/tests/runfailure-client-mds-recover.sh b/lustre/tests/runfailure-client-mds-recover.sh deleted file mode 100755 index a4b46a5..0000000 --- a/lustre/tests/runfailure-client-mds-recover.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -echo `date` creating /mnt/lustre/foo -echo 0x80000107 > /proc/sys/lustre/fail_loc -touch /mnt/lustre/foo & -ps axww | grep touch -echo "touch program suspended and hanging -- sleeping 5 secs" -sleep 5 -ls -l /mnt/lustre/foo - -echo 0x0000107 > /proc/sys/lustre/fail_loc -touch /mnt/lustre/bar & -ps axww | grep touch -echo "touch program will have repeated failures sleeping 10" - -sleep 10 - -echo 0 > /proc/sys/lustre/fail_loc -echo "failure cleared" -sleep 5 -ls -l /mnt/lustre/bar diff --git a/lustre/tests/runregression-net.sh b/lustre/tests/runregression-net.sh deleted file mode 100644 index b724548..0000000 --- a/lustre/tests/runregression-net.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/sh -export PATH=/sbin:/usr/sbin:$PATH - -SRCDIR="`dirname $0`/" -. $SRCDIR/common.sh - -setup_opts $@ - -setup_portals -setup_lustre - -# TODO: obdctl needs to check on the progress of each forked thread -# (IPC SHM, sockets?) to see if it hangs. -for CMD in test_getattr test_brw_read test_brw_write; do - case $CMD in - test_brw_read) CMD=test_brw; RW=r ;; - test_brw_write) CMD=test_brw; RW=w ;; - *) RW= ;; - esac - - setup_server || exit -1 - setup_client || exit -1 - - OSC_DEVNO=`$OBDCTL name2dev OSCDEV` - - # We use '--threads 1 X' instead of '--device X' so that - # obdctl can modnitor the forked thread for progress (TODO). - $OBDCTL --threads 1 v $OSC_DEVNO $CMD 1 $RW v || exit -1 - $OBDCTL --threads 1 v $OSC_DEVNO $CMD 100 $RW v || exit -1 - - #cleanup_client || exit -1 - #cleanup_server || exit -1 - - #setup_server || exit -1 - #setup_client || exit -1 - - debug_server_off - debug_client_off - $OBDCTL --threads 1 v $OSC_DEVNO $CMD 10000 $RW 100 || exit -1 - $OBDCTL --threads 1 v $OSC_DEVNO $CMD 1000000 $RW -10 || exit -1 - - debug_server_on - debug_client_on - $OBDCTL --threads 2 v $OSC_DEVNO $CMD 100 $RW v || exit -1 - - debug_server_off - debug_client_off - $OBDCTL --threads 2 v $OSC_DEVNO $CMD 10000 $RW 100 || exit -1 - $OBDCTL --threads 2 v $OSC_DEVNO $CMD 1000000 $RW -30 || exit -1 - - $OBDCTL --threads 10 v $OSC_DEVNO $CMD 10000 $RW 1000 || exit -1 - $OBDCTL --threads 100 v $OSC_DEVNO $CMD 10000 $RW -30 || exit -1 - - cleanup_client || exit -1 - cleanup_server || exit -1 -done - -cleanup_lustre -cleanup_portals diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh deleted file mode 100644 index f0da26d..0000000 --- a/lustre/tests/sanity.sh +++ /dev/null @@ -1,132 +0,0 @@ -!/bin/bash - -echo '=============================== test 1' -mkdir /mnt/lustre/d1 -mkdir /mnt/lustre/d1/d2 -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '=============================== test 2' -mkdir /mnt/lustre/d2 -touch /mnt/lustre/d2/f -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 3 -mkdir /mnt/lustre/d3 -umount /mnt/lustre -../utils/lconf --start 70 local.xml -touch /mnt/lustre/d3/f -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 4 -mkdir /mnt/lustre/d4 -umount /mnt/lustre -../utils/lconf --start 70 local.xml -mkdir /mnt/lustre/d4/d2 -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 5 -mkdir /mnt/lustre/d5 -mkdir /mnt/lustre/d5/d2 -chmod 0666 /mnt/lustre/d5/d2 -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 6 -touch /mnt/lustre/f6 -chmod 0666 /mnt/lustre/f6 -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 7 -mkdir /mnt/lustre/d7 -./mcreate /mnt/lustre/d7/f -chmod 0666 /mnt/lustre/d7/f -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 8 -mkdir /mnt/lustre/d8 -touch /mnt/lustre/d8/f -chmod 0666 /mnt/lustre/d8/f -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - - -echo '=============9=================' test 9 -mkdir /mnt/lustre/d9 -mkdir /mnt/lustre/d9/d2 -mkdir /mnt/lustre/d9/d2/d3 -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - - -echo '===============================' test 10 -mkdir /mnt/lustre/d10 -mkdir /mnt/lustre/d10/d2 -touch /mnt/lustre/d10/d2/f -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 11 -mkdir /mnt/lustre/d11 -mkdir /mnt/lustre/d11/d2 -chmod 0666 /mnt/lustre/d11/d2 -chmod 0555 /mnt/lustre/d11/d2 -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 12 -mkdir /mnt/lustre/d12 -touch /mnt/lustre/d12/f -chmod 0666 /mnt/lustre/d12/f -chmod 0555 /mnt/lustre/d12/f -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 13 -mkdir /mnt/lustre/d13 -cp /etc/passwd /mnt/lustre/d13/f -> /mnt/lustre/d13/f -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 14 -mkdir /mnt/lustre/d14 -touch /mnt/lustre/d14/f -rm /mnt/lustre/d14/f -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 15 -mkdir /mnt/lustre/d15 -touch /mnt/lustre/d15/f -mv /mnt/lustre/d15/f /mnt/lustre/d15/f2 -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml - -echo '===============================' test 16 -mkdir /mnt/lustre/d16 -touch /mnt/lustre/d16/f -rm -rf /mnt/lustre/d16/f -umount /mnt/lustre -dmesg | grep -i destruct -../utils/lconf --start 70 local.xml diff --git a/lustre/tests/sanityN.sh b/lustre/tests/sanityN.sh deleted file mode 100644 index 9c50574..0000000 --- a/lustre/tests/sanityN.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash - -export NAME=$NAME -clean() { - echo -n "cleanup..." - sh llmount2-hackcleanup.sh > /dev/null -} - -CLEAN=clean -start() { - echo -n "mounting..." - sh llmount2-hack.sh > /dev/null - echo -n "mounted" -} -START=start - -error () { - echo $1 - exit 1 -} - -mkdir -p /mnt/lustre2 -mount | grep /mnt/lustre2 || $START - -echo -n "test 1: check create on 2 mtpt's..." -touch /mnt/lustre1/f1 -[ -f /mnt/lustre2/f1 ] || error "test 1 failure" -echo "pass" - -echo -n "test 2: check attribute updates on 2 mtpt's..." -chmod a+x /mnt/lustre2/f1 -[ -x /mnt/lustre1/f1 ] || error "test 2 failure" -echo "pass" - -echo -n "test 3: check after remount attribute updates on 2 mtpt's..." -chmod a-x /mnt/lustre2/f1 -$CLEAN -$START - -[ ! -x /mnt/lustre1/f1 ] || error "test 3 failure" -echo "pass" - -echo -n "test 4: symlink on one mtpt, readlink on another..." -( cd /mnt/lustre1 ; ln -s this/is/good lnk ) - -[ "Xthis/is/good" = X`perl -e 'print readlink("/mnt/lustre2/lnk");'` ] || error "test 4 fails" -echo "pass" - -echo -n "test 5: fstat validation on multiple mount points..." -./multifstat /mnt/lustre1/fstatfile /mnt/lustre2/fstatfile || error "test 5 fails" -echo "pass" - -echo -n "test 9: remove of open file on other node..." -touch /mnt/lustre1/f9 -tail -f /mnt/lustre1/f9 & -rm /mnt/lustre2/f9 -kill %1 -cat /mnt/lustre1/f9 && error "test 9 fails" -echo "pass" - -$CLEAN - -exit diff --git a/lustre/tests/stat.c b/lustre/tests/stat.c deleted file mode 100644 index b719900..0000000 --- a/lustre/tests/stat.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char ** argv) -{ - int rc; - struct stat buf; - - if (argc < 2) { - printf("Usage %s filename\n", argv[0]); - return 1; - } - - rc = stat(argv[1], &buf); - if (rc) { - printf("stat(%s) error: %s\n", argv[1], strerror(errno)); - } - return rc; -} diff --git a/lustre/tests/writeme.c b/lustre/tests/writeme.c deleted file mode 100644 index ab8692f..0000000 --- a/lustre/tests/writeme.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - int fd, rc; - int i = 0; - char buf[4096]; - - memset(buf, 0, 4096); - - if (argc != 2) { - printf("Usage openme \n"); - exit(1); - } - - fd = open(argv[1], O_RDWR | O_CREAT, 0600); - if (fd == -1) { - printf("Error opening %s\n", argv[1]); - exit(1); - } - - while (1) { - sprintf(buf, "write %d\n", i); - rc = write(fd, buf, sizeof(buf)); - sleep(1); - } - return 0; -} diff --git a/lustre/utils/automatic-reconnect-sample b/lustre/utils/automatic-reconnect-sample deleted file mode 100755 index bf9ecc4..0000000 --- a/lustre/utils/automatic-reconnect-sample +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh - -if [ -z "$1" ]; then - echo "No UUID given to Lustre upcall!" | wall - exit 1 -fi - -# FIXME: OSTHOST can't be hard-coded! -OST=$1 -OSTHOST=dev7 -LUSTRE=/home/pschwan/lustre/lustre - -while ( ! ping -c 1 -w 3 $OSTHOST ) ; do - sleep 2 -done; - -echo -n "OST $OSTHOST UUID $OST responding to pings : " -date - -$LUSTRE/utils/lctl < - -# This file is part of Lustre, http://www.lustre.org. -# -# Lustre is free software; you can redistribute it and/or -# modify it under the terms of version 2 of the GNU General Public -# License as published by the Free Software Foundation. -# -# Lustre is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Lustre; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -""" -genXml - lustre xml configurtion data generator - - Basic plan for genXml usage: -#generate xml file -./lmc --output config.xml --node --ldapserver -./lmc --merge config.xml --node --ldapserver - -#This reads arguments from files in default locations and generate the xml file -./genConfig - -""" - -import sys, os, getopt, string, socket -import xml.dom.minidom -from xml.dom.ext import PrettyPrint -from lutils import * - -lustreNodes = {} -lustreNode = 0 -lustreClient = 0 -lustreMds = {} -lustreOst = {} -#lustreOsc = 0 -tmpuuid = "" -ConnId = 0 - -# Determine full path to use for an external command -# searches dirname(argv[0]) first, then PATH -""" -def find_prog(cmd): - syspath = string.split(os.environ['PATH'], ':') - cmdpath = os.path.dirname(sys.argv[0]) - syspath.insert(0, cmdpath); - syspath.insert(0, os.path.join(cmdpath, '../../portals/linux/utils/')) - for d in syspath: - prog = os.path.join(d,cmd) - if os.access(prog, os.X_OK): - return prog - return '' -""" -# ============================================================ -# handle lmc interface -class LMCInterface: - """ - Manage communication with lmc - """ - - def __init__(self, cmd): - """ - Initialize close by finding the lmc script. - """ - self.lmc = find_prog(cmd) - if not self.lmc: - debug('! lmc not found') - raise CommandError('lmc', "unable to find lmc script .") - self.lmc = 'lmc' - - def run(self, cmds): - """ - run lmc - the cmds are written to stdin of lmc - """ - debug("+", self.lmc, cmds) - p = popen2.Popen3(self.lmc, 1) - p.tochild.write(cmds + "\n") - p.tochild.close() - out = p.fromchild.readlines() - err = p.childerr.readlines() - ret = p.wait() - if os.WIFEXITED(ret): - rc = os.WEXITSTATUS(ret) - else: - rc = 0 - if rc or len(err): - print err, rc - raise CommandError(self.lmc, err, rc) - return rc, out - - def runcmd(self, *args): - """ - run lmc using the command line - """ - cmd = string.join(map(str,args)) - debug("+", self.lmc, cmd) - rc, out = run(self.lmc, cmd) - if rc: - raise CommandError(self.lmc, out, rc) - return rc, out - - -def genXml(nodename, ldapserver, port, options): - global ldlm_name - global ldlm_uuid - global lustreNode - global lustreClient - global lustreMds - global lustreOst - global ConnId - lovs = [] - if options.has_key('output'): - outFile = options['output'] - elif options.has_key('merge'): - outFile = options['merge'] - - LMC = LMCInterface('lmc') - base = "fs=lustre" - myCon=MyConn(ldapserver,port) - myCon.open() - ConnId=myCon.id - lustreNode = LustreNode(nodename) - if not options.has_key('add'): - lustreNode.getEntry_from_ldap(ConnId,base) - for i in range(len(lustreNode.netUUIDs)): - NET = lustreNode.lustreNet[i] - if options.has_key('output'): - cmds = """ --output %s --node %s --net %s %s """ % (outFile, lustreNode.id, NET.id, NET.netType) - elif options.has_key('merge'): - cmds = """ --merge %s --node %s --net %s %s """ % (outFile, lustreNode.id, NET.netType) - LMC.runcmd(cmds) - - - - mds_uuids = lustreNode.lustreNodeProfile.mdsUUIDs - for tmpuuid in mds_uuids: - lustreMds[tmpuuid]=LustreMds() - lustreMds[tmpuuid].getEntry_from_ldap(ConnId,base,tmpuuid) - MDS = lustreMds[tmpuuid] - Dev = lustreMds[tmpuuid].lustreDev - cmds = """ --merge %s --node %s --mds %s %s %s """ % (outFile, lustreNode.id, lustreMds[tmpuuid].devName,Dev.device,Dev.size) - LMC.runcmd(cmds) - LOV = lustreMds[tmpuuid].lustreLov - lovs.append(LOV) - cmds = """ --merge %s --lov %s %s %s %s %s""" % (outFile, LOV.devName, MDS.devName, LOV.stripeSize, LOV.stripeCount, LOV.pattern) - LMC.runcmd(cmds) - - - ost_uuids = lustreNode.lustreNodeProfile.ostUUIDs - for tmpuuid in ost_uuids: - lustreOst[tmpuuid] = LustreOst() - lustreOst[tmpuuid].getEntry_from_ldap(ConnId,base,tmpuuid) - OST = lustreOst[tmpuuid] - DEV = OST.lustreObd.lustreDev - for i in range(len(lovs)): - for oscuuid in lovs[i].oscUUIDs: - OSC = lovs[i].lustreOsc[oscuuid] - if OST.ostUUID == OSC.ostUUID: - cmds = """ --merge %s --node %s --lov %s --ost %s %s """ % (outFile, lustreNode.id, LOV.devName, DEV.device, DEV.size) - LMC.runcmd(cmds) - else: - pass - #print "not matched:", OSC.ostUUID - - - if lustreNode.lustreNodeProfile.clientUUID: - client_uuid = "" - lustreClient = LustreClient(lustreNode) - client_uuid = lustreNode.lustreNodeProfile.clientUUID - lustreClient.getEntry_from_ldap(ConnId,base,str(client_uuid)) - for mnt_uuid in lustreClient.mountUUIDs: - tmpuuid = mnt_uuid - MTPT = lustreClient.lustreMount[mnt_uuid] - MDS = MTPT.lustreMds - LOV = MTPT.lustreLov - cmds = """ --merge %s --node %s --mtpt %s %s %s """ % (outFile, lustreNode.id, MTPT.mountPath, MDS.devName, LOV.devName) - LMC.runcmd(cmds) - - - -############################################################ -# Command line processing -# -def parse_cmdline(argv): - short_opts = "ho:i:m:" - long_opts = ["node=", "merge=", "output=", "ldapserver=", "port="] - opts = [] - args = [] - options = {} - try: - opts, args = getopt.getopt(argv, short_opts, long_opts) - except getopt.error: - print "invalid opt" - usage() - - for o, a in opts: - # Commands to create new devices - if o == "--node": - options['node'] = a - if o == "--ldapserver": - options['ldapserver'] = a - if o == "--port": - options['port'] = a - - # Options for commands - - # lmc options - if o in ("-h", "--help"): - usage() - if o in ("-o", "--output"): - options['output'] = a - if o in ("-m", "--merge"): - options['merge'] = a - if o == "--add": - options['add'] = a - - return options, args - - -program_name = "" -def main(): - global program_name - arglist = string.split(sys.argv[0], '/') - program_name = arglist[len(arglist)-1] - if program_name != 'genConfig': - options, args = parse_cmdline(sys.argv[1:]) - outFile = '-' - if options.has_key('ldapserver'): - ldapserver = options['ldapserver'] - - if options.has_key('node'): - nodename = options['node'] - else: - nodename = socket.gethostname() - - if options.has_key('port'): - port = int(options['port']) - else: - port = 389 - - if options.has_key('add'): - outFile = options['add'] - - genXml(nodename,ldapserver,port,options) - else: - options = {} - args = [] - outFile = '/etc/lustre/config.xml' - fp=open("/etc/lustre/ldapserver","r") - line=fp.readline() - fp.close() - ldapinfo=string.split(line,':') - ldapserver=ldapinfo[0] - port=ldapinfo[1] - nodename = socket.gethostname() - nodename = 'lustre4' - genXml(nodename,ldapserver,port,options) - -if __name__ == "__main__": - main() - - diff --git a/lustre/utils/ha_assist.sh b/lustre/utils/ha_assist.sh deleted file mode 100755 index 832b274..0000000 --- a/lustre/utils/ha_assist.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -echo -n `date` >> /tmp/halog -echo "- please supply a new mds" >> /tmp/halog - -echo "- suppose we have a new one" >> /tmp/halog -sleep 1 - -/usr/src/obd/utils/obdctl < - -# This file is part of Lustre, http://www.lustre.org. -# -# Lustre is free software; you can redistribute it and/or -# modify it under the terms of version 2 of the GNU General Public -# License as published by the Free Software Foundation. -# -# Lustre is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Lustre; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -import lustreLdap, sys, os, socket, string, popen2 - - - -# Determine full path to use for an external command -# searches dirname(argv[0]) first, then PATH -def find_prog(cmd): - syspath = string.split(os.environ['PATH'], ':') - cmdpath = os.path.dirname(sys.argv[0]) - syspath.insert(0, cmdpath); - syspath.insert(0, os.path.join(cmdpath, '../../portals/linux/utils/')) - for d in syspath: - prog = os.path.join(d,cmd) - if os.access(prog, os.X_OK): - return prog - return '' - -# handle lctl interface -class LCTLInterface: - """ - Manage communication with lctl - """ - - def __init__(self, cmd): - """ - Initialize close by finding the lctl binary. - """ - self.lctl = find_prog(cmd) - if not self.lctl: - lustreLdap.debug('! lctl not found') - self.lctl = 'lctl' - - def run(self, cmds): - """ - run lctl - the cmds are written to stdin of lctl - lctl doesn't return errors when run in script mode, so - stderr is checked - should modify command line to accept multiple commands, or - create complex command line options - """ - lustreLdap.debug("+", self.lctl, cmds) - p = popen2.Popen3(self.lctl, 1) - p.tochild.write(cmds + "\n") - p.tochild.close() - out = p.fromchild.readlines() - err = p.childerr.readlines() - ret = p.wait() - if os.WIFEXITED(ret): - rc = os.WEXITSTATUS(ret) - else: - rc = 0 - if rc or len(err): - lustreLdap.debug(self.lctl, err, rc) - sys.exit(1) - return rc, out - - def runcmd(self, *args): - """ - run lctl using the command line - """ - cmd = string.join(map(str,args)) - debug("+", self.lctl, cmd) - rc, out = run(self.lctl, cmd) - if rc: - lustreLdap.debug(self.lctl, out, rc) - sys.exit(1) - return rc, out - -def network(failedUUID, failoverUUID, failoverNode, failovernetType, failoverPort): - lctl=LCTLInterface('lctl') - if failovernetType == 'tcp': - cmd = """ - network %s - close_uuid %s - del_uuid %s - connect %s %d - add_uuid %s %s - name2dev RPCDEV - probe - newconn %s - quit""" % (failovernetType, failedUUID, failedUUID, failoverNode, int(failoverPort), failoverUUID, failoverNode, failoverUUID) - print cmd - lctl.run(cmd) - - -def main(): - FailedNetUUID = sys.argv[1:][0] - print FailedNetUUID - print "ha assist checking for problems" - if not os.access("/tmp/halog", os.R_OK): - print "no problems ..exiting" - sys.exit(1) - - try: - fp = open("/etc/lustre/ldapserver", "r") - line = fp.readline() - fp.close() - except IOError, e: - log(e) - - ldapinfo = string.split(line,':') - server = ldapinfo[0] - port = ldapinfo[1] - base = "fs=lustre" - myCon = lustreLdap.MyConn(server, port) - myCon.open() - - connId = myCon.id - # initilize the new network object class - lustreNet = lustreLdap.LustreNet() - # brings the failed network object class from LDAP the query is - lustreNet.getEntry_from_ldap(connId, base, FailedNetUUID) - - nodename = socket.gethostname() - - nodename = lustreNet.id - failoverNetUUID = lustreNet.fnetUUID - #Query the failover network information - lustreNet = lustreLdap.LustreNet() - lustreNet.getEntry_from_ldap(connId, base, failoverNetUUID) - - network(FailedNetUUID, failoverNetUUID, lustreNet.id, lustreNet.netType, lustreNet.port) - - - -if __name__ == "__main__": - main() - - - diff --git a/lustre/utils/lconf.in b/lustre/utils/lconf.in deleted file mode 100755 index d7ca788..0000000 --- a/lustre/utils/lconf.in +++ /dev/null @@ -1,1796 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (C) 2002 Cluster File Systems, Inc. -# Author: Robert Read -# This file is part of Lustre, http://www.lustre.org. -# -# Lustre is free software; you can redistribute it and/or -# modify it under the terms of version 2 of the GNU General Public -# License as published by the Free Software Foundation. -# -# Lustre is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Lustre; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -# lconf - lustre configuration tool -# -# lconf is the main driver script for starting and stopping -# lustre filesystem services. -# -# Based in part on the XML obdctl modifications done by Brian Behlendorf - -import sys, getopt -import string, os, stat, popen2, socket, time, random -import re, exceptions -import xml.dom.minidom - -# Global parameters -TCP_ACCEPTOR = '' -MAXTCPBUF = 1048576 -DEFAULT_TCPBUF = 1048576 -# -# Maximum number of devices to search for. -# (the /dev/loop* nodes need to be created beforehand) -MAX_LOOP_DEVICES = 256 -PORTALS_DIR = '@PORTALSLOC@' - -first_cleanup_error = 0 -def cleanup_error(rc): - global first_cleanup_error - if not first_cleanup_error: - first_cleanup_error = rc - - -def usage(): - print """usage: lconf config.xml - -config.xml Lustre configuration in xml format. ---get URL to fetch a config file ---node Load config for --d | --cleanup Cleans up config. (Shutdown) --f | --force Forced unmounting and/or obd detach during cleanup --v | --verbose Print system commands as they are run --h | --help Print this help ---gdb Prints message after creating gdb module script - and sleeps for 5 seconds. --n | --noexec Prints the commands and steps that will be run for a - config without executing them. This can used to check if a - config file is doing what it should be doing. (Implies -v) ---nomod Skip load/unload module step. ---nosetup Skip device setup/cleanup step. ---reformat Reformat all devices (without question) ---dump Dump the kernel debug log before portals is unloaded ---minlevel Specify the minimum level of services to configure/cleanup (default 0) ---maxlevel Specify the maximum level of services to configure/cleanup (default 100) - Levels are aproximatly like: - 10 - network - 20 - device, ldlm - 30 - obd, mdd - 40 - mds, ost - 50 - mdc, osc - 60 - lov, lovconfig - 70 - mountpoint, echo_client -""" - TODO = """ ---ldap server LDAP server with lustre config database ---makeldiff Translate xml source to LDIFF -This are perhaps not needed: ---lustre="src dir" Base directory of lustre sources. Used to search - for modules. ---portals=src Portals source -""" - sys.exit() - -# ============================================================ -# Config parameters, encapsulated in a class -class Config: - def __init__(self): - # flags - self._noexec = 0 - self._verbose = 0 - self._reformat = 0 - self._cleanup = 0 - self._gdb = 0 - self._nomod = 0 - self._nosetup = 0 - self._force = 0 - # parameters - self._modules = None - self._node = None - self._url = None - self._gdb_script = '/tmp/ogdb' - self._debug_path = '/tmp/lustre-log' - self._dump_file = None - self._src_dir = None - self._minlevel = 0 - self._maxlevel = 100 - - def verbose(self, flag = None): - if flag: self._verbose = flag - return self._verbose - - def noexec(self, flag = None): - if flag: self._noexec = flag - return self._noexec - - def reformat(self, flag = None): - if flag: self._reformat = flag - return self._reformat - - def cleanup(self, flag = None): - if flag: self._cleanup = flag - return self._cleanup - - def gdb(self, flag = None): - if flag: self._gdb = flag - return self._gdb - - def nomod(self, flag = None): - if flag: self._nomod = flag - return self._nomod - - def nosetup(self, flag = None): - if flag: self._nosetup = flag - return self._nosetup - - def force(self, flag = None): - if flag: self._force = flag - return self._force - - def node(self, val = None): - if val: self._node = val - return self._node - - def url(self, val = None): - if val: self._url = val - return self._url - - def gdb_script(self): - if os.path.isdir('/r'): - return '/r' + self._gdb_script - else: - return self._gdb_script - - def debug_path(self): - if os.path.isdir('/r'): - return '/r' + self._debug_path - else: - return self._debug_path - - def src_dir(self, val = None): - if val: self._src_dir = val - return self._src_dir - - def dump_file(self, val = None): - if val: self._dump_file = val - return self._dump_file - - def minlevel(self, val = None): - if val: self._minlevel = int(val) - return self._minlevel - - def maxlevel(self, val = None): - if val: self._maxlevel = int(val) - return self._maxlevel - - - -config = Config() - -# ============================================================ -# debugging and error funcs - -def fixme(msg = "this feature"): - raise LconfError, msg + ' not implmemented yet.' - -def panic(*args): - msg = string.join(map(str,args)) - if not config.noexec(): - raise LconfError(msg) - else: - print "! " + msg - -def log(*args): - msg = string.join(map(str,args)) - print msg - -def logall(msgs): - for s in msgs: - print string.strip(s) - -def debug(*args): - if config.verbose(): - msg = string.join(map(str,args)) - print msg - -# ============================================================ -# locally defined exceptions -class CommandError (exceptions.Exception): - def __init__(self, cmd_name, cmd_err, rc=None): - self.cmd_name = cmd_name - self.cmd_err = cmd_err - self.rc = rc - - def dump(self): - import types - if type(self.cmd_err) == types.StringType: - if self.rc: - print "! %s (%d): %s" % (self.cmd_name, self.rc, self.cmd_err) - else: - print "! %s: %s" % (self.cmd_name, self.cmd_err) - elif type(self.cmd_err) == types.ListType: - if self.rc: - print "! %s (error %d):" % (self.cmd_name, self.rc) - else: - print "! %s:" % (self.cmd_name) - for s in self.cmd_err: - print "> %s" %(string.strip(s)) - else: - print self.cmd_err - -class LconfError (exceptions.Exception): - def __init__(self, args): - self.args = args - - -# ============================================================ -# handle lctl interface -class LCTLInterface: - """ - Manage communication with lctl - """ - - def __init__(self, cmd): - """ - Initialize close by finding the lctl binary. - """ - self.lctl = find_prog(cmd) - if not self.lctl: - if config.noexec(): - debug('! lctl not found') - self.lctl = 'lctl' - else: - raise CommandError('lctl', "unable to find lctl binary.") - - def run(self, cmds): - """ - run lctl - the cmds are written to stdin of lctl - lctl doesn't return errors when run in script mode, so - stderr is checked - should modify command line to accept multiple commands, or - create complex command line options - """ - debug("+", self.lctl, cmds) - if config.noexec(): return (0, []) - p = popen2.Popen3(self.lctl, 1) - p.tochild.write(cmds + "\n") - p.tochild.close() - out = p.fromchild.readlines() - err = p.childerr.readlines() - ret = p.wait() - if os.WIFEXITED(ret): - rc = os.WEXITSTATUS(ret) - else: - rc = 0 - if rc or len(err): - raise CommandError(self.lctl, err, rc) - return rc, out - - def runcmd(self, *args): - """ - run lctl using the command line - """ - cmd = string.join(map(str,args)) - debug("+", self.lctl, cmd) - rc, out = run(self.lctl, cmd) - if rc: - raise CommandError(self.lctl, out, rc) - return rc, out - - - def network(self, net, nid): - """ initialized network and add "self" """ - # Idea: "mynid" could be used for all network types to add "self," and then - # this special case would be gone and the "self" hack would be hidden. - if net in ('tcp', 'toe'): - cmds = """ - network %s - mynid %s - add_uuid self %s - quit""" % (net, nid, nid) - else: - cmds = """ - network %s - add_uuid self %s - quit""" % (net, nid) - - self.run(cmds) - - # create a new connection - def connect(self, net, nid, port, servuuid, send_mem, recv_mem): - if net in ('tcp', 'toe'): - cmds = """ - network %s - add_uuid %s %s - send_mem %d - recv_mem %d - connect %s %d - quit""" % (net, servuuid, nid, send_mem, recv_mem, nid, port, ) - else: - cmds = """ - network %s - add_uuid %s %s - connect %s %d - quit""" % (net, servuuid, nid, nid, port, ) - - self.run(cmds) - - # add a route to a range - def add_route(self, net, gw, lo, hi): - cmds = """ - network %s - add_route %s %s %s - quit """ % (net, gw, lo, hi) - self.run(cmds) - - - def del_route(self, net, gw, lo, hi): - cmds = """ - ignore_errors - network %s - del_route %s - quit """ % (net, lo) - self.run(cmds) - - # add a route to a host - def add_route_host(self, net, uuid, gw, tgt): - cmds = """ - network %s - add_uuid %s %s - add_route %s %s - quit """ % (net, uuid, tgt, gw, tgt) - self.run(cmds) - - # add a route to a range - def del_route_host(self, net, uuid, gw, tgt): - cmds = """ - ignore_errors - network %s - del_uuid %s - del_route %s - quit """ % (net, uuid, tgt) - self.run(cmds) - - # disconnect one connection - def disconnect(self, net, nid, port, servuuid): - cmds = """ - ignore_errors - network %s - disconnect %s - del_uuid %s - quit""" % (net, nid, servuuid) - self.run(cmds) - - # disconnect all - def disconnectAll(self, net): - cmds = """ - ignore_errors - network %s - del_uuid self - disconnect - quit""" % (net) - self.run(cmds) - - # create a new device with lctl - def newdev(self, attach, setup = ""): - cmds = """ - newdev - attach %s - setup %s - quit""" % (attach, setup) - self.run(cmds) - - # cleanup a device - def cleanup(self, name, uuid): - cmds = """ - ignore_errors - device $%s - cleanup - detach %s - quit""" % (name, ('', 'force')[config.force()]) - self.run(cmds) - - # create an lov - def lov_setconfig(self, uuid, mdsuuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist): - cmds = """ - device $%s - probe - lov_setconfig %s %d %d %d %s %s - quit""" % (mdsuuid, uuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist) - self.run(cmds) - - # dump the log file - def dump(self, dump_file): - cmds = """ - debug_kernel %s 1 - quit""" % (dump_file) - self.run(cmds) - - # get list of devices - def device_list(self): - rc, out = self.runcmd('device_list') - return out - - # get lustre version - def lustre_version(self): - rc, out = self.runcmd('version') - return out - -# ============================================================ -# Various system-level functions -# (ideally moved to their own module) - -# Run a command and return the output and status. -# stderr is sent to /dev/null, could use popen3 to -# save it if necessary -def run(*args): - cmd = string.join(map(str,args)) - debug ("+", cmd) - if config.noexec(): return (0, []) - f = os.popen(cmd + ' 2>&1') - out = f.readlines() - ret = f.close() - if ret: - ret = ret >> 8 - else: - ret = 0 - return (ret, out) - -# Run a command in the background. -def run_daemon(*args): - cmd = string.join(map(str,args)) - debug ("+", cmd) - if config.noexec(): return 0 - f = os.popen(cmd + ' 2>&1') - ret = f.close() - if ret: - ret = ret >> 8 - else: - ret = 0 - return ret - -# Determine full path to use for an external command -# searches dirname(argv[0]) first, then PATH -def find_prog(cmd): - syspath = string.split(os.environ['PATH'], ':') - cmdpath = os.path.dirname(sys.argv[0]) - syspath.insert(0, cmdpath); - syspath.insert(0, os.path.join(cmdpath, PORTALS_DIR+'/linux/utils/')) - for d in syspath: - prog = os.path.join(d,cmd) - debug(prog) - if os.access(prog, os.X_OK): - return prog - return '' - -# Recursively look for file starting at base dir -def do_find_file(base, mod): - fullname = os.path.join(base, mod) - if os.access(fullname, os.R_OK): - return fullname - for d in os.listdir(base): - dir = os.path.join(base,d) - if os.path.isdir(dir): - module = do_find_file(dir, mod) - if module: - return module - -def find_module(dev_dir, modname): - mod = '%s.o' % (modname) - - module = dev_dir +'/'+ mod - try: - if os.access(module, os.R_OK): - return module - except OSError: - pass - return None - -# is the path a block device? -def is_block(path): - s = () - try: - s = os.stat(path) - except OSError: - return 0 - return stat.S_ISBLK(s[stat.ST_MODE]) - -# build fs according to type -# fixme: dangerous -def mkfs(fstype, dev): - if(fstype in ('ext3', 'extN')): - mkfs = 'mkfs.ext2 -j -b 4096' - elif (fstype == 'reiserfs'): - mkfs = 'mkfs.reiserfs -f' - else: - print 'unsupported fs type: ', fstype - if not is_block(dev): - if(fstype in ('ext3', 'extN')): - force = '-F' - elif (fstype == 'reiserfs'): - force = '' - else: - print 'unsupported fs type: ', fstype - else: - force = '' - (ret, out) = run (mkfs, force, dev) - if ret: - panic("Unable to build fs:", dev) - # enable hash tree indexing on fsswe - # FIXME: this check can probably go away on 2.5 - if fstype == 'extN': - htree = 'echo "feature FEATURE_C5" | debugfs -w' - (ret, out) = run (htree, dev) - if ret: - panic("Unable to enable htree:", dev) - -# some systems use /dev/loopN, some /dev/loop/N -def loop_base(): - import re - loop = '/dev/loop' - if not os.access(loop + str(0), os.R_OK): - loop = loop + '/' - if not os.access(loop + str(0), os.R_OK): - panic ("can't access loop devices") - return loop - -# find loop device assigned to thefile -def find_loop(file): - loop = loop_base() - for n in xrange(0, MAX_LOOP_DEVICES): - dev = loop + str(n) - if os.access(dev, os.R_OK): - (stat, out) = run('losetup', dev) - if (out and stat == 0): - m = re.search(r'\((.*)\)', out[0]) - if m and file == m.group(1): - return dev - else: - break - return '' - -# create file if necessary and assign the first free loop device -def init_loop(file, size, fstype): - dev = find_loop(file) - if dev: - print 'WARNING file:', file, 'already mapped to', dev - return dev - if config.reformat() or not os.access(file, os.R_OK | os.W_OK): - run("dd if=/dev/zero bs=1k count=0 seek=%d of=%s" %(size, file)) - loop = loop_base() - # find next free loop - for n in xrange(0, MAX_LOOP_DEVICES): - dev = loop + str(n) - if os.access(dev, os.R_OK): - (stat, out) = run('losetup', dev) - if (stat): - run('losetup', dev, file) - return dev - else: - print "out of loop devices" - return '' - print "out of loop devices" - return '' - -# undo loop assignment -def clean_loop(file): - dev = find_loop(file) - if dev: - ret, out = run('losetup -d', dev) - if ret: - log('unable to clean loop device:', dev, 'for file:', file) - logall(out) - -# determine if dev is formatted as a filesystem -def need_format(fstype, dev): - # FIXME don't know how to implement this - return 0 - -# initialize a block device if needed -def block_dev(dev, size, fstype, format): - if config.noexec(): return dev - if not is_block(dev): - dev = init_loop(dev, size, fstype) - if config.reformat() or (need_format(fstype, dev) and format == 'yes'): - mkfs(fstype, dev) - -# else: -# panic("device:", dev, -# "not prepared, and autoformat is not set.\n", -# "Rerun with --reformat option to format ALL filesystems") - - return dev - -def if2addr(iface): - """lookup IP address for an interface""" - rc, out = run("/sbin/ifconfig", iface) - if rc or not out: - return None - addr = string.split(out[1])[1] - ip = string.split(addr, ':')[1] - return ip - -def get_local_address(net_type, wildcard): - """Return the local address for the network type.""" - local = "" - if net_type in ('tcp', 'toe'): - if ':' in wildcard: - iface, star = string.split(wildcard, ':') - local = if2addr(iface) - if not local: - panic ("unable to determine ip for:", wildcard) - else: - host = socket.gethostname() - local = socket.gethostbyname(host) - elif net_type == 'elan': - # awk '/NodeId/ { print $2 }' '/proc/elan/device0/position' - try: - fp = open('/proc/elan/device0/position', 'r') - lines = fp.readlines() - fp.close() - for l in lines: - a = string.split(l) - if a[0] == 'NodeId': - local = a[1] - break - except IOError, e: - log(e) - elif net_type == 'gm': - fixme("automatic local address for GM") - return local - - -def is_prepared(uuid): - """Return true if a device exists for the uuid""" - # expect this format: - # 1 UP ldlm ldlm ldlm_UUID 2 - try: - out = lctl.device_list() - for s in out: - if uuid == string.split(s)[4]: - return 1 - except CommandError, e: - e.dump() - return 0 - - -# ============================================================ -# Classes to prepare and cleanup the various objects -# -class Module: - """ Base class for the rest of the modules. The default cleanup method is - defined here, as well as some utilitiy funcs. - """ - def __init__(self, module_name, dom_node): - self.dom_node = dom_node - self.module_name = module_name - self.name = get_attr(dom_node, 'name') - self.uuid = get_attr(dom_node, 'uuid') - self.kmodule_list = [] - self._server = None - self._connected = 0 - - def info(self, *args): - msg = string.join(map(str,args)) - print self.module_name + ":", self.name, self.uuid, msg - - - def lookup_server(self, srv_uuid): - """ Lookup a server's network information """ - net = get_ost_net(self.dom_node.parentNode, srv_uuid) - if not net: - panic ("Unable to find a server for:", srv_uuid) - self._server = Network(net) - - def get_server(self): - return self._server - - def cleanup(self): - """ default cleanup, used for most modules """ - self.info() - srv = self.get_server() - if srv and local_net(srv): - try: - lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid) - except CommandError, e: - log(self.module_name, "disconnect failed: ", self.name) - e.dump() - cleanup_error(e.rc) - try: - lctl.cleanup(self.name, self.uuid) - except CommandError, e: - log(self.module_name, "cleanup failed: ", self.name) - e.dump() - cleanup_error(e.rc) - - def add_module(self, dev_dir, modname): - """Append a module to list of modules to load.""" - self.kmodule_list.append((dev_dir, modname)) - - def mod_loaded(self, modname): - """Check if a module is already loaded. Look in /proc/modules for it.""" - fp = open('/proc/modules') - lines = fp.readlines() - fp.close() - # please forgive my tired fingers for this one - ret = filter(lambda word, mod=modname: word == mod, - map(lambda line: string.split(line)[0], lines)) - return ret - - def load_module(self): - """Load all the modules in the list in the order they appear.""" - for dev_dir, mod in self.kmodule_list: - # (rc, out) = run ('/sbin/lsmod | grep -s', mod) - if self.mod_loaded(mod) and not config.noexec(): - continue - log ('loading module:', mod) - if config.src_dir(): - module = find_module(dev_dir, mod) - if not module: - panic('module not found:', mod) - (rc, out) = run('/sbin/insmod', module) - if rc: - raise CommandError('insmod', out, rc) - else: - (rc, out) = run('/sbin/modprobe', mod) - if rc: - raise CommandError('modprobe', out, rc) - - def cleanup_module(self): - """Unload the modules in the list in reverse order.""" - rev = self.kmodule_list - rev.reverse() - for dev_dir, mod in rev: - if not self.mod_loaded(mod): - continue - # debug hack - if mod == 'portals' and config.dump_file(): - lctl.dump(config.dump_file()) - log('unloading module:', mod) - if config.noexec(): - continue - (rc, out) = run('/sbin/rmmod', mod) - if rc: - log('! unable to unload module:', mod) - logall(out) - - -class Network(Module): - def __init__(self,dom_node): - Module.__init__(self, 'NETWORK', dom_node) - self.net_type = get_attr(dom_node,'type') - self.nid = get_text(dom_node, 'server', '*') - self.port = get_text_int(dom_node, 'port', 0) - self.send_mem = get_text_int(dom_node, 'send_mem', DEFAULT_TCPBUF) - self.recv_mem = get_text_int(dom_node, 'recv_mem', DEFAULT_TCPBUF) - if '*' in self.nid: - self.nid = get_local_address(self.net_type, self.nid) - if not self.nid: - panic("unable to set nid for", self.net_type, self.nid) - debug("nid:", self.nid) - - self.add_module(PORTALS_DIR+"/linux/oslib", 'portals') - if node_needs_router(): - self.add_module(PORTALS_DIR+"/linux/router", 'kptlrouter') - if self.net_type == 'tcp': - self.add_module(PORTALS_DIR+"/linux/socknal", 'ksocknal') - if self.net_type == 'toe': - self.add_module(PORTALS_DIR+"/linux/toenal", 'ktoenal') - if self.net_type == 'elan': - self.add_module(PORTALS_DIR+"/linux/rqswnal", 'kqswnal') - if self.net_type == 'gm': - self.add_module(PORTALS_DIR+"/linux/gmnal", 'kgmnal') - self.add_module(config.src_dir()+'obdclass', 'obdclass') - self.add_module(config.src_dir()+'ptlrpc', 'ptlrpc') - - def prepare(self): - self.info(self.net_type, self.nid, self.port) - if self.net_type in ('tcp', 'toe'): - nal_id = '' # default is socknal - if self.net_type == 'toe': - nal_id = '-N 4' - ret, out = run(TCP_ACCEPTOR, '-s', self.send_mem, '-r', self.recv_mem, nal_id, self.port) - if ret: - raise CommandError(TCP_ACCEPTOR, out, ret) - ret = self.dom_node.getElementsByTagName('route_tbl') - for a in ret: - for r in a.getElementsByTagName('route'): - net_type = get_attr(r, 'type') - gw = get_attr(r, 'gw') - lo = get_attr(r, 'lo') - hi = get_attr(r,'hi', '') - lctl.add_route(net_type, gw, lo, hi) - if net_type in ('tcp', 'toe') and net_type == self.net_type and hi == '': - srv = nid2server(self.dom_node.parentNode.parentNode, lo) - if not srv: - panic("no server for nid", lo) - else: - lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_mem, srv.recv_mem) - - - lctl.network(self.net_type, self.nid) - lctl.newdev(attach = "ptlrpc RPCDEV RPCDEV_UUID") - - def cleanup(self): - self.info(self.net_type, self.nid, self.port) - ret = self.dom_node.getElementsByTagName('route_tbl') - for a in ret: - for r in a.getElementsByTagName('route'): - lo = get_attr(r, 'lo') - hi = get_attr(r,'hi', '') - if self.net_type in ('tcp', 'toe') and hi == '': - srv = nid2server(self.dom_node.parentNode.parentNode, lo) - if not srv: - panic("no server for nid", lo) - else: - try: - lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid) - except CommandError, e: - print "disconnect failed: ", self.name - e.dump() - cleanup_error(e.rc) - try: - lctl.del_route(self.net_type, self.nid, lo, hi) - except CommandError, e: - print "del_route failed: ", self.name - e.dump() - cleanup_error(e.rc) - - try: - lctl.cleanup("RPCDEV", "RPCDEV_UUID") - except CommandError, e: - print "cleanup failed: ", self.name - e.dump() - cleanup_error(e.rc) - try: - lctl.disconnectAll(self.net_type) - except CommandError, e: - print "disconnectAll failed: ", self.name - e.dump() - cleanup_error(e.rc) - if self.net_type in ('tcp', 'toe'): - # yikes, this ugly! need to save pid in /var/something - run("killall acceptor") - -class LDLM(Module): - def __init__(self,dom_node): - Module.__init__(self, 'LDLM', dom_node) - self.add_module(config.src_dir()+'ldlm', 'ldlm') - def prepare(self): - if is_prepared(self.uuid): - return - self.info() - lctl.newdev(attach="ldlm %s %s" % (self.name, self.uuid), - setup ="") - -class LOV(Module): - def __init__(self,dom_node): - Module.__init__(self, 'LOV', dom_node) - self.mds_uuid = get_first_ref(dom_node, 'mds') - mds= lookup(dom_node.parentNode, self.mds_uuid) - self.mds_name = getName(mds) - devs = dom_node.getElementsByTagName('devices') - if len(devs) > 0: - dev_node = devs[0] - self.stripe_sz = get_attr_int(dev_node, 'stripesize', 65536) - self.stripe_off = get_attr_int(dev_node, 'stripeoffset', 0) - self.pattern = get_attr_int(dev_node, 'pattern', 0) - self.devlist = get_all_refs(dev_node, 'osc') - self.stripe_cnt = get_attr_int(dev_node, 'stripecount', len(self.devlist)) - self.add_module(config.src_dir()+'mdc', 'mdc') - self.add_module(config.src_dir()+'lov', 'lov') - - def prepare(self): - if is_prepared(self.uuid): - return - for osc_uuid in self.devlist: - osc = lookup(self.dom_node.parentNode, osc_uuid) - if osc: - n = OSC(osc) - try: - # Ignore connection failures, because the LOV will DTRT with - # an unconnected OSC. - n.prepare(ignore_connect_failure=1) - except CommandError: - print "Error preparing OSC %s (inactive)\n" % osc_uuid - else: - panic('osc not found:', osc_uuid) - mdc_uuid = prepare_mdc(self.dom_node.parentNode, self.mds_uuid) - self.info(self.mds_uuid, self.stripe_cnt, self.stripe_sz, - self.stripe_off, self.pattern, self.devlist, self.mds_name) - lctl.newdev(attach="lov %s %s" % (self.name, self.uuid), - setup ="%s" % (mdc_uuid)) - - def cleanup(self): - if not is_prepared(self.uuid): - return - for osc_uuid in self.devlist: - osc = lookup(self.dom_node.parentNode, osc_uuid) - if osc: - n = OSC(osc) - n.cleanup() - else: - panic('osc not found:', osc_uuid) - Module.cleanup(self) - cleanup_mdc(self.dom_node.parentNode, self.mds_uuid) - - - def load_module(self): - for osc_uuid in self.devlist: - osc = lookup(self.dom_node.parentNode, osc_uuid) - if osc: - n = OSC(osc) - n.load_module() - break - else: - panic('osc not found:', osc_uuid) - Module.load_module(self) - - - def cleanup_module(self): - Module.cleanup_module(self) - for osc_uuid in self.devlist: - osc = lookup(self.dom_node.parentNode, osc_uuid) - if osc: - n = OSC(osc) - n.cleanup_module() - break - else: - panic('osc not found:', osc_uuid) - -class LOVConfig(Module): - def __init__(self,dom_node): - Module.__init__(self, 'LOVConfig', dom_node) - self.lov_uuid = get_first_ref(dom_node, 'lov') - l = lookup(dom_node.parentNode, self.lov_uuid) - self.lov = LOV(l) - - def prepare(self): - lov = self.lov - self.info(lov.mds_uuid, lov.stripe_cnt, lov.stripe_sz, lov.stripe_off, - lov.pattern, lov.devlist, lov.mds_name) - lctl.lov_setconfig(lov.uuid, lov.mds_name, lov.stripe_cnt, - lov.stripe_sz, lov.stripe_off, lov.pattern, - string.join(lov.devlist)) - - def cleanup(self): - #nothing to do here - pass - - -class MDS(Module): - def __init__(self,dom_node): - Module.__init__(self, 'MDS', dom_node) - self.devname, self.size = get_device(dom_node) - self.fstype = get_text(dom_node, 'fstype') - # FIXME: if fstype not set, then determine based on kernel version - self.format = get_text(dom_node, 'autoformat', "no") - if self.fstype == 'extN': - self.add_module(config.src_dir()+'extN', 'extN') - self.add_module(config.src_dir()+'mds', 'mds') - self.add_module(config.src_dir()+'obdclass', 'fsfilt_%s'%(self.fstype)) - - def prepare(self): - if is_prepared(self.uuid): - return - self.info(self.devname, self.fstype, self.format) - blkdev = block_dev(self.devname, self.size, self.fstype, self.format) - if not is_prepared('MDT_UUID'): - lctl.newdev(attach="mdt %s %s" % ('MDT', 'MDT_UUID'), - setup ="") - lctl.newdev(attach="mds %s %s" % (self.name, self.uuid), - setup ="%s %s" %(blkdev, self.fstype)) - def cleanup(self): - if is_prepared('MDT_UUID'): - try: - lctl.cleanup("MDT", "MDT_UUID") - except CommandError, e: - print "cleanup failed: ", self.name - e.dump() - cleanup_error(e.rc) - if not is_prepared(self.uuid): - return - Module.cleanup(self) - clean_loop(self.devname) - -# Very unusual case, as there is no MDC element in the XML anymore -# Builds itself from an MDS node -class MDC(Module): - def __init__(self,dom_node): - self.mds = MDS(dom_node) - self.dom_node = dom_node - self.module_name = 'MDC' - self.kmodule_list = [] - self._server = None - self._connected = 0 - - host = socket.gethostname() - self.name = 'MDC_%s' % (self.mds.name) - self.uuid = '%s_%05x_%05x' % (self.name, int(random.random() * 1048576), - int(random.random() * 1048576)) - - self.lookup_server(self.mds.uuid) - self.add_module(config.src_dir()+'mdc', 'mdc') - - def prepare(self): - if is_prepared(self.uuid): - return - self.info(self.mds.uuid) - srv = self.get_server() - lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_mem, srv.recv_mem) - lctl.newdev(attach="mdc %s %s" % (self.name, self.uuid), - setup ="%s %s" %(self.mds.uuid, srv.uuid)) - -class OBD(Module): - def __init__(self, dom_node): - Module.__init__(self, 'OBD', dom_node) - self.obdtype = get_attr(dom_node, 'type') - self.devname, self.size = get_device(dom_node) - self.fstype = get_text(dom_node, 'fstype') - # FIXME: if fstype not set, then determine based on kernel version - self.format = get_text(dom_node, 'autoformat', 'yes') - if self.fstype == 'extN': - self.add_module(config.src_dir()+'extN', 'extN') - self.add_module(config.src_dir()+'' + self.obdtype, self.obdtype) - self.add_module(config.src_dir()+'obdclass' , 'fsfilt_%s' % (self.fstype)) - - # need to check /proc/mounts and /etc/mtab before - # formatting anything. - # FIXME: check if device is already formatted. - def prepare(self): - if is_prepared(self.uuid): - return - self.info(self.obdtype, self.devname, self.size, self.fstype, self.format) - if self.obdtype == 'obdecho': - blkdev = '' - else: - blkdev = block_dev(self.devname, self.size, self.fstype, self.format) - lctl.newdev(attach="%s %s %s" % (self.obdtype, self.name, self.uuid), - setup ="%s %s" %(blkdev, self.fstype)) - def cleanup(self): - if not is_prepared(self.uuid): - return - Module.cleanup(self) - if not self.obdtype == 'obdecho': - clean_loop(self.devname) - -class OST(Module): - def __init__(self,dom_node): - Module.__init__(self, 'OST', dom_node) - self.obd_uuid = get_first_ref(dom_node, 'obd') - self.add_module(config.src_dir()+'ost', 'ost') - - def prepare(self): - if is_prepared(self.uuid): - return - self.info(self.obd_uuid) - lctl.newdev(attach="ost %s %s" % (self.name, self.uuid), - setup ="%s" % (self.obd_uuid)) - - -# virtual interface for OSC and LOV -class VOSC(Module): - def __init__(self,dom_node): - Module.__init__(self, 'VOSC', dom_node) - if dom_node.nodeName == 'lov': - self.osc = LOV(dom_node) - else: - self.osc = OSC(dom_node) - def prepare(self): - self.osc.prepare() - def cleanup(self): - self.osc.cleanup() - def load_module(self): - self.osc.load_module() - def cleanup_module(self): - self.osc.cleanup_module() - - -class OSC(Module): - def __init__(self,dom_node): - Module.__init__(self, 'OSC', dom_node) - self.obd_uuid = get_first_ref(dom_node, 'obd') - self.ost_uuid = get_first_ref(dom_node, 'ost') - self.lookup_server(self.ost_uuid) - self.add_module(config.src_dir()+'osc', 'osc') - - def prepare(self, ignore_connect_failure = 0): - if is_prepared(self.uuid): - return - self.info(self.obd_uuid, self.ost_uuid) - srv = self.get_server() - try: - if local_net(srv): - lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_mem, srv.recv_mem) - else: - r = find_route(srv) - if r: - lctl.add_route_host(r[0], srv.uuid, r[1], r[2]) - else: - panic ("no route to", srv.nid) - except CommandError: - if (ignore_connect_failure == 0): - pass - - lctl.newdev(attach="osc %s %s" % (self.name, self.uuid), - setup ="%s %s" %(self.obd_uuid, srv.uuid)) - - def cleanup(self): - if not is_prepared(self.uuid): - return - srv = self.get_server() - if local_net(srv): - Module.cleanup(self) - else: - self.info(self.obd_uuid, self.ost_uuid) - r = find_route(srv) - if r: - try: - lctl.del_route_host(r[0], srv.uuid, r[1], r[2]) - except CommandError, e: - print "del_route failed: ", self.name - e.dump() - cleanup_error(e.rc) - Module.cleanup(self) - - -class ECHO_CLIENT(Module): - def __init__(self,dom_node): - Module.__init__(self, 'ECHO_CLIENT', dom_node) - self.add_module('lustre/obdecho', 'obdecho') - self.lov_uuid = get_first_ref(dom_node, 'osc') - l = lookup(self.dom_node.parentNode, self.lov_uuid) - self.osc = VOSC(l) - - def prepare(self): - if is_prepared(self.uuid): - return - self.osc.prepare() # XXX This is so cheating. -p - self.info(self.lov_uuid) - - lctl.newdev(attach="echo_client %s %s" % (self.name, self.uuid), - setup = self.lov_uuid) - - def cleanup(self): - if not is_prepared(self.uuid): - return - self.osc.cleanup() - - def load_module(self): - self.osc.load_module() - Module.load_module(self) - def cleanup_module(self): - Module.cleanup_module(self) - self.osc.cleanup_module() - - -class Mountpoint(Module): - def __init__(self,dom_node): - Module.__init__(self, 'MTPT', dom_node) - self.path = get_text(dom_node, 'path') - self.mds_uuid = get_first_ref(dom_node, 'mds') - self.lov_uuid = get_first_ref(dom_node, 'osc') - self.add_module(config.src_dir()+'mdc', 'mdc') - self.add_module(config.src_dir()+'llite', 'llite') - l = lookup(self.dom_node.parentNode, self.lov_uuid) - self.osc = VOSC(l) - - def prepare(self): - self.osc.prepare() - mdc_uuid = prepare_mdc(self.dom_node.parentNode, self.mds_uuid) - self.info(self.path, self.mds_uuid, self.lov_uuid) - cmd = "mount -t lustre_lite -o osc=%s,mdc=%s none %s" % \ - (self.lov_uuid, mdc_uuid, self.path) - run("mkdir", self.path) - ret, val = run(cmd) - if ret: - panic("mount failed:", self.path) - - def cleanup(self): - self.info(self.path, self.mds_uuid,self.lov_uuid) - if config.force(): - (rc, out) = run("umount -f", self.path) - else: - (rc, out) = run("umount", self.path) - if rc: - log("umount failed, cleanup will most likely not work.") - l = lookup(self.dom_node.parentNode, self.lov_uuid) - self.osc.cleanup() - cleanup_mdc(self.dom_node.parentNode, self.mds_uuid) - - def load_module(self): - self.osc.load_module() - Module.load_module(self) - def cleanup_module(self): - Module.cleanup_module(self) - self.osc.cleanup_module() - - -# ============================================================ -# XML processing and query -# TODO: Change query funcs to use XPath, which is muc cleaner - -def get_device(obd): - list = obd.getElementsByTagName('device') - if len(list) > 0: - dev = list[0] - dev.normalize(); - size = get_attr_int(dev, 'size', 0) - return dev.firstChild.data, size - return '', 0 - -# Get the text content from the first matching child -# If there is no content (or it is all whitespace), return -# the default -def get_text(dom_node, tag, default=""): - list = dom_node.getElementsByTagName(tag) - if len(list) > 0: - dom_node = list[0] - dom_node.normalize() - if dom_node.firstChild: - txt = string.strip(dom_node.firstChild.data) - if txt: - return txt - return default - -def get_text_int(dom_node, tag, default=0): - list = dom_node.getElementsByTagName(tag) - n = default - if len(list) > 0: - dom_node = list[0] - dom_node.normalize() - if dom_node.firstChild: - txt = string.strip(dom_node.firstChild.data) - if txt: - try: - n = int(txt) - except ValueError: - panic("text value is not integer:", txt) - return n - -def get_attr(dom_node, attr, default=""): - v = dom_node.getAttribute(attr) - if v: - return v - return default - -def get_attr_int(dom_node, attr, default=0): - n = default - v = dom_node.getAttribute(attr) - if v: - try: - n = int(v) - except ValueError: - panic("attr value is not integer", v) - return n - -def get_first_ref(dom_node, tag): - """ Get the first uuidref of the type TAG. Used one only - one is expected. Returns the uuid.""" - uuid = None - refname = '%s_ref' % tag - list = dom_node.getElementsByTagName(refname) - if len(list) > 0: - uuid = getRef(list[0]) - return uuid - -def get_all_refs(dom_node, tag): - """ Get all the refs of type TAG. Returns list of uuids. """ - uuids = [] - refname = '%s_ref' % tag - list = dom_node.getElementsByTagName(refname) - if len(list) > 0: - for i in list: - uuids.append(getRef(i)) - return uuids - -def get_ost_net(dom_node, uuid): - ost = lookup(dom_node, uuid) - uuid = get_first_ref(ost, 'network') - if not uuid: - return None - return lookup(dom_node, uuid) - -def nid2server(dom_node, nid): - netlist = dom_node.getElementsByTagName('network') - for net_node in netlist: - if get_text(net_node, 'server') == nid: - return Network(net_node) - return None - -def lookup(dom_node, uuid): - for n in dom_node.childNodes: - if n.nodeType == n.ELEMENT_NODE: - if getUUID(n) == uuid: - return n - else: - n = lookup(n, uuid) - if n: return n - return None - -# Get name attribute of dom_node -def getName(dom_node): - return dom_node.getAttribute('name') - -def getRef(dom_node): - return dom_node.getAttribute('uuidref') - -# Get name attribute of dom_node -def getUUID(dom_node): - return dom_node.getAttribute('uuid') - -# the tag name is the service type -# fixme: this should do some checks to make sure the dom_node is a service -def getServiceType(dom_node): - return dom_node.nodeName - -# -# determine what "level" a particular node is at. -# the order of iniitailization is based on level. -def getServiceLevel(dom_node): - type = getServiceType(dom_node) - ret=0; - if type in ('network',): - ret = 10 - elif type in ('device', 'ldlm'): - ret = 20 - elif type in ('obd', 'mdd'): - ret = 30 - elif type in ('mds','ost'): - ret = 40 - elif type in ('mdc','osc'): - ret = 50 - elif type in ('lov', 'lovconfig'): - ret = 60 - elif type in ('mountpoint', 'echo_client'): - ret = 70 - - if ret < config.minlevel() or ret > config.maxlevel(): - ret = 0 - return ret - -# -# return list of services in a profile. list is a list of tuples -# [(level, dom_node),] -def getServices(lustreNode, profileNode): - list = [] - for n in profileNode.childNodes: - if n.nodeType == n.ELEMENT_NODE: - servNode = lookup(lustreNode, getRef(n)) - if not servNode: - print n - panic('service not found: ' + getRef(n)) - level = getServiceLevel(servNode) - if level > 0: - list.append((level, servNode)) - list.sort() - return list - -def getByName(lustreNode, name, tag): - ndList = lustreNode.getElementsByTagName(tag) - for nd in ndList: - if getName(nd) == name: - return nd - return None - - -############################################################ -# MDC UUID hack - -# FIXME: clean this mess up! -# -saved_mdc = {} -def prepare_mdc(dom_node, mds_uuid): - global saved_mdc - mds_node = lookup(dom_node, mds_uuid); - if not mds_node: - panic("no mds:", mds_uuid) - if saved_mdc.has_key(mds_uuid): - return saved_mdc[mds_uuid] - mdc = MDC(mds_node) - mdc.prepare() - saved_mdc[mds_uuid] = mdc.uuid - return mdc.uuid - -def cleanup_mdc(dom_node, mds_uuid): - global saved_mdc - mds_node = lookup(dom_node, mds_uuid); - if not mds_node: - panic("no mds:", mds_uuid) - if not saved_mdc.has_key(mds_uuid): - mdc = MDC(mds_node) - mdc.cleanup() - saved_mdc[mds_uuid] = mdc.uuid - - -############################################################ -# routing ("rooting") -# -routes = [] -local_node = [] -router_flag = 0 - -def init_node(dom_node): - global local_node, router_flag - netlist = dom_node.getElementsByTagName('network') - for dom_net in netlist: - type = get_attr(dom_net, 'type') - gw = get_text(dom_net, 'server') - local_node.append((type, gw)) - -def node_needs_router(): - return router_flag - -def get_routes(type, gw, dom_net): - """ Return the routes as a list of tuples of the form: - [(type, gw, lo, hi),]""" - res = [] - tbl = dom_net.getElementsByTagName('route_tbl') - for t in tbl: - routes = t.getElementsByTagName('route') - for r in routes: - lo = get_attr(r, 'lo') - hi = get_attr(r, 'hi', '') - res.append((type, gw, lo, hi)) - return res - - -def init_route_config(lustre): - """ Scan the lustre config looking for routers. Build list of - routes. """ - global routes, router_flag - routes = [] - list = lustre.getElementsByTagName('node') - for node in list: - if get_attr(node, 'router'): - router_flag = 1 - for (local_type, local_nid) in local_node: - gw = None - netlist = node.getElementsByTagName('network') - for dom_net in netlist: - if local_type == get_attr(dom_net, 'type'): - gw = get_text(dom_net, 'server') - break - if not gw: - continue - for dom_net in netlist: - if local_type != get_attr(dom_net, 'type'): - for route in get_routes(local_type, gw, dom_net): - routes.append(route) - - -def local_net(net): - global local_node - for iface in local_node: - if net.net_type == iface[0]: - return 1 - return 0 - -def find_route(net): - global local_node, routes - frm_type = local_node[0][0] - to_type = net.net_type - to = net.nid - debug ('looking for route to', to_type,to) - for r in routes: - if r[2] == to: - return r - return None - - - - -############################################################ -# lconf level logic -# Start a service. -def startService(dom_node, module_flag): - type = getServiceType(dom_node) - debug('Service:', type, getName(dom_node), getUUID(dom_node)) - # there must be a more dynamic way of doing this... - n = None - if type == 'ldlm': - n = LDLM(dom_node) - elif type == 'lov': - n = LOV(dom_node) - elif type == 'lovconfig': - n = LOVConfig(dom_node) - elif type == 'network': - n = Network(dom_node) - elif type == 'obd': - n = OBD(dom_node) - elif type == 'ost': - n = OST(dom_node) - elif type == 'mds': - n = MDS(dom_node) - elif type == 'osc': - n = VOSC(dom_node) - elif type == 'mdc': - n = MDC(dom_node) - elif type == 'mountpoint': - n = Mountpoint(dom_node) - elif type == 'echo_client': - n = ECHO_CLIENT(dom_node) - else: - panic ("unknown service type:", type) - - if module_flag: - if config.nomod(): - return - if config.cleanup(): - n.cleanup_module() - else: - n.load_module() - else: - if config.nosetup(): - return - if config.cleanup(): - n.cleanup() - else: - n.prepare() - -# -# Prepare the system to run lustre using a particular profile -# in a the configuration. -# * load & the modules -# * setup networking for the current node -# * make sure partitions are in place and prepared -# * initialize devices with lctl -# Levels is important, and needs to be enforced. -def startProfile(lustreNode, profileNode, module_flag): - if not profileNode: - panic("profile:", profile, "not found.") - services = getServices(lustreNode, profileNode) - if config.cleanup(): - services.reverse() - for s in services: - startService(s[1], module_flag) - - -# -# Load profile for -def doHost(lustreNode, hosts): - global routes - dom_node = None - for h in hosts: - dom_node = getByName(lustreNode, h, 'node') - if dom_node: - break - if not dom_node: - print 'lconf: No host entry found in '+sys.argv[1] - return - - if not get_attr(dom_node, 'router'): - init_node(dom_node) - init_route_config(lustreNode) - else: - global router_flag - router_flag = 1 - - # Two step process: (1) load modules, (2) setup lustre - # if not cleaning, load modules first. - module_flag = not config.cleanup() - reflist = dom_node.getElementsByTagName('profile') - for profile in reflist: - startProfile(lustreNode, profile, module_flag) - - if not config.cleanup(): - sys_set_debug_path() - script = config.gdb_script() - run(lctl.lctl, ' modules >', script) - if config.gdb(): - # dump /tmp/ogdb and sleep/pause here - log ("The GDB module script is in", script) - time.sleep(5) - - module_flag = not module_flag - for profile in reflist: - startProfile(lustreNode, profile, module_flag) - -############################################################ -# Command line processing -# -def parse_cmdline(argv): - short_opts = "hdnvf" - long_opts = ["ldap", "reformat", "lustre=", "verbose", "gdb", - "portals=", "makeldiff", "cleanup", "noexec", - "help", "node=", "nomod", "nosetup", - "dump=", "force", "minlevel=", "maxlevel="] - opts = [] - args = [] - try: - opts, args = getopt.getopt(argv, short_opts, long_opts) - except getopt.error: - print "invalid opt" - usage() - - for o, a in opts: - if o in ("-h", "--help"): - usage() - if o in ("-d","--cleanup"): - config.cleanup(1) - if o in ("-v", "--verbose"): - config.verbose(1) - if o in ("-n", "--noexec"): - config.noexec(1) - config.verbose(1) - if o == "--portals": - config.portals = a - if o == "--lustre": - config.lustre = a - if o == "--reformat": - config.reformat(1) - if o == "--node": - config.node(a) - if o == "--gdb": - config.gdb(1) - if o == "--nomod": - config.nomod(1) - if o == "--nosetup": - config.nosetup(1) - if o == "--dump": - config.dump_file(a) - if o in ("-f", "--force"): - config.force(1) - if o in ("--minlevel",): - config.minlevel(a) - if o in ("--maxlevel",): - config.maxlevel(a) - - return args - -def fetch(url): - import urllib - data = "" - try: - s = urllib.urlopen(url) - data = s.read() - except: - usage() - return data - -def setupModulePath(cmd): - global PORTALS_DIR - base = os.path.dirname(cmd) - if os.access(base+"/Makefile", os.R_OK): - config.src_dir(base + "/../") - if PORTALS_DIR[0] != '/': - PORTALS_DIR= config.src_dir()+PORTALS_DIR - -def sys_set_debug_path(): - debug("debug path: ", config.debug_path()) - if config.noexec(): - return - try: - fp = open('/proc/sys/portals/debug_path', 'w') - fp.write(config.debug_path()) - fp.close() - except IOError, e: - print e - -#/proc/sys/net/core/rmem_max -#/proc/sys/net/core/wmem_max -def sys_set_netmem_max(path, max): - debug("setting", path, "to at least", max) - if config.noexec(): - return - fp = open(path) - str = fp.readline() - fp.close - cur = int(str) - if max > cur: - fp = open(path, 'w') - fp.write('%d\n' %(max)) - fp.close() - - -def sys_make_devices(): - if not os.access('/dev/portals', os.R_OK): - run('mknod /dev/portals c 10 240') - if not os.access('/dev/obd', os.R_OK): - run('mknod /dev/obd c 10 241') - - -# Add dir to the global PATH, if not already there. -def add_to_path(new_dir): - syspath = string.split(os.environ['PATH'], ':') - if new_dir in syspath: - return - os.environ['PATH'] = os.environ['PATH'] + ':' + new_dir - - -DEFAULT_PATH = ('/sbin', '/usr/sbin', '/bin', '/usr/bin') -# ensure basic elements are in the system path -def sanitise_path(): - for dir in DEFAULT_PATH: - add_to_path(dir) - -# Initialize or shutdown lustre according to a configuration file -# * prepare the system for lustre -# * configure devices with lctl -# Shutdown does steps in reverse -# -def main(): - global TCP_ACCEPTOR, lctl, MAXTCPBUF - setupModulePath(sys.argv[0]) - - host = socket.gethostname() - - # the PRNG is normally seeded with time(), which is not so good for starting - # time-synchronized clusters - input = open('/dev/urandom', 'r') - if not input: - print 'Unable to open /dev/urandom!' - sys.exit(1) - seed = input.read(32) - input.close() - random.seed(seed) - - sanitise_path() - - args = parse_cmdline(sys.argv[1:]) - if len(args) > 0: - if not os.access(args[0], os.R_OK): - print 'File not found or readable:', args[0] - sys.exit(1) - dom = xml.dom.minidom.parse(args[0]) - elif config.url(): - xmldata = fetch(config.url()) - dom = xml.dom.minidom.parseString(xmldata) - else: - usage() - - node_list = [] - if config.node(): - node_list.append(config.node()) - else: - if len(host) > 0: - node_list.append(host) - node_list.append('localhost') - debug("configuring for host: ", node_list) - - if len(host) > 0: - config._debug_path = config._debug_path + '-' + host - config._gdb_script = config._gdb_script + '-' + host - - TCP_ACCEPTOR = find_prog('acceptor') - if not TCP_ACCEPTOR: - if config.noexec(): - TCP_ACCEPTOR = 'acceptor' - debug('! acceptor not found') - else: - panic('acceptor not found') - - lctl = LCTLInterface('lctl') - - sys_make_devices() - sys_set_netmem_max('/proc/sys/net/core/rmem_max', MAXTCPBUF) - sys_set_netmem_max('/proc/sys/net/core/wmem_max', MAXTCPBUF) - doHost(dom.documentElement, node_list) - -if __name__ == "__main__": - try: - main() - except LconfError, e: - print e - except CommandError, e: - e.dump() - sys.exit(e.rc) - - if first_cleanup_error: - sys.exit(first_cleanup_error) - diff --git a/lustre/utils/llparser.pm b/lustre/utils/llparser.pm deleted file mode 100644 index dc1792f..0000000 --- a/lustre/utils/llparser.pm +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/perl -# Author: Hariharan Thantry -# Date: 12/13/2002 - -package llparser; -require Exporter; -@ISA = qw(Exporter); -@EXPORT = qw(parse_file $e_subsys $e_mask $e_processor $e_time $e_file $e_line $e_function $e_pid $e_stack $e_fmtstr $e_backref $e_treeparent $e_numchildren $e_youngestchild $e_next $e_pidhead); - -($e_subsys, - $e_mask, - $e_processor, - $e_time, - $e_file, - $e_line, - $e_function, - $e_pid, - $e_stack, - $e_fmtstr, - $e_treeparent, - $e_numchildren, - $e_youngestchild, - $e_pidhead, - $e_next, - $e_backref) = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - -$MAX_STACK_SIZE = 8192; - -$REGEX=qr/^\s*(\w+)\s*:\s*(\d+)\s*:\s*(\d+)\s*:\s*(\d+\.(?:\d+))\s*\(\s*([^:]+)\s*:\s*(\d+)\s*:\s*([^()]+)\s*\(\)\s*(\d+)\s*\+\s*(\d+)\s*(?:.*)\):(.*)$/; - -# Create backlinks between array entries based on the calling sequence -# For each new PID encountered, the first entry will be present in the -# PID hash. - -sub create_links { - my $arrayref = shift @_; - my $pidhashref = shift @_; - my $pidparent; - my %local_hash; - my $hash_lineref; - #my $lineref; - my $bool = 0; - - foreach $lineref (@$arrayref) { - $pidparent = $pidhashref->{$lineref->[$e_pid]}; - if ($pidparent->[$e_next] == 0) { - $pidparent->[$e_next] = $lineref; - if (exists $local_hash{$lineref->[$e_pid]} && $bool) { - $hash_lineref=$local_hash{$lineref->[$e_pid]}; - $hash_lineref->[$e_next] =$lineref; - $bool = 0; - #print "LINE UPDATED: [@$hash_lineref]\n"; - #print "NEXT LINE ADDR:$lineref, CONTENT: @$lineref \n"; - } - } elsif ($local_hash{$lineref->[$e_pid]} == 0) { - # True only for the first line, the marker line. - $local_hash{$lineref->[$e_pid]}=$lineref; - #print "LINE ADDED TO HASH: @$lineref\n"; - $bool = 1; - } - - if ($lineref->[$e_stack] < $pidparent->[$e_stack]) { - $lineref->[$e_backref] = $pidparent; - $pidparent->[$e_numchildren]++; - $pidhashref->{$lineref->[$e_pid]}=$lineref; - - } elsif ($lineref->[$e_stack] > $pidparent->[$e_stack]) { - LINE: while($lineref->[$e_stack] > $pidparent->[$e_stack]) { - last LINE if ($pidparent->[$e_backref] == 0); - $pidparent = $pidparent->[$e_backref]; - } - $lineref->[$e_backref] = $pidparent; - $pidparent->[$e_numchildren]++; - $pidhashref->{$lineref->[$e_pid]}=$lineref; - - } else { - $lineref->[$e_numchildren] = 0; - $lineref->[$e_backref] = $pidparent->[$e_backref]; - $pidhashref->{$lineref->[$e_pid]} = $lineref; - ($lineref->[$e_backref])->[$e_numchildren]++; - } - $lineref->[$e_youngestchild] = $lineref; - while ($pidparent->[$e_backref] != 0) { - $pidparent->[$e_youngestchild] = $lineref; - $pidparent = $pidparent->[$e_backref]; - } - $pidparent->[$e_youngestchild] = $lineref; - $lineref->[$e_pidhead]=$pidparent; - } - return $arrayref; -} - -# Main loop, parses the debug log - -sub parse_file { - my %hasharray; - $backref = 0; - $treeparent = 0; - $numchildren = 0; - $youngestchild = 0; - $next = 0; - $pidhead = 0; - - while(<>){ - if (/$REGEX/) { - @parsed_line=($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $treeparent, $numchildren, $youngestchild, $pidhead, $next, $backref); - if (!exists($hasharray{$parsed_line[$e_pid]})) { - # Push a marker for the beginning of this PID - my @marker_line; - $marker_line[$e_subsys] = 0; - $marker_line[$e_mask] = 0; - $marker_line[$e_processor] = 0; - $marker_line[$e_time] = $parsed_line[$e_time]; - $marker_line[$e_file] = 0; - $marker_line[$e_line] = 0; - $marker_line[$e_function] = 0; - $marker_line[$e_pid] = $parsed_line[$e_pid]; - $marker_line[$e_stack] = $MAX_STACK_SIZE; - $marker_line[$e_fmtstr] = ""; - $marker_line[$e_treeparent] = 0; - $marker_line[$e_numchildren] = 0; - $marker_line[$e_youngestchild] = 0; - $marker_line[$e_pidhead] = 0; - $marker_line[$e_next]= \@parsed_line; - $marker_line[$e_backref] = 0; - $hasharray{$parsed_line[$e_pid]} = \@marker_line; - push @$array_parsed, [ @marker_line ]; - - } - push @$array_parsed, [ @parsed_line ]; - } - } - $array_parsed=create_links($array_parsed, \%hasharray); - #print_array($array_parsed); - return $array_parsed; -} - -sub print_array { - - my $arrayref = shift; - foreach $lineref(@$arrayref){ - if ($lineref->[$e_backref]==0){ - print "MARKER LINE(addr): $lineref contents: [ @$lineref ]\n"; - } else { - - print "REGULAR LINE (addr) :$lineref contents: [ @$lineref ]\n"; - } - } - -} -1; -#$array_parsed=parse_file(); -#print_array($array_parsed); diff --git a/lustre/utils/lstripe.c b/lustre/utils/lstripe.c deleted file mode 100644 index 65055a5..0000000 --- a/lustre/utils/lstripe.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - - -/****************** Custom includes ********************/ -#include -#include - - -/****************** Functions ******************/ - -void usage(char *pgm) -{ - fprintf(stderr, "\nIncorrect parameters! Correct usage:\n\n" ); - fprintf(stderr, "%s \n", pgm); - - fprintf(stderr, "\n\nArgument explanations:\n---------------------\n\n"); - fprintf(stderr, " = the full name and path of the output file to create\n"); - fprintf(stderr, " = the number of bytes to have in each stripe.\n"); - fprintf(stderr, " = the OST number to start the striping on.\n"); - fprintf(stderr, " = the number of stripes to use.\n"); - - fprintf(stderr, "\n\nExamples:\n---------\n\n"); - - fprintf(stderr, "%s /mnt/lustre/ost1 131072 0 1\n", pgm); - fprintf(stderr, "\t\tcreates a file only on ost1.\n\n"); - - fprintf(stderr, "%s /mnt/lustre/ost2 131072 1 1\n", pgm); - fprintf(stderr, "\t\tcreates a file only on ost2.\n\n"); - - fprintf(stderr, "%s /mnt/lustre/ost1and2 131072 0 2\n", pgm); - fprintf(stderr, "\t\tcreates a 128k file with 2 stripes, on ost1 and ost2.\n"); - - fprintf(stderr, "%s /mnt/lustre/ost1and2 131072 1 2\n", pgm); - fprintf(stderr, "\t\tcreates a 128k file with 2 stripes, on ost2 and ost1.\n"); -} - -int create_file(char *name, long stripe_size, int stripe_offset, - int stripe_count) -{ - struct lov_mds_md a_striping; - int fd, result = 0; - - /* Initialize IOCTL striping pattern structure */ - a_striping.lmm_magic = LOV_MAGIC; - a_striping.lmm_stripe_pattern = 0; - a_striping.lmm_stripe_size = stripe_size; - a_striping.lmm_stripe_offset = stripe_offset; - a_striping.lmm_stripe_count = stripe_count; - - fd = open(name, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644); - if (fd < 0) { - fprintf(stderr, "\nUnable to open '%s': %s\n", - name, strerror(errno)); - result = -errno; - } else if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, &a_striping)) { - fprintf(stderr, "\nError on ioctl for '%s' (%d): %s\n", - name, fd, strerror(errno)); - result = -errno; - } else if (close(fd) < 0) { - fprintf(stderr, "\nError on close for '%s' (%d): %s\n", - name, fd, strerror(errno)); - result = -errno; - } - - return result; -} - -int main(int argc, char *argv[]) -{ - int result; - long st_size; - int st_offset, - st_count; - - /* Check to make sure we have enough parameters */ - if (argc != 5) { - usage(argv[0]); - return(-1); - } - - /* Get the stripe size */ - st_size = atol(argv[2]); - - /* Get the stripe offset*/ - st_offset = atoi(argv[3]); - - /* Get the stripe count */ - st_count = atoi(argv[4]); - - /* Create the file, as specified. Return and display any errors. */ - result = create_file(argv[1], st_size, st_offset, st_count); - - return result; -} diff --git a/lustre/utils/lustre.dtd b/lustre/utils/lustre.dtd deleted file mode 100644 index ba4af32..0000000 --- a/lustre/utils/lustre.dtd +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lustre/utils/lustreLdap.py b/lustre/utils/lustreLdap.py deleted file mode 100755 index b8bf376..0000000 --- a/lustre/utils/lustreLdap.py +++ /dev/null @@ -1,1785 +0,0 @@ -#!/usr/bin/env python -# -# Author: Ravindranadh Chowdary Sahukara -# This file is part of Lustre, http://www.lustre.org. -# -# Lustre is free software; you can redistribute it and/or -# modify it under the terms of version 2 of the GNU General Public -# License as published by the Free Software Foundation. -# -# Lustre is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Lustre; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -# lconf - lustre configuration tool -# -# lconf is the main driver script for starting and stopping -# lustre filesystem services. -# -# Based in part on the XML obdctl modifications done by Brian Behlendorf - -from types import DictType, ListType, TupleType, StringType -import string, os, stat, popen2, socket, time, random -import sys, getopt -import re, exceptions -import xml.dom.minidom -from sys import exit -from string import split,join - - -# Global parameters -DEFAULT_TCPBUF = 0 - - -def panic(*args): - msg = string.join(map(str,args)) - print "! " + msg - exit(1) - -def debug(*args): - msg = string.join(map(str,args)) - print msg - - -names = {} -uuids = {} - - -def new_name(bas): - ctr = 2 - ret = bas - while names.has_key(ret): - ret = "%s_%d" % (bas, ctr) - ctr = 1 + ctr - names[ret] = 1 - return str(ret) - -def new_uuid(name): - return "%s_UUID" % (name) - - -def getServices(lustreNode, profileNode): - list = [] - for n in profileNode.childNodes: - if n.nodeType == n.ELEMENT_NODE: - servNode = lookup(lustreNode, getRef(n)) - if not servNode: - print n - panic('service not found: ' + getRef(n)) - list.append((servNode)) - #list.sort() - return list - -def getByName(lustreNode, name, tag): - ndList = lustreNode.getElementsByTagName(tag) - for nd in ndList: - if getName(nd) == name: - return nd - return None - - - -class Module: - """ Base class for the rest of the modules. """ - def __init__(self, module_name, dom_node): - self.dom_node = dom_node - self.module_name = module_name - self.name = get_attr(dom_node, 'name') - self.uuid = get_attr(dom_node, 'uuid') - self.kmodule_list = [] - self._server = None - self._connected = 0 - - def info(self, *args): - msg = string.join(map(str,args)) - print self.module_name + ":", self.name, self.uuid, msg - - - def lookup_server(self, srv_uuid): - """ Lookup a servers network information """ - net = get_ost_net(self.dom_node.parentNode, srv_uuid) - if not net: - panic ("Unable to find a server for:", srv_uuid) - self._server = Network(net) - - def get_server(self): - return self._server - - -class Network(Module): - def __init__(self,dom_node): - Module.__init__(self, 'NETWORK', dom_node) - self.net_type = get_attr(dom_node,'type') - self.nid = get_text(dom_node, 'server', '*') - self.port = get_text_int(dom_node, 'port', 0) - self.send_mem = get_text_int(dom_node, 'send_mem', DEFAULT_TCPBUF) - self.recv_mem = get_text_int(dom_node, 'recv_mem', DEFAULT_TCPBUF) - if '*' in self.nid: - self.nid = get_local_address(self.net_type, self.nid) - if not self.nid: - panic("unable to set nid for", self.net_type, self.nid) - debug("nid:", self.nid) - - -class LDLM(Module): - def __init__(self,dom_node): - Module.__init__(self, 'LDLM', dom_node) - -class LOV(Module): - def __init__(self,dom_node): - Module.__init__(self, 'LOV', dom_node) - self.mds_uuid = get_first_ref(dom_node, 'mds') - mds= lookup(dom_node.parentNode, self.mds_uuid) - self.mds_name = getName(mds) - devs = dom_node.getElementsByTagName('devices') - if len(devs) > 0: - dev_node = devs[0] - self.stripe_sz = get_attr_int(dev_node, 'stripesize', 65536) - self.stripe_off = get_attr_int(dev_node, 'stripeoffset', 0) - self.pattern = get_attr_int(dev_node, 'pattern', 0) - self.devlist = get_all_refs(dev_node, 'osc') - self.stripe_cnt = get_attr_int(dev_node, 'stripecount', len(self.devlist)) - -class LOVConfig(Module): - def __init__(self,dom_node): - Module.__init__(self, 'LOVConfig', dom_node) - self.lov_uuid = get_first_ref(dom_node, 'lov') - l = lookup(dom_node.parentNode, self.lov_uuid) - self.lov = LOV(l) - - -class MDS(Module): - def __init__(self,dom_node): - Module.__init__(self, 'MDS', dom_node) - self.devname, self.size = get_device(dom_node) - self.fstype = get_text(dom_node, 'fstype') - # FIXME: if fstype not set, then determine based on kernel version - self.format = get_text(dom_node, 'autoformat', "no") - self.lookup_server(self.uuid) - -# Very unusual case, as there is no MDC element in the XML anymore -# Builds itself from an MDS node -class OBD(Module): - def __init__(self, dom_node): - Module.__init__(self, 'OBD', dom_node) - self.obdtype = get_attr(dom_node, 'type') - self.devname, self.size = get_device(dom_node) - self.fstype = get_text(dom_node, 'fstype') - # FIXME: if fstype not set, then determine based on kernel version - self.format = get_text(dom_node, 'autoformat', 'yes') - -class OST(Module): - def __init__(self,dom_node): - Module.__init__(self, 'OST', dom_node) - self.obd_uuid = get_first_ref(dom_node, 'obd') - - -# virtual interface for OSC and LOV -class VOSC(Module): - def __init__(self,dom_node): - Module.__init__(self, 'VOSC', dom_node) - if dom_node.nodeName == 'lov': - self.osc = LOV(dom_node) - else: - self.osc = OSC(dom_node) - -class OSC(Module): - def __init__(self,dom_node): - Module.__init__(self, 'OSC', dom_node) - self.obd_uuid = get_first_ref(dom_node, 'obd') - self.ost_uuid = get_first_ref(dom_node, 'ost') - self.lookup_server(self.ost_uuid) - -class Mountpoint(Module): - def __init__(self,dom_node): - Module.__init__(self, 'MTPT', dom_node) - self.path = get_text(dom_node, 'path') - self.mds_uuid = get_first_ref(dom_node, 'mds') - self.lov_uuid = get_first_ref(dom_node, 'osc') - l = lookup(self.dom_node.parentNode, self.lov_uuid) - self.osc = VOSC(l) - -# ============================================================ - -def get_device(obd): - list = obd.getElementsByTagName('device') - if len(list) > 0: - dev = list[0] - dev.normalize(); - size = get_attr_int(dev, 'size', 0) - return str(dev.firstChild.data), str(size) - return '', 0 - -# Get the text content from the first matching child -# If there is no content (or it is all whitespace), return -# the default -def get_text(dom_node, tag, default=""): - list = dom_node.getElementsByTagName(tag) - if len(list) > 0: - dom_node = list[0] - dom_node.normalize() - if dom_node.firstChild: - txt = string.strip(dom_node.firstChild.data) - if txt: - return txt - return default - -def get_text_int(dom_node, tag, default=0): - list = dom_node.getElementsByTagName(tag) - n = default - if len(list) > 0: - dom_node = list[0] - dom_node.normalize() - if dom_node.firstChild: - txt = string.strip(dom_node.firstChild.data) - if txt: - try: - n = int(txt) - except ValueError: - panic("text value is not integer:", txt) - return n - -def get_attr(dom_node, attr, default=""): - v = dom_node.getAttribute(attr) - if v: - return str(v) - return str(default) - -def get_attr_int(dom_node, attr, default=0): - n = default - v = dom_node.getAttribute(attr) - if v: - try: - n = int(v) - except ValueError: - panic("attr value is not integer", v) - return n - -def get_first_ref(dom_node, tag): - """ Get the first uuidref of the type TAG. Used one only - one is expected. Returns the uuid.""" - uuid = None - refname = '%s_ref' % tag - list = dom_node.getElementsByTagName(refname) - if len(list) > 0: - uuid = getRef(list[0]) - return uuid - -def get_all_refs(dom_node, tag): - """ Get all the refs of type TAG. Returns list of uuids. """ - uuids = [] - refname = '%s_ref' % tag - list = dom_node.getElementsByTagName(refname) - if len(list) > 0: - for i in list: - uuids.append(getRef(i)) - return uuids - -def get_ost_net(dom_node, uuid): - ost = lookup(dom_node, uuid) - uuid = get_first_ref(ost, 'network') - if not uuid: - return None - return lookup(dom_node, uuid) - -def lookup(dom_node, uuid): - for n in dom_node.childNodes: - if n.nodeType == n.ELEMENT_NODE: - if getUUID(n) == uuid: - return n - else: - n = lookup(n, uuid) - if n: return n - return None - -# Get name attribute of dom_node -def getName(dom_node): - return str(dom_node.getAttribute('name')) - -def getRef(dom_node): - return dom_node.getAttribute('uuidref') - -# Get name attribute of dom_node -def getUUID(dom_node): - return str(dom_node.getAttribute('uuid')) - -# the tag name is the service type -def getServiceType(dom_node): - return dom_node.nodeName - - - -############################################################################## -# LDAP related stuff tarts here... - -import ldap -import _ldap - -#returns the lustre ldap specific filters - -class lustre_ldap: - def __init__(self): - self.filter=0 - - def get_filter(self,lustreRdn): - filter="(&"+lustreRdn+")" - return filter - -# make a connection to LDAP server and abd bind -class MyConn: - def __init__(self,host,port): - self.id = 0 - self.host = host - self.port = port - self.base = "fs=lustre" - - def open(self): - self.id = ldap.open(self.host) - if self.id == None: - print "unable to open a connection" - - try: - # lustre tree starts from here...the DN is (cn=Manager ,fs=lustre) - status = self.id.simple_bind("cn=Manager, fs=lustre","secret") - except _ldap.LDAPError: - print "unable to bind" - - - -# Lustre Node object class definition as per defined in the lustre.schema - -class LustreNode: - def __init__(self, nodename): - self.objectClass = "lustreNode" - self.nodeUUID = 0 - self.id = nodename - self.netUUIDs = [] - self.profileUUID = 0 - self.routerUUID = 0 - self.ldlmUUID = 0 - - self.lustreNet = {} - self.lustreNodeProfile = 0 - self.lustreLdlm = 0 - - self.nodeUUID_str = "nodeUUID" - self.id_str = "id" - self.netUUIDs_str = "netUUIDs" - self.ldlmUUID_str = "ldlmUUID" - self.profileUUID_str = "profileUUID" - self.routerUUID_str = "routerUUID" - self.node_str = "node" - - def get_object_class(self): - return self.objectClass - - def get_rdn(self): - retval = "(objectClass="+self.objectClass+") (id="+self.id+")" - return retval - - # Initilize lustre Node Object class after read drom LDAP server - def init_node(self, node_entry): - self.id = node_entry[0][1][self.id_str][0] - self.nodeUUID = node_entry[0][1][self.nodeUUID_str][0] - for i in range(len(node_entry[0][1][self.netUUIDs_str])): - self.netUUIDs.append(node_entry[0][1][self.netUUIDs_str][i]) - if node_entry[0][1].has_key(self.profileUUID_str): - self.profileUUID = node_entry[0][1][self.profileUUID_str][0] - if node_entry[0][1].has_key(self.ldlmUUID_str): - self.ldlmUUID = node_entry[0][1][self.ldlmUUID_str][0] - - if node_entry[0][1].has_key(self.routerUUID_str): - self.routerUUID = node_entry[0][1][self.routerUUID_str][0] - - # Brings the lustre Node object entries from LDAP server - def getEntry_from_ldap(self, conn_id, base): - try: - lustre_util = lustre_ldap() - # the filter has id=,type=node,fs=lustre - # base is "fs=lustre" - filter = lustre_util.get_filter(self.get_rdn()) - result = conn_id.search_s(base, ldap.SCOPE_SUBTREE, filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - #network object class - if self.netUUIDs: - for netuuid in self.netUUIDs: - # loading the network object class from LDAP, since this related to lustre node class - self.lustreNet[netuuid] = LustreNet() - self.lustreNet[netuuid].getEntry_from_ldap(conn_id, base, netuuid) - - # The ldlm object class - if self.ldlmUUID: - # loading the ldlm object class from LDAP, since this related to lustre node class - self.lustreLdlm = LustreLdlm() - self.lustreLdlm.getEntry_from_ldap(conn_id, base, self.ldlmUUID) - - # The lustre node profile object class - if self.profileUUID: - # loading the node profile object class from LDAP, since this related to lustre node class - # The node profile contains the clientUUID, mdsUUIDs (multiple) and ostUUIDs(multiple) - # the rest of the object class queried from LDAP server useing above UUIDs - self.lustreNodeProfile = LustreNodeProfile() - self.lustreNodeProfile.getEntry_from_ldap(conn_id, base, self.profileUUID) - - except ldap.NO_SUCH_OBJECT: - print "no results Found" - exit(1) - - def get_dn(self,id): - return self.id_str+"="+id+",type="+self.node_str+",fs=lustre" - - # add entries into LDAP server, All of them are must fields - def addEntry_into_ldap(self, conn_id, id, nodeUUID, netUUIDs, profileUUID, routerUUID, ldlmUUID): - modlist = [] - dn = self.get_dn(self.id) - modlist.append(("objectClass", [self.objectClass])) - modlist.append((self.id_str, id)) - modlist.append((self.nodeUUID_str, nodeUUID)) - modlist.append((self.netUUIDs_str, netUUIDs)) - modlist.append((self.profileUUID_str, profileUUID)) - modlist.append((self.routerUUID_str, routerUUID)) - modlist.append((self.ldlmUUID_str, ldlmUUID)) - modlist.append(("fs", ["lustre"])) - status = 0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - debug("lustre Node: "+ id +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - # print values of object class - def print_node(self): - print "lustre Node Attributes......" - print "objectClass: %s" % self.objectClass - print "node UUID: %s" % self.nodeUUID - print "node name: %s" % self.id - for i in range(len(self.netUUIDs)): - print "network UUID%d: %s" % (i,self.netUUIDs[i]) - print "Node Profile UUID: %s" % self.profileUUID - print "Router UUID: %s" % self.routerUUID - print "Ldlm UUID: %s" % self.ldlmUUID - print - for i in range(len(self.netUUIDs)): - self.lustreNet[i].print_net() - - self.lustreNodeProfile.print_profile() - self.lustreLdlm.print_ldlm() - - - -# lustre Client object class It have mount uuid and net uuid, but the net uuid may not required at present. -class LustreClient: - def __init__(self,lustreNode): - self.objectClass = "lustreClient" - self.clientUUID = 0 - self.mountUUIDs = [] - self.netUUID = 0 - - self.lustreNode = lustreNode - self.lustreNet = 0 - self.lustreMount = {} - - - self.clientUUID_attr = "clientUUID" - self.mountUUID_attr = "mountUUIDs" - self.netUUID_attr = "netUUID" - self.client_attr = "client" - - def ge_object_class(self): - return self.objectClass - - def get_rdn(self,attr_value): - retval = "(objectClass="+self.objectClass+") (clientUUID="+attr_value+")" - return retval - - - # load the object class with client config params - def init_node(self,node_entry): - self.clientUUID = node_entry[0][1][self.clientUUID_attr][0] - for i in range(len(node_entry[0][1][self.mountUUID_attr])): - self.mountUUIDs.append(node_entry[0][1][self.mountUUID_attr][i]) - self.netUUID = node_entry[0][1][self.netUUID_attr][0] - - - # brings the client config params from LDAP, here the search criteria is clientUUID=lustre1_client_UUID,type=client,fs=lustre, this is called as dn - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util = lustre_ldap() - # filter has "clientUUID=lustre1_client_UUID,type=client,fs=lustre" - # the base is "fs=lustre" - filter = lustre_util.get_filter(self.get_rdn(attr_val)) - result = conn_id.search_s(base, ldap.SCOPE_SUBTREE, filter) - if result == []: - print "Client Error No Results found" - sys.exit(1) - - self.init_node(result) - - if self.netUUID: - self.lustreNet = LustreNet() - self.lustreNet.getEntry_from_ldap(conn_id, base, self.netUUID) - else: - print "Unable to find the LDLM uuid in Client Object Class..." - - if self.mountUUIDs: - for mntuuid in self.mountUUIDs: - self.lustreMount[mntuuid] = LustreMount() - self.lustreMount[mntuuid].getEntry_from_ldap(conn_id, base, mntuuid) - - - def get_dn(self, uuid): - retval = self.clientUUID_attr+"="+uuid+",type="+self.client_attr+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id, clientUUID, mountUUIDs, netUUID): - modlist = [] - dn = self.get_dn(clientUUID) - modlist.append(("objectClass", [self.objectClass])) - modlist.append((self.clientUUID_attr, clientUUID)) - modlist.append((self.mountUUID_attr, mountUUIDs)) - modlist.append((self.netUUID_attr, netUUID[0])) - modlist.append(("fs", ["lustre"])) - status = 0 - try: - conn_id.add_s(dn, modlist) - except _ldap.LDAPError: - debug("lustre client: "+ clientUUID +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - - def print_client(self): - print "Lustre Client Configurations..............." - print "client Object Calss: %s" % self.objectClass - print "client UUID: %s" % self.clientUUID - print "This client supporting %d file systems" % len(self.mountUUIDs) - if self.lustreNet: - self.lustreNet.print_net() - - if self.mountUUIDs: - for mntuuid in self.mountUUIDs: - self.lustreMount[mntuuid].print_mount() - - - - -class LustreMount: - def __init__(self): - self.objectClass = "lustreMount" - self.mountUUID = 0 - self.mdsUUID = 0 - self.lovUUID = 0 - self.mountPath = "" - self.default = 0 - - self.lustreMds = 0 - self.lustreLov = 0 - - self.mountUUID_attr = "mountUUID" - self.mdsUUID_attr = "mdsUUID" - self.lovUUID_attr = "lovUUID" - self.mountPath_attr = "mountPath" - self.default_attr = "default" - self.type = "mountPoint" - - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self, attr_value): - retval = "(objectClass="+self.objectClass+") (mountUUID="+attr_value+")" - return retval - - - def init_node(self, record): - self.mdsUUID = record[0][1][self.mdsUUID_attr][0] - self.mountUUID = record[0][1][self.mountUUID_attr][0] - self.lovUUID = record[0][1][self.lovUUID_attr][0] - self.mountPath = record[0][1][self.mountPath_attr][0] - self.default = record[0][1][self.default_attr][0] - - def getEntry_from_ldap(self, conn_id, base, attr_val): - lustre_util = lustre_ldap() - filter = lustre_util.get_filter(self.get_rdn(attr_val)) - result = conn_id.search_s(base, ldap.SCOPE_SUBTREE, filter) - if result == []: - print "Mount Error No Results found" - sys.exit(1) - self.init_node(result) - - if self.mdsUUID: - self.lustreMds = LustreMds() - self.lustreMds.getEntry_from_ldap(conn_id, base, self.mdsUUID) - - if self.lovUUID: - self.lustreLov = LustreLov() - self.lustreLov.getEntry_from_ldap(conn_id, base, self.lovUUID) - - def get_dn(self, uuid): - retval = self.mountUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self, conn_id, mountUUID, mdsUUID, lovUUID, mountPath, default = 0): - modlist = [] - dn=self.get_dn(mountUUID) - modlist.append(("objectClass", [self.objectClass])) - modlist.append((self.mountUUID_attr, mountUUID)) - modlist.append((self.mdsUUID_attr, mdsUUID)) - modlist.append((self.lovUUID_attr, lovUUID)) - modlist.append((self.mountPath_attr, mountPath)) - modlist.append((self.default_attr, default)) - modlist.append(("fs", ["lustre"])) - status = 0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - debug("lustre Mount: "+ mountUUID +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - - def print_mount(self): - - print "Lustre mount point attributes......" - print "mount object class: %s" % self.objectClass - print "mount UUID: %s" % self.mountUUID - print "mds UUID: %s" % self.mdsUUID - print "lov UUID: %s" % self.lovUUID - print "mount point: %s" % self.mountPath - if self.default: - print "This file system is default file system for this cleint" - else: - print "This file system is not a default file system for this cleint" - - if self.lustreMds: - self.lustreMds.print_mds() - if self.lustreLov: - self.lustreLov.print_lov() - - -class LustreOsc: - def __init__(self): - self.objectClass = "lustreOSC" - self.oscUUID = 0 - self.devName = "" - self.obdUUID = 0 - self.ostUUID = 0 - - self.lustreObd = 0 - self.lustreOst = 0 - - self.oscUUID_attr = "oscUUID" - self.devName_attr = "devName" - self.obdUUID_attr = "obdUUID" - self.ostUUID_attr = "ostUUID" - self.type = "OSC" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self, attr_value): - retval = "(objectClass="+self.objectClass+") (oscUUID="+attr_value+")" - return retval - - - def init_node(self, record): - self.oscUUID=record[0][1][self.oscUUID_attr][0] - self.obdUUID=record[0][1][self.obdUUID_attr][0] - self.ostUUID=record[0][1][self.ostUUID_attr][0] - self.devName=record[0][1][self.devName_attr][0] - - - def getEntry_from_ldap(self, conn_id, base, attr_val): - lustre_util = lustre_ldap() - filter = lustre_util.get_filter(self.get_rdn(attr_val)) - result = conn_id.search_s(base, ldap.SCOPE_SUBTREE, filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - if self.obdUUID: - self.lustreObd = LustreObd() - self.lustreObd.getEntry_from_ldap(conn_id, base, self.obdUUID) - - if self.ostUUID: - self.lustreOst = LustreOst() - self.lustreOst.getEntry_from_ldap(conn_id, base, self.ostUUID) - - def get_dn(self, uuid): - retval = self.oscUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self, conn_id, oscUUID, devName, obdUUID, ostUUID): - modlist = [] - dn=self.get_dn(oscUUID) - modlist.append(("objectClass", [self.objectClass])) - modlist.append((self.oscUUID_attr, oscUUID)) - modlist.append((self.devName_attr, devName)) - modlist.append((self.obdUUID_attr, obdUUID)) - modlist.append((self.ostUUID_attr, ostUUID)) - modlist.append(("fs", ["lustre"])) - status = 0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - debug("lustre OSC : "+ oscUUID +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - - def print_osc(self): - print "Lustre Osc Attrributes.." - print "object class: %s" % self.objectClass - print "oscUUID: %s" % self.oscUUID - print "devName: %s" % self.devName - print "obdUUID: %s" % self.obdUUID - print "ostUUID: %s" % self.ostUUID - print - if self.lustreObd: - self.lustreObd.print_obd() - print - if self.lustreOst: - self.lustreOst.print_ost() - print - - -class LustreMdc: - def __init__(self): - self.objectClass="lustreMDC" - self.mdcUUID=0 - self.devName="" - self.mdsUUID=0 - - self.lustreMds=0 - - self.mdcUUID_attr="mdcUUID" - self.devName_attr="devName" - self.mdsUUID_attr="mdsUUID" - self.type="MDC" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (mdcUUID="+attr_value+")" - return retval - - - def init_node(self,record): - self.mdcUUID=record[0][1][self.mdcUUID_attr][0] - self.mdsUUID=record[0][1][self.mdsUUID_attr][0] - self.devName=record[0][1][self.devName_attr][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - if self.mdsUUID: - self.lustreMds=LustreMds() - self.lustreMds.getEntry_from_ldap(conn_id,base,self.mdsUUID) - - - def get_dn(self,uuid): - retval=self.mdcUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.mdcUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.mdcUUID_attr,[self.mdcUUID])) - modlist.append((self.devName_attr,self.devName)) - modlist.append((self.mdsUUID_attr,[self.mdsUUID])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_mdc(self): - print "Lustre Mdc attributes....." - print "Mdc UUID: %s" % self.mdcUUID - print "dev name: %s" % self.devName - print "Mds UUId: %s" % self.mdsUUID - print - if self.lustreMds: - self.lustreMds.print_mds() - - - -class LustreOst: - def __init__(self): - self.objectClass = "lustreOST" - self.ostUUID = 0 - self.devName = "" - self.obdUUID = 0 - - self.lustreObd = 0 - - self.ostUUID_attr = "ostUUID" - self.devName_attr = "devName" - self.obdUUID_attr = "obdUUID" - self.type = "OST" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval = "(objectClass="+self.objectClass+") (ostUUID="+attr_value+")" - return retval - - def init_node(self, record): - self.ostUUID = record[0][1][self.ostUUID_attr][0] - self.obdUUID = record[0][1][self.obdUUID_attr][0] - self.devName = record[0][1][self.devName_attr][0] - - def getEntry_from_ldap(self, conn_id, base, attr_val): - lustre_util = lustre_ldap() - filter = lustre_util.get_filter(self.get_rdn(attr_val)) - result = conn_id.search_s(base, ldap.SCOPE_SUBTREE, filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - if self.obdUUID: - self.lustreObd = LustreObd() - self.lustreObd.getEntry_from_ldap(conn_id, base, self.obdUUID) - - - def get_dn(self,uuid): - retval = self.ostUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self, conn_id, ostUUID, devName, obdUUID): - modlist = [] - dn=self.get_dn(ostUUID) - modlist.append(("objectClass", [self.objectClass])) - modlist.append((self.ostUUID_attr, ostUUID)) - modlist.append((self.devName_attr, devName)) - modlist.append((self.obdUUID_attr, obdUUID)) - modlist.append(("fs", ["lustre"])) - status=0 - try: - conn_id.add_s(dn, modlist) - except _ldap.LDAPError: - debug("lustre OST : "+ ostUUID +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - - def print_ost(self): - print "Lustre Ost Attributes...." - print "object class: %s" % self.objectClass - print "ostUUID: %s" % self.ostUUID - print "devName: %s" % self.devName - print "obdUUID: %s" % self.obdUUID - print - if self.lustreObd: - self.lustreObd.print_obd() - - - -class LustreMds: - def __init__(self): - self.objectClass = "lustreMDS" - self.mdsUUID = 0 - self.devName = "" - self.devUUID = 0 - self.lovUUID = 0 - self.fUUID = 0 - - self.lustreDev = 0 - self.lustreLov = 0 - - self.mdsUUID_attr = "mdsUUID" - self.devName_attr = "devName" - self.devUUID_attr = "devUUID" - self.lovUUID_attr = "lovUUID" - self.fUUID_attr = "fUUID" - self.type = "MDS" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self, attr_value): - retval = "(objectClass="+self.objectClass+") (mdsUUID="+attr_value+")" - return retval - - - def init_node(self,record): - self.mdsUUID = record[0][1][self.mdsUUID_attr][0] - self.devUUID = record[0][1][self.devUUID_attr][0] - self.lovUUID = record[0][1][self.lovUUID_attr][0] - #self.fUUID = record[0][1][self.fUUID_attr][0] - self.devName = record[0][1][self.devName_attr][0] - - def getEntry_from_ldap(self, conn_id, base, attr_val): - lustre_util = lustre_ldap() - filter = lustre_util.get_filter(self.get_rdn(attr_val)) - result = conn_id.search_s(base, ldap.SCOPE_SUBTREE, filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - - if self.devUUID: - self.lustreDev = LustreDevice() - self.lustreDev.getEntry_from_ldap(conn_id, base, self.devUUID) - - if self.lovUUID: - self.lustreLov = LustreLov() - self.lustreLov.getEntry_from_ldap(conn_id, base, self.lovUUID) - - - def get_dn(self, uuid): - retval = self.mdsUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self, conn_id, mdsUUID, devName, devUUID, lovUUID, fUUID): - modlist = [] - dn = self.get_dn(mdsUUID) - modlist.append(("objectClass", [self.objectClass])) - modlist.append((self.mdsUUID_attr, mdsUUID)) - modlist.append((self.devName_attr, devName)) - modlist.append((self.devUUID_attr, devUUID)) - if lovUUID: - modlist.append((self.lovUUID_attr, lovUUID)) - modlist.append((self.fUUID_attr, fUUID)) - modlist.append(("fs", ["lustre"])) - status = 0 - - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - debug("lustre MDS : "+ mdsUUID +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - - def print_mds(self): - print "Lustre Mds Attributes..." - print "object Class: %s" % self.objectClass - print "mdsUUID: %s" % self.mdsUUID - print "devName: %s" % self.devName - print "devUUID: %s" % self.devUUID - #print "fUUID: %s" % self.fUUID - print "lovUUID: %s" % self.lovUUID - print - if self.lustreLov: - self.lustreLov.print_lov() - print - - -class LustreLov: - def __init__(self): - self.objectClass = "lustreLOV" - self.lovUUID = 0 - self.devName = "" - self.oscUUIDs = [] - self.stripeOffset = 0 - self.stripeSize = 0 - self.stripeCount = 0 - self.pattern = 0 - - self.lustreOsc = {} - - self.lovUUID_attr = "lovUUID" - self.devName_attr = "devName" - self.oscUUID_attr = "oscUUIDs" - self.stripeOffset_attr = "stripeOffset" - self.stripeSize_attr = "stripeSize" - self.stripeCount_attr = "stripeCount" - self.pattern_attr = "pattern" - self.type = "LOV" - - def get_object_class(self): - return self.objectCalss - - - - def get_rdn(self,attr_value): - retval = "(objectClass="+self.objectClass+") (lovUUID="+attr_value+")" - return retval - - - def init_node(self, record): - nofvals = len(record[0][1][self.oscUUID_attr]) - for i in range(nofvals): - self.oscUUIDs.append(record[0][1][self.oscUUID_attr][i]) - - self.stripeOffset = record[0][1][self.stripeOffset_attr][0] - self.lovUUID = record[0][1][self.lovUUID_attr][0] - self.devName = record[0][1][self.devName_attr][0] - self.stripeSize = record[0][1][self.stripeSize_attr][0] - self.stripeCount = record[0][1][self.stripeCount_attr][0] - self.pattern = record[0][1][self.pattern_attr][0] - - def getEntry_from_ldap(self, conn_id, base, attr_val): - lustre_util = lustre_ldap() - filter = lustre_util.get_filter(self.get_rdn(attr_val)) - result = conn_id.search_s(base, ldap.SCOPE_SUBTREE, filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - - if self.oscUUIDs: - for uuid in self.oscUUIDs: - self.lustreOsc[uuid] = LustreOsc() - self.lustreOsc[uuid].getEntry_from_ldap(conn_id, base, uuid) - - def get_dn(self,uuid): - retval = self.lovUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self, conn_id, lovUUID, devName, oscUUIDs, stripeOffset, stripeSize, stripeCount, pattern): - modlist = [] - dn=self.get_dn(lovUUID) - modlist.append(("objectClass", [self.objectClass])) - modlist.append((self.lovUUID_attr, lovUUID)) - modlist.append((self.devName_attr, devName)) - modlist.append((self.oscUUID_attr, oscUUIDs)) - modlist.append((self.stripeOffset_attr, stripeOffset)) - modlist.append((self.stripeSize_attr, stripeSize)) - modlist.append((self.stripeCount_attr, stripeCount)) - modlist.append((self.pattern_attr, pattern)) - modlist.append(("fs", ["lustre"])) - status = 0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - debug("lustre LOV: "+ lovUUID +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - - def print_lov(self): - print "Lustre LOV attributes..." - print "object class: %s" % self.objectClass - print "lovUUID: %s" % self.lovUUID - print "devName: %s" % self.devName - print "oscUUIDs are" - for i in range(len(self.oscUUIDs)): - print "oscUUID[%d]: %s" % (i,self.oscUUIDs[i]) - print "stripeOffset: %s" % self.stripeOffset - print "stripe Size: %s" % self.stripeSize - print "stripe Count: %s" % self.stripeCount - print "pattern: %s" % self.pattern - - print - if self.oscUUIDs: - for uuid in self.oscUUIDs: - if self.lustreOsc: - self.lustreOsc[uuid].print_osc() - print - - -class LustreDevice: - def __init__(self): - self.objectClass = "lustreDevice" - self.id = "" - self.fid = "" - self.devUUID = 0 - self.netUUID = 0 - self.fnetUUID = 0 - self.device = "" - self.auto = 0 - self.fsType = "" - self.size = 0 - - self.id_attr = "id" - self.fid_attr = "fid" - self.devUUID_attr = "devUUID" - self.netUUID_attr = "netUUID" - self.fnetUUID_attr = "fnetUUID" - self.device_attr = "device" - self.auto_attr = "auto" - self.fsType_attr = "fsType" - self.size_attr = "size" - self.type = "device" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self, attr_value): - retval = "(objectClass="+self.objectClass+") (devUUID="+attr_value+")" - return retval - - def init_node(self, record): - self.devUUID = record[0][1][self.devUUID_attr][0] - self.netUUID = record[0][1][self.netUUID_attr][0] - self.fnetUUID = record[0][1][self.fnetUUID_attr][0] - self.id = record[0][1][self.id_attr][0] - self.fid = record[0][1][self.fid_attr][0] - self.device = record[0][1][self.device_attr][0] - self.auto = record[0][1][self.auto_attr][0] - self.fsType = record[0][1][self.fsType_attr][0] - self.size = record[0][1][self.size_attr][0] - - def getEntry_from_ldap(self, conn_id, base, attr_val): - lustre_util = lustre_ldap() - filter = lustre_util.get_filter(self.get_rdn(attr_val)) - result = conn_id.search_s(base, ldap.SCOPE_SUBTREE, filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - def get_dn(self,uuid): - retval = self.devUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self, conn_id, devUUID, netUUID, fnetUUID, id, fid, device, auto, fsType, size): - modlist = [] - dn = self.get_dn(devUUID) - modlist.append(("objectClass", [self.objectClass])) - modlist.append((self.devUUID_attr, devUUID)) - modlist.append((self.netUUID_attr, netUUID)) - modlist.append((self.fnetUUID_attr, fnetUUID)) - modlist.append((self.id_attr, id)) - modlist.append((self.fid_attr, fid)) - modlist.append((self.device_attr, device)) - modlist.append((self.auto_attr, auto)) - modlist.append((self.fsType_attr, fsType)) - modlist.append((self.size_attr, size)) - modlist.append(("fs", ["lustre"])) - status = 0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - debug("lustre Device : "+ devUUID +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - - def print_device(self): - print "lustre Device object...." - print "object Calss: %s" % self.objectClass - print "node name: %s" % self.id - print "failover node name: %s" % self.fid - print "devUUID: %s" % self.devUUID - print "netUUID: %s" % self.netUUID - print "failover netUUID: %s" % self.fnetUUID - print "device: %s" % self.device - print "autoformat: %s" % self.auto - print "fs type: %s" % self.fsType - print "size of device: %s" % self.size - - - -class LustreObd: - def __init__(self): - self.objectClass = "lustreOBD" - self.obdUUID = 0 - self.devName = "" - self.devUUID = 0 - self.fUUID = 0 - - self.lustreDev = 0 - - self.obdUUID_attr = "obdUUID" - self.devName_attr = "devName" - self.devUUID_attr = "devUUID" - self.fUUID_attr = "fUUID" - self.type = "OBD" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval = "(objectClass="+self.objectClass+") (obdUUID="+attr_value+")" - return retval - - def init_node(self, record): - self.obdUUID = record[0][1][self.obdUUID_attr][0] - self.devName = record[0][1][self.devName_attr][0] - self.devUUID = record[0][1][self.devUUID_attr][0] - self.fUUID = record[0][1][self.fUUID_attr][0] - - def getEntry_from_ldap(self, conn_id, base, attr_val): - lustre_util = lustre_ldap() - filter = lustre_util.get_filter(self.get_rdn(attr_val)) - result = conn_id.search_s(base, ldap.SCOPE_SUBTREE, filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - if self.devUUID: - self.lustreDev = LustreDevice() - self.lustreDev.getEntry_from_ldap(conn_id, base, self.devUUID) - - - def get_dn(self,uuid): - retval = self.obdUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self, conn_id, obdUUID, devName, devUUID, fUUID): - modlist = [] - dn=self.get_dn(obdUUID) - modlist.append(("objectClass", [self.objectClass])) - modlist.append((self.obdUUID_attr, obdUUID)) - modlist.append((self.devName_attr, devName)) - modlist.append((self.devUUID_attr, devUUID)) - modlist.append((self.fUUID_attr, fUUID)) - modlist.append(("fs", ["lustre"])) - status = 0 - try: - conn_id.add_s(dn, modlist) - except _ldap.LDAPError: - debug("lustre OBD : "+ obdUUID +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - - def print_obd(self): - print "Lustre Obd attributes...." - print "object Class: %s" % self.objectClass - print "obdUUID: %s" % self.obdUUID - print "devName: %s" % self.devName - print "devUUID: %s" % self.devUUID - print "fUUID: %s" % self.fUUID - print - if self.lustreDev: - self.lustreDev.print_device() - print - - -class LustreLdlm: - def __init__(self): - self.objectClass="lustreLDLM" - self.ldlmUUID=0 - self.devName="" - - self.ldlmUUID_attr="ldlmUUID" - self.devName_attr="devName" - self.type="LDLM" - - def get_object_class(self): - return self.objectCalss - - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (ldlmUUID="+attr_value+")" - return retval - - def init_node(self,record): - self.ldlmUUID=record[0][1][self.ldlmUUID_attr][0] - self.devName=record[0][1][self.devName_attr][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - - def get_dn(self,uuid): - retval=self.ldlmUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self, conn_id, ldlmUUID, devName): - modlist=[] - dn=self.get_dn(ldlmUUID) - modlist.append(("objectClass", self.objectClass)) - modlist.append((self.ldlmUUID_attr, ldlmUUID)) - modlist.append((self.devName_attr, devName)) - modlist.append(("fs", "lustre")) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - debug("LDLM UUID: "+ ldlmUUID +" already added") - #debug("LDLM UUID: "+ _ldap.LDAPError +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - - def print_ldlm(self): - print "Printing LDLM attributes..........." - print "ldlm Object Class: %s" % self.objectClass - print "ldlm UUID: %s" % self.ldlmUUID - print "ldlm Name: %s" % self.devName - print "\n" * 5 - - -class LustreNet: - def __init__(self): - self.objectClass = "lustreNetwork" - self.netUUID = 0 - self.id = 0 - self.fnetUUID = 0 - self.netType = "" - self.netAddress = "" - self.port = 0 - self.recvMem = 0 - self.sendMem = 0 - - self.netUUID_attr = "netUUID" - self.fnetUUID_attr = "fnetUUID" - self.id_attr = "id" - self.netType_attr = "netType" - self.netAddress_attr = "netAddress" - self.port_attr = "port" - self.recvMem_attr = "recvMem" - self.sendMem_attr = "sendMem" - self.type = "net" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self, attr_value): - retval = "(objectClass="+self.objectClass+") (netUUID="+attr_value+")" - return retval - - def init_node(self, record): - self.netUUID = record[0][1][self.netUUID_attr][0] - self.fnetUUID = record[0][1][self.fnetUUID_attr][0] - self.id = record[0][1][self.id_attr][0] - self.netType = record[0][1][self.netType_attr][0] - self.netAddress = record[0][1][self.netAddress_attr][0] - self.port = record[0][1][self.port_attr][0] - self.recvMem = record[0][1][self.recvMem_attr][0] - self.sendMem = record[0][1][self.sendMem_attr][0] - - def getEntry_from_ldap(self, conn_id, base, attr_val): - lustre_util = lustre_ldap() - filter = lustre_util.get_filter(self.get_rdn(attr_val)) - result = conn_id.search_s(base, ldap.SCOPE_SUBTREE, filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - - def get_dn(self, uuid): - retval = self.netUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id, id, netUUID, fnetUUID, netType, netAddress, port, recvMem, sendMem): - modlist = [] - dn=self.get_dn(netUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.netUUID_attr,[netUUID])) - modlist.append((self.fnetUUID_attr,[fnetUUID])) - modlist.append((self.id_attr,[id])) - modlist.append((self.netType_attr,[netType])) - modlist.append((self.netAddress_attr,[netAddress])) - modlist.append((self.port_attr,[port])) - modlist.append((self.recvMem_attr,[recvMem])) - modlist.append((self.sendMem_attr,[sendMem])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - debug("lustre Network : "+ netUUID +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - - def print_net(self): - print "Lustre Network Attributes:......" - print "object Class: %s" % self.objectClass - print "network UUID: %s" % self.netUUID - print "failover network UUID: %s" % self.fnetUUID - print "node name : %s" % self.id - print "network Type: %s" % self.netType - print "IP Address: %s" % self.netAddress - print "port: %s" % self.port - print "receive memory: %s" % self.recvMem - print "send memory: %s" % self.sendMem - print - - -class LustreNodeProfile: - def __init__(self): - self.objectClass="lustreNodeProfile" - self.profileUUID=0 - self.mdsUUIDs=[] - self.ostUUIDs=[] - self.clientUUID=0 - - self.profileUUID_str="profileUUID" - self.mdsUUIDs_str="mdsUUIDs" - self.ostUUIDs_str="ostUUIDs" - self.clientUUID_str="clientUUID" - self.type="profile" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (profileUUID="+attr_value+")" - return retval - - def init_node(self,node_entry): - self.profileUUID=node_entry[0][1][self.profileUUID_str][0] - if node_entry[0][1].has_key(self.mdsUUIDs_str): - for i in range(len(node_entry[0][1][self.mdsUUIDs_str])): - self.mdsUUIDs.append(node_entry[0][1][self.mdsUUIDs_str][i]) - - if node_entry[0][1].has_key(self.ostUUIDs_str): - for i in range(len(node_entry[0][1][self.ostUUIDs_str])): - self.ostUUIDs.append(node_entry[0][1][self.ostUUIDs_str][i]) - - if node_entry[0][1].has_key(self.clientUUID_str): - self.clientUUID=node_entry[0][1][self.clientUUID_str][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - def get_dn(self,uuid): - retval=self.profileUUID_str+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id,profileUUID,mdsUUIDs,ostUUIDs,clientUUID): - modlist=[] - dn=self.get_dn(profileUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.profileUUID_str,[profileUUID])) - if mdsUUIDs: - modlist.append((self.mdsUUIDs_str,mdsUUIDs)) - if ostUUIDs: - modlist.append((self.ostUUIDs_str,ostUUIDs)) - if clientUUID: - modlist.append((self.clientUUID_str,[clientUUID])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - debug("lustre Profile: "+ profileUUID +" already added") - return status - - def initobj(self,*args): - print "init obj :", args - - def print_profile(self): - print "Lustre Node Profile Attributes:......" - print "object Class: %s" % self.objectClass - print "profile UUID: %s" % self.profileUUID - print "This node supports %d mds servers:" % len(self.mdsUUIDs) - for i in range(len(self.mdsUUIDs)): - print "Mds UUID%d: %s" % (i,self.mdsUUIDs[i]) - print "This node supports %d ost servers:" % len(self.ostUUIDs) - for i in range(len(self.ostUUIDs)): - print "Ost UUID%d: %s" % (i,self.ostUUIDs[i]) - print "Client UUID: %s" % self.clientUUID - print - - -def get_matched_osc(ConnId,ostuuid): - result = ConnId.search_s("fs=lustre",ldap.SCOPE_SUBTREE,"objectclass=lustreOSC") - lustreOSC = 0 - if result: - for i in range(len(result)): - tmpuuid = result[i][1]['ostUUID'][0] - if ostuuid == tmpuuid: - lustreOSC = LustreOsc() - lustreOSC.init_node([result[i]]) - break - - else: - print "no result" - - return lustreOSC - - -def get_matched_lov(ConnId,oscuuid): - result = ConnId.search_s("fs=lustre",ldap.SCOPE_SUBTREE,"objectclass=lustreLOV") - lustreLOV = 0 - tmpuuids = [] - if result: - for i in range(len(result)): - tmpuuids = result[i][1]['oscUUIDs'] - for uuid in tmpuuids: - if oscuuid == uuid: - lustreLOV = LustreLov() - lustreLOV.init_node([result[i]]) - return lustreLOV - return 0 - - - - - - - - -net_uuids = [] -def loadNetworkconfig(dom_node,node): - global net_uuids - node_name = get_attr(node,'name') - net = Network(dom_node) - net_uuids.append(net.uuid) - failnetUUID = net.uuid - lustreNet = LustreNet() - lustreNet.addEntry_into_ldap(connId, node_name, net.uuid, failnetUUID, net.net_type, str(net.nid), str(net.port), str(net.send_mem), str(net.recv_mem)) - - -ldlm_uuid = 0 -def loadLDLMconfig(dom_node,node): - "This is fill LDLM details...:" - global ldlm_uuid - ldlm = LDLM(dom_node) - ldlm_uuid = ldlm.uuid - lustreLdlm = LustreLdlm() - lustreLdlm.addEntry_into_ldap(connId, ldlm.uuid, ldlm.name) - -lov_uuids = [] -lovUUID = 0 -def loadLOVconfig(dom_node,node): - global lov_uuids - global lovUUID - lov_uuid = get_first_ref(dom_node, 'lov') - lov_node = lookup(dom_node.parentNode, lov_uuid) - lov = LOV(lov_node) - lov_uuids.append(lov.uuid) - lovUUID = lov.uuid - node_name = get_attr(node,'name') - osc_uuids = [] - for uuid in lov.devlist: - osc_uuids.append(str(uuid)) - objlov = LustreLov() - objlov.addEntry_into_ldap(connId, lov.uuid, lov.name, osc_uuids, str(lov.stripe_off), str(lov.stripe_sz), str(lov.stripe_cnt), str(lov.pattern)) - - lov_devs = lov_node.getElementsByTagName('devices') - devlist = get_all_refs(lov_devs[0], 'osc') - for osc_uuid in devlist: - osc_node = lookup(dom_node.parentNode,osc_uuid) - osc = OSC(osc_node) - lustreOsc = LustreOsc() - lustreOsc .addEntry_into_ldap(connId, osc.uuid, osc.name, str(osc.obd_uuid), str(osc.ost_uuid)) - -mds_uuids = [] -def loadMDSconfig( dom_node,node): - global mds_uuids - global lovUUID - node_name = getName(node) - mds = MDS(dom_node) - mds_net = mds.get_server() - - netuuid = mds_net.uuid - failnetuuid = netuuid - fid = mds_net.nid - device_name = new_name('DEVICE_'+node_name) - devuuid = new_uuid(device_name) - lov_uuid = get_first_ref(dom_node, 'lov') - - objdevice = LustreDevice() - objdevice.addEntry_into_ldap(connId, devuuid, netuuid, netuuid, node_name, node_name, str(mds.devname), str(mds.format), str(mds.fstype), str(mds.size)) - - lovcfg_uuids = get_all_refs(node, 'lovconfig') - for lovcfg_uuid in lovcfg_uuids: - lovcfg = 0 - if lovcfg_uuid: - lovcfg_node = lookup(dom_node.parentNode, lovcfg_uuid ) - lovcfg = LOVConfig(lovcfg_node) - lov_uuid = 0 - if lovcfg: - lov_uuid = str(lovcfg.lov_uuid) - lov_node = lookup(dom_node.parentNode, lov_uuid) - lov = LOV(lov_node) - if mds.uuid == lov.mds_uuid: - #print "Match found" - break - - lustreMds = LustreMds() - lustreMds.addEntry_into_ldap(connId, mds.uuid, mds.name, devuuid, lov_uuid, mds.uuid) - mds_uuids.append(mds.uuid) - - -def loadOBDconfig(dom_node,node): - global net_uuids - node_name = get_attr(node,'name') - obd = OBD(dom_node) - device_name = new_name('DEVICE_'+node_name) - devuuid = new_uuid(device_name) - - lustreDev = LustreDevice() - lustreDev.addEntry_into_ldap(connId, devuuid, net_uuids[0], net_uuids[0], node_name, node_name, str(obd.devname), str(obd.format), str(obd.fstype), str(obd.size)) - - lustreObd = LustreObd() - lustreObd.addEntry_into_ldap(connId, obd.uuid, obd.name, devuuid, obd.uuid) - - -mount_uuids = [] -def loadMountpointconfig(dom_node,node): - global mount_uuids - node_name = get_attr(node,'name') - mount = Mountpoint(dom_node) - - mountuuid = new_uuid(mount.name) - mount_uuids.append(mountuuid) - lustreMount = LustreMount() - lustreMount.addEntry_into_ldap(connId, mountuuid, str(mount.mds_uuid), str(mount.lov_uuid),str(mount.path), "No") - - - -ost_uuids = [] -def loadOSTconfig(dom_node,node): - global ost_uuids - ost = OST(dom_node) - node_name = get_attr(node,'name') - - lustreOst = LustreOst() - lustreOst.addEntry_into_ldap(connId, ost.uuid, ost.name, str(ost.obd_uuid)) - ost_uuids.append(ost.uuid) - -############################################################ -# lconf level logic -# Start a service. - - - - -def LoadProfile(lustreNode,profileNode,node): - global mount_uuids - global profile_uuid - node_name = get_attr(node,'name') - if not profileNode: - panic("profile:",profile,"not found.") - services = getServices(lustreNode,profileNode) - if services: - for service in services: - dom_node = service - type = getServiceType(dom_node) - if type == 'ldlm': - loadLDLMconfig(dom_node,node) - elif type == 'obd': - loadOBDconfig(dom_node,node) - elif type == 'lovconfig': - loadLOVconfig(dom_node,node) - elif type == 'network': - loadNetworkconfig(dom_node,node) - elif type == 'ost': - loadOSTconfig(dom_node,node) - elif type == 'mds': - loadMDSconfig(dom_node,node) - elif type == 'mountpoint': - loadMountpointconfig(dom_node,node) - else: - panic ("unknown service type:", type) - - - clientuuid = 0 - if mount_uuids: - clientuuid = node_name + "clientUUID" - lustre_Node = LustreNode(node_name) - lustreClient = LustreClient(lustre_Node) - lustreClient.addEntry_into_ldap(connId, clientuuid, mount_uuids, net_uuids) - - - profile_uuid = str(node_name+"profileUUID") - nodeprofile = LustreNodeProfile() - nodeprofile.addEntry_into_ldap(connId, profile_uuid, mds_uuids, ost_uuids, clientuuid) - -def Initilize_globals(): - global mds_uuids - global ost_uuids - global net_uuids - global clientuuid - global profile_uuid - global ldlm_uuid - global mount_uuids - mount_uuids = [] - mds_uuids = [] - ost_uuids = [] - net_uuids = [] - lov_uuids = [] - clientuuid = 0 - profile_uuid = 0 - ldlm_uuid = 0 - -def print_globals(): - global mds_uuids - global ost_uuids - global net_uuids - global clientuuid - global profile_uuid - global ldlm_uuid - print "mds_uuids :", mds_uuids - print "ost_uuids :", ost_uuids - print "net_uuids :", net_uuids - print "client uuid :", clientuuid - print "profile_uuid :", profile_uuid - print "ldlm_uuid :", ldlm_uuid - -connId = 0 -def loadXml(lustreNode): - global net_uuids - global ldlm_uuid - global profile_uuid - dom_node = None - Initilize_globals() - - global connId - server = "blackswan.india.hp.com" - port=389 - binddn="cn=Manager,fs=lustre" - base="fs=lustre" - myCon=MyConn(server,port) - myCon.open() - connId=myCon.id - - nodelist = [] - nodelist = lustreNode.getElementsByTagName('node') - for i in range(len(nodelist)): - node_name = getName(nodelist[i]) - node_uuid = getUUID(nodelist[i]) - dom_node = getByName(lustreNode, node_name, 'node') - if dom_node == None: - break - Node = LustreNode(node_name) - reflist = dom_node.getElementsByTagName('profile') - if reflist: - for profile in reflist: - LoadProfile(lustreNode,profile,dom_node) - Node.addEntry_into_ldap(connId,node_name,node_uuid,net_uuids,profile_uuid,net_uuids,ldlm_uuid) - Initilize_globals() - - diff --git a/lustre/utils/lutils.py b/lustre/utils/lutils.py deleted file mode 100644 index f003493..0000000 --- a/lustre/utils/lutils.py +++ /dev/null @@ -1,2643 +0,0 @@ - -#!/usr/bin/env python -# -# Copyright (C) 2002 Cluster File Systems, Inc. -# Author: Robert Read -# This file is part of Lustre, http://www.lustre.org. -# -# Lustre is free software; you can redistribute it and/or -# modify it under the terms of version 2 of the GNU General Public -# License as published by the Free Software Foundation. -# -# Lustre is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Lustre; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -# lconf - lustre configuration tool -# -# lconf is the main driver script for starting and stopping -# lustre filesystem services. -# -# Based in part on the XML obdctl modifications done by Brian Behlendorf - -import sys, getopt -import string, os, stat, popen2, socket, time, random -import re, exceptions -import xml.dom.minidom - -# Global parameters -TCP_ACCEPTOR = '' -MAXTCPBUF = 1048576 -DEFAULT_TCPBUF = 1048576 -# -# Maximum number of devices to search for. -# (the /dev/loop* nodes need to be created beforehand) -MAX_LOOP_DEVICES = 256 - - -first_cleanup_error = 0 -def cleanup_error(rc): - global first_cleanup_error - if not first_cleanup_error: - first_cleanup_error = rc - - - - -# ============================================================ -# Config parameters, encapsulated in a class -class Config: - def __init__(self): - # flags - self._noexec = 0 - self._verbose = 0 - self._reformat = 0 - self._cleanup = 0 - self._gdb = 0 - self._nomod = 0 - self._nosetup = 0 - self._force = 0 - # parameters - self._modules = None - self._node = None - self._url = None - self._gdb_script = '/tmp/ogdb' - self._debug_path = '/tmp/lustre-log' - self._dump_file = None - self._src_dir = None - self._minlevel = 0 - self._maxlevel = 100 - self._ldap = 0 - - def ldapadd(self, flag = None): - if flag: self._ldap= flag - return self._ldap - - def verbose(self, flag = None): - if flag: self._verbose = flag - return self._verbose - - def noexec(self, flag = None): - if flag: self._noexec = flag - return self._noexec - - def reformat(self, flag = None): - if flag: self._reformat = flag - return self._reformat - - def cleanup(self, flag = None): - if flag: self._cleanup = flag - return self._cleanup - - def gdb(self, flag = None): - if flag: self._gdb = flag - return self._gdb - - def nomod(self, flag = None): - if flag: self._nomod = flag - return self._nomod - - def nosetup(self, flag = None): - if flag: self._nosetup = flag - return self._nosetup - - def force(self, flag = None): - if flag: self._force = flag - return self._force - - def node(self, val = None): - if val: self._node = val - return self._node - - def url(self, val = None): - if val: self._url = val - return self._url - - def gdb_script(self): - if os.path.isdir('/r'): - return '/r' + self._gdb_script - else: - return self._gdb_script - - def debug_path(self): - if os.path.isdir('/r'): - return '/r' + self._debug_path - else: - return self._debug_path - - def src_dir(self, val = None): - if val: self._src_dir = val - return self._src_dir - - def dump_file(self, val = None): - if val: self._dump_file = val - return self._dump_file - - def minlevel(self, val = None): - if val: self._minlevel = int(val) - return self._minlevel - - def maxlevel(self, val = None): - if val: self._maxlevel = int(val) - return self._maxlevel - - - -config = Config() - -# ============================================================ -# debugging and error funcs - -def fixme(msg = "this feature"): - raise LconfError, msg + ' not implmemented yet.' - -def panic(*args): - msg = string.join(map(str,args)) - if not config.noexec(): - raise LconfError(msg) - else: - print "! " + msg - -def log(*args): - msg = string.join(map(str,args)) - print msg - -def logall(msgs): - for s in msgs: - print string.strip(s) - -def debug(*args): - if config.verbose(): - msg = string.join(map(str,args)) - print msg - -# ============================================================ -# locally defined exceptions -class CommandError (exceptions.Exception): - def __init__(self, cmd_name, cmd_err, rc=None): - self.cmd_name = cmd_name - self.cmd_err = cmd_err - self.rc = rc - - def dump(self): - import types - if type(self.cmd_err) == types.StringType: - if self.rc: - print "! %s (%d): %s" % (self.cmd_name, self.rc, self.cmd_err) - else: - print "! %s: %s" % (self.cmd_name, self.cmd_err) - elif type(self.cmd_err) == types.ListType: - if self.rc: - print "! %s (error %d):" % (self.cmd_name, self.rc) - else: - print "! %s:" % (self.cmd_name) - for s in self.cmd_err: - print "> %s" %(string.strip(s)) - else: - print self.cmd_err - -class LconfError (exceptions.Exception): - def __init__(self, args): - self.args = args - -# Determine full path to use for an external command -# searches dirname(argv[0]) first, then PATH -def find_prog(cmd): - syspath = string.split(os.environ['PATH'], ':') - cmdpath = os.path.dirname(sys.argv[0]) - syspath.insert(0, cmdpath); - syspath.insert(0, os.path.join(cmdpath, '../../portals/linux/utils/')) - for d in syspath: - prog = os.path.join(d,cmd) - if os.access(prog, os.X_OK): - return prog - return '' - -# ============================================================ -# handle lctl interface -class LCTLInterface: - """ - Manage communication with lctl - """ - - def __init__(self, cmd): - """ - Initialize close by finding the lctl binary. - """ - self.lctl = find_prog(cmd) - if not self.lctl: - if config.noexec(): - debug('! lctl not found') - self.lctl = 'lctl' - else: - raise CommandError('lctl', "unable to find lctl binary.") - - def run(self, cmds): - """ - run lctl - the cmds are written to stdin of lctl - lctl doesn't return errors when run in script mode, so - stderr is checked - should modify command line to accept multiple commands, or - create complex command line options - """ - debug("+", self.lctl, cmds) - if config.noexec(): return (0, []) - p = popen2.Popen3(self.lctl, 1) - p.tochild.write(cmds + "\n") - p.tochild.close() - out = p.fromchild.readlines() - err = p.childerr.readlines() - ret = p.wait() - if os.WIFEXITED(ret): - rc = os.WEXITSTATUS(ret) - else: - rc = 0 - if rc or len(err): - raise CommandError(self.lctl, err, rc) - return rc, out - - def runcmd(self, *args): - """ - run lctl using the command line - """ - cmd = string.join(map(str,args)) - debug("+", self.lctl, cmd) - rc, out = run(self.lctl, cmd) - if rc: - raise CommandError(self.lctl, out, rc) - return rc, out - - - def network(self, net, nid): - """ initialized network and add "self" """ - # Idea: "mynid" could be used for all network types to add "self," and then - # this special case would be gone and the "self" hack would be hidden. - global lctl - if net in ('tcp', 'toe'): - cmds = """ - network %s - mynid %s - add_uuid self %s - quit""" % (net, nid, nid) - else: - cmds = """ - network %s - add_uuid self %s - quit""" % (net, nid) - - self.run(cmds) - - # create a new connection - def connect(self, net, nid, port, servuuid, send_mem, recv_mem): - if net in ('tcp', 'toe'): - cmds = """ - network %s - add_uuid %s %s - send_mem %d - recv_mem %d - connect %s %d - quit""" % (net, servuuid, nid, send_mem, recv_mem, nid, port, ) - else: - cmds = """ - network %s - add_uuid %s %s - connect %s %d - quit""" % (net, servuuid, nid, nid, port, ) - - self.run(cmds) - - # add a route to a range - def add_route(self, net, gw, lo, hi): - cmds = """ - network %s - add_route %s %s %s - quit """ % (net, gw, lo, hi) - self.run(cmds) - - - def del_route(self, net, gw, lo, hi): - cmds = """ - ignore_errors - network %s - del_route %s - quit """ % (net, lo) - self.run(cmds) - - # add a route to a host - def add_route_host(self, net, uuid, gw, tgt): - cmds = """ - network %s - add_uuid %s %s - add_route %s %s - quit """ % (net, uuid, tgt, gw, tgt) - self.run(cmds) - - # add a route to a range - def del_route_host(self, net, uuid, gw, tgt): - cmds = """ - ignore_errors - network %s - del_uuid %s - del_route %s - quit """ % (net, uuid, tgt) - self.run(cmds) - - # disconnect one connection - def disconnect(self, net, nid, port, servuuid): - cmds = """ - ignore_errors - network %s - disconnect %s - del_uuid %s - quit""" % (net, nid, servuuid) - self.run(cmds) - - # disconnect all - def disconnectAll(self, net): - cmds = """ - ignore_errors - network %s - del_uuid self - disconnect - quit""" % (net) - self.run(cmds) - - # create a new device with lctl - def newdev(self, attach, setup = ""): - cmds = """ - newdev - attach %s - setup %s - quit""" % (attach, setup) - self.run(cmds) - - # cleanup a device - def cleanup(self, name, uuid): - cmds = """ - ignore_errors - device $%s - cleanup - detach %s - quit""" % (name, ('', 'force')[config.force()]) - self.run(cmds) - - # create an lov - def lov_setconfig(self, uuid, mdsuuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist): - cmds = """ - device $%s - probe - lov_setconfig %s %d %d %d %s %s - quit""" % (mdsuuid, uuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist) - self.run(cmds) - - # dump the log file - def dump(self, dump_file): - cmds = """ - debug_kernel %s 1 - quit""" % (dump_file) - self.run(cmds) - - # get list of devices - def device_list(self): - rc, out = self.runcmd('device_list') - return out - -lctl = LCTLInterface('lctl') -# ============================================================ -# Various system-level functions -# (ideally moved to their own module) - -# Run a command and return the output and status. -# stderr is sent to /dev/null, could use popen3 to -# save it if necessary -def run(*args): - cmd = string.join(map(str,args)) - debug ("+", cmd) - if config.noexec(): return (0, []) - f = os.popen(cmd + ' 2>&1') - out = f.readlines() - ret = f.close() - if ret: - ret = ret >> 8 - else: - ret = 0 - return (ret, out) - -# Run a command in the background. -def run_daemon(*args): - cmd = string.join(map(str,args)) - debug ("+", cmd) - if config.noexec(): return 0 - f = os.popen(cmd + ' 2>&1') - ret = f.close() - if ret: - ret = ret >> 8 - else: - ret = 0 - return ret - - -# Recursively look for file starting at base dir -def do_find_file(base, mod): - fullname = os.path.join(base, mod) - if os.access(fullname, os.R_OK): - return fullname - for d in os.listdir(base): - dir = os.path.join(base,d) - if os.path.isdir(dir): - module = do_find_file(dir, mod) - if module: - return module - -def find_module(src_dir, dev_dir, modname): - mod = '%s.o' % (modname) - module = src_dir +'/'+ dev_dir +'/'+ mod - try: - if os.access(module, os.R_OK): - return module - except OSError: - pass - return None - -# is the path a block device? -def is_block(path): - s = () - try: - s = os.stat(path) - except OSError: - return 0 - return stat.S_ISBLK(s[stat.ST_MODE]) - -# build fs according to type -# fixme: dangerous -def mkfs(fstype, dev): - if(fstype in ('ext3', 'extN')): - mkfs = 'mkfs.ext2 -j -b 4096' - else: - print 'unsupported fs type: ', fstype - if not is_block(dev): - force = '-F' - else: - force = '' - (ret, out) = run (mkfs, force, dev) - if ret: - panic("Unable to build fs:", dev) - # enable hash tree indexing on fsswe - # FIXME: this check can probably go away on 2.5 - if fstype == 'extN': - htree = 'echo "feature FEATURE_C5" | debugfs -w' - (ret, out) = run (htree, dev) - if ret: - panic("Unable to enable htree:", dev) - -# some systems use /dev/loopN, some /dev/loop/N -def loop_base(): - import re - loop = '/dev/loop' - if not os.access(loop + str(0), os.R_OK): - loop = loop + '/' - if not os.access(loop + str(0), os.R_OK): - panic ("can't access loop devices") - return loop - -# find loop device assigned to thefile -def find_loop(file): - loop = loop_base() - for n in xrange(0, MAX_LOOP_DEVICES): - dev = loop + str(n) - if os.access(dev, os.R_OK): - (stat, out) = run('losetup', dev) - if (out and stat == 0): - m = re.search(r'\((.*)\)', out[0]) - if m and file == m.group(1): - return dev - else: - break - return '' - -# create file if necessary and assign the first free loop device -def init_loop(file, size, fstype): - dev = find_loop(file) - if dev: - print 'WARNING file:', file, 'already mapped to', dev - return dev - if config.reformat() or not os.access(file, os.R_OK | os.W_OK): - run("dd if=/dev/zero bs=1k count=0 seek=%d of=%s" %(size, file)) - loop = loop_base() - # find next free loop - for n in xrange(0, MAX_LOOP_DEVICES): - dev = loop + str(n) - if os.access(dev, os.R_OK): - (stat, out) = run('losetup', dev) - if (stat): - run('losetup', dev, file) - return dev - else: - print "out of loop devices" - return '' - print "out of loop devices" - return '' - -# undo loop assignment -def clean_loop(file): - dev = find_loop(file) - if dev: - ret, out = run('losetup -d', dev) - if ret: - log('unable to clean loop device:', dev, 'for file:', file) - logall(out) - -# determine if dev is formatted as a filesystem -def need_format(fstype, dev): - # FIXME don't know how to implement this - return 0 - -# initialize a block device if needed -def block_dev(dev, size, fstype, format): - if config.noexec(): return dev - if not is_block(dev): - dev = init_loop(dev, size, fstype) - if config.reformat() or (need_format(fstype, dev) and format == 'yes'): - mkfs(fstype, dev) - -# else: -# panic("device:", dev, -# "not prepared, and autoformat is not set.\n", -# "Rerun with --reformat option to format ALL filesystems") - - return dev - -def if2addr(iface): - """lookup IP address for an interface""" - rc, out = run("/sbin/ifconfig", iface) - if rc or not out: - return None - addr = string.split(out[1])[1] - ip = string.split(addr, ':')[1] - return ip - -def get_local_address(net_type, wildcard): - """Return the local address for the network type.""" - local = "" - if net_type in ('tcp', 'toe'): - if ':' in wildcard: - iface, star = string.split(wildcard, ':') - local = if2addr(iface) - if not local: - panic ("unable to determine ip for:", wildcard) - else: - host = socket.gethostname() - local = socket.gethostbyname(host) - elif net_type == 'elan': - # awk '/NodeId/ { print $2 }' '/proc/elan/device0/position' - try: - fp = open('/proc/elan/device0/position', 'r') - lines = fp.readlines() - fp.close() - for l in lines: - a = string.split(l) - if a[0] == 'NodeId': - local = a[1] - break - except IOError, e: - log(e) - elif net_type == 'gm': - fixme("automatic local address for GM") - return local - - -def is_prepared(uuid): - """Return true if a device exists for the uuid""" - # expect this format: - # 1 UP ldlm ldlm ldlm_UUID 2 - try: - out = lctl.device_list() - for s in out: - if uuid == string.split(s)[4]: - return 1 - except CommandError, e: - e.dump() - return 0 - - - -############################################################ -# MDC UUID hack - -# FIXME: clean this mess up! -# -saved_mdc = {} -def prepare_mdc(dom_node, mds_uuid): - global saved_mdc - mds_node = lookup(dom_node, mds_uuid); - if not mds_node: - panic("no mds:", mds_uuid) - if saved_mdc.has_key(mds_uuid): - return saved_mdc[mds_uuid] - mdc = MDC(mds_node) - mdc.prepare() - saved_mdc[mds_uuid] = mdc.uuid - return mdc.uuid - -def cleanup_mdc(dom_node, mds_uuid): - global saved_mdc - mds_node = lookup(dom_node, mds_uuid); - if not mds_node: - panic("no mds:", mds_uuid) - if not saved_mdc.has_key(mds_uuid): - mdc = MDC(mds_node) - mdc.cleanup() - saved_mdc[mds_uuid] = mdc.uuid - - -# ============================================================ -# Classes to prepare and cleanup the various objects -# -class Module: - """ Base class for the rest of the modules. The default cleanup method is - defined here, as well as some utilitiy funcs. - """ - def __init__(self, module_name, dom_node): - self.dom_node = dom_node - self.module_name = module_name - self.name = get_attr(dom_node, 'name') - self.uuid = get_attr(dom_node, 'uuid') - self.kmodule_list = [] - self._server = None - self._connected = 0 - - def info(self, *args): - msg = string.join(map(str,args)) - print self.module_name + ":", self.name, self.uuid, msg - - - def lookup_server(self, srv_uuid): - """ Lookup a server's network information """ - net = get_ost_net(self.dom_node.parentNode, srv_uuid) - if not net: - panic ("Unable to find a server for:", srv_uuid) - self._server = Network(net) - - def get_server(self): - return self._server - - def cleanup(self): - """ default cleanup, used for most modules """ - self.info() - srv = self.get_server() - if srv and local_net(srv): - try: - lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid) - except CommandError, e: - log(self.module_name, "disconnect failed: ", self.name) - e.dump() - cleanup_error(e.rc) - try: - lctl.cleanup(self.name, self.uuid) - except CommandError, e: - log(self.module_name, "cleanup failed: ", self.name) - e.dump() - cleanup_error(e.rc) - - def add_module(self, dev_dir, modname): - """Append a module to list of modules to load.""" - self.kmodule_list.append((dev_dir, modname)) - - def mod_loaded(self, modname): - """Check if a module is already loaded. Look in /proc/modules for it.""" - fp = open('/proc/modules') - lines = fp.readlines() - fp.close() - # please forgive my tired fingers for this one - ret = filter(lambda word, mod=modname: word == mod, - map(lambda line: string.split(line)[0], lines)) - return ret - - def load_module(self): - """Load all the modules in the list in the order they appear.""" - for dev_dir, mod in self.kmodule_list: - # (rc, out) = run ('/sbin/lsmod | grep -s', mod) - if self.mod_loaded(mod) and not config.noexec(): - continue - log ('loading module:', mod) - if config.src_dir(): - module = find_module(config.src_dir(),dev_dir, mod) - if not module: - panic('module not found:', mod) - (rc, out) = run('/sbin/insmod', module) - if rc: - raise CommandError('insmod', out, rc) - else: - (rc, out) = run('/sbin/modprobe', mod) - if rc: - raise CommandError('modprobe', out, rc) - - def cleanup_module(self): - """Unload the modules in the list in reverse order.""" - rev = self.kmodule_list - rev.reverse() - for dev_dir, mod in rev: - if not self.mod_loaded(mod): - continue - # debug hack - if mod == 'portals' and config.dump_file(): - lctl.dump(config.dump_file()) - log('unloading module:', mod) - if config.noexec(): - continue - (rc, out) = run('/sbin/rmmod', mod) - if rc: - log('! unable to unload module:', mod) - logall(out) - - -class Network(Module): - def __init__(self,dom_node): - Module.__init__(self, 'NETWORK', dom_node) - self.net_type = get_attr(dom_node,'type') - self.nid = get_text(dom_node, 'server', '*') - self.port = get_text_int(dom_node, 'port', 0) - self.send_mem = get_text_int(dom_node, 'send_mem', DEFAULT_TCPBUF) - self.recv_mem = get_text_int(dom_node, 'recv_mem', DEFAULT_TCPBUF) - if '*' in self.nid: - self.nid = get_local_address(self.net_type, self.nid) - if not self.nid: - panic("unable to set nid for", self.net_type, self.nid) - debug("nid:", self.nid) - - if config.ldapadd(): - return - - self.add_module('portals/linux/oslib/', 'portals') - if node_needs_router(): - self.add_module('portals/linux/router', 'kptlrouter') - if self.net_type == 'tcp': - self.add_module('portals/linux/socknal', 'ksocknal') - if self.net_type == 'toe': - self.add_module('portals/linux/toenal', 'ktoenal') - if self.net_type == 'elan': - self.add_module('portals/linux/rqswnal', 'kqswnal') - if self.net_type == 'gm': - self.add_module('portals/linux/gmnal', 'kgmnal') - self.add_module('lustre/obdclass', 'obdclass') - self.add_module('lustre/ptlrpc', 'ptlrpc') - - def prepare(self): - global lctl - self.info(self.net_type, self.nid, self.port) - if self.net_type in ('tcp', 'toe'): - nal_id = '' # default is socknal - if self.net_type == 'toe': - nal_id = '-N 4' - ret, out = run(TCP_ACCEPTOR, '-s', self.send_mem, '-r', self.recv_mem, nal_id, self.port) - if ret: - raise CommandError(TCP_ACCEPTOR, out, ret) - ret = self.dom_node.getElementsByTagName('route_tbl') - for a in ret: - for r in a.getElementsByTagName('route'): - net_type = get_attr(r, 'type') - gw = get_attr(r, 'gw') - lo = get_attr(r, 'lo') - hi = get_attr(r,'hi', '') - lctl.add_route(net_type, gw, lo, hi) - if net_type in ('tcp', 'toe') and net_type == self.net_type and hi == '': - srv = nid2server(self.dom_node.parentNode.parentNode, lo) - if not srv: - panic("no server for nid", lo) - else: - lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_mem, srv.recv_mem) - - lctl.network(self.net_type, self.nid) - lctl.newdev(attach = "ptlrpc RPCDEV RPCDEV_UUID") - - def cleanup(self): - self.info(self.net_type, self.nid, self.port) - ret = self.dom_node.getElementsByTagName('route_tbl') - for a in ret: - for r in a.getElementsByTagName('route'): - lo = get_attr(r, 'lo') - hi = get_attr(r,'hi', '') - if self.net_type in ('tcp', 'toe') and hi == '': - srv = nid2server(self.dom_node.parentNode.parentNode, lo) - if not srv: - panic("no server for nid", lo) - else: - try: - lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid) - except CommandError, e: - print "disconnect failed: ", self.name - e.dump() - cleanup_error(e.rc) - try: - lctl.del_route(self.net_type, self.nid, lo, hi) - except CommandError, e: - print "del_route failed: ", self.name - e.dump() - cleanup_error(e.rc) - - try: - lctl.cleanup("RPCDEV", "RPCDEV_UUID") - except CommandError, e: - print "cleanup failed: ", self.name - e.dump() - cleanup_error(e.rc) - try: - lctl.disconnectAll(self.net_type) - except CommandError, e: - print "disconnectAll failed: ", self.name - e.dump() - cleanup_error(e.rc) - if self.net_type in ('tcp', 'toe'): - # yikes, this ugly! need to save pid in /var/something - run("killall acceptor") - -class LDLM(Module): - def __init__(self,dom_node): - Module.__init__(self, 'LDLM', dom_node) - if config.ldapadd(): - return - self.add_module('lustre/ldlm', 'ldlm') - def prepare(self): - if is_prepared(self.uuid): - return - self.info() - lctl.newdev(attach="ldlm %s %s" % (self.name, self.uuid), - setup ="") - -class LOV(Module): - def __init__(self,dom_node): - Module.__init__(self, 'LOV', dom_node) - self.mds_uuid = get_first_ref(dom_node, 'mds') - mds= lookup(dom_node.parentNode, self.mds_uuid) - self.mds_name = getName(mds) - devs = dom_node.getElementsByTagName('devices') - if len(devs) > 0: - dev_node = devs[0] - self.stripe_sz = get_attr_int(dev_node, 'stripesize', 65536) - self.stripe_off = get_attr_int(dev_node, 'stripeoffset', 0) - self.pattern = get_attr_int(dev_node, 'pattern', 0) - self.devlist = get_all_refs(dev_node, 'osc') - self.stripe_cnt = get_attr_int(dev_node, 'stripecount', len(self.devlist)) - if config.ldapadd(): - return - self.add_module('lustre/mdc', 'mdc') - self.add_module('lustre/lov', 'lov') - - def prepare(self): - if is_prepared(self.uuid): - return - for osc_uuid in self.devlist: - osc = lookup(self.dom_node.parentNode, osc_uuid) - if osc: - n = OSC(osc) - n.prepare() - else: - panic('osc not found:', osc_uuid) - mdc_uuid = prepare_mdc(self.dom_node.parentNode, self.mds_uuid) - self.info(self.mds_uuid, self.stripe_cnt, self.stripe_sz, - self.stripe_off, self.pattern, self.devlist, self.mds_name) - lctl.newdev(attach="lov %s %s" % (self.name, self.uuid), - setup ="%s" % (mdc_uuid)) - - def cleanup(self): - if not is_prepared(self.uuid): - return - for osc_uuid in self.devlist: - osc = lookup(self.dom_node.parentNode, osc_uuid) - if osc: - n = OSC(osc) - n.cleanup() - else: - panic('osc not found:', osc_uuid) - Module.cleanup(self) - cleanup_mdc(self.dom_node.parentNode, self.mds_uuid) - - - def load_module(self): - for osc_uuid in self.devlist: - osc = lookup(self.dom_node.parentNode, osc_uuid) - if osc: - n = OSC(osc) - n.load_module() - break - else: - panic('osc not found:', osc_uuid) - Module.load_module(self) - - - def cleanup_module(self): - Module.cleanup_module(self) - for osc_uuid in self.devlist: - osc = lookup(self.dom_node.parentNode, osc_uuid) - if osc: - n = OSC(osc) - n.cleanup_module() - break - else: - panic('osc not found:', osc_uuid) - -class LOVConfig(Module): - def __init__(self,dom_node): - Module.__init__(self, 'LOVConfig', dom_node) - self.lov_uuid = get_first_ref(dom_node, 'lov') - l = lookup(dom_node.parentNode, self.lov_uuid) - self.lov = LOV(l) - - def prepare(self): - lov = self.lov - self.info(lov.mds_uuid, lov.stripe_cnt, lov.stripe_sz, lov.stripe_off, - lov.pattern, lov.devlist, lov.mds_name) - lctl.lov_setconfig(lov.uuid, lov.mds_name, lov.stripe_cnt, - lov.stripe_sz, lov.stripe_off, lov.pattern, - string.join(lov.devlist)) - - def cleanup(self): - #nothing to do here - pass - - -class MDS(Module): - def __init__(self,dom_node): - Module.__init__(self, 'MDS', dom_node) - self.devname, self.size = get_device(dom_node) - self.fstype = get_text(dom_node, 'fstype') - # FIXME: if fstype not set, then determine based on kernel version - self.format = get_text(dom_node, 'autoformat', "no") - if config.ldapadd(): - return - if self.fstype == 'extN': - self.add_module('lustre/extN', 'extN') - self.add_module('lustre/mds', 'mds') - self.add_module('lustre/mds', 'mds_%s' % (self.fstype)) - - def prepare(self): - if is_prepared(self.uuid): - return - self.info(self.devname, self.fstype, self.format) - blkdev = block_dev(self.devname, self.size, self.fstype, self.format) - if not is_prepared('MDT_UUID'): - lctl.newdev(attach="mdt %s %s" % ('MDT', 'MDT_UUID'), - setup ="") - lctl.newdev(attach="mds %s %s" % (self.name, self.uuid), - setup ="%s %s" %(blkdev, self.fstype)) - def cleanup(self): - if is_prepared('MDT_UUID'): - try: - lctl.cleanup("MDT", "MDT_UUID") - except CommandError, e: - print "cleanup failed: ", self.name - e.dump() - cleanup_error(e.rc) - if not is_prepared(self.uuid): - return - Module.cleanup(self) - clean_loop(self.devname) - -# Very unusual case, as there is no MDC element in the XML anymore -# Builds itself from an MDS node -class MDC(Module): - def __init__(self,dom_node): - self.mds = MDS(dom_node) - self.dom_node = dom_node - self.module_name = 'MDC' - self.kmodule_list = [] - self._server = None - self._connected = 0 - - host = socket.gethostname() - self.name = 'MDC_%s' % (self.mds.name) - self.uuid = '%s_%05x_%05x' % (self.name, int(random.random() * 1048576), - int(random.random() * 1048576)) - - self.lookup_server(self.mds.uuid) - if config.ldapadd(): - return - self.add_module('lustre/mdc', 'mdc') - - def prepare(self): - if is_prepared(self.uuid): - return - self.info(self.mds.uuid) - srv = self.get_server() - lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_mem, srv.recv_mem) - lctl.newdev(attach="mdc %s %s" % (self.name, self.uuid), - setup ="%s %s" %(self.mds.uuid, srv.uuid)) - -class OBD(Module): - def __init__(self, dom_node): - Module.__init__(self, 'OBD', dom_node) - self.obdtype = get_attr(dom_node, 'type') - self.devname, self.size = get_device(dom_node) - self.fstype = get_text(dom_node, 'fstype') - # FIXME: if fstype not set, then determine based on kernel version - self.format = get_text(dom_node, 'autoformat', 'yes') - if config.ldapadd(): - return - if self.fstype == 'extN': - self.add_module('lustre/extN', 'extN') - self.add_module('lustre/' + self.obdtype, self.obdtype) - - # need to check /proc/mounts and /etc/mtab before - # formatting anything. - # FIXME: check if device is already formatted. - def prepare(self): - if is_prepared(self.uuid): - return - self.info(self.obdtype, self.devname, self.size, self.fstype, self.format) - if self.obdtype == 'obdecho': - blkdev = '' - else: - blkdev = block_dev(self.devname, self.size, self.fstype, self.format) - lctl.newdev(attach="%s %s %s" % (self.obdtype, self.name, self.uuid), - setup ="%s %s" %(blkdev, self.fstype)) - def cleanup(self): - if not is_prepared(self.uuid): - return - Module.cleanup(self) - if not self.obdtype == 'obdecho': - clean_loop(self.devname) - -class OST(Module): - def __init__(self,dom_node): - Module.__init__(self, 'OST', dom_node) - self.obd_uuid = get_first_ref(dom_node, 'obd') - if config.ldapadd(): - return - self.add_module('lustre/ost', 'ost') - - def prepare(self): - if is_prepared(self.uuid): - return - self.info(self.obd_uuid) - lctl.newdev(attach="ost %s %s" % (self.name, self.uuid), - setup ="%s" % (self.obd_uuid)) - - -# virtual interface for OSC and LOV -class VOSC(Module): - def __init__(self,dom_node): - Module.__init__(self, 'VOSC', dom_node) - if dom_node.nodeName == 'lov': - self.osc = LOV(dom_node) - else: - self.osc = OSC(dom_node) - def prepare(self): - self.osc.prepare() - def cleanup(self): - self.osc.cleanup() - def load_module(self): - self.osc.load_module() - def cleanup_module(self): - self.osc.cleanup_module() - - -class OSC(Module): - def __init__(self,dom_node): - Module.__init__(self, 'OSC', dom_node) - self.obd_uuid = get_first_ref(dom_node, 'obd') - self.ost_uuid = get_first_ref(dom_node, 'ost') - self.lookup_server(self.ost_uuid) - if config.ldapadd(): - return - self.add_module('lustre/osc', 'osc') - - def prepare(self): - if is_prepared(self.uuid): - return - self.info(self.obd_uuid, self.ost_uuid) - srv = self.get_server() - if local_net(srv): - lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_mem, srv.recv_mem) - else: - r = find_route(srv) - if r: - lctl.add_route_host(r[0], srv.uuid, r[1], r[2]) - else: - panic ("no route to", srv.nid) - - lctl.newdev(attach="osc %s %s" % (self.name, self.uuid), - setup ="%s %s" %(self.obd_uuid, srv.uuid)) - - def cleanup(self): - if not is_prepared(self.uuid): - return - srv = self.get_server() - if local_net(srv): - Module.cleanup(self) - else: - self.info(self.obd_uuid, self.ost_uuid) - r = find_route(srv) - if r: - try: - lctl.del_route_host(r[0], srv.uuid, r[1], r[2]) - except CommandError, e: - print "del_route failed: ", self.name - e.dump() - cleanup_error(e.rc) - Module.cleanup(self) - - -class ECHO_CLIENT(Module): - def __init__(self,dom_node): - Module.__init__(self, 'ECHO_CLIENT', dom_node) - self.obd_uuid = get_first_ref(dom_node, 'osc') - debug("HERE",self.obd_uuid) - self.add_module('lustre/obdecho', 'obdecho') - - def prepare(self): - if is_prepared(self.uuid): - return - self.info(self.obd_uuid) - - lctl.newdev(attach="echo_client %s %s" % (self.name, self.uuid), - setup = self.obd_uuid) - - def cleanup(self): - if not is_prepared(self.uuid): - return - Module.cleanup(self) - - -class Mountpoint(Module): - def __init__(self,dom_node): - Module.__init__(self, 'MTPT', dom_node) - self.path = get_text(dom_node, 'path') - self.mds_uuid = get_first_ref(dom_node, 'mds') - self.lov_uuid = get_first_ref(dom_node, 'osc') - l = lookup(self.dom_node.parentNode, self.lov_uuid) - self.osc = VOSC(l) - if config.ldapadd(): - return - self.add_module('lustre/mdc', 'mdc') - self.add_module('lustre/llite', 'llite') - - def prepare(self): - self.osc.prepare() - mdc_uuid = prepare_mdc(self.dom_node.parentNode, self.mds_uuid) - self.info(self.path, self.mds_uuid, self.lov_uuid) - cmd = "mount -t lustre_lite -o osc=%s,mdc=%s none %s" % \ - (self.lov_uuid, mdc_uuid, self.path) - run("mkdir", self.path) - ret, val = run(cmd) - if ret: - panic("mount failed:", self.path) - - def cleanup(self): - self.info(self.path, self.mds_uuid,self.lov_uuid) - if config.force(): - (rc, out) = run("umount -f", self.path) - else: - (rc, out) = run("umount", self.path) - if rc: - log("umount failed, cleanup will most likely not work.") - l = lookup(self.dom_node.parentNode, self.lov_uuid) - self.osc.cleanup() - cleanup_mdc(self.dom_node.parentNode, self.mds_uuid) - - def load_module(self): - self.osc.load_module() - Module.load_module(self) - def cleanup_module(self): - Module.cleanup_module(self) - self.osc.cleanup_module() - - -# ============================================================ -# XML processing and query -# TODO: Change query funcs to use XPath, which is muc cleaner - -def get_device(obd): - list = obd.getElementsByTagName('device') - if len(list) > 0: - dev = list[0] - dev.normalize(); - size = get_attr_int(dev, 'size', 0) - return dev.firstChild.data, size - return '', 0 - -# Get the text content from the first matching child -# If there is no content (or it is all whitespace), return -# the default -def get_text(dom_node, tag, default=""): - list = dom_node.getElementsByTagName(tag) - if len(list) > 0: - dom_node = list[0] - dom_node.normalize() - if dom_node.firstChild: - txt = string.strip(dom_node.firstChild.data) - if txt: - return txt - return default - -def get_text_int(dom_node, tag, default=0): - list = dom_node.getElementsByTagName(tag) - n = default - if len(list) > 0: - dom_node = list[0] - dom_node.normalize() - if dom_node.firstChild: - txt = string.strip(dom_node.firstChild.data) - if txt: - try: - n = int(txt) - except ValueError: - panic("text value is not integer:", txt) - return n - -def get_attr(dom_node, attr, default=""): - v = dom_node.getAttribute(attr) - if v: - return v - return default - -def get_attr_int(dom_node, attr, default=0): - n = default - v = dom_node.getAttribute(attr) - if v: - try: - n = int(v) - except ValueError: - panic("attr value is not integer", v) - return n - -def get_first_ref(dom_node, tag): - """ Get the first uuidref of the type TAG. Used one only - one is expected. Returns the uuid.""" - uuid = None - refname = '%s_ref' % tag - list = dom_node.getElementsByTagName(refname) - if len(list) > 0: - uuid = getRef(list[0]) - return uuid - -def get_all_refs(dom_node, tag): - """ Get all the refs of type TAG. Returns list of uuids. """ - uuids = [] - refname = '%s_ref' % tag - list = dom_node.getElementsByTagName(refname) - if len(list) > 0: - for i in list: - uuids.append(getRef(i)) - return uuids - -def get_ost_net(dom_node, uuid): - ost = lookup(dom_node, uuid) - uuid = get_first_ref(ost, 'network') - if not uuid: - return None - return lookup(dom_node, uuid) - -def nid2server(dom_node, nid): - netlist = dom_node.getElementsByTagName('network') - for net_node in netlist: - if get_text(net_node, 'server') == nid: - return Network(net_node) - return None - -def lookup(dom_node, uuid): - for n in dom_node.childNodes: - if n.nodeType == n.ELEMENT_NODE: - if getUUID(n) == uuid: - return n - else: - n = lookup(n, uuid) - if n: return n - return None - -# Get name attribute of dom_node -def getName(dom_node): - return dom_node.getAttribute('name') - -def getRef(dom_node): - return dom_node.getAttribute('uuidref') - -# Get name attribute of dom_node -def getUUID(dom_node): - return dom_node.getAttribute('uuid') - -# the tag name is the service type -# fixme: this should do some checks to make sure the dom_node is a service -def getServiceType(dom_node): - return dom_node.nodeName - - -############################################################ -# routing ("rooting") -# -routes = [] -local_node = [] -router_flag = 0 - -def init_node(dom_node): - global local_node, router_flag - netlist = dom_node.getElementsByTagName('network') - for dom_net in netlist: - type = get_attr(dom_net, 'type') - gw = get_text(dom_net, 'server') - local_node.append((type, gw)) - -def node_needs_router(): - return router_flag - -def get_routes(type, gw, dom_net): - """ Return the routes as a list of tuples of the form: - [(type, gw, lo, hi),]""" - res = [] - tbl = dom_net.getElementsByTagName('route_tbl') - for t in tbl: - routes = t.getElementsByTagName('route') - for r in routes: - lo = get_attr(r, 'lo') - hi = get_attr(r, 'hi', '') - res.append((type, gw, lo, hi)) - return res - - -def init_route_config(lustre): - """ Scan the lustre config looking for routers. Build list of - routes. """ - global routes, router_flag - routes = [] - list = lustre.getElementsByTagName('node') - for node in list: - if get_attr(node, 'router'): - router_flag = 1 - for (local_type, local_nid) in local_node: - gw = None - netlist = node.getElementsByTagName('network') - for dom_net in netlist: - if local_type == get_attr(dom_net, 'type'): - gw = get_text(dom_net, 'server') - break - if not gw: - continue - for dom_net in netlist: - if local_type != get_attr(dom_net, 'type'): - for route in get_routes(local_type, gw, dom_net): - routes.append(route) - - -def local_net(net): - global local_node - for iface in local_node: - if net.net_type == iface[0]: - return 1 - return 0 - -def find_route(net): - global local_node, routes - frm_type = local_node[0][0] - to_type = net.net_type - to = net.nid - debug ('looking for route to', to_type,to) - for r in routes: - if r[2] == to: - return r - return None - - - - -############################################################################## -# Here it starts LDAP related stuff. - -import ldap -import _ldap - -#returns the lustre ldap specific filters - -class lustre_ldap: - def __init__(self): - self.filter=0 - - def get_filter(self,lustreRdn): - filter="(&"+lustreRdn+")" - return filter - -# make a connection to LDAP server and abd bind -class MyConn: - def __init__(self,host,port): - self.id=0 - self.host=host - self.port=port - self.base="fs=lustre" - - def open(self): - self.id=ldap.open(self.host) - if self.id == None: - print "unable to open a connection" - - try: - # lustre tree starts from here...the DN is (cn=Manager ,fs=lustre) - status=self.id.simple_bind("cn=Manager, fs=lustre","secret") - except _ldap.LDAPError: - print "unable to bind" - - - -# Lustre Node object class definition as per defined in the lustre.schema - -class LustreNode: - def __init__(self,nodename): - self.objectClass="lustreNode" - self.nodeUUID = 0 - self.id= nodename - self.netUUIDs = [] - self.profileUUID = 0 - self.routerUUID = 0 - self.ldlmUUID = 0 - - self.lustreNet = {} - self.lustreNodeProfile = 0 - self.lustreLdlm = 0 - - self.nodeUUID_str="nodeUUID" - self.id_str="id" - self.netUUIDs_str="netUUIDs" - self.ldlmUUID_str="ldlmUUID" - self.profileUUID_str="profileUUID" - self.routerUUID_str="routerUUID" - self.node_str="node" - - def get_object_class(self): - return self.objectClass - - def get_rdn(self): - retval="(objectClass="+self.objectClass+") (id="+self.id+")" - return retval - - # Initilize lustre Node Object class after read drom LDAP server - def init_node(self,node_entry): - self.id=node_entry[0][1][self.id_str][0] - self.nodeUUID=node_entry[0][1][self.nodeUUID_str][0] - for i in range(len(node_entry[0][1][self.netUUIDs_str])): - self.netUUIDs.append(node_entry[0][1][self.netUUIDs_str][i]) - if node_entry[0][1].has_key(self.profileUUID_str): - self.profileUUID=node_entry[0][1][self.profileUUID_str][0] - if node_entry[0][1].has_key(self.ldlmUUID_str): - self.ldlmUUID=node_entry[0][1][self.ldlmUUID_str][0] - - if node_entry[0][1].has_key(self.routerUUID_str): - self.routerUUID=node_entry[0][1][self.routerUUID_str][0] - - # Brings the lustre Node object entries from LDAP server - def getEntry_from_ldap(self,conn_id,base): - try: - lustre_util=lustre_ldap() - # the filter has id=,type=node,fs=lustre - # base is "fs=lustre" - filter=lustre_util.get_filter(self.get_rdn()) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - #network object class - if self.netUUIDs: - for i in range(len(self.netUUIDs)): - # loading the network object class from LDAP, since this related to lustre node class - self.lustreNet[i]=LustreNet() - self.lustreNet[i].getEntry_from_ldap(conn_id,base,self.netUUIDs[i]) - - # The ldlm object class - if self.ldlmUUID: - # loading the ldlm object class from LDAP, since this related to lustre node class - self.lustreLdlm=LustreLdlm() - self.lustreLdlm.getEntry_from_ldap(conn_id,base,self.ldlmUUID) - - # The lustre node profile object class - if self.profileUUID: - # loading the node profile object class from LDAP, since this related to lustre node class - # The node profile contains the clientUUID, mdsUUIDs (multiple) and ostUUIDs(multiple) - # the rest of the object class queried from LDAP server useing above UUIDs - self.lustreNodeProfile=LustreNodeProfile() - self.lustreNodeProfile.getEntry_from_ldap(conn_id,base,self.profileUUID) - - except ldap.NO_SUCH_OBJECT: - print "no results Found" - exit(1) - - def get_dn(self,id): - return self.id_str+"="+id+",type="+self.node_str+",fs=lustre" - - # add entries into LDAP server, All of them are must fields - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.id) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.id_str,[self.id])) - modlist.append((self.nodeUUID_str,[self.nodeUUID])) - modlist.append((self.netUUIDs_str,self.netUUIDs)) - modlist.append((self.profileUUID_str,[self.profileUUID])) - modlist.append((self.routerUUID_str,[self.routerUUID])) - modlist.append((self.ldlmUUID_str,[self.ldlmUUID])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - return status - - def initobj(self,*args): - print "init obj :", args - # print values of object class - def print_node(self): - print "lustre Node Attributes......" - print "objectClass: %s" % self.objectClass - print "node UUID: %s" % self.nodeUUID - print "node name: %s" % self.id - for i in range(len(self.netUUIDs)): - print "network UUID%d: %s" % (i,self.netUUIDs[i]) - print "Node Profile UUID: %s" % self.profileUUID - print "Router UUID: %s" % self.routerUUID - print "Ldlm UUID: %s" % self.ldlmUUID - print - for i in range(len(self.netUUIDs)): - self.lustreNet[i].print_net() - - self.lustreNodeProfile.print_profile() - self.lustreLdlm.print_ldlm() - - - -# lustre Client object class It have mount uuid and net uuid, but the net uuid may not required at present. -class LustreClient: - def __init__(self,lustreNode): - self.objectClass="lustreClient" - self.clientUUID=0 - self.mountUUIDs=[] - self.netUUID=0 - - self.lustreNode=lustreNode - self.lustreNet= 0 - self.lustreMount={} - - - self.clientUUID_attr="clientUUID" - self.mountUUID_attr="mountUUIDs" - self.netUUID_attr="netUUID" - self.client_attr="client" - - def ge_object_class(self): - return self.objectClass - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (clientUUID="+attr_value+")" - return retval - - - # load the object class with client config params - def init_node(self,node_entry): - self.clientUUID=node_entry[0][1][self.clientUUID_attr][0] - for i in range(len(node_entry[0][1][self.mountUUID_attr])): - self.mountUUIDs.append(node_entry[0][1][self.mountUUID_attr][i]) - self.netUUID=node_entry[0][1][self.netUUID_attr][0] - - - # brings the client config params from LDAP, here the search criteria is clientUUID=lustre1_client_UUID,type=client,fs=lustre, this is called as dn - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - # filter has "clientUUID=lustre1_client_UUID,type=client,fs=lustre" - # the base is "fs=lustre" - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Client Error No Results found" - sys.exit(1) - - self.init_node(result) - - if self.netUUID: - self.lustreNet=LustreNet() - self.lustreNet.getEntry_from_ldap(conn_id,base,self.netUUID) - else: - print "Unable to find the LDLM uuid in Client Object Class..." - - if self.mountUUIDs: - for mntuuid in self.mountUUIDs: - self.lustreMount[mntuuid]=LustreMount() - self.lustreMount[mntuuid].getEntry_from_ldap(conn_id,base,mntuuid) - - - def get_dn(self,uuid): - retval=self.clientUUID_attr+"="+uuid+",type="+self.client_attr+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.clientUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.clientUUID_attr,[self.clientUUID])) - modlist.append((self.mountUUID_attr,self.mountUUIDs)) - modlist.append((self.netUUID_attr,[self.netUUID])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_client(self): - print "Lustre Client Configurations..............." - print "client Object Calss: %s" % self.objectClass - print "client UUID: %s" % self.clientUUID - print "This client supporting %d file systems" % len(self.mountUUIDs) - if self.lustreNet: - self.lustreNet.print_net() - - if self.mountUUIDs: - for mntuuid in self.mountUUIDs: - self.lustreMount[mntuuid].print_mount() - - - - -class LustreMount: - def __init__(self): - self.objectClass="lustreMount" - self.mountUUID=0 - self.mdsUUID=0 - self.lovUUID=0 - self.mountPath="" - self.default=0 - - self.lustreMds=0 - self.lustreLov=0 - - self.mountUUID_attr="mountUUID" - self.mdsUUID_attr="mdsUUID" - self.lovUUID_attr="lovUUID" - self.mountPath_attr="mountPath" - self.default_attr="default" - self.type="mountPoint" - - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (mountUUID="+attr_value+")" - return retval - - - def init_node(self,record): - self.mdsUUID=record[0][1][self.mdsUUID_attr][0] - self.mountUUID=record[0][1][self.mountUUID_attr][0] - self.lovUUID=record[0][1][self.lovUUID_attr][0] - self.mountPath=record[0][1][self.mountPath_attr][0] - self.default=record[0][1][self.default_attr][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Mount Error No Results found" - sys.exit(1) - self.init_node(result) - - if self.mdsUUID: - self.lustreMds=LustreMds() - self.lustreMds.getEntry_from_ldap(conn_id,base,self.mdsUUID) - - if self.lovUUID: - self.lustreLov=LustreLov() - self.lustreLov.getEntry_from_ldap(conn_id,base,self.lovUUID) - - def get_dn(self,uuid): - retval=self.mountUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.mountUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.mountUUID_attr,[self.mountUUID])) - modlist.append((self.mdcUUID_attr,self.mdcUUID)) - modlist.append((self.lovUUID_attr,[self.lovUUID])) - modlist.append((self.mountPath_attr,[self.mountPath])) - modlist.append((self.default_attr,[self.default])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_mount(self): - - print "Lustre mount point attributes......" - print "mount object class: %s" % self.objectClass - print "mount UUID: %s" % self.mountUUID - print "mds UUID: %s" % self.mdsUUID - print "lov UUID: %s" % self.lovUUID - print "mount point: %s" % self.mountPath - if self.default: - print "This file system is default file system for this cleint" - else: - print "This file system is not a default file system for this cleint" - - if self.lustreMds: - self.lustreMds.print_mds() - if self.lustreLov: - self.lustreLov.print_lov() - - -class LustreOsc: - def __init__(self): - self.objectClass="lustreOSC" - self.oscUUID=0 - self.devName="" - self.obdUUID=0 - self.ostUUID=0 - - self.lustreObd=0 - self.lustreOst=0 - - self.oscUUID_attr="oscUUID" - self.devName_attr="devName" - self.obdUUID_attr="obdUUID" - self.ostUUID_attr="ostUUID" - self.type="OSC" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (oscUUID="+attr_value+")" - return retval - - - def init_node(self,record): - self.oscUUID=record[0][1][self.oscUUID_attr][0] - self.obdUUID=record[0][1][self.obdUUID_attr][0] - self.ostUUID=record[0][1][self.ostUUID_attr][0] - self.devName=record[0][1][self.devName_attr][0] - - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - if self.obdUUID: - self.lustreObd=LustreObd() - self.lustreObd.getEntry_from_ldap(conn_id,base,self.obdUUID) - - if self.ostUUID: - self.lustreOst=LustreOst() - self.lustreOst.getEntry_from_ldap(conn_id,base,self.ostUUID) - - def get_dn(self,uuid): - retval=self.oscUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.oscUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.oscUUID_attr,[self.oscUUID])) - modlist.append((self.devName_attr,self.devName)) - modlist.append((self.obdUUID_attr,[self.obdUUID])) - modlist.append((self.ostUUID_attr,[self.ostUUID])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_osc(self): - print "Lustre Osc Attrributes.." - print "object class: %s" % self.objectClass - print "oscUUID: %s" % self.oscUUID - print "devName: %s" % self.devName - print "obdUUID: %s" % self.obdUUID - print "ostUUID: %s" % self.ostUUID - print - if self.lustreObd: - self.lustreObd.print_obd() - print - if self.lustreOst: - self.lustreOst.print_ost() - print - - -class LustreMdc: - def __init__(self): - self.objectClass="lustreMDC" - self.mdcUUID=0 - self.devName="" - self.mdsUUID=0 - - self.lustreMds=0 - - self.mdcUUID_attr="mdcUUID" - self.devName_attr="devName" - self.mdsUUID_attr="mdsUUID" - self.type="MDC" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (mdcUUID="+attr_value+")" - return retval - - - def init_node(self,record): - self.mdcUUID=record[0][1][self.mdcUUID_attr][0] - self.mdsUUID=record[0][1][self.mdsUUID_attr][0] - self.devName=record[0][1][self.devName_attr][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - if self.mdsUUID: - self.lustreMds=LustreMds() - self.lustreMds.getEntry_from_ldap(conn_id,base,self.mdsUUID) - - - def get_dn(self,uuid): - retval=self.mdcUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.mdcUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.mdcUUID_attr,[self.mdcUUID])) - modlist.append((self.devName_attr,self.devName)) - modlist.append((self.mdsUUID_attr,[self.mdsUUID])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_mdc(self): - print "Lustre Mdc attributes....." - print "Mdc UUID: %s" % self.mdcUUID - print "dev name: %s" % self.devName - print "Mds UUId: %s" % self.mdsUUID - print - if self.lustreMds: - self.lustreMds.print_mds() - - - -class LustreOst: - def __init__(self): - self.objectClass="lustreOST" - self.ostUUID=0 - self.devName="" - self.obdUUID=0 - - self.lustreObd=0 - - self.ostUUID_attr="ostUUID" - self.devName_attr="devName" - self.obdUUID_attr="obdUUID" - self.type="OST" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (ostUUID="+attr_value+")" - return retval - - def init_node(self,record): - self.ostUUID=record[0][1][self.ostUUID_attr][0] - self.obdUUID=record[0][1][self.obdUUID_attr][0] - self.devName=record[0][1][self.devName_attr][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - if self.obdUUID: - self.lustreObd=LustreObd() - self.lustreObd.getEntry_from_ldap(conn_id,base,self.obdUUID) - - - def get_dn(self,uuid): - retval=self.ostUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.ostUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.ostUUID_attr,[self.ostUUID])) - modlist.append((self.devName_attr,[self.devName])) - modlist.append((self.obdUUID_attr,[self.obdUUID])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_ost(self): - print "Lustre Ost Attributes...." - print "object class: %s" % self.objectClass - print "ostUUID: %s" % self.ostUUID - print "devName: %s" % self.devName - print "obdUUID: %s" % self.obdUUID - print - if self.lustreObd: - self.lustreObd.print_obd() - - - -class LustreMds: - def __init__(self): - self.objectClass="lustreMDS" - self.mdsUUID=0 - self.devName="" - self.devUUID=0 - self.lovUUID=0 - self.fUUID=0 - - self.lustreDev=0 - self.lustreLov=0 - - self.mdsUUID_attr="mdsUUID" - self.devName_attr="devName" - self.devUUID_attr="devUUID" - self.lovUUID_attr="lovUUID" - self.fUUID_attr="fUUID" - self.type="MDS" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (mdsUUID="+attr_value+")" - return retval - - - def init_node(self,record): - self.mdsUUID=record[0][1][self.mdsUUID_attr][0] - self.devUUID=record[0][1][self.devUUID_attr][0] - self.lovUUID=record[0][1][self.lovUUID_attr][0] - #self.fUUID=record[0][1][self.fUUID_attr][0] - self.devName=record[0][1][self.devName_attr][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - - if self.devUUID: - self.lustreDev=LustreDevice() - self.lustreDev.getEntry_from_ldap(conn_id,base,self.devUUID) - - if self.lovUUID: - self.lustreLov=LustreLov() - self.lustreLov.getEntry_from_ldap(conn_id,base,self.lovUUID) - - - def get_dn(self,uuid): - retval=self.mdsUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.mdsUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.mdsUUID_attr,[self.mdsUUID])) - modlist.append((self.devName_attr,[self.devName])) - modlist.append((self.devUUID_attr,[self.devUUID])) - modlist.append((self.lovUUID_attr,[self.lovUUID])) - modlist.append((self.fUUID_attr,[self.fUUID])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_mds(self): - print "Lustre Mds Attributes..." - print "object Class: %s" % self.objectClass - print "mdsUUID: %s" % self.mdsUUID - print "devName: %s" % self.devName - print "devUUID: %s" % self.devUUID - #print "fUUID: %s" % self.fUUID - print "lovUUID: %s" % self.lovUUID - print - if self.lustreLov: - self.lustreLov.print_lov() - print - - -class LustreLov: - def __init__(self): - self.objectClass="lustreLOV" - self.lovUUID=0 - self.devName = "" - self.oscUUIDs= [] - self.stripeOffset=0 - self.stripeSize=0 - self.stripeCount=0 - self.pattern=0 - - self.lustreOsc = {} - - self.lovUUID_attr="lovUUID" - self.devName_attr="devName" - self.oscUUID_attr="oscUUIDs" - self.stripeOffset_attr="stripeOffset" - self.stripeSize_attr="stripeSize" - self.stripeCount_attr="stripeCount" - self.pattern_attr="pattern" - self.type="LOV" - - def get_object_class(self): - return self.objectCalss - - - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (lovUUID="+attr_value+")" - return retval - - - def init_node(self,record): - nofvals=len(record[0][1][self.oscUUID_attr]) - for i in range(nofvals): - self.oscUUIDs.append(record[0][1][self.oscUUID_attr][i]) - - self.stripeOffset=record[0][1][self.stripeOffset_attr][0] - self.lovUUID=record[0][1][self.lovUUID_attr][0] - self.devName = record[0][1][self.devName_attr][0] - self.stripeSize=record[0][1][self.stripeSize_attr][0] - self.stripeCount=record[0][1][self.stripeCount_attr][0] - self.pattern=record[0][1][self.pattern_attr][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - - if self.oscUUIDs: - for uuid in self.oscUUIDs: - self.lustreOsc[uuid]=LustreOsc() - self.lustreOsc[uuid].getEntry_from_ldap(conn_id,base,uuid) - - def get_dn(self,uuid): - retval=self.lovUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.lovUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.lovUUID_attr,[self.lovUUID])) - modlist.append((self.devName_attr,[self.devName])) - modlist.append((self.oscUUID_attr,self.oscUUIDs)) - modlist.append((self.stripeOffset_attr,[self.stripeOffset])) - modlist.append((self.stripeSize_attr,[self.stripeSize])) - modlist.append((self.stripeCount_attr,[self.stripeCount])) - modlist.append((self.pattern_attr,[self.pattern])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_lov(self): - print "Lustre LOV attributes..." - print "object class: %s" % self.objectClass - print "lovUUID: %s" % self.lovUUID - print "devName: %s" % self.devName - print "oscUUIDs are" - for i in range(len(self.oscUUIDs)): - print "oscUUID[%d]: %s" % (i,self.oscUUIDs[i]) - print "stripeOffset: %s" % self.stripeOffset - print "stripe Size: %s" % self.stripeSize - print "stripe Count: %s" % self.stripeCount - print "pattern: %s" % self.pattern - - print - if self.oscUUIDs: - for uuid in self.oscUUIDs: - if self.lustreOsc: - self.lustreOsc[uuid].print_osc() - print - - -class LustreDevice: - def __init__(self): - self.objectClass="lustreDevice" - self.id="" - self.fid="" - self.devUUID=0 - self.netUUID=0 - self.fnetUUID=0 - self.device="" - self.auto=0 - self.fsType="" - self.size=0 - - self.id_attr="id" - self.fid_attr="fid" - self.devUUID_attr="devUUID" - self.netUUID_attr="netUUID" - self.fnetUUID_attr="fnetUUID" - self.device_attr="device" - self.auto_attr="auto" - self.fsType_attr="fsType" - self.size_attr="size" - self.type="device" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (devUUID="+attr_value+")" - return retval - - def init_node(self,record): - self.devUUID=record[0][1][self.devUUID_attr][0] - self.netUUID=record[0][1][self.netUUID_attr][0] - self.fnetUUID=record[0][1][self.fnetUUID_attr][0] - self.id=record[0][1][self.id_attr][0] - self.fid=record[0][1][self.fid_attr][0] - self.device=record[0][1][self.device_attr][0] - self.auto=record[0][1][self.auto_attr][0] - self.fsType=record[0][1][self.fsType_attr][0] - self.size=record[0][1][self.size_attr][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - def get_dn(self,uuid): - retval=self.devUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.devUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.devUUID_attr,[self.devUUID])) - modlist.append((self.netUUID_attr,[self.netUUID])) - modlist.append((self.fnetUUID_attr,[self.fnetUUID])) - modlist.append((self.id_attr,[self.id])) - modlist.append((self.fid_attr,[self.fid])) - modlist.append((self.device_attr,self.device)) - modlist.append((self.auto_attr,[self.auto])) - modlist.append((self.fsType_attr,[self.fsType])) - modlist.append((self.size_attr,[self.size])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_device(self): - print "lustre Device object...." - print "object Calss: %s" % self.objectClass - print "node name: %s" % self.id - print "failover node name: %s" % self.fid - print "devUUID: %s" % self.devUUID - print "netUUID: %s" % self.netUUID - print "failover netUUID: %s" % self.fnetUUID - print "device: %s" % self.device - print "autoformat: %s" % self.auto - print "fs type: %s" % self.fsType - print "size of device: %s" % self.size - - - -class LustreObd: - def __init__(self): - self.objectClass="lustreOBD" - self.obdUUID=0 - self.devName="" - self.devUUID=0 - self.fUUID=0 - - self.lustreDev = 0 - - self.obdUUID_attr="obdUUID" - self.devName_attr="devName" - self.devUUID_attr="devUUID" - self.fUUID_attr="fUUID" - self.type="OBD" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (obdUUID="+attr_value+")" - return retval - - def init_node(self,record): - self.obdUUID=record[0][1][self.obdUUID_attr][0] - self.devName=record[0][1][self.devName_attr][0] - self.devUUID=record[0][1][self.devUUID_attr][0] - self.fUUID=record[0][1][self.fUUID_attr][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - if self.devUUID: - self.lustreDev=LustreDevice() - self.lustreDev.getEntry_from_ldap(conn_id,base,self.devUUID) - - - def get_dn(self,uuid): - retval=self.obdUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.obdUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.obdUUID_attr,[self.obdUUID])) - modlist.append((self.devName_attr,[self.devName])) - modlist.append((self.devUUID_attr,[self.devUUID])) - modlist.append((self.fUUID_attr,[self.fUUID])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_obd(self): - print "Lustre Obd attributes...." - print "object Class: %s" % self.objectClass - print "obdUUID: %s" % self.obdUUID - print "devName: %s" % self.devName - print "devUUID: %s" % self.devUUID - print "fUUID: %s" % self.fUUID - print - if self.lustreDev: - self.lustreDev.print_device() - print - - -class LustreLdlm: - def __init__(self): - self.objectClass="lustreLDLM" - self.ldlmUUID=0 - self.devName="" - - self.ldlmUUID_attr="ldlmUUID" - self.devName_attr="devName" - self.type="LDLM" - - def get_object_class(self): - return self.objectCalss - - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (ldlmUUID="+attr_value+")" - return retval - - def init_node(self,record): - self.ldlmUUID=record[0][1][self.ldlmUUID_attr][0] - self.devName=record[0][1][self.devName_attr][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - - def get_dn(self,uuid): - retval=self.ldlmUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id): - modlist=[] - dn=self.get_dn(self.ldlmUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.ldlmUUID_attr,[self.ldlmUUID])) - modlist.append((self.devName_attr,[self.devName])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_ldlm(self): - print "Printing LDLM attributes..........." - print "ldlm Object Class: %s" % self.objectClass - print "ldlm UUID: %s" % self.ldlmUUID - print "ldlm Name: %s" % self.devName - print "\n" * 5 - - -class LustreNet: - def __init__(self): - self.objectClass="lustreNetwork" - self.netUUID=0 - self.id=0 - self.fnetUUID=0 - self.netType="" - self.netAddress="" - self.port=0 - self.recvMem=0 - self.sendMem=0 - - self.netUUID_attr="netUUID" - self.fnetUUID_attr="fnetUUID" - self.id_attr="id" - self.netType_attr="netType" - self.netAddress_attr="netAddress" - self.port_attr="port" - self.recvMem_attr="recvMem" - self.sendMem_attr="sendMem" - self.type="net" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (netUUID="+attr_value+")" - return retval - - def init_node(self,record): - self.netUUID=record[0][1][self.netUUID_attr][0] - self.fnetUUID=record[0][1][self.fnetUUID_attr][0] - self.id=record[0][1][self.id_attr][0] - self.netType=record[0][1][self.netType_attr][0] - self.netAddress=record[0][1][self.netAddress_attr][0] - self.port=record[0][1][self.port_attr][0] - self.recvMem=record[0][1][self.recvMem_attr][0] - self.sendMem=record[0][1][self.sendMem_attr][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - - def get_dn(self,uuid): - retval=self.netUUID_attr+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id,id,fnetUUID,netUUID,netType,netAddress,port,recvMem,sendMem): - modlist=[] - dn=self.get_dn(netUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.netUUID_attr,[netUUID])) - modlist.append((self.fnetUUID_attr,[fnetUUID])) - modlist.append((self.id_attr,[id])) - modlist.append((self.netType_attr,[netType])) - modlist.append((self.netAddress_attr,[netAddress])) - modlist.append((self.port_attr,[port])) - modlist.append((self.recvMem_attr,[recvMem])) - modlist.append((self.sendMem_attr,[sendMem])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_net(self): - print "Lustre Network Attributes:......" - print "object Class: %s" % self.objectClass - print "network UUID: %s" % self.netUUID - print "failover network UUID: %s" % self.fnetUUID - print "node name : %s" % self.id - print "network Type: %s" % self.netType - print "IP Address: %s" % self.netAddress - print "port: %s" % self.port - print "receive memory: %s" % self.recvMem - print "send memory: %s" % self.sendMem - print - - -class LustreNodeProfile: - def __init__(self): - self.objectClass="lustreNodeProfile" - self.profileUUID=0 - self.mdsUUIDs=[] - self.ostUUIDs=[] - self.clientUUID=0 - - self.profileUUID_str="profileUUID" - self.mdsUUIDs_str="mdsUUIDs" - self.ostUUIDs_str="ostUUIDs" - self.clientUUID_str="clientUUID" - self.type="profile" - - def get_object_class(self): - return self.objectCalss - - def get_rdn(self,attr_value): - retval="(objectClass="+self.objectClass+") (profileUUID="+attr_value+")" - return retval - - def init_node(self,node_entry): - self.profileUUID=node_entry[0][1][self.profileUUID_str][0] - if node_entry[0][1].has_key(self.mdsUUIDs_str): - for i in range(len(node_entry[0][1][self.mdsUUIDs_str])): - self.mdsUUIDs.append(node_entry[0][1][self.mdsUUIDs_str][i]) - - if node_entry[0][1].has_key(self.ostUUIDs_str): - for i in range(len(node_entry[0][1][self.ostUUIDs_str])): - self.ostUUIDs.append(node_entry[0][1][self.ostUUIDs_str][i]) - - if node_entry[0][1].has_key(self.clientUUID_str): - self.clientUUID=node_entry[0][1][self.clientUUID_str][0] - - def getEntry_from_ldap(self,conn_id,base,attr_val): - lustre_util=lustre_ldap() - filter=lustre_util.get_filter(self.get_rdn(attr_val)) - result=conn_id.search_s(base,ldap.SCOPE_SUBTREE,filter) - if result == []: - print "Error No Results found" - sys.exit(1) - self.init_node(result) - - def get_dn(self,uuid): - retval=self.profileUUID_str+"="+uuid+",type="+self.type+",fs=lustre" - return retval - - def addEntry_into_ldap(self,conn_id,profileUUID,mdsUUIDs,ostUUIDs,clientUUID): - modlist=[] - dn=self.get_dn(profileUUID) - modlist.append(("objectClass",[self.objectClass])) - modlist.append((self.profileUUID_str,[profileUUID])) - modlist.append((self.mdsUUIDs_str,mdsUUIDs)) - modlist.append((self.ostUUIDs_str,ostUUIDs)) - modlist.append((self.clientUUID_str,[clientUUID])) - modlist.append(("fs",["lustre"])) - status=0 - try: - conn_id.add_s(dn,modlist) - except _ldap.LDAPError: - print "not added" - sys.exit(1) - return status - - def initobj(self,*args): - print "init obj :", args - - def print_profile(self): - print "Lustre Node Profile Attributes:......" - print "object Class: %s" % self.objectClass - print "profile UUID: %s" % self.profileUUID - print "This node supports %d mds servers:" % len(self.mdsUUIDs) - for i in range(len(self.mdsUUIDs)): - print "Mds UUID%d: %s" % (i,self.mdsUUIDs[i]) - print "This node supports %d ost servers:" % len(self.ostUUIDs) - for i in range(len(self.ostUUIDs)): - print "Ost UUID%d: %s" % (i,self.ostUUIDs[i]) - print "Client UUID: %s" % self.clientUUID - print - - -def get_matched_osc(ConnId,ostuuid): - result = ConnId.search_s("fs=lustre",ldap.SCOPE_SUBTREE,"objectclass=lustreOSC") - lustreOSC = 0 - if result: - for i in range(len(result)): - tmpuuid = result[i][1]['ostUUID'][0] - if ostuuid == tmpuuid: - lustreOSC = LustreOsc() - lustreOSC.init_node([result[i]]) - break - - else: - print "no result" - - return lustreOSC - - -def get_matched_lov(ConnId,oscuuid): - print "inside.. get matched lov:", oscuuid - result = ConnId.search_s("fs=lustre",ldap.SCOPE_SUBTREE,"objectclass=lustreLOV") - lustreLOV = 0 - tmpuuids = [] - if result: - for i in range(len(result)): - tmpuuids = result[i][1]['oscUUIDs'] - for uuid in tmpuuids: - if oscuuid == uuid: - lustreLOV = LustreLov() - lustreLOV.init_node([result[i]]) - return lustreLOV - return 0 - - - - -- 1.8.3.1