From f0f586252af8e3c488df9c0ee75885b4edd8d2cd Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Thu, 5 Dec 2002 08:42:45 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'unlabeled-1.4.770'. --- lustre/.cvsignore | 14 - lustre/BUGS | 15 - lustre/BUILDING | 25 - lustre/COPYING | 352 --- lustre/ChangeLog | 244 -- lustre/FDL | 355 --- lustre/Makefile.am | 31 - lustre/README | 8 - lustre/Rules | 24 - lustre/archdep.m4 | 97 - lustre/autogen.sh | 6 - lustre/configure.in | 125 - lustre/doc/.cvsignore | 23 - lustre/doc/Makefile.am | 124 - lustre/doc/VERSIONING | 91 - lustre/doc/chbar.sh | 243 -- lustre/doc/lconf.lyx | 133 -- lustre/doc/lctl.lyx | 540 ----- lustre/doc/lmc.lyx | 310 --- lustre/doc/postbar | 151 -- lustre/doc/tex2pdf | 3043 ------------------------ lustre/extN/.cvsignore | 19 - lustre/extN/Makefile.am | 146 -- lustre/extN/ext3-2.4.18-fixes.diff | 353 --- lustre/extN/ext3-2.4.18-ino_sb_macro.diff | 1556 ------------ 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 | 1787 -------------- lustre/include/.cvsignore | 11 - lustre/include/config.h.in | 10 - lustre/include/linux/.cvsignore | 15 - lustre/include/linux/Makefile | 7 - lustre/include/linux/lprocfs_status.h | 132 - lustre/include/linux/lustre_debug.h | 53 - lustre/include/linux/lustre_dlm.h | 463 ---- lustre/include/linux/lustre_export.h | 45 - lustre/include/linux/lustre_ha.h | 61 - lustre/include/linux/lustre_idl.h | 547 ----- lustre/include/linux/lustre_import.h | 52 - lustre/include/linux/lustre_lib.h | 587 ----- lustre/include/linux/lustre_lite.h | 262 -- lustre/include/linux/lustre_mds.h | 250 -- lustre/include/linux/lustre_net.h | 363 --- lustre/include/linux/obd.h | 420 ---- lustre/include/linux/obd_class.h | 879 ------- lustre/include/linux/obd_echo.h | 13 - lustre/include/linux/obd_ext2.h | 49 - lustre/include/linux/obd_filter.h | 50 - lustre/include/linux/obd_lov.h | 31 - lustre/include/linux/obd_ost.h | 42 - lustre/include/linux/obd_snap.h | 29 - lustre/include/linux/obd_snap_support.h | 85 - lustre/include/linux/obd_support.h | 195 -- lustre/include/linux/obd_trace.h | 20 - lustre/install-sh | 251 -- lustre/ldlm/.cvsignore | 3 - lustre/ldlm/Makefile.am | 15 - lustre/ldlm/l_lock.c | 108 - lustre/ldlm/ldlm_extent.c | 97 - lustre/ldlm/ldlm_lock.c | 1061 --------- lustre/ldlm/ldlm_lockd.c | 794 ------- lustre/ldlm/ldlm_request.c | 797 ------- lustre/ldlm/ldlm_resource.c | 522 ---- lustre/ldlm/ldlm_test.c | 646 ----- lustre/lib/.cvsignore | 8 - lustre/lib/Makefile.am | 4 - lustre/lib/client.c | 267 --- lustre/lib/ll_pack.c | 67 - lustre/lib/mds_updates.c | 478 ---- lustre/lib/obd_pack.c | 80 - lustre/lib/simple.c | 236 -- lustre/lib/target.c | 175 -- lustre/llite/.cvsignore | 8 - lustre/llite/Makefile.am | 21 - lustre/llite/commit_callback.c | 133 -- lustre/llite/dcache.c | 185 -- lustre/llite/dir.c | 751 ------ lustre/llite/file.c | 844 ------- lustre/llite/lproc_llite.c | 249 -- lustre/llite/namei.c | 988 -------- lustre/llite/recover.c | 55 - lustre/llite/rw.c | 429 ---- lustre/llite/super.c | 621 ----- lustre/llite/super25.c | 659 ----- lustre/llite/symlink.c | 123 - lustre/llite/sysctl.c | 67 - lustre/lov/.cvsignore | 3 - lustre/lov/Makefile.am | 15 - lustre/lov/lov_obd.c | 1503 ------------ lustre/lov/lov_pack.c | 176 -- lustre/lov/lproc_lov.c | 204 -- lustre/mdc/.cvsignore | 8 - lustre/mdc/Makefile.am | 22 - lustre/mdc/lproc_mdc.c | 128 - lustre/mdc/mdc_reint.c | 197 -- lustre/mdc/mdc_request.c | 730 ------ lustre/mds/.cvsignore | 8 - lustre/mds/Makefile.am | 31 - lustre/mds/handler.c | 1839 -------------- lustre/mds/lproc_mds.c | 183 -- lustre/mds/mds_ext2.c | 145 -- lustre/mds/mds_ext3.c | 357 --- lustre/mds/mds_extN.c | 356 --- lustre/mds/mds_fs.c | 513 ---- lustre/mds/mds_lov.c | 211 -- lustre/mds/mds_reint.c | 867 ------- lustre/missing | 336 --- lustre/mkinstalldirs | 40 - lustre/nodist | 21 - lustre/obdclass/.cvsignore | 8 - lustre/obdclass/Makefile.am | 14 - lustre/obdclass/class_obd.c | 715 ------ lustre/obdclass/debug.c | 156 -- lustre/obdclass/genops.c | 503 ---- lustre/obdclass/lprocfs_status.c | 331 --- lustre/obdclass/sysctl.c | 133 -- lustre/obdclass/uuid.c | 136 -- lustre/obdecho/.cvsignore | 8 - lustre/obdecho/Makefile.am | 15 - lustre/obdecho/echo.c | 507 ---- lustre/obdecho/echo_client.c | 277 --- lustre/obdecho/lproc_echo.c | 67 - lustre/obdfilter/.cvsignore | 8 - lustre/obdfilter/Makefile.am | 25 - lustre/obdfilter/filter.c | 1864 --------------- lustre/obdfilter/lproc_obdfilter.c | 145 -- lustre/osc/.cvsignore | 8 - lustre/osc/Makefile.am | 25 - lustre/osc/lproc_osc.c | 119 - lustre/osc/osc_request.c | 1029 -------- lustre/ost/.cvsignore | 8 - lustre/ost/Makefile.am | 24 - lustre/ost/lproc_ost.c | 162 -- lustre/ost/ost_handler.c | 702 ------ lustre/patches/.cvsignore | 8 - lustre/patches/patch-2.4.18 | 1536 ------------ lustre/patches/patch-2.4.18-14 | 1369 ----------- lustre/patches/patch-2.4.18-alpha | 16 - lustre/patches/patch-2.4.18-chaos12 | 1521 ------------ lustre/patches/patch-2.4.18-chaos13 | 12 - lustre/patches/patch-2.4.18-chaos22 | 165 -- lustre/patches/patch-2.4.18-chaos25 | 1447 ----------- lustre/patches/patch-2.4.18-um | 49 - lustre/patches/ubd-io-fail-2.4.18 | 34 - lustre/ptlrpc/.cvsignore | 9 - lustre/ptlrpc/Makefile.am | 14 - lustre/ptlrpc/client.c | 812 ------- lustre/ptlrpc/connection.c | 169 -- lustre/ptlrpc/events.c | 288 --- lustre/ptlrpc/lproc_ptlrpc.c | 52 - lustre/ptlrpc/niobuf.c | 488 ---- lustre/ptlrpc/pack_generic.c | 138 -- lustre/ptlrpc/recovd.c | 361 --- lustre/ptlrpc/recover.c | 277 --- lustre/ptlrpc/rpc.c | 283 --- lustre/ptlrpc/service.c | 442 ---- lustre/scripts/.cvsignore | 9 - lustre/scripts/Makefile.am | 10 - lustre/scripts/dodiff.sh | 5 - lustre/scripts/license-status | 26 - lustre/scripts/lustre | 77 - lustre/scripts/lustre.spec.in | 128 - lustre/scripts/nodelustre | 46 - lustre/scripts/version_tag.pl | 157 -- lustre/tests/.cvsignore | 29 - lustre/tests/Makefile.am | 50 - lustre/tests/README | 85 - lustre/tests/acceptance-small.sh | 84 - lustre/tests/ba-echo.sh | 38 - lustre/tests/ba-mount.sh | 53 - lustre/tests/client-echo.cfg | 3 - lustre/tests/client-mount.cfg | 6 - lustre/tests/client-mount2.cfg | 10 - lustre/tests/common.sh | 713 ------ lustre/tests/create.pl | 61 - lustre/tests/createdestroy.c | 224 -- lustre/tests/createmany.c | 40 - lustre/tests/directio.c | 62 - lustre/tests/elan-client.cfg | 5 - lustre/tests/elan-server.cfg | 5 - lustre/tests/ext2_10000.gz | Bin 10228 -> 0 bytes lustre/tests/ext2_25000.gz | Bin 25136 -> 0 bytes lustre/tests/ext3_10000.gz | Bin 12172 -> 0 bytes lustre/tests/fs.sh | 27 - lustre/tests/fsx.c | 1152 --------- lustre/tests/intent-test.sh | 122 - lustre/tests/intent-test2.sh | 70 - lustre/tests/ldaptest.c | 27 - lustre/tests/ldlm.cfg | 3 - lustre/tests/leak_finder.pl | 63 - lustre/tests/llcleanup.sh | 19 - lustre/tests/lldlm.sh | 40 - lustre/tests/llecho.sh | 49 - lustre/tests/llechocleanup.sh | 10 - lustre/tests/llext3.sh | 10 - lustre/tests/llmodules.sh | 41 - lustre/tests/llmount-client.sh | 9 - lustre/tests/llmount-server.sh | 9 - lustre/tests/llmount.sh | 14 - lustre/tests/llmount2-hack.sh | 21 - lustre/tests/llmountcleanup.sh | 26 - lustre/tests/llmountcleanup2-hack.sh | 25 - lustre/tests/llrext3.sh | 10 - lustre/tests/llrmount.sh | 13 - lustre/tests/llrsetup.sh | 15 - lustre/tests/llsetup.sh | 15 - lustre/tests/llsimple.sh | 11 - lustre/tests/local.sh | 35 - lustre/tests/lov.sh | 32 - lustre/tests/lovstripe.c | 164 -- lustre/tests/lustre.cfg | 49 - lustre/tests/mcr-individual-ost-nogw-config.sh | 46 - lustre/tests/mcr-mds-failover-config.sh | 48 - lustre/tests/mcr-routed-config.sh | 93 - lustre/tests/mcr.sh | 45 - lustre/tests/mcrlov.sh | 51 - lustre/tests/mdcreq.sh | 37 - lustre/tests/mdcreqcleanup.sh | 34 - lustre/tests/mds.cfg | 7 - lustre/tests/mkdirmany.c | 40 - lustre/tests/modules.cfg | 3 - lustre/tests/mount2.sh | 35 - lustre/tests/mount2fs.sh | 43 - lustre/tests/munlink.c | 23 - lustre/tests/net-client.cfg | 6 - lustre/tests/net-local.cfg | 6 - lustre/tests/net-server.cfg | 6 - lustre/tests/obddisk.cfg | 6 - lustre/tests/obdecho.cfg | 4 - lustre/tests/obdfilter.cfg | 7 - lustre/tests/openclose.c | 143 -- lustre/tests/openme.c | 23 - lustre/tests/openunlink.c | 132 - lustre/tests/ostreq.sh | 37 - lustre/tests/rundbench | 10 - lustre/tests/runfailure-client-mds-recover.sh | 103 - lustre/tests/runfailure-mds | 63 - lustre/tests/runfailure-net | 66 - lustre/tests/runfailure-ost | 51 - lustre/tests/runiozone | 17 - lustre/tests/runregression-brw.sh | 112 - lustre/tests/runregression-mds.sh | 67 - lustre/tests/runregression-net.sh | 100 - lustre/tests/runslabinfo | 5 - lustre/tests/runtests | 115 - lustre/tests/runvmstat | 2 - lustre/tests/sanity.sh | 218 -- lustre/tests/setuid.c | 27 - lustre/tests/snaprun.sh | 36 - lustre/tests/stat.c | 24 - lustre/tests/tbox.sh | 116 - lustre/tests/tchmod.c | 17 - lustre/tests/test.c | 101 - lustre/tests/test2.c | 60 - lustre/tests/test_brw.c | 209 -- lustre/tests/testreq.c | 140 -- lustre/tests/toexcl.c | 24 - lustre/tests/trivial.sh | 11 - lustre/tests/truncate.c | 24 - lustre/tests/uml.sh | 63 - lustre/tests/writeme.c | 32 - lustre/utils/.cvsignore | 13 - lustre/utils/Makefile.am | 18 - lustre/utils/ha_assist.sh | 5 - lustre/utils/ha_assist2.sh | 35 - lustre/utils/lconf | 1782 -------------- lustre/utils/lctl.c | 239 -- lustre/utils/lfind.c | 323 --- lustre/utils/llanalyze | 268 --- lustre/utils/lmc | 850 ------- lustre/utils/lstripe.c | 101 - lustre/utils/lustre.dtd | 110 - lustre/utils/mds-failover-sample | 20 - lustre/utils/obd.c | 1624 ------------- lustre/utils/obdctl.c | 103 - lustre/utils/obdctl.h | 63 - lustre/utils/parser.c | 722 ------ lustre/utils/parser.h | 74 - 280 files changed, 63917 deletions(-) delete mode 100644 lustre/.cvsignore delete mode 100644 lustre/BUGS delete mode 100644 lustre/BUILDING delete mode 100644 lustre/COPYING delete mode 100644 lustre/ChangeLog delete mode 100644 lustre/FDL delete mode 100644 lustre/Makefile.am delete mode 100644 lustre/README delete mode 100644 lustre/Rules delete mode 100644 lustre/archdep.m4 delete mode 100644 lustre/autogen.sh delete mode 100644 lustre/configure.in delete mode 100644 lustre/doc/.cvsignore delete mode 100644 lustre/doc/Makefile.am delete mode 100644 lustre/doc/VERSIONING delete mode 100755 lustre/doc/chbar.sh delete mode 100644 lustre/doc/lconf.lyx delete mode 100644 lustre/doc/lctl.lyx delete mode 100644 lustre/doc/lmc.lyx delete mode 100755 lustre/doc/postbar delete mode 100755 lustre/doc/tex2pdf delete mode 100644 lustre/extN/.cvsignore delete mode 100644 lustre/extN/Makefile.am delete mode 100644 lustre/extN/ext3-2.4.18-fixes.diff delete mode 100644 lustre/extN/ext3-2.4.18-ino_sb_macro.diff 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/.cvsignore delete mode 100644 lustre/include/config.h.in delete mode 100644 lustre/include/linux/.cvsignore delete mode 100644 lustre/include/linux/Makefile delete mode 100644 lustre/include/linux/lprocfs_status.h delete mode 100644 lustre/include/linux/lustre_debug.h delete mode 100644 lustre/include/linux/lustre_dlm.h delete mode 100644 lustre/include/linux/lustre_export.h delete mode 100644 lustre/include/linux/lustre_ha.h delete mode 100644 lustre/include/linux/lustre_idl.h delete mode 100644 lustre/include/linux/lustre_import.h delete mode 100644 lustre/include/linux/lustre_lib.h delete mode 100644 lustre/include/linux/lustre_lite.h delete mode 100644 lustre/include/linux/lustre_mds.h delete mode 100644 lustre/include/linux/lustre_net.h delete mode 100644 lustre/include/linux/obd.h delete mode 100644 lustre/include/linux/obd_class.h delete mode 100644 lustre/include/linux/obd_echo.h delete mode 100644 lustre/include/linux/obd_ext2.h delete mode 100644 lustre/include/linux/obd_filter.h delete mode 100644 lustre/include/linux/obd_lov.h delete mode 100644 lustre/include/linux/obd_ost.h delete mode 100644 lustre/include/linux/obd_snap.h delete mode 100644 lustre/include/linux/obd_snap_support.h delete mode 100644 lustre/include/linux/obd_support.h delete mode 100644 lustre/include/linux/obd_trace.h delete mode 100755 lustre/install-sh delete mode 100644 lustre/ldlm/.cvsignore delete mode 100644 lustre/ldlm/Makefile.am delete mode 100644 lustre/ldlm/l_lock.c delete mode 100644 lustre/ldlm/ldlm_extent.c delete mode 100644 lustre/ldlm/ldlm_lock.c delete mode 100644 lustre/ldlm/ldlm_lockd.c delete mode 100644 lustre/ldlm/ldlm_request.c delete mode 100644 lustre/ldlm/ldlm_resource.c delete mode 100644 lustre/ldlm/ldlm_test.c delete mode 100644 lustre/lib/.cvsignore delete mode 100644 lustre/lib/Makefile.am delete mode 100644 lustre/lib/client.c delete mode 100644 lustre/lib/ll_pack.c delete mode 100644 lustre/lib/mds_updates.c delete mode 100644 lustre/lib/obd_pack.c delete mode 100644 lustre/lib/simple.c delete mode 100644 lustre/lib/target.c delete mode 100644 lustre/llite/.cvsignore delete mode 100644 lustre/llite/Makefile.am delete mode 100644 lustre/llite/commit_callback.c delete mode 100644 lustre/llite/dcache.c delete mode 100644 lustre/llite/dir.c delete mode 100644 lustre/llite/file.c delete mode 100644 lustre/llite/lproc_llite.c delete mode 100644 lustre/llite/namei.c delete mode 100644 lustre/llite/recover.c delete mode 100644 lustre/llite/rw.c delete mode 100644 lustre/llite/super.c delete mode 100644 lustre/llite/super25.c delete mode 100644 lustre/llite/symlink.c delete mode 100644 lustre/llite/sysctl.c delete mode 100644 lustre/lov/.cvsignore delete mode 100644 lustre/lov/Makefile.am delete mode 100644 lustre/lov/lov_obd.c delete mode 100644 lustre/lov/lov_pack.c delete mode 100644 lustre/lov/lproc_lov.c delete mode 100644 lustre/mdc/.cvsignore delete mode 100644 lustre/mdc/Makefile.am delete mode 100644 lustre/mdc/lproc_mdc.c delete mode 100644 lustre/mdc/mdc_reint.c delete mode 100644 lustre/mdc/mdc_request.c delete mode 100644 lustre/mds/.cvsignore delete mode 100644 lustre/mds/Makefile.am delete mode 100644 lustre/mds/handler.c delete mode 100644 lustre/mds/lproc_mds.c delete mode 100644 lustre/mds/mds_ext2.c delete mode 100644 lustre/mds/mds_ext3.c delete mode 100644 lustre/mds/mds_extN.c delete mode 100644 lustre/mds/mds_fs.c delete mode 100644 lustre/mds/mds_lov.c delete mode 100644 lustre/mds/mds_reint.c delete mode 100755 lustre/missing delete mode 100755 lustre/mkinstalldirs delete mode 100644 lustre/nodist delete mode 100644 lustre/obdclass/.cvsignore delete mode 100644 lustre/obdclass/Makefile.am delete mode 100644 lustre/obdclass/class_obd.c delete mode 100644 lustre/obdclass/debug.c delete mode 100644 lustre/obdclass/genops.c delete mode 100644 lustre/obdclass/lprocfs_status.c delete mode 100644 lustre/obdclass/sysctl.c delete mode 100644 lustre/obdclass/uuid.c delete mode 100644 lustre/obdecho/.cvsignore delete mode 100644 lustre/obdecho/Makefile.am delete mode 100644 lustre/obdecho/echo.c delete mode 100644 lustre/obdecho/echo_client.c delete mode 100644 lustre/obdecho/lproc_echo.c delete mode 100644 lustre/obdfilter/.cvsignore delete mode 100644 lustre/obdfilter/Makefile.am delete mode 100644 lustre/obdfilter/filter.c delete mode 100644 lustre/obdfilter/lproc_obdfilter.c delete mode 100644 lustre/osc/.cvsignore delete mode 100644 lustre/osc/Makefile.am delete mode 100644 lustre/osc/lproc_osc.c delete mode 100644 lustre/osc/osc_request.c delete mode 100644 lustre/ost/.cvsignore delete mode 100644 lustre/ost/Makefile.am delete mode 100644 lustre/ost/lproc_ost.c delete mode 100644 lustre/ost/ost_handler.c delete mode 100644 lustre/patches/.cvsignore delete mode 100644 lustre/patches/patch-2.4.18 delete mode 100644 lustre/patches/patch-2.4.18-14 delete mode 100644 lustre/patches/patch-2.4.18-alpha delete mode 100644 lustre/patches/patch-2.4.18-chaos12 delete mode 100644 lustre/patches/patch-2.4.18-chaos13 delete mode 100644 lustre/patches/patch-2.4.18-chaos22 delete mode 100644 lustre/patches/patch-2.4.18-chaos25 delete mode 100644 lustre/patches/patch-2.4.18-um delete mode 100644 lustre/patches/ubd-io-fail-2.4.18 delete mode 100644 lustre/ptlrpc/.cvsignore delete mode 100644 lustre/ptlrpc/Makefile.am delete mode 100644 lustre/ptlrpc/client.c delete mode 100644 lustre/ptlrpc/connection.c delete mode 100644 lustre/ptlrpc/events.c delete mode 100644 lustre/ptlrpc/lproc_ptlrpc.c delete mode 100644 lustre/ptlrpc/niobuf.c delete mode 100644 lustre/ptlrpc/pack_generic.c delete mode 100644 lustre/ptlrpc/recovd.c delete mode 100644 lustre/ptlrpc/recover.c delete mode 100644 lustre/ptlrpc/rpc.c delete mode 100644 lustre/ptlrpc/service.c delete mode 100644 lustre/scripts/.cvsignore delete mode 100644 lustre/scripts/Makefile.am delete mode 100755 lustre/scripts/dodiff.sh delete mode 100755 lustre/scripts/license-status delete mode 100755 lustre/scripts/lustre delete mode 100644 lustre/scripts/lustre.spec.in delete mode 100755 lustre/scripts/nodelustre delete mode 100644 lustre/scripts/version_tag.pl delete mode 100644 lustre/tests/.cvsignore delete mode 100644 lustre/tests/Makefile.am delete mode 100644 lustre/tests/README delete mode 100755 lustre/tests/acceptance-small.sh delete mode 100644 lustre/tests/ba-echo.sh delete mode 100644 lustre/tests/ba-mount.sh delete mode 100644 lustre/tests/client-echo.cfg delete mode 100644 lustre/tests/client-mount.cfg delete mode 100644 lustre/tests/client-mount2.cfg delete mode 100644 lustre/tests/common.sh delete mode 100644 lustre/tests/create.pl delete mode 100644 lustre/tests/createdestroy.c 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 100644 lustre/tests/ext2_10000.gz delete mode 100644 lustre/tests/ext2_25000.gz delete mode 100644 lustre/tests/ext3_10000.gz delete mode 100644 lustre/tests/fs.sh delete mode 100644 lustre/tests/fsx.c delete mode 100755 lustre/tests/intent-test.sh delete mode 100644 lustre/tests/intent-test2.sh delete mode 100644 lustre/tests/ldaptest.c delete mode 100644 lustre/tests/ldlm.cfg delete mode 100644 lustre/tests/leak_finder.pl delete mode 100755 lustre/tests/llcleanup.sh delete mode 100755 lustre/tests/lldlm.sh delete mode 100644 lustre/tests/llecho.sh delete mode 100755 lustre/tests/llechocleanup.sh delete mode 100755 lustre/tests/llext3.sh delete mode 100644 lustre/tests/llmodules.sh delete mode 100644 lustre/tests/llmount-client.sh delete mode 100644 lustre/tests/llmount-server.sh delete mode 100755 lustre/tests/llmount.sh delete mode 100644 lustre/tests/llmount2-hack.sh delete mode 100755 lustre/tests/llmountcleanup.sh delete mode 100644 lustre/tests/llmountcleanup2-hack.sh delete mode 100755 lustre/tests/llrext3.sh delete mode 100755 lustre/tests/llrmount.sh delete mode 100644 lustre/tests/llrsetup.sh delete mode 100644 lustre/tests/llsetup.sh delete mode 100755 lustre/tests/llsimple.sh delete mode 100755 lustre/tests/local.sh delete mode 100755 lustre/tests/lov.sh delete mode 100644 lustre/tests/lovstripe.c delete mode 100644 lustre/tests/lustre.cfg delete mode 100755 lustre/tests/mcr-individual-ost-nogw-config.sh delete mode 100755 lustre/tests/mcr-mds-failover-config.sh delete mode 100755 lustre/tests/mcr-routed-config.sh delete mode 100755 lustre/tests/mcr.sh delete mode 100755 lustre/tests/mcrlov.sh delete mode 100644 lustre/tests/mdcreq.sh delete mode 100755 lustre/tests/mdcreqcleanup.sh delete mode 100644 lustre/tests/mds.cfg delete mode 100755 lustre/tests/mkdirmany.c delete mode 100755 lustre/tests/modules.cfg delete mode 100644 lustre/tests/mount2.sh delete mode 100644 lustre/tests/mount2fs.sh delete mode 100755 lustre/tests/munlink.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/obddisk.cfg delete mode 100644 lustre/tests/obdecho.cfg delete mode 100644 lustre/tests/obdfilter.cfg delete mode 100644 lustre/tests/openclose.c delete mode 100644 lustre/tests/openme.c delete mode 100644 lustre/tests/openunlink.c delete mode 100644 lustre/tests/ostreq.sh delete mode 100755 lustre/tests/rundbench delete mode 100755 lustre/tests/runfailure-client-mds-recover.sh delete mode 100755 lustre/tests/runfailure-mds delete mode 100755 lustre/tests/runfailure-net delete mode 100755 lustre/tests/runfailure-ost delete mode 100755 lustre/tests/runiozone delete mode 100644 lustre/tests/runregression-brw.sh delete mode 100755 lustre/tests/runregression-mds.sh delete mode 100644 lustre/tests/runregression-net.sh delete mode 100755 lustre/tests/runslabinfo delete mode 100755 lustre/tests/runtests delete mode 100755 lustre/tests/runvmstat delete mode 100644 lustre/tests/sanity.sh delete mode 100644 lustre/tests/setuid.c delete mode 100755 lustre/tests/snaprun.sh delete mode 100644 lustre/tests/stat.c delete mode 100644 lustre/tests/tbox.sh delete mode 100644 lustre/tests/tchmod.c delete mode 100755 lustre/tests/test.c delete mode 100755 lustre/tests/test2.c delete mode 100644 lustre/tests/test_brw.c delete mode 100644 lustre/tests/testreq.c delete mode 100644 lustre/tests/toexcl.c delete mode 100755 lustre/tests/trivial.sh delete mode 100644 lustre/tests/truncate.c delete mode 100644 lustre/tests/uml.sh delete mode 100644 lustre/tests/writeme.c delete mode 100644 lustre/utils/.cvsignore delete mode 100644 lustre/utils/Makefile.am delete mode 100755 lustre/utils/ha_assist.sh delete mode 100755 lustre/utils/ha_assist2.sh delete mode 100755 lustre/utils/lconf delete mode 100644 lustre/utils/lctl.c delete mode 100644 lustre/utils/lfind.c delete mode 100644 lustre/utils/llanalyze delete mode 100755 lustre/utils/lmc delete mode 100644 lustre/utils/lstripe.c delete mode 100644 lustre/utils/lustre.dtd delete mode 100755 lustre/utils/mds-failover-sample delete mode 100644 lustre/utils/obd.c delete mode 100644 lustre/utils/obdctl.c delete mode 100644 lustre/utils/obdctl.h delete mode 100644 lustre/utils/parser.c delete mode 100644 lustre/utils/parser.h diff --git a/lustre/.cvsignore b/lustre/.cvsignore deleted file mode 100644 index 111b232..0000000 --- a/lustre/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -.Xrefs -aclocal.m4 -config.log -config.status -config.cache -configure -Makefile -Makefile.in -.deps -tags -TAGS -lustre*.tar.gz -cscope.files -cscope.out diff --git a/lustre/BUGS b/lustre/BUGS deleted file mode 100644 index 9cf6fa2..0000000 --- a/lustre/BUGS +++ /dev/null @@ -1,15 +0,0 @@ -include /dev/obd in the documentation - - -attach: attaching ext2obd allows ext2 module to be unloaded. Unload, -then do cleanup, get Oops... - -syncing: invalid IOCTL - -create: more than one object - -preallocate: IOCTL - -statfs: - -restoresnap: decrements directory count for ext2 diff --git a/lustre/BUILDING b/lustre/BUILDING deleted file mode 100644 index deaa5e8..0000000 --- a/lustre/BUILDING +++ /dev/null @@ -1,25 +0,0 @@ -BUILDING LUSTRE ---------------- - -To build the lustre obd module, you must first build portals. - -Portals is available from the same CVS repository of the lustre -project module portals, see http://www.lustre.org - -To build: - sh autogen.sh - ./configure --enable-linuxdir=/usr/src/linux --enable-portalsdir=/usr/src/portals - make - -To play with Lustre Lite: - cd obd/tests - sh llmount.sh - -To clean up: - sh llmountcleanup.sh - -Feedback: - lustre-devel@lists.sf.net - lustre-discuss@lists.sf.net - -- Peter - \ No newline at end of file diff --git a/lustre/COPYING b/lustre/COPYING deleted file mode 100644 index c69cfd8..0000000 --- a/lustre/COPYING +++ /dev/null @@ -1,352 +0,0 @@ - - NOTE! This copyright does *not* cover user programs that use kernel - services by normal system calls - this is merely considered normal use - of the kernel, and does *not* fall under the heading of "derived work". - Also note that the GPL below is copyrighted by the Free Software - Foundation, but the instance of code that it refers to (the Linux - kernel) is copyrighted by me and others who actually wrote it. - - Linus Torvalds - ----------------------------------------- - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program 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 program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/lustre/ChangeLog b/lustre/ChangeLog deleted file mode 100644 index 45d39ab..0000000 --- a/lustre/ChangeLog +++ /dev/null @@ -1,244 +0,0 @@ -TBA - * bug fixes - - LRU counters were broken, causing constant lock purge (433, 432) - - garbage on read from stripes with failed OSTs (441) - - mark OSCs as active before reconnecting during recovery (438) - - lov_enqueue and lov_cancel need to handle inactive OSTs (403) - -2002-12-02 Andreas Dilger - * version v0_5_18 - * bug fixes - - fix many simultaneous client startup (392) - - fix dentry->d_it clobbering - - credentials weren't being shipped for readdir/getattr operations - - remove invalid assertions triggered during some concurrent MD - updates - - proper Lustre versions added (336, 389) - - fix memory leak for create error case (398) - - fix LOV locking bug that would get cli/srv out of sync - - fix echo client over LOV (409) - - fix dbench 2, extN refcount problem (170, 258, 356, 418) - - fix double-O_EXCL intent crash (424) - - avoid sending multiple lock CANCELs (352) - * Features - - MDS can do multi-client recovery (modulo bugs in new code) - * Documentation - - many updates, edits, cleanups - -2002-11-18 Phil Schwan - * version v0_5_17 - * bug fixes - - fix null d_it dereference (346) - - fix full OST/dbench hang (333) - - fix permission problem with file removal (286) - - fix removal of OSCs from LOV when they fail - - fix NULL deref during bulk timeout (214) - - fix problems related to multiple filesystems on one MDS (241) - - fixed serious subtle metadata locking bugs - - free locks on clients when inodes are removed due to memory - pressure (201) - - fix inode pointer in lock data (285) - - partial support for multiple MDS on a single host (241) - - data locks weren't cancelled at clear_inode time (290, 311) - - intent locks could lead to unbounded lock growth (205) - - added a maximum lock count, an LRU list, and a flusher - - fix multiple rename (365) - - properly abstracted the echo client - - OSC locked 1 byte too many; fixed - - rewrote brw callback code: - - fixed recovery bugs related to LOVs (306) - - fixed too-many-pages-in-one-write crash (191) - - fixed (again) crash in sync_io_timeout (214) - - probably fixed callback-related race (385) - * protocol change - - Add capability to MDS protocol - - LDLM cancellations and callbacks on different portals - -2002-10-28 Andreas Dilger - * version v0_5_16 - * bug fixes: - - limit client IOV size to PTL_MD_MAX_IOV (611336, 191) - - defer open object destruction to close time (601981, 138) - - open/close OST file handle in obdo (OBD_MD_FLHANDLE) (601981, 138) - - move LDLM_ENQUEUE/CONVERT back to MDS portal (625069) - - abstract ll_lookup2, fix ll_revalidate2 to use abstraction (256) - - don't call obd_setattr in ll_file_release for destroyed objects - * protocol change to lustre_msg: move |version| and add |flags| - * protocol change to osc_punch: "start" in "o_size", "end" in "o_blocks" - * lock replay: for LDLM_FL_REPLAY trust client to do right thing - * added replay of create, unlink, link and rename operations during - MDS failover; recovery should be much more robust now - * remove failed OSCs from LOVs (only lov_create uses this so far) - * the lustre-HOWTO was brought (more) up to date (582544) - -2002-10-23 Phil Schwan - * version v0_5_15 - * bug fixes: - - in-use dentries weren't being reused properly (617851) - - prevent multiple LDLM setup (599178) - - fix LOV size calculations for truncate (617853) - - fix client handling of MDS intent errors (POSIX) - - fix permission bug in lovstripe.c test (624321) - - fix MDS thread deadlock - move LDLM handler to DLM portal (625069) - - truncate past end of file could corrupt data - - proper cleanup after timeouts, crashes, etc (592524, 550815) - - a race in recovery could return ETIMEDOUT to apps (623947) - - building outside the source directory was fixed - * the lustre-HOWTO was brought (more) up to date (582544) - * major progress was made on recovery functionality - -2002-10-10 Phil Schwan - * version v0_5_14 - * bug fixes: - - recovery deadlock fix - - rm -rf causes LBUG fix (617817) - - file open by multiple tasks fix (618962) - - directory permissions bugs (602707 and 620007) - - journal_stop fixed with locking (611313) - - O_APPEND failures resolved (618273, perhaps 614459) - - lconf PATH fix (619770) - - IA64 build fix (621450) - - RPC buffer sizes scale with amount of memory - -2002-10-01 Phil Schwan - * version v0_5_13 - * bug fixes: - - locks would be cancelled without throwing away data pages, - resulting in inconsistent data (605627) - - inode attributes were not always being refreshed (605627, 612449) - - lconf now continues to cleanup after lctl reports an error - - MDS now enforces user permissions (602707) - - lprocfs cleanup fixed, but not yet enabled (614157) - - fixed infinite server hang, should a client not respond to an AST - - avoid going into recovery if user calls readlink() with a buffer - that's too small (613941) - - AST RPCs no longer require replies (614867) -- this may be changed - - don't crash server if client sends an IOV that's too big (611336) - - fixed lock conversion deadlock (611892) - - fixed the following of symlinks (614622) - * recovery: the server can remove locks from a client that dies, other - clients can make progress - * more extN patch fixes - * compile-time configurable ptlrpc buffer allocations - * documentation - - collaborative read cache document - - Lustre Lite Performance CDR document-in-progress - -2002-09-20 Andreas Dilger - * version v0_5_12 - * bug fix - - fix typo in patch-2.4.18 - -2002-09-20 Andreas Dilger - * version v0_5_11 - * bug fixes - - clear ptlrpc request each time in handle_incoming_request() - - unlink of files now destroys the object on the OST - -2002-09-19 Peter Braam - * version 0_5_10 - * add hard link support - * change obdfile creation method - * kernel patch changed - -2002-09-19 Peter Braam - * version 0_5_9 - * bug fix - - stack overflow bug in extN fixed - -2002-09-18 Andreas Dilger - * version 0_5_8 - * documentation updates - - add man pages for config tools - - update tests/README to describe testing with new config tools - - finish metadata API descriptions - * bug fixes and cleanups - - statfs workaround for 16TB limit - - LOV stripe allocation improved, can stripe on subset of OSTs - - LOV file size/IO offset was wrong for files > 4GB in size - - object EA data was being dropped, caused files to be unreadable - - memory overflow with non-LOV OST caused memory corruption - - fixed regression tests to work with new config tools, obdfilter - - fixed bug when directory size became larger than 1 block - - fixed bug (for single client case) when PWD was deleted - - invalidate local directory pages when doing intent-based ops - - avoid LDLM oops when lock callback contained bad data - -2002-09-09 Andreas Dilger - * version 0_5_7 - * documentation updates - * bug fixes and cleanups - - configuration tools - - LOV - - imports/exports - - 64-bit compile warnings - - 64-bit internal statfs data - - many more - * test_brw on persistent OST devices - * MDS recovery - * lprocfs (disabled) - -2002-09-04 Andreas Dilger - * version 0_5_6 - * documentation updates - * bug fixes and cleanups - * configuration tools - -2002-08-30 Peter J. Braam - - * version v0_5_5 - * many small fixes to 0_5_4 - * io/network handling - * thinkos in MDS operations - -2002-08-24 Peter J. Braam - - * version v0_5_4 - * crucial basic fixes to 0.5.3 - * IOR, Iozone work over Elan - * EOF locks added - -2002-08-07 Phil Schwan - * version 0_5_3, our first alpha - * we use the new Portals iovs - * documentation updates - * bug fixes and cleanups - * small changes in the DLM wire protocol - -2002-07-25 Peter J. Braam - * version 0_5_1 with some initial stability, - * locking on MD and file I/O. - * documentation updates - * several bug fixes since 0.5.0 - * small changes in wire protocol - -2002-07-18 Phil Schwan - * version v0_4_5 - * delivered as Lustre Light Alpha - * fixed a crash after handling invalid MDS requests - * fixed directory pages for architectures with non-4k pages sizes - -2002-07-11 Andreas Dilger - * release version v0_4_4 - * Moves TCP acceptor to be on port 2432 (unused Coda port) instead - of 1234. - * Fixes a number of interruption problems with OST operations. - * Update documentation for portals header changes - * Move all wire protocol structs/defines to lustre_idl.h - * Fixes symlink length bug. - * Add tcpdump to repository. - -2002-07-05 Andreas Dilger - * release version v0_4_3 - * Fixes statfs for inodes on extN. - * Fixes bug in runtests which would delete /etc/hosts. - * Use 64-bit object IDs wherever possible (not into VFS though) - Remove ost_get_info, which is unused by lustre, and out of date. - -2002-07-03 Peter Braam - * release version v0_4_2 Fixes a lookup error (type not passed) - * move forward to head of Portals - * move forward to latest Lustre kernel - -2002-06-25 Peter Braam - * release version v0_4_1. Hopefully stable on single node use. diff --git a/lustre/FDL b/lustre/FDL deleted file mode 100644 index b42936b..0000000 --- a/lustre/FDL +++ /dev/null @@ -1,355 +0,0 @@ - GNU Free Documentation License - Version 1.1, March 2000 - - Copyright (C) 2000 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - -0. PREAMBLE - -The purpose of this License is to make a manual, textbook, or other -written document "free" in the sense of freedom: to assure everyone -the effective freedom to copy and redistribute it, with or without -modifying it, either commercially or noncommercially. Secondarily, -this License preserves for the author and publisher a way to get -credit for their work, while not being considered responsible for -modifications made by others. - -This License is a kind of "copyleft", which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft -license designed for free software. - -We have designed this License in order to use it for manuals for free -software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; -it can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference. - - -1. APPLICABILITY AND DEFINITIONS - -This License applies to any manual or other work that contains a -notice placed by the copyright holder saying it can be distributed -under the terms of this License. The "Document", below, refers to any -such manual or work. Any member of the public is a licensee, and is -addressed as "you". - -A "Modified Version" of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. - -A "Secondary Section" is a named appendix or a front-matter section of -the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall subject -(or to related matters) and contains nothing that could fall directly -within that overall subject. (For example, if the Document is in part a -textbook of mathematics, a Secondary Section may not explain any -mathematics.) The relationship could be a matter of historical -connection with the subject or with related matters, or of legal, -commercial, philosophical, ethical or political position regarding -them. - -The "Invariant Sections" are certain Secondary Sections whose titles -are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. - -The "Cover Texts" are certain short passages of text that are listed, -as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. - -A "Transparent" copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, whose contents can be viewed and edited directly and -straightforwardly with generic text editors or (for images composed of -pixels) generic paint programs or (for drawings) some widely available -drawing editor, and that is suitable for input to text formatters or -for automatic translation to a variety of formats suitable for input -to text formatters. A copy made in an otherwise Transparent file -format whose markup has been designed to thwart or discourage -subsequent modification by readers is not Transparent. A copy that is -not "Transparent" is called "Opaque". - -Examples of suitable formats for Transparent copies include plain -ASCII without markup, Texinfo input format, LaTeX input format, SGML -or XML using a publicly available DTD, and standard-conforming simple -HTML designed for human modification. Opaque formats include -PostScript, PDF, proprietary formats that can be read and edited only -by proprietary word processors, SGML or XML for which the DTD and/or -processing tools are not generally available, and the -machine-generated HTML produced by some word processors for output -purposes only. - -The "Title Page" means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the material -this License requires to appear in the title page. For works in -formats which do not have any title page as such, "Title Page" means -the text near the most prominent appearance of the work's title, -preceding the beginning of the body of the text. - - -2. VERBATIM COPYING - -You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies -to the Document are reproduced in all copies, and that you add no other -conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further -copying of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. - -You may also lend copies, under the same conditions stated above, and -you may publicly display copies. - - -3. COPYING IN QUANTITY - -If you publish printed copies of the Document numbering more than 100, -and the Document's license notice requires Cover Texts, you must enclose -the copies in covers that carry, clearly and legibly, all these Cover -Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -the back cover. Both covers must also clearly and legibly identify -you as the publisher of these copies. The front cover must present -the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. -Copying with changes limited to the covers, as long as they preserve -the title of the Document and satisfy these conditions, can be treated -as verbatim copying in other respects. - -If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages. - -If you publish or distribute Opaque copies of the Document numbering -more than 100, you must either include a machine-readable Transparent -copy along with each Opaque copy, or state in or with each Opaque copy -a publicly-accessible computer-network location containing a complete -Transparent copy of the Document, free of added material, which the -general network-using public has access to download anonymously at no -charge using public-standard network protocols. If you use the latter -option, you must take reasonably prudent steps, when you begin -distribution of Opaque copies in quantity, to ensure that this -Transparent copy will remain thus accessible at the stated location -until at least one year after the last time you distribute an Opaque -copy (directly or through your agents or retailers) of that edition to -the public. - -It is requested, but not required, that you contact the authors of the -Document well before redistributing any large number of copies, to give -them a chance to provide you with an updated version of the Document. - - -4. MODIFICATIONS - -You may copy and distribute a Modified Version of the Document under -the conditions of sections 2 and 3 above, provided that you release -the Modified Version under precisely this License, with the Modified -Version filling the role of the Document, thus licensing distribution -and modification of the Modified Version to whoever possesses a copy -of it. In addition, you must do these things in the Modified Version: - -A. Use in the Title Page (and on the covers, if any) a title distinct - from that of the Document, and from those of previous versions - (which should, if there were any, be listed in the History section - of the Document). You may use the same title as a previous version - if the original publisher of that version gives permission. -B. List on the Title Page, as authors, one or more persons or entities - responsible for authorship of the modifications in the Modified - Version, together with at least five of the principal authors of the - Document (all of its principal authors, if it has less than five). -C. State on the Title page the name of the publisher of the - Modified Version, as the publisher. -D. Preserve all the copyright notices of the Document. -E. Add an appropriate copyright notice for your modifications - adjacent to the other copyright notices. -F. Include, immediately after the copyright notices, a license notice - giving the public permission to use the Modified Version under the - terms of this License, in the form shown in the Addendum below. -G. Preserve in that license notice the full lists of Invariant Sections - and required Cover Texts given in the Document's license notice. -H. Include an unaltered copy of this License. -I. Preserve the section entitled "History", and its title, and add to - it an item stating at least the title, year, new authors, and - publisher of the Modified Version as given on the Title Page. If - there is no section entitled "History" in the Document, create one - stating the title, year, authors, and publisher of the Document as - given on its Title Page, then add an item describing the Modified - Version as stated in the previous sentence. -J. Preserve the network location, if any, given in the Document for - public access to a Transparent copy of the Document, and likewise - the network locations given in the Document for previous versions - it was based on. These may be placed in the "History" section. - You may omit a network location for a work that was published at - least four years before the Document itself, or if the original - publisher of the version it refers to gives permission. -K. In any section entitled "Acknowledgements" or "Dedications", - preserve the section's title, and preserve in the section all the - substance and tone of each of the contributor acknowledgements - and/or dedications given therein. -L. Preserve all the Invariant Sections of the Document, - unaltered in their text and in their titles. Section numbers - or the equivalent are not considered part of the section titles. -M. Delete any section entitled "Endorsements". Such a section - may not be included in the Modified Version. -N. Do not retitle any existing section as "Endorsements" - or to conflict in title with any Invariant Section. - -If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles. - -You may add a section entitled "Endorsements", provided it contains -nothing but endorsements of your Modified Version by various -parties--for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. - -You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. - -The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. - - -5. COMBINING DOCUMENTS - -You may combine the Document with other documents released under this -License, under the terms defined in section 4 above for modified -versions, provided that you include in the combination all of the -Invariant Sections of all of the original documents, unmodified, and -list them all as Invariant Sections of your combined work in its -license notice. - -The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by -adding at the end of it, in parentheses, the name of the original -author or publisher of that section if known, or else a unique number. -Make the same adjustment to the section titles in the list of -Invariant Sections in the license notice of the combined work. - -In the combination, you must combine any sections entitled "History" -in the various original documents, forming one section entitled -"History"; likewise combine any sections entitled "Acknowledgements", -and any sections entitled "Dedications". You must delete all sections -entitled "Endorsements." - - -6. COLLECTIONS OF DOCUMENTS - -You may make a collection consisting of the Document and other documents -released under this License, and replace the individual copies of this -License in the various documents with a single copy that is included in -the collection, provided that you follow the rules of this License for -verbatim copying of each of the documents in all other respects. - -You may extract a single document from such a collection, and distribute -it individually under this License, provided you insert a copy of this -License into the extracted document, and follow this License in all -other respects regarding verbatim copying of that document. - - -7. AGGREGATION WITH INDEPENDENT WORKS - -A compilation of the Document or its derivatives with other separate -and independent documents or works, in or on a volume of a storage or -distribution medium, does not as a whole count as a Modified Version -of the Document, provided no compilation copyright is claimed for the -compilation. Such a compilation is called an "aggregate", and this -License does not apply to the other self-contained works thus compiled -with the Document, on account of their being thus compiled, if they -are not themselves derivative works of the Document. - -If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one quarter -of the entire aggregate, the Document's Cover Texts may be placed on -covers that surround only the Document within the aggregate. -Otherwise they must appear on covers around the whole aggregate. - - -8. TRANSLATION - -Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License provided that you also include the -original English version of this License. In case of a disagreement -between the translation and the original English version of this -License, the original English version will prevail. - - -9. TERMINATION - -You may not copy, modify, sublicense, or distribute the Document except -as expressly provided for under this License. Any other attempt to -copy, modify, sublicense or distribute the Document is void, and will -automatically terminate your rights under this License. However, -parties who have received copies, or rights, from you under this -License will not have their licenses terminated so long as such -parties remain in full compliance. - - -10. FUTURE REVISIONS OF THIS LICENSE - -The Free Software Foundation may publish new, revised versions -of the GNU Free Documentation License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. See -http://www.gnu.org/copyleft/. - -Each version of the License is given a distinguishing version number. -If the Document specifies that a particular numbered version of this -License "or any later version" applies to it, you have the option of -following the terms and conditions either of that specified version or -of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. - - -ADDENDUM: How to use this License for your documents - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: - - Copyright (c) YEAR YOUR NAME. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.1 - or any later version published by the Free Software Foundation; - with the Invariant Sections being LIST THEIR TITLES, with the - Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. - A copy of the license is included in the section entitled "GNU - Free Documentation License". - -If you have no Invariant Sections, write "with no Invariant Sections" -instead of saying which ones are invariant. If you have no -Front-Cover Texts, write "no Front-Cover Texts" instead of -"Front-Cover Texts being LIST"; likewise for Back-Cover Texts. - -If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, -to permit their use in free software. diff --git a/lustre/Makefile.am b/lustre/Makefile.am deleted file mode 100644 index 6fcadf3..0000000 --- a/lustre/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -AUTOMAKE_OPTIONS = foreign - -if LINUX25 -DIRS24 = mds -else -DIRS24 = extN mds -endif - -# NOTE: keep extN before mds and obdfilter -SUBDIRS = $(DIRS24) obdclass utils ptlrpc ldlm lib obdfilter mdc osc ost llite -SUBDIRS+= obdecho lov tests doc scripts - -DIST_SUBDIRS = $(SUBDIRS) -EXTRA_DIST = BUGS FDL Rules include patches archdep.m4 - -# We get the version from the spec file. -CONFIGURE_DEPENDENCIES = scripts/lustre.spec.in - -dist-hook: - find $(distdir) -name .deps | xargs rm -rf - find $(distdir) -name CVS | xargs rm -rf - -include $(top_srcdir)/Rules - -rpms: dist Makefile - rpm -ta $(distdir).tar.gz diff --git a/lustre/README b/lustre/README deleted file mode 100644 index a7b7240..0000000 --- a/lustre/README +++ /dev/null @@ -1,8 +0,0 @@ -Instructions for building, configuring, and running Lustre can be found in -the file doc/lustre-HOWTO.txt. - -If you have checked lustre directly out of CVS, then you either need to -get lyx to build the lustre-HOWTO.txt from the source file, get the PDF -version from the lustre.org website, or install the lustre-doc RPM for -the formatted text version (or read the somewhat cryptic lustre-HOWTO.lin -file if you are desperate). diff --git a/lustre/Rules b/lustre/Rules deleted file mode 100644 index cbcf51f..0000000 --- a/lustre/Rules +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -# Build a kernel module, name.o, and install it in $(moduledir) by: -# MODULE = name -# module_DATA = name.o -# EXTRA_PROGRAMS = name -# name_SOURCES = my.c files.c -# include $(top_srcdir)/Rules - -$(MODULE).o: $($(MODULE)_OBJECTS) - $(LD) -m "`$(LD) --help | awk '/supported emulations/ {print $$4}'`" -r -o $(MODULE).o $($(MODULE)_OBJECTS) - -tags: - rm -f $(top_srcdir)/TAGS - rm -f $(top_srcdir)/tags - find $(top_srcdir)/../portals/ -name '*.[hc]' | xargs etags -a - find $(top_srcdir) -name '*.[hc]' | xargs etags -a - find $(top_srcdir)/../portals/ -name '*.[hc]' | xargs ctags -a - find $(top_srcdir) -name '*.[hc]' | xargs ctags -a - -AM_CPPFLAGS="-I$(top_builddir)/include" diff --git a/lustre/archdep.m4 b/lustre/archdep.m4 deleted file mode 100644 index b11266c..0000000 --- a/lustre/archdep.m4 +++ /dev/null @@ -1,97 +0,0 @@ -AC_MSG_CHECKING(if you are running user mode linux for $host_cpu ...) -if test -e $LINUX/include/asm-um ; then -if test X`ls -id $LINUX/include/asm/ | awk '{print $1}'` = X`ls -id $LINUX/include/asm-um | awk '{print $1}'` ; then - host_cpu="um"; - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no (asm doesn't point at asm-um)) -fi - -else - AC_MSG_RESULT(no (asm-um missing)) -fi - -AC_MSG_CHECKING(setting make flags system architecture: ) -case ${host_cpu} in - um ) - AC_MSG_RESULT($host_cpu) - KCFLAGS='-g -Wall -pipe -Wno-trigraphs -Wstrict-prototypes -fno-strict-aliasing -fno-common ' - KCPPFLAGS='-D__KERNEL__ -U__i386__ -Ui386 -DUM_FASTCALL -D__arch_um__ -DSUBARCH="i386" -DNESTING=0 -D_LARGEFILE64_SOURCE -Derrno=kernel_errno -DPATCHLEVEL=4 -DMODULE -I$(LINUX)/arch/um/include ' - MOD_LINK=elf_i386 -;; - i*86 ) - AC_MSG_RESULT($host_cpu) - KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -pipe' - KCPPFLAGS='-D__KERNEL__ -DMODULE ' - MOD_LINK=elf_i386 -;; - - alphaev6 ) - AC_MSG_RESULT($host_cpu) - KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mno-fp-regs -ffixed-8 -mcpu=ev5 -Wa,-mev6' - KCPPFLAGS='-D__KERNEL__ -DMODULE ' - MOD_LINK=elf64alpha -;; - - alphaev67 ) - AC_MSG_RESULT($host_cpu) - KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mno-fp-regs -ffixed-8 -mcpu=ev5 -Wa,-mev6' - KCPPFLAGS='-D__KERNEL__ -DMODULE ' - MOD_LINK=elf64alpha -;; - - alpha* ) - AC_MSG_RESULT($host_cpu) - KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mno-fp-regs -ffixed-8 -mcpu=ev5 -Wa,-mev5' - KCPPFLAGS='-D__KERNEL__ -DMODULE ' - MOD_LINK=elf64alpha -;; - - ia64 ) - AC_MSG_RESULT($host_cpu) - KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -pipe -ffixed-r13 -mfixed-range=f10-f15,f32-f127 -falign-functions=32 -mb-step' - KCPPFLAGS='-D__KERNEL__ -DMODULE' - MOD_LINK=elf64_ia64 -;; - - sparc64 ) - AC_MSG_RESULT($host_cpu) - KCFLAGS='-O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fomit-frame-pointer -fno-strict-aliasing -fno-common -Wno-unused -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow -ffixed-g4 -fcall-used-g5 -fcall-used-g7 -Wno-sign-compare -Wa,--undeclared-regs' - KCPPFLAGS='-D__KERNEL__' - MOD_LINK=elf64_sparc - -;; - - powerpc ) - AC_MSG_RESULT($host_cpu) - KCFLAGS='-O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fomit-frame-pointer -fno-strict-aliasing -fno-common -D__powerpc__ -fsigned-char -msoft-float -pipe -ffixed-r2 -Wno-uninitialized -mmultiple -mstring' - KCPPFLAGS='-D__KERNEL__' - MOD_LINK=elf32ppclinux -;; - - *) - AC_ERROR("Unknown Linux Platform: $host_cpu") -;; -esac - -AC_MSG_CHECKING(for MODVERSIONS) -if egrep -e 'MODVERSIONS.*1' $LINUX/include/linux/autoconf.h >/dev/null 2>&1; -then - MFLAGS="-DMODULE -DMODVERSIONS -include $LINUX/include/linux/modversions.h -DEXPORT_SYMTAB" - AC_MSG_RESULT(yes) -else - MFLAGS= - AC_MSG_RESULT(no) -fi - -AC_MSG_CHECKING(for SMP) -if egrep -e SMP=y $LINUX/.config >/dev/null 2>&1; then - SMPFLAG= - AC_MSG_RESULT(yes) -else - SMPFLAG= - AC_MSG_RESULT(no) -fi - -CFLAGS="$KCFLAGS $MFLAGS" -ARCHCPPFLAGS="$KCPPFLAGS" diff --git a/lustre/autogen.sh b/lustre/autogen.sh deleted file mode 100644 index 9accad4..0000000 --- a/lustre/autogen.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -find . -type d -name .deps | xargs rm -rf -aclocal && -automake --add-missing && -${AUTOCONF:-autoconf} diff --git a/lustre/configure.in b/lustre/configure.in deleted file mode 100644 index c40124e..0000000 --- a/lustre/configure.in +++ /dev/null @@ -1,125 +0,0 @@ -AC_INIT -AC_CANONICAL_SYSTEM - -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -# Automake variables. Steal the version number from lustre.spec.in. -AM_INIT_AUTOMAKE(lustre, builtin([esyscmd], [sed -ne '/^%define version /{ s/.*version //; p; q; }' scripts/lustre.spec.in])) -#AM_MAINTAINER_MODE -AC_PROG_CC -AC_PROG_RANLIB - -# -# Check for required packages - -# this doesn't seem to work on older autoconf -# AC_CHECK_LIB(readline, readline,,) - -AC_ARG_ENABLE(readline, [ --enable-readline use readline library],, - enable_readline="yes") - -if test "$enable_readline" = "yes" ; then - LIBREADLINE="-lreadline -lncurses" - HAVE_LIBREADLINE="-DHAVE_LIBREADLINE=1" -else - LIBREADLINE="" - HAVE_LIBREADLINE="" -fi -AC_SUBST(LIBREADLINE) -AC_SUBST(HAVE_LIBREADLINE) - -# Kernel build environment. -ac_default_prefix= -bindir='${exec_prefix}/usr/bin' -sbindir='${exec_prefix}/usr/sbin' - -linuxdir_def=/usr/src/linux -AC_ARG_WITH(linux, [ --with-linux=[path] set path to Linux source (default=/usr/src/linux)], enable_linuxdir=$withval) -AC_ARG_ENABLE(linuxdir, [ --enable-linuxdir=[path] (deprecated) set path to Linux source (default=/usr/src/linux)],, enable_linuxdir=$linuxdir_def) - -LINUX=$enable_linuxdir -AC_SUBST(LINUX) - -sinclude(archdep.m4) - -AC_MSG_CHECKING(if you are running linux 2.5...) -if test -e $LINUX/include/linux/namei.h ; then - linux25=yes - AC_MSG_RESULT(yes) -else - linux25=no - AC_MSG_RESULT(no) -fi -AM_CONDITIONAL(LINUX25, test x$linux25 = xyes) - -KINCFLAGS='-I. -I$(top_srcdir)/include -I$(PORTALS)/include -I$(LINUX)/include' -CPPFLAGS="$KINCFLAGS $ARCHCPPFLAGS" - -portalsdir_def='$(top_srcdir)/../portals' -AC_ARG_WITH(portals, [ --with-portals=[path] set path to Portals source (default=../portals)], enable_portalsdir=$withval) -AC_ARG_ENABLE(portalsdir, [ --enable-portalsdir=[path] (deprecated) set path to Portals source (default=$(top_srcdir)/../portals)],, enable_portalsdir=$portalsdir_def) -PORTALS=$enable_portalsdir -AC_SUBST(PORTALS) - -portalslib_def=$enable_portalsdir/linux/utils -AC_ARG_WITH(portalslib, [ --with-portalslib=[path] set path to Portals library (default=../portals/linux/utils)], enable_portalslib=$withval) -AC_ARG_ENABLE(portalslib, [ --enable-portalslib=[path] (deprecated) set path to Portals lib (default=../portals/linux/utils)],, enable_portalslib=$portalslib_def) - - -if ! test -z "$enable_portalslib"; then - PORTALSLIB=${enable_portalslib} -fi - - -AC_SUBST(PORTALSLIB) - -AC_MSG_CHECKING(if make dep has been run in kernel source) -if test -f $LINUX/include/linux/config.h ; then - AC_MSG_RESULT(yes) -else - AC_MSG_ERROR(** cannot find $LINUX/include/linux/config.h. Run make dep in $LINUX.) -fi - -AC_MSG_CHECKING(if autoconf.h is in kernel source) -if test -f $LINUX/include/linux/autoconf.h ; then - AC_MSG_RESULT(yes) -else - AC_MSG_ERROR(** cannot find $LINUX/include/linux/autoconf.h. Run make config in $LINUX.) -fi - - -AC_MSG_CHECKING(for Linux release) - -dnl We need to rid ourselves of the nasty [ ] quotes. -changequote(, ) -dnl Get release from version.h -RELEASE="`sed -ne 's/.*UTS_RELEASE[ \"]*\([0-9.a-zA-Z-]*\).*/\1/p' $LINUX/include/linux/version.h`" -changequote([, ]) - -moduledir='$(libdir)/modules/'$RELEASE/kernel -AC_SUBST(moduledir) - -modulefsdir='$(moduledir)/fs/$(PACKAGE)' -AC_SUBST(modulefsdir) - -AC_MSG_RESULT($RELEASE) -AC_SUBST(RELEASE) - -# Directories for documentation and demos. -docdir='${prefix}/usr/share/doc/$(PACKAGE)' -AC_SUBST(docdir) - -demodir='$(docdir)/demo' -AC_SUBST(demodir) - -# not needed until the AC_CHECK_LIB(readline) above works -# AM_CONFIG_HEADER(include/config.h) - -AC_OUTPUT(Makefile lib/Makefile ldlm/Makefile obdecho/Makefile ptlrpc/Makefile \ - lov/Makefile osc/Makefile mdc/Makefile mds/Makefile ost/Makefile \ - utils/Makefile tests/Makefile obdfilter/Makefile obdclass/Makefile \ - llite/Makefile doc/Makefile scripts/Makefile \ - scripts/lustre.spec extN/Makefile) diff --git a/lustre/doc/.cvsignore b/lustre/doc/.cvsignore deleted file mode 100644 index fdf1642..0000000 --- a/lustre/doc/.cvsignore +++ /dev/null @@ -1,23 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -tags -TAGS -OBD-HOWTO.html -OBD-HOWTO.txt -lustre-HOWTO.lyx -lustre-HOWTO.txt -lustre-pdf.bbl -lustre-pdf.blg -lustre-pdf.log -lustre-pdf.out -lustre-pdf.toc -*.eps -lustre.lyx -*.tex -*.pdf -*.aux diff --git a/lustre/doc/Makefile.am b/lustre/doc/Makefile.am deleted file mode 100644 index d261050..0000000 --- a/lustre/doc/Makefile.am +++ /dev/null @@ -1,124 +0,0 @@ -# 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 -LYX2PDF = GS_OPTIONS=-dCompatibilityLevel=1.1 $(srcdir)/tex2pdf -overwrite -TEX2PDF = GS_OPTIONS=-dCompatibilityLevel=1.1 $(srcdir)/tex2pdf -overwrite -LYX2PS = lyx --export ps -LYX2TEX = lyx --export latex -LYX2TXT = lyx --export text -LYX2HTML = lyx --export html -LATEX = latex -DVIPS = dvips -PS2PDF = ps2pdf -TEXEXPAND = texexpand -SUFFIXES = .lin .lyx .pdf .ps .sgml .html .txt .tex .fig .eps .dvi - -DOCS = lustre.pdf lustre-HOWTO.txt -HOWTODOC = lustre-HOWTO.txt -IMAGES := $(patsubst %.fig,%.eps,$(wildcard *.fig)) -LYXFILES= $(filter-out $(patsubst %.lin,%.lyx,$(wildcard *.lin)),\ - $(wildcard *.lin *.lyx)) - -MAINTAINERCLEANFILES = $(IMAGES) $(DOCS) $(VERSIONED) -CLEANFILES = *.aux *.tex doc.old/*.aux doc.old/*.tex *.eps *.log *.pdf -VERSIONED = lustre-HOWTO.lyx lustre.lyx doc.old/lustre-HOWTO.lyx doc.old/lustre.lyx -GENERATED = $(VERSIONED) lustre-full.tex lustre-chbar.tex - -EXTRA_DIST = chbar.sh postbar tex2pdf $(DOCS) $(IMAGES) $(LYXFILES) lustre.bib - -all: $(HOWTODOC) -docs: $(DOCS) - -# These variables are set by lbuild/check-build. -RPMRELEASE ?= RELEASE -KERNTYPE ?= chaos -KERNRPM ?= kernel-2.4.18lustre13-RELEASE.i386.rpm - -# update date and version in document -date := $(shell date +%x) -tag := $(shell echo '$$Name: $$' | sed -e 's/^\$$Na''me: *\$$$$/HEAD/; s/^\$$Na''me: \(.*\) \$$$$/\1/') -addversion = sed -e 's|@T''AG@|$(tag)|g; s|@VER''SION@|$(VERSION)|g; s|@DA''TE@|$(date)|g; s|@RPM''RELEASE@|$(RPMRELEASE)|g; s|@KERN''TYPE@|$(KERNTYPE)|g; s|@KERN''RPM@|$(KERNRPM)|g' - -# Regenerate when the $(VERSION) or $Name: $ changes. -.INTERMEDIATE: $(GENERATED) -$(VERSIONED) : %.lyx: %.lin Makefile - $(addversion) $< > $@ - -.lyx.pdf: - @echo $(LYX2PDF) $< && $(LYX2PDF) $< || printf "\n*** Warning: not creating PDF docs; install lyx to rectify this\n" - -.lyx.ps: - @echo $(LYX2PS) $< && $(LYX2PS) $< || printf "\n*** Warning: not creating PostScript docs; install lyx to rectify this\n" - -.lyx.tex: - @echo $(LYX2TEX) $< && $(LYX2TEX) $< || printf "\n*** Warning: not creating LaTeX docs; install lyx to rectify this\n" - -.lyx.txt: - @echo $(LYX2TXT) $< && $(LYX2TXT) $< || printf "\n*** Warning: not creating text docs; install lyx to rectify this\n" - -.lyx.html: - @echo $(LYX2HTML) $< && $(LYX2HTML) $< || printf "\n*** Warning: not creating HTML docs; install lyx to rectify this\n" - -.tex.pdf: - $(TEX2PDF) $< - -.tex.dvi: - $(LATEX) $< - $(LATEX) $< - -.dvi.ps: - $(DVIPS) $< -o $@ - -.ps.pdf: - $(PS2PDF) $< $@ - -lustre.tex lustre.pdf lustre.txt lustre.html: $(IMAGES) $(LYXFILES) lustre-HOWTO.lyx -.fig.eps: - -fig2dev -L eps $< > $@ - -syncweb: lustre.pdf - cp lustre.pdf /usr/src/www/content/lustre/docs/lustre.pdf - ( cd /usr/src/www ; make lustre ; make synclustre ) -.PHONY: syncweb chbar - -# Build a changebar document from the files in doc.old and this directory. -chbar: lustre-chbar.pdf - -# FIXME: Temporary rules until pdftex displays changebars correctly. -lustre-chbar.pdf: lustre-chbar-nopdf.ps - $(PS2PDF) $< $@ -lustre-chbar-nopdf.ps: lustre-chbar-nopdf.dvi - $(DVIPS) $< -o $@ -lustre-chbar-nopdf.dvi: lustre-chbar-nopdf.tex - $(LATEX) $< - $(LATEX) $< -lustre-chbar-nopdf.tex: lustre-chbar.tex - sed -e 's/^\(.*usepackage.*pdftex\)/%\1/' $< > $@ - -%-chbar.tex: chbar.sh postbar doc.old/%-full.tex %-full.tex - $(SHELL) $(srcdir)/chbar.sh doc.old/$*-full.tex $*-full.tex | $(srcdir)/postbar > $@ - -# This rule needs to come before the next %-full.tex rule. -doc.old/lustre.tex: doc.old/lustre-HOWTO.lyx -doc.old/%-full.tex: doc.old/%.tex - cd doc.old && $(TEXEXPAND) -texinputs=. -output=$*-full.tex $*.tex - -# This rule needs to come after the more specific doc.old rule. -%-full.tex: %.tex - $(TEXEXPAND) -texinputs=. -texinputs=$(srcdir) -output=$@ $< - -# Check out the old directory if it doesn't exist. -doc.old/lustre.lin doc.old/lustre-HOWTO.lin: - @if test "X$(OLD)" = X; then \ - echo "You must populate doc.old or specify a CVS tag like OLD=v0_5_1"; \ - exit 1; \ - fi - rm -rf doc.old - mkdir doc.old - cvs checkout -r $(OLD) -d doc.old lustre/doc - -dist-hook: - rm -rf $(distdir)/figs/CVS - -include $(top_srcdir)/Rules diff --git a/lustre/doc/VERSIONING b/lustre/doc/VERSIONING deleted file mode 100644 index 839c746..0000000 --- a/lustre/doc/VERSIONING +++ /dev/null @@ -1,91 +0,0 @@ -Lustre versioning -================= - -0.0.1 2/19/2002 -0.0.2 3/14/2002 describe branches / stable tag -0.0.3 6/10/2002 describe release mechanisms - -This document describes versioning of source and binaries for Lustre. - -Packages -======== - -RPM's that you build should get 3 figure versions, CVS versions will -be 4 digits, and can correspond to test RPM's, and lead up to the -package version. So let's plan on releasing - -So you'd build 2 sets of test rpms this week: - -0.0.9.1 -0.0.9.2 - -we decide it's fine then and we release - -0.1.0 - -We go on developing with - -0.1.0.{1,2,3,4,...} - -as test releases and then we release: - -0.1.1 - -The 0.1 sequence is an unstable sequence, like 2.5 for the kernel is. -So we expect lots of 0.1.X releases leading up to a stable 0.2 (or -1.0) at the time of deployment. - -CVS -=== - -Versions will have 4 digits: - major.minor.patch.test - -Such versions will be tagged in CVS as: - v1_2_11_7 -and referred to as: - 1.2.11.7 -encoded as: - 0x01021107 - -Usage: ------- - -New numbers are used as follows: - -1. major: - - increased when major new functionality becomes available -2. minor: - - even: for each new release with new functionality - - odd : when a new development cycle starts after a release -3. patch: - - when a development snapshot or release update becomes available - - all these are announced on lustre-devel@lists.sf.net -4. test: - - when developers feel it is time to exchange a named version - -What will run, what won't ? ---------------------------- - -1. If the test level is non-zero, i.e. there are 4 digits in the - version, no guarantees of any kind are made. - -2. For three digit releases/tags the code should perform - according to the announcement. - -Moving tags ------------ - -The last stable release will be tagged: CVS tag "t_last_stable" -The last operational development snapshot will be CVS tag "dstable" - -Branches --------- - -Any and all development must be done on branches, and can only merge to the -HEAD if _at_least_ tests/acceptance-small.sh and IOR with 5 SMP nodes and -2 clients/node with 1GB file/client pass without any errors or cleanup -problems. Additional tests may be added in the future, so the tests in the -current CVS head must pass before a branch can be merged back to the trunk. - -See http://lustre.org/docs/branches.html for details on CVS branch usage. diff --git a/lustre/doc/chbar.sh b/lustre/doc/chbar.sh deleted file mode 100755 index 7825241..0000000 --- a/lustre/doc/chbar.sh +++ /dev/null @@ -1,243 +0,0 @@ -#!/bin/sh -# Gadget to take two LaTeX files and produce a third which -# has changebars highlighting the difference between them. -# -# Version 1.2 -# Author: -# Don Ward, Careful Computing (don@careful.co.uk) -# v1.0 April 1989 -# v1.1 Feb 93 Amended to use changebar.sty (v3.0) and dvips -# v1.2 Aug 95 Added support for LaTeX209/LaTeX2e -# Added RCS support to retrive old files - -CMD=`basename $0` - -SED=sed -RM="rm -f" -DIFF=diff -ED=ed -AWK=awk -GREP=grep -MV=mv -CAT=cat -MKDIR=mkdir -CO="co" - -TMPDIR=${TMP-/tmp}/$CMD.$$ -trap 'test $DEBUG = NO && rm -rf $TMPDIR' 0 1 2 3 6 7 13 15 -mkdir $TMPDIR || { echo "cannot create directory \`$TMPDIR'." >&2; exit 1; } -TMPFILE=${TMPDIR}/$CMD.$$ -SED_CMD_FILE=$TMPFILE.sed - -usage() -{ -$CAT << _END_ -Usage: - $CMD [-hgG] [-d dir] old new [output] - default output is stdout - - $CMD [-hgG] [-d dir] old - new file on stdin, output on stdout - - $CMD [-hgG] -d dir -r rev files - old file retrieved using RCS - - Gadget to take two LaTeX files and produce a third which - has changebars highlighting the difference between them. - Changebars are inserted for differences after '\begin{document}'. - - Feature: \`new' can not be named \`-'. - - Options are: - -d dir : Write the output to file \`dir/new', if \`new' is given or - to file \`dir/old'. - If \`dir' does not exist, it is created. - If \`output' is given, it is discarded. - - -r rev : If the LaTeX \`files' are kept under control of the - Revision Control System RCS, the old files of - the revision \`rev' can be retrived. - \`rev' is specified using the RCS conventions. - This option must be used together with the \`-d dir' option. - \`files' must be a nonempty list of files. - - -h : Print this info text. - -g : Print some debugging info. - -G : Even more debug info. - - Version 1.2: August 3. 1995 -_END_ -exit 1 -} - -# parse options and arguments -DEBUG="NO" -DIR= -REV= -# process options -while getopts d:r:gGh i $* -do - case $i in - d ) DIR=$OPTARG;; - r ) REV=$OPTARG;; - g ) DEBUG="YES" ;; - G ) set -x; DEBUG="YES";; - h | \ - * ) usage ;; - esac -done - -shift `expr $OPTIND - 1` - -case $# in - 1 ) OLD=$1; NEW="-"; OUT="" ;; - 2 ) OLD=$1; NEW=$2; OUT="" ;; - 3 ) OLD=$1; NEW=$2; OUT="$3" ;; - * ) usage ;; -esac - -# check correct options -if [ ! -z "$DIR" ] -then - [ -d $DIR ] || $MKDIR $DIR -fi - -if [ ! -z "$REV" ] -then - [ -z "$DIR" ] && usage - FILES=$* -else - FILES=$NEW -fi - -# do the work -for NEW in $FILES -do - if [ ! -z "$DIR" ] - then - if [ $NEW = "-" ] - then - OUT=$DIR/$OLD - else - OUT=$DIR/$NEW - fi - fi - if [ ! -z "$REV" ] - then - OLD=${TMPFILE}.old - $CO -p"$REV" -q $NEW > $OLD - fi - - [ $DEBUG = "YES" ] && echo "OLD=\`$OLD' NEW=\`$NEW' OUT=\`$OUT'" - - # gather some info about the file - # Since we have for sure only the name of the OLD file, ... - $GREP "^\\\\begin{document}" $OLD > /dev/null - if [ $? -eq 0 ] - then - [ $DEBUG = "YES" ] && echo "contains a \\begin{document}" - HAS_BEGIN_DOC="YES" - else - [ $DEBUG = "YES" ] && echo "contains no \\begin{document}" - HAS_BEGIN_DOC="NO" - fi - - # Method to do the work: - # 1 Use diff to get an ed script to go from file1 to file2. - # 2 Breath on it a bit (with sed) to insert changebar commands. - # 3 Apply modified ed script to produce (nearly) the output. - # 4 Use awk to insert the changebars option into the \documentstyle - # and to handle changebar commands inside verbatim environments. - # 5 Remove changebars before \begin{document} with sed - - # SED commands to edit ED commands to edit old file - $CAT > $SED_CMD_FILE <<\_END_ -/^\.$/i\ -\\cbend{}% -/^[0-9][0-9]*[ac]$/a\ -\\cbstart{}% -/^[0-9][0-9]*,[0-9][0-9]*[ac]$/a\ -\\cbstart{}% -/^[0-9][0-9]*d$/a\ -i\ -\\cbdelete{}%\ -. -/^[0-9][0-9]*,[0-9][0-9]*d$/a\ -i\ -\\cbdelete{}%\ -. -_END_ - - # note DIFF accepts `-' as stdin - $DIFF -b -e $OLD $NEW | \ - ( $SED -f $SED_CMD_FILE ; echo w ${TMPFILE}.1 ; echo q ) | \ - $ED - $OLD - - # AWK commands to insert Changebars style and to protect - # changebar commands in verbatim environments - # and to tell what driver is in use; we assume the `dvips' driver - - $AWK ' - BEGIN {kind=""; # we saw now \documentXXX[]{} - } - /^\\documentstyle/{ - kind = "209"; - if (index($0, "changebar") == 0 ) { - opts = index($0, "[") - if (opts > 0) - printf "%schangebar,%s\n",substr($0,1,opts),substr($0,opts+1) - else - printf "\\documentstyle[changebar]%s\n", substr($0,15) - next - } - } - /^\\documentclass/{ - kind = "2e"; - printf "%s\n", $0 - printf "\\usepackage[dvips]{changebar}\n" - next - } - /\\begin{document}/ {if (kind == "209" ) {print "\\driver{dvips}"}} - /\\begin{verbatim}/{++nesting} - /\\end{verbatim}/{--nesting} - /\\cbstart{}%|\\cbend{}%|\cbdelete{}%/ { - if ( nesting > 0) { - # changebar command in a verbatim environment: Temporarily exit, - # do the changebar command and reenter. - # - # The obvious ( printf "\\end{verbatim}%s\\begin{verbatim} , $0 ) - # leaves too much vertical space around the changed line(s). - # The following magic seeems to work - # - print "\\end{verbatim}\\nointerlineskip" - print "\\vskip -\\ht\\strutbox\\vskip -\\ht\\strutbox" - printf "\\vbox to 0pt{\\vskip \\ht\\strutbox%s\\vss}\n", $0 - print "\\begin{verbatim}" - next - } - } - { print $0 } - ' ${TMPFILE}.1 > ${TMPFILE}.2 - - # if a \begin{document} is contained in the file, - # remove the changebar commands before them - - if [ $HAS_BEGIN_DOC = "YES" ] - then - SED_CMD="1,/\\\\begin{document}/s/\(\\\\cb[sed][tne][adl][^{}]*{}%\)$/%%\1/" - $SED "$SED_CMD" ${TMPFILE}.2 > ${TMPFILE}.3 - else - $CAT ${TMPFILE}.2 > ${TMPFILE}.3 - fi - if [ -z "$OUT" ] - then - $CAT ${TMPFILE}.3 - else - $MV ${TMPFILE}.3 $OUT - fi - -done - -[ $DEBUG = "NO" ] && $RM ${TMPFILE}.* - -############################################################### diff --git a/lustre/doc/lconf.lyx b/lustre/doc/lconf.lyx deleted file mode 100644 index 0095c6f..0000000 --- a/lustre/doc/lconf.lyx +++ /dev/null @@ -1,133 +0,0 @@ -#LyX 1.2 created this file. For more info see http://www.lyx.org/ -\lyxformat 220 -\textclass amsart -\language english -\inputencoding auto -\fontscheme times -\graphics default -\paperfontsize default -\spacing single -\papersize letterpaper -\paperpackage a4 -\use_geometry 0 -\use_amsmath 0 -\use_natbib 0 -\use_numerical_citations 0 -\paperorientation portrait -\secnumdepth 3 -\tocdepth 3 -\paragraph_separation skip -\defskip medskip -\quotes_language english -\quotes_times 2 -\papercolumns 1 -\papersides 1 -\paperpagestyle default - -\layout Section - -lconf -\layout Subsection - -NAME -\layout Standard - -lconf- Lustre file system configuration utility -\layout Subsection - -SYNOPSIS -\layout Standard - - -\series bold -lconf\SpecialChar ~ -[--node ] [-d,--cleanup] [--noexec] [--gdb] [--nosetup] - [--nomod] [-n,--noexec] [-v,--verbose] [-h,--help] -\layout Subsection - -DESCRIPTION -\layout Standard - -This program configures a node following directives in the -\layout Description - ---node\SpecialChar ~ -node_name Specifiy a specific node to configure. - By default, LCONF will search for nodes with the local hostname and 'localhost'. - When --node is used, only node_name is searched for. - If a matching node is not found in the config, then LCONF exits with an - error. -\layout Description - ---cleanup Unconfigure a node. - The same config and --node argument used for configuration needs to be - used for cleanup as well. - This will attempt to undo all of the configuration steps done by LCONF, - including unloading the kernel modules. -\layout Description - ---noexec Print, but don't execute, the steps lconf will perform. - This is useful for debugging a configuration, and when used with --node, - can be run on any host. -\layout Description - ---gdb Causes LCONF to print a message and pause for 5 seconds after creating - a gdb module script and before doing any lustre configuration. - (The gdb module script is always created, however.) -\layout Description - ---nosetup Only load modules, do not configure devices or services -\layout Description - ---nomod Only setup devices and services, do not load modules -\layout Description - ---noexec,-n Don't do anything, but print what would happen. -\layout Description - ---verbose,-v Be verbose and show actions while going along -\layout Description - --h,--help Print help. -\layout Description - ---maxlevel\SpecialChar ~ - [NOT IMPLEMENTED] Perform configuration of devices and - services up to level given. - -\emph on -level -\emph default - can take the values -\series bold -net, dev, svc, fs. - -\series default -When used in conjunction with cleanup services are torn down up to a certain - level. -\layout Subsection - -EXAMPLES -\layout Standard - -On client nodes this is typically invoked as -\layout LyX-Code - -lconf --node client config.xml -\layout Standard - -in order to give clients, regardless of hostname a single configuration. -\layout Subsection - -BUGS -\layout Standard - -None are known. -\layout Subsection - -AUTHOR -\layout Standard - -Cluster File Systems, Inc. - 2002 - created -\the_end diff --git a/lustre/doc/lctl.lyx b/lustre/doc/lctl.lyx deleted file mode 100644 index 154b646..0000000 --- a/lustre/doc/lctl.lyx +++ /dev/null @@ -1,540 +0,0 @@ -#LyX 1.2 created this file. For more info see http://www.lyx.org/ -\lyxformat 220 -\textclass amsart-plain -\language english -\inputencoding auto -\fontscheme times -\graphics default -\paperfontsize default -\spacing single -\papersize letterpaper -\paperpackage a4 -\use_geometry 0 -\use_amsmath 0 -\use_natbib 0 -\use_numerical_citations 0 -\paperorientation portrait -\secnumdepth 3 -\tocdepth 3 -\paragraph_separation skip -\defskip medskip -\quotes_language english -\quotes_times 2 -\papercolumns 1 -\papersides 1 -\paperpagestyle default - -\layout Section - -LCTL -\layout Subsection - -NAME -\layout Standard - -lctl - low level Lustre file system configuration utility -\layout Subsection - -SYNOPSIS -\layout Standard - - -\series bold -lctl -\layout Standard - - -\series bold -lctl\SpecialChar ~ ---device\SpecialChar ~ - -\layout Standard - - -\series bold -lctl\SpecialChar ~ ---threads\SpecialChar ~ -\SpecialChar ~ -\SpecialChar ~ -\SpecialChar ~ - -\layout Subsection - -DESCRIPTION -\layout Standard - -The program can be invoked in interactive mode by issuing -\series bold -lctl. - -\series default - After that commands are issued as below. - The most common commands in lctl are (in matching pairs) -\family typewriter -device -\family default -, -\family typewriter -attach -\family default - and -\family typewriter -detach -\family default -, -\family typewriter -setup -\family default - and -\family typewriter -cleanup -\family default -, -\family typewriter -connect -\family default - and -\family typewriter -disconnect -\family default -, -\family typewriter -help -\family default -, and -\family typewriter -quit -\family default -. - To get a complete listing of available commands, type -\family typewriter -help -\family default - at the lctl prompt. - To get basic help on the meaning and syntax of a command, type -\family typewriter -help command -\family default -. - Command completion is activated with the -\family typewriter -TAB -\family default - key, and command history is available via the up- and down-arrow keys. - -\layout Standard - -For non-interactive single threaded use, one uses the second invocation - which runs -\emph on -command -\emph default - after connecting to the -\emph on -device. - -\emph default - -\layout Description - ---device The device number to be used for the operation. - The value of devno is an integer, normally found by calling -\emph on -lctl name2dev -\emph default -on a device name. - -\layout Description - ---threads How many threads should be forked doing the command specified. - The numthreads variable is a strictly positivie integer indicating how - many threads should be started. - Verbose can take values , -\emph on -devno -\emph default -is used as above. -\layout LyX-Code - -\layout LyX-Code - -\layout Description - -network\SpecialChar ~ -config -\begin_deeper -\layout Description - -network\SpecialChar ~ - Indicate what kind of network applies for the - configuration commands that follow -\layout Description - -connect\SpecialChar ~ -[[\SpecialChar ~ -]\SpecialChar ~ -|\SpecialChar ~ -] This will establish a connection to - a remote network network id given by the hostname/port combination or the - elan id -\layout Description - -disconnect\SpecialChar ~ - Disconnect from a remote nid -\layout Description - -mynid\SpecialChar ~ -[nid] Informs the socknal of the local nid. - It defaults to hostname for tcp networks and is automatically setup for - elan/myrinet networks -\layout Description - -add_uuid\SpecialChar ~ -\SpecialChar ~ - Associate a given UUID with an -\emph on -nid -\emph default - -\layout Description - -close_uuid\SpecialChar ~ - Disconnect a UUID -\layout Description - -del_uuid\SpecialChar ~ - Delete a UUID association -\layout Description - -add_route\SpecialChar ~ -\SpecialChar ~ -\SpecialChar ~ -[target] Add an entry to the routing table for - the given target -\layout Description - -del_route\SpecialChar ~ - Delete an entry for the target from the routing table -\layout Description - -route_list Print the complete routing table -\layout Description - -recv_mem\SpecialChar ~ -[size] Set the socket receive buffer size, if the size is omited - the default size for the buffer is printed -\layout Description - -send_mem\SpecialChar ~ -[size] Set send buffer size for the socket, if size is omited the - default size for the buffer is printed -\layout Description - -nagle\SpecialChar ~ -[on/off] Enable/disable nagle, omiting the arguement will cause the - default value to be printed -\end_deeper -\layout Description - -device\SpecialChar ~ -selection -\begin_deeper -\layout Description - -newdev Create a new device -\layout Description - -name2dev This command can be used to determine a device number for the given - device name. -\layout Description - -device This will select the specified OBD device. - All other commands depend on the device being set. - -\layout Description - -device_list Show all the devices -\end_deeper -\layout Description - -device\SpecialChar ~ -config -\begin_deeper -\layout Description - -attach\SpecialChar ~ -type\SpecialChar ~ -[name\SpecialChar ~ -[uuid]] -\shape italic -Attach -\shape default - a type to the current device (which you need to set using the -\family typewriter -device -\family default - command) and give that device a name and UUID. - This allows us to identify the device for use later, and also tells us - what type of device we will have. -\layout Description - -setup\SpecialChar ~ - Type specific device setup commands. - For obdfilter a setup command tells the driver which block device it should - use for storage and what type of filesystem is on that device. - -\layout Description - -cleanup Cleanup a previously setup device -\layout Description - -detach Remove driver (and name and uuid) from the current device -\layout Description - -lov_setconfig\SpecialChar ~ -lov-uuid\SpecialChar ~ -default-stripe-count\SpecialChar ~ -default-stripe-size\SpecialChar ~ -offset\SpecialChar ~ -pattern\SpecialChar ~ -UUID1\SpecialChar ~ -[U -UID2...] Write LOV configuration to an MDS device -\layout Description - -lov_getconfig\SpecialChar ~ -lov-uuid Read LOV configuration from an MDS device. - Returns default-stripe-count, default-stripe-size, offset, pattern, and - a list of OST UUIDs. -\end_deeper -\layout Description - -device\SpecialChar ~ -operations -\begin_deeper -\layout Description - -probe\SpecialChar ~ -[timeout] Build a connection handle to a device. - This command is used to suspend configuration till the lctl command has - ensured that the mds and osc services are available. - This is to avoid mount failures in a reebooting cluster -\layout Description - -close -\layout Description - -getattr\SpecialChar ~ - Get attributes for an OST object -\layout Description - -setattr\SpecialChar ~ -\SpecialChar ~ - Set mode attribute for OST object -\layout Description - -create\SpecialChar ~ -[num\SpecialChar ~ -[mode\SpecialChar ~ -[verbose]]] Create the specified number of OST objects - with the given -\layout Description - -destroy\SpecialChar ~ - Destroy an OST object -\layout Description - -test_getattr\SpecialChar ~ -\SpecialChar ~ -[verbose\SpecialChar ~ -[[t]objid]] Do getattrs on OST object - (objectid+1 on each thread) -\layout Description - -test_brw\SpecialChar ~ -[t]\SpecialChar ~ -[write\SpecialChar ~ -[verbose\SpecialChar ~ -[npages\SpecialChar ~ -[[t]objid]]]] Do bulk read/writes - on OST object ( per I/O) -\layout Description - -test_ldlm Perform lock manager test -\layout Description - -ldlm_regress_start\SpecialChar ~ -%s\SpecialChar ~ -[numthreads\SpecialChar ~ -[refheld\SpecialChar ~ -[numres\SpecialChar ~ -[numext]]]] Start lock manager - stress test -\layout Description - -ldlm_regress_stop Stop lock manager stress test -\layout Description - -dump_ldlm Dump all lock manager state, this is very useful for debugging -\layout Description - -newconn\SpecialChar ~ -\SpecialChar ~ -[newuuid] -\end_deeper -\layout Description - -debug -\begin_deeper -\layout Description - -debug_kernel\SpecialChar ~ -[file]\SpecialChar ~ -[raw] Get debug buffer and dump to a fileusage -\layout Description - -debug_file\SpecialChar ~ -\SpecialChar ~ -[output]\SpecialChar ~ -[raw] Read debug buffer from input and dump to - outputusage -\layout Description - -clear Clear kernel debug buffer -\layout Description - -mark\SpecialChar ~ - Insert marker text in kernel debug buffer -\layout Description - -filter\SpecialChar ~ - Filter message type from the kernel debug - buffer -\layout Description - -show\SpecialChar ~ - Show specific type of messages -\layout Description - -debug_list\SpecialChar ~ - List all the subsystem and debug types -\layout Description - -panic Force the kernel to panic -\end_deeper -\layout Description - -control -\begin_deeper -\layout Description - -help Show a complete list of commands, help can be used to - get help on specific command -\layout Description - -exit Close the lctl session -\layout Description - -quit Close the lctl session -\end_deeper -\layout Subsection - -EXAMPLES -\layout Description - -attach -\layout LyX-Code - -# lctl -\newline -lctl > newdev -\newline -lctl > attach obdfilter OBDDEV OBDUUID -\layout Description - -connect -\layout LyX-Code - -lctl > name2dev OSCDEV -\newline -2 -\newline -lctl > device 2 -\newline -lctl > connect -\newline - -\layout Description - -getattr -\layout LyX-Code - -lctl > getattr 12 -\newline -id: 12 -\newline -grp: 0 -\newline -atime: 1002663714 -\newline -mtime: 1002663535 -\newline -ctime: 1002663535 -\newline -size: 10 -\newline -blocks: 8 -\newline -blksize: 4096 -\newline -mode: 100644 -\newline -uid: 0 -\newline -gid: 0 -\newline -flags: 0 -\newline -obdflags: 0 -\newline -nlink: 1 -\newline -valid: ffffffff -\newline -inline: -\newline -obdmd: -\newline -lctl > disconnect -\newline -Finished (success) -\layout Description - -setup -\layout LyX-Code - -lctl > setup /dev/loop0 extN -\newline -lctl > quit -\layout LyX-Code - -\layout Subsection - -BUGS -\layout Standard - -None are known. -\layout Subsection - -AUTHOR -\layout Standard - -Cluster File Systems, Inc. - 2002 - created -\the_end diff --git a/lustre/doc/lmc.lyx b/lustre/doc/lmc.lyx deleted file mode 100644 index 39e602f..0000000 --- a/lustre/doc/lmc.lyx +++ /dev/null @@ -1,310 +0,0 @@ -#LyX 1.2 created this file. For more info see http://www.lyx.org/ -\lyxformat 220 -\textclass amsart -\language english -\inputencoding auto -\fontscheme times -\graphics default -\paperfontsize default -\spacing single -\papersize letterpaper -\paperpackage a4 -\use_geometry 0 -\use_amsmath 0 -\use_natbib 0 -\use_numerical_citations 0 -\paperorientation portrait -\secnumdepth 3 -\tocdepth 3 -\paragraph_separation skip -\defskip medskip -\quotes_language english -\quotes_times 2 -\papercolumns 1 -\papersides 1 -\paperpagestyle default - -\layout Section - -lmc -\layout Subsection - -NAME -\layout Standard - -lmc - lustre configuration maker. -\layout Subsection - -SYNOPSIS -\layout Standard - - -\series bold -lmc [options] --add [args] -\layout Standard - - -\series bold -NOT IMPLEMENTED -- lmc [options] --remove [args] -\layout Standard - - -\series bold -NOT IMPLEMENTED -- lmc [options] --convert [args] -\layout Subsection - -DESCRIPTION -\layout Standard - -At present lmc when invoked adds configuration data to the config file. - lmc will also be able to remove configuration data or convert its forma. - One generates a single config file for the cluster at present including - at the minimum mds's, mtpt's and ost's and whatever those reference (e.g. - net's and profiles) -\layout Standard - -The objecttype refers to a collection of related configuration entities - and can be one of -\series bold -net, mds, lov, ost, mtpt, route, oscref. - -\series default -We describe the arguments required for the addition of each objecttype. - [NOT implemented] Lmc can also remove items from or convert the format - of configuration data. -\layout Standard - -to generate configuration data associated with systems in a Lustre cluster. - -\layout Description - ---add\SpecialChar ~ -net Adds a network device descriptor for the given node, with parameters - as indicated. -\begin_deeper -\layout Standard - -The arguments required are -\layout Description - ---node\SpecialChar ~ -''node_name'' If not present this will create a new node with the - given name. - This is also used to specify a specific node for other elements, and the -\layout Description - ---nettype\SpecialChar ~ - this can be -\series bold -tcp, elan, gm -\layout Description - ---nid\SpecialChar ~ -nid the network id, e.g. - ElanID or IP address as used by portals. - If host_name is '*', then the local address while be substituted when the - node is configured with lconf. -\layout Description - ---router optional flag to mark this node as a router -\layout Description - ---profile optional flag to mark this node as a profile node. - This is automatically true if the the --nid argument contains a '*'. -\layout Description - ---port\SpecialChar ~ -[port] optional argument to indicate the tcp port. - The default is 988. - -\layout Description - ---tcpbuf\SpecialChar ~ - optional argument -\end_deeper -\layout Description - ---add\SpecialChar ~ -mds -\begin_deeper -\layout Description - ---mds\SpecialChar ~ - -\layout Description - ---device\SpecialChar ~ - -\layout Description - ---size\SpecialChar ~ - optional argument indicating the size of the device to be created - (used typically for loop devices). -\layout Description - ---node\SpecialChar ~ - Adds an MDS to the specified node. - This requires a --node argument, and it must not be a profile node. -\end_deeper -\layout Description - ---add\SpecialChar ~ -lov Creates an LOV with the specified parameters. - The mds_name must already exist in the descriptor. -\begin_deeper -\layout Description - ---lov_ -\layout Description - ---mds_ -\layout Description - ---stripesize\SpecialChar ~ - -\layout Description - ---stripecount\SpecialChar ~ - -\layout Description - ---pattern\SpecialChar ~ - Pattern can be 0. -\end_deeper -\layout Description - ---add\SpecialChar ~ -ost Creates an OBD, OST, and OSC. - The OST and OBD are created on the specified node. -\begin_deeper -\layout Description - ---ost\SpecialChar ~ - [NOT IMPLEMENTED] Name to give to this OST target. -\layout Description - ---node\SpecialChar ~ - Node on which the OST service is run, can not be a profile - node. -\layout Description - ---device\SpecialChar ~ - -\layout Description - ---size\SpecialChar ~ -[size] -\layout Description - ---lov\SpecialChar ~ - Name of LOV to which this OSC will be attached. - -\layout Description - ---obduuid\SpecialChar ~ -UUID specify the UUID of the OBD device. - The default value is OBD_nodename_UUID. -\end_deeper -\layout Description - ---add\SpecialChar ~ -mtpt Creates a mount point on the specified node. - Either an LOV or OSC name can be used. -\begin_deeper -\layout Description - ---node\SpecialChar ~ -node node or profile node that will use the mtpt -\layout Description - ---path\SpecialChar ~ -/mnt/path\SpecialChar ~ - -\layout Description - ---mds\SpecialChar ~ -mds_name -\layout Description - ---mdc\SpecialChar ~ -lov_name|osc_name -\end_deeper -\layout Description - ---add\SpecialChar ~ -route Creates a static route through a gateway to a specific nid or - a range of nids. -\begin_deeper -\layout Description - ---node\SpecialChar ~ -node node or profile node to add the route to -\layout Description - ---gw\SpecialChar ~ -nid the nid of the gateway (must be a local interface or a peer) -\layout Description - ---tgt\SpecialChar ~ -nid for a specific route, this is the target nid -\layout Description - ---lo\SpecialChar ~ -nid for a range route, this is the lo value nid -\layout Description - ---hi\SpecialChar ~ -nid for a range route, this is the hi value nid -\end_deeper -\layout Description - ---add\SpecialChar ~ -oscref Adds an OSC reference to a node. - This is only necessary when the the OSC will be used without a mountpoint. -\begin_deeper -\layout Description - ---node\SpecialChar ~ -node node or profile node to add the OSC ref to -\layout Description - ---osc\SpecialChar ~ -osc_name Name of the OSC to add a reference to. - The --add ost command automatically creates the OSC, and the name will - be OSC_, where node is the name of node the OST is on. -\end_deeper -\layout Description - -Options: -\begin_deeper -\layout Description - ---output\SpecialChar ~ -filename Sends output to the file. - If the file exists, it will be overwritten. -\layout Description - ---merge\SpecialChar ~ -filename Add the new element to an existing file. - -\end_deeper -\layout Subsection - -EXAMPLES -\layout Standard - -Real life examples are given in the lustre-conf man page. -\layout Subsection - -BUGS -\layout Standard - -None are known. -\layout Subsection - -AUTHOR -\layout Standard - -Cluster File Systems, Inc. - 2002 - created -\the_end diff --git a/lustre/doc/postbar b/lustre/doc/postbar deleted file mode 100755 index 349d41c..0000000 --- a/lustre/doc/postbar +++ /dev/null @@ -1,151 +0,0 @@ -#! /usr/bin/perl -# postbar - Massage chbar.sh output into valid LaTeX -# Copyright (C) 2002 Cluster File Systems, Inc. -# Gord Eagle , 2002-08-10 - -my $progname = $0; -$progname =~ s|^.*/||; -my $CHANGE_ENVIRONMENT = '\\\\(begin|end)\\{([^\\}]+)\\}'; -my (@envname, @envdepth, @envbuf); -my $phony_preamble = 0; -my $cbdepth = 0; -my $cbfound = 0; - -# Tell whether an environment cannot have arbitrary changebars. -sub fragile_environment -{ - my ($env) = @_; - return $env ne 'document'; -} - - -# Tell whether we can hava arbitrary stuff. -sub toplevel -{ - my ($env) = @_; - return $env eq 'document'; -} - - -sub out -{ - my (@msg) = @_; - if ($#envbuf < 0 || toplevel($envname[0])) { - print @msg; - } else { - $envbuf[0] .= join('', @msg); - } -} - - -# Leave an environment. -sub end_environment -{ - my ($env) = @_; - - #out("%$progname end $env\n"); - if ($envname[0] ne $env) { - die "Expecting \\end{$envname[0]} but got \\end{$env}\n"; - } - - if ($cbfound) { - # Did we find a changebar? - $cbfound = !toplevel($envname[1]); - if (!$cbfound) { - # We found one, and the parent environment is the top level. - if ($cbdepth == $envdepth[0]) { - # There was no change in depth, so mark the environment. - $envbuf[0] = "\\cbstart{}%$progname\n" . $envbuf[0]; - out("\\cbend{}%$progname\n"); - } elsif ($envdepth[0] > $cbdepth) { - # There were more ends in the environment, so append them. - for (my $i = 0; $i < $envdepth[0] - $cbdepth; $i ++) { - out("\\cbend{}%$progname\n"); - } - } else { - # There were more starts, so prepend them. - my $starts; - for (my $i = 0; $i < $cbdepth - $envdepth[0]; $i ++) { - $starts .= "\\cbstart{}%$progname\n"; - } - $envbuf[0] = $starts . $envbuf[0]; - } - } - } - - # Drop the environment from the list. - shift(@envname); - shift(@envdepth); - out(shift(@envbuf)); -} - - -while ($_ = ) { - chomp; - my $env; - if (!/\\begin.*\\end/ && /$CHANGE_ENVIRONMENT/o) { - $env = $2; - if ($1 eq 'begin') { - # Enter the new environment. - unshift(@envname, $env); - unshift(@envdepth, $cbdepth); - unshift(@envbuf, ''); - #out("%$progname depth=$cbdepth, $#envname ($env)\n"); - } elsif (!$phony_preamble) { - out("$_\n"); - end_environment($env); - next; - } - } - - if ($#envname >= 0 && /^\\documentclass/) { - $phony_preamble = 1; - } - - if ($phony_preamble) { - # Comment out and ignore the redundant preambles. - out("%$progname $_\n"); - $phony_preamble = 0 if ($env eq 'document'); - next; - } elsif ($#envname >= 0) { - # Track the current changebar depth. - if (/^\\cbstart/) { - $cbdepth ++; - if (!toplevel($envname[0])) { - $cbfound = 1; - out("%$progname $_\n"); - next; - } - } elsif (/^\\cbend/) { - if ($cbdepth == 0) { - die "$progname: Too many \\cbend{}s\n"; - } - $cbdepth --; - if (!toplevel($envname[0])) { - $cbfound = 1; - out("%$progname $_\n"); - next; - } - } elsif (/^\\cbdelete/ && fragile_environment($envname[0])) { - # What to do with delete bars? - out("%$progname $_\n"); - next; - } - out("$_\n"); - } else { - out("$_\n"); - # Add the options to the usepackage. - if (/^\\usepackage.*\{changebar\}$/) { - # Prevent PostScript dictionary overflow errors. - out("\\def\\cb\@maxpoint{15}\n"); - - # Show the bars. - out("\\outerbarstrue\n"); - } - } - - if (defined($env)) { - } -} - -exit(0); diff --git a/lustre/doc/tex2pdf b/lustre/doc/tex2pdf deleted file mode 100755 index d9a7176..0000000 --- a/lustre/doc/tex2pdf +++ /dev/null @@ -1,3043 +0,0 @@ -#!/usr/bin/perl -w - -# tex2pdf - script for translating latex docs to pdf -# -# Copyright (C) 2000-2002 by Steffen Evers and others -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -# The GNU General Public License is also available online: -# http://www.gnu.org/licenses/gpl.html -# -# Thanks a lot to all the people that have already contributed to this project! -# -# The changelog including the credits has become too long. So, I have removed it -# from the script, but it is still available online (see below). -# -# Special thanks to the following people for their contribution -# (see the changelog for details): -# Matej Cepl, Herbert Voss, Nicolas Marsgui, Bruce Foster, Mark van Rossum, -# Matt Bandy, Garrick Chien Welsh, Stacy J. Prowell, Pavel Sedivy, -# Holger Daszler, Olaf Gabler, Ahmet Sekercioglui, Richard, Steffen Macke, -# Rainer Dorsch & friends, Jean-Pierre Chretien, Fernando Perez, -# Ha Duong Minh, Oscar Lopez -# -# Project Homepage: http://tex2pdf.berlios.de -# Developer Homepage: http://developer.berlios.de/projects/tex2pdf -# Mailing lists: http://developer.berlios.de/mail/?group_id=57 -# Changelog: http://tex2pdf.berlios.de/changelog.html -# -# Anyone is invited to help to improve tex2pdf. Therefore any kind of feedback -# is welcome. Maybe you even would like to hack the code and send us your -# changes. This would help a lot and is highly appreciated. Think about it :-) -# Subscribing to the developer mailing list might be a first step (see above). -# -# Send feedback to: tex2pdf-devel@lists.berlios.de -# - -######## Imports - -use File::Basename; -use File::Copy; -use Getopt::Long; -use Sys::Hostname; -use Cwd; -use strict; - -####### global variables - -my $MYRELEASE="3.0.21"; -my $MYHOSTNAME=hostname; -my $MYNAME=basename $0; -my $MYUSER=$ENV{'USER'}; -my $USER_HOME=$ENV{'HOME'}; -if (not $MYUSER) { $MYUSER = 'nobody'; } -if (not $USER_HOME) { $USER_HOME = '/tmp'; } - -my @TMPFILES=(); -my @TMP_TEX_FILES=(); -my $NUM_PARAM_MIN=0; -my $NUM_PARAM_MAX=9; -my @REF_DOCS; -my $MTP_PREAMBLE_FILENAME="preamble.cfg"; -my $MTP_TMP_BASESUFFIX="-mp"; -my @EPS_SUFFIXES=('eps','ps','ps.gz','eps.gz' ); -my $PDF_ORIG_SUFFIX='pdf.orig'; -my @BITMAP_SUFFIXES=( 'jpg', 'png', 'tif' ); - -# (initial) log file of this script -# this log file will be moved to the specified log_dir after configuration -# and the variable will be updated to the new name -my $MYLOGFILE="$USER_HOME/tex2pdf-$$.log"; -my $LOGFILE_VERBOSITY=9; - -### text token for no value -my $NIL="NOVALUE"; -my $UNDEF="undefined"; - -### token for boolean 'false', 'no' -my $NO="no"; -my $FALSE=0; - -### token for boolean 'true', 'yes' -my $YES="yes"; -my $TRUE=1; - -### file to store private parameters -# If you only want to change your private parameters change them there -# default: $HOME/.tex2pdf3rc -my $RC_FILENAME="$USER_HOME/.tex2pdf3rc"; -my $MYRCFILE_VERSION=7; -my $RCVERSION_STRING="rcfile_version"; - -## set global variable configured to prevent access to configuration -# parameters before configuration process is finished -my $CONFIGURED=$FALSE; -my $PRE_CONFIG_VERBOSITY=4; - -########################## NEW PERL CONFIGURATON - -my %CONFIGURATION = (); -my %PARAMETER_LIST = (); -my @PARAMETER_ORDER = (); -my %PARAMETER_TYPES = (); - -## Array index for the various information in each parameter specifcation -## referenced by %PARAMETER_LIST -my $TYPE=0; -my $OPT_ALIAS=1; -my $OPT_SPEC=2; -my $DEF_VALUE=3; -my $DESCRIPTION=4; -my $QUESTION=5; -my $EXPLANATION=6; - -&add_param_type('paper', - [ ['a4paper' , 'a4 paper' ], - [ 'letterpaper', 'letter paper' ], - [ 'legalpaper', 'legal paper' ], - [ 'executivepaper', 'executive paper' ], - [ $NIL, 'do not set value - leave it to hyperref' ] - ] ); - -&add_param_type('color', - [ [ 'yellow', 'LaTeX color yellow' ], - [ 'red', 'LaTeX color red' ], - [ 'green', 'LaTeX color green' ], - [ 'cyan', 'LaTeX color cyan' ], - [ 'blue', 'LaTeX color blue' ], - [ 'magenta', 'LaTeX color magenta' ], - [ 'black', 'LaTeX color black' ], - [ $NIL , 'do not set this value - leave it to hyperref' ] - ] ); - -&add_param_type('destination', - [ [ 'source', 'directory of the LaTeX source document' ] , - [ 'input', 'root directory of referenced material' ], - [ 'custom', 'custom directory as specified' ] - ] ); - -### Option parameters: these parameters have no default value and can not -# be configured interactively, but only as a command line option -# an option parameter is not allowed to have a default value, question or -# explanation -# and all parameter of type action are treated as option parameters -# $key, $type, $def_value, $opt_alias, $opt_spec, $description, $question, $explanation - -&add_param('help', 'action', undef, '|h', '', - 'print a short help text and exit'); - -&add_param('version', 'action', undef, '|v', '', - 'print the version of this script and exit'); - -&add_param('print_config', 'action', undef, '|o', '', - 'print the current configuration and exit'); - -&add_param('configure', 'action', undef, '|c', '', - 'configure all parameters interactivly, store them and exit'); - -&add_param('title', 'text', undef, '|t', '=s', - 'set PDF info title for specified document'); - -&add_param('author', 'text', undef, '|a', '=s', - 'set PDF info author for specified document'); - -&add_param('input_path', 'directory', undef, '', '=s', - 'set path for referenced material in main document'); - -### Full parameters -# parameter type action is not allowed -# $key, $type, $def_value, $opt_alias, $opt_spec, $description, $question, $explanation - -&add_param('logdir', 'directory',"$USER_HOME/tex2pdf-log/", '', '=s', - 'set directory for saving log files', - 'What log directory should be used?', - "The log directory is used to store information about the generation\n" - ."process for later review, e.g. for debugging."); - -&add_param('lyxrc_path', 'directory', "$USER_HOME/.lyx/", '', '=s', - 'set the configuration directory of LyX', - 'What is the directory for your LyX configuration data?', - "If I have to generate a LateX file from a LyX file I need to clear two " - ."temporary\nfiles in your LyX configuration directory. They will " - ."be backuped and normally\ndo not contain any valuable data anyway. If " - ."you do not use LyX, simply leave\nthe default."); - -&add_param('lyx_exec', 'text', "lyx", '', '=s', - 'specify the LyX executable for converting lyx to latex', - 'Which executable should I use for converting LyX docs to LaTeX?', - "I use LyX to generate a LateX file from a LyX file. As you might use\n" - ."several versions of LyX at the same time or do not have it in your path" - ."\nyou can give me the apropriate executable here (e.g. '/usr/bin/lyx')." - ."\nIn most cases the default 'lyx' should be fine."); - -&add_param('debug', 'bool', $NO, '', '!', -'do not delete temporary files after execution and be as verbose as possible', - 'Do you want to debug this script?', - "I will not remove any temporary files. This could cause problems on a " - ."second\nexecution as I might refuse to overwrite these files for security " - ."reasons.\nYou have to remove them manually in this case. Additionally, I " - ."will provide\nas much information during execution as possible."); - -&add_param('delete_pdf_images', 'bool', $NO, '', '!', - 'delete generated PDF image files after execution', - 'Should generated PDF image files be deleted after execution?', - "Pdflatex cannot handle EPS images. Therefore all such images need to be\n" - ."translated to PDF in advance. After a successful generation of the final " - ."PDF \ndocument or after encountering an error I could leave this PDF " - ."images for\n later executions or simply delete them."); - -&add_param('clean_on_abort', 'bool', $YES, '', '!', - 'also delete temporary files after abort', - 'Should temporary files be deleted when aborting?', - "When the generation of the PDF file fails for some reason you might still " - ."want\nto keep already generated temporary files for some reason, e.g. " - ."debugging.\nIf you do not want to keep them set this parameter to 'yes'."); - -&add_param('tmp_base_suffix', 'text', '-pdf', '', '=s', - 'specify the extension of the basename for temporary TeX files', - 'What string should be used as basename suffix for temporary files?', - "I have to find names for my temporary files. Therefore I construct a new " - ."name\nfrom the original filename and this string. Me and various called " - ."applications\nwill then create several files with this constructed " - ."basename and different\nextensions. When cleaning up I will simple " - ."delete all files with the\nconstructed basenames I have used."); - -&add_param('overwrite', 'bool', $NO, '', '!', - 'ignore existence of files with same basename as temporary TeX files', - 'Should I overwrite existing (temporary) files?', - "In spite of the precaution with the appended base suffix, there still " - ."might\nexist files with an identical basename. If you set this option I " - ."will consider\nsuch files as old temporary files and overwrite them " - ."during generation.\nHowever, I will not remove any files with this " - ."constructed basename on the\nclean up. You have to remove them manually."); - -&add_param('clean_logs', 'bool', $YES, '|l', '!', - 'delete all log files in log directory before execution', - 'Should the old log files be removed before execution?', - "I can remove old log files prior to execution. However, you might " - ."experience\nproblems if you run the script on several documents at the " - ."same time. If you\nwant to be on the safe side, answer '$NO'. Than you " - ."have to remove the logs\nmanually from time to time."); - -&add_param('check_commands', 'bool', $YES, '', '!', - 'make sure that required shell commands does exist before start', - 'Should I look for required executables?', - "As I use several different applications for PDF generation you might want " - ."to \nmake sure that they are available before the real work starts."); - -&add_param('destination', 'destination', 'source', '', '=s', - 'specifiy final location of generated PDF document', - 'Where should I store the resulting PDF document?', - "Depending on the application that starts this script (or you if you call " - ."it\ndirectly) you might want to have the resulting PDF document located " - ."at\ndifferent places."); - -&add_param('custom_path', 'directory', $USER_HOME.'/', '|d', '=s', - "specify custom path for 'destination' parameter", - 'What custom directory should be used?', - "When ever you specifiy to store the generated PDF document (command line " - ."or\nconfiguration) in a custom directory I will put it here."); - -&add_param('colorlinks', 'three', $YES, '', '!', - 'activate colored links in PDF doc (hyperref)', - 'Should colors be used for links?', - "I can use different colors for links inside the PDF document.\nYou can " - ."use '$UNDEF' to tell me that you would like to leave this up to\n" - ."independent hyperref configuration."); - -&add_param('paper', 'paper', 'a4paper', '|p', '=s', - 'specify papersize of the PDF doc (hyperref)', - 'What papersize should be used?', - "I can set the papersize of the resulting PDF document"); - -&add_param('citecolor', 'color', 'blue', '', '=s', - 'specify color of citations in PDF doc (hyperref)', - 'What color should be used for citation?', ""); - -&add_param('urlcolor', 'color', 'blue', '', '=s', - 'specify color of URLs in PDF doc (hyperref)', - 'What color should be used for URLs?', ""); - -&add_param('linkcolor', 'color', 'blue', '', '=s', - 'specify color of internal links in PDF doc (hyperref)', - 'What color should be used for normal internal links?', ""); - -&add_param('pagecolor', 'color', 'blue', '', '=s', - 'specify color of links to other pages in PDF doc (hyperref)', - 'What color should be used for page links?', ""); - -&add_param('link_toc_page', 'bool', $YES, '', '!', - 'link table of contents to pages instead of sections (hyperref)', - 'Should TOC be linked to pages?', - "The table of contents of the resulting PDF document is normally linked to " - ."the\ncorresponding section. However, you can also link it to the " - ."corresponding page\ninstead."); - -&add_param('default_title', 'text', $NIL, '', '=s', - 'set default PDF info title', - 'What is the default title?', - "A PDF document contains meta data about itself: the document info.\nOne " - ."of the info fields is the document title. You can set a default value\n" - ."which will be used in the case the script cannot determine a proper " - ."title from\nthe LaTeX document and you have not set one on the command " - ."line.\nYou can use '$NIL' to tell me that you would like to leave this " - ."up to\nindependent hyperref configuration."); - -&add_param('default_author', 'text', $NIL, '', '=s', - 'set default PDF info author', - 'What is the default author?', - "A PDF document contains meta data about itself: the document info.\nOne " - ."of the info fields is the document author. You can set a default value\n" - ."which will be used in the case the script cannot determine a proper " - ."author\nfrom the LaTeX document and you have not set one on the command " - ."line.\nYou can use '$NIL' to tell me that you would like to leave this " - ."up to\nindependent hyperref configuration."); - -&add_param('force_index', 'bool', $NO, '|i', '!', - 'force explicit inclusion of (existing) index in PDF doc', - 'Should the call of makeindex be forced?', - "Older versions of pdflatex have not included the index of a document\n" - ."automatically. If you are missing the index in your document you can " - ."force the\ncall of makeindex on the condition that an index file was " - ."generated."); - -&add_param('makeindex_opts', 'text', '', '', '=s', - 'specify extra options for shell execution of makeindex', - 'What additional options for makeindex should be used?', - "Sometimes, people would like to pass some extra options over to makeindex. " - ."This\nis the right place to do that. Everyone else can leave this empty."); - -&add_param('bibtex', 'three', $NIL, '|b', '!', - 'set bibtex behavior', - 'How should bibtex be used?', - "The bibtex usage can be specified.\nPossible values are: '$YES' (always " - ."run bibtex), '$NO' (never run bibtex)\nand '$UNDEF' (scan tex file for " - ."a bibtex entry and run it if required)."); - -&add_param('gloss', 'three', $NIL, '', '!', - 'set gloss behavior', - 'How should gloss be used?', - "The gloss usage can be specified.\nPossible values are: '$YES' (always " - ."run bibtex on file.gls), '$NO' (never run bibtex on file.gls)\nand '$UNDEF' (scan tex file for " - ."a gloss entry and run it if required)."); - -&add_param('thumbpdf', 'bool', $NO, '|n', '!', - 'generate thumbnails for PDF document', - 'Should PNG thumbnails be created?', - "I can use thumbpdf to include thumbnails of the document pages in the PDF " - ."file.\nThis requires Ghostscript 5.50 or higher."); - -&add_param('ppower', 'bool', $NO, '|w', '!', - 'postprocess PDF document with ppower', - 'Should ppower postprocess the PDF document?', - "I can use ppower to postprocess the PDF " - ."file.\nThis requires ppower 4.0 or higher."); - -&add_param('authorindex', 'bool', $NO, '', '!', - 'generate author index for PDF document', - 'Should authorindex process the PDF document?', - "I can use authorindex to process to include an author index in the PDF " - ."file.\nThis requires authorindex."); - - -&add_param('mtp_preamble', 'bool', $NO, '|r', '!', - "add the file $MTP_PREAMBLE_FILENAME at the current dir to metapost files", - "Should the $MTP_PREAMBLE_FILENAME file be added to the metapost files?", - "I can add $MTP_PREAMBLE_FILENAME to metapost " - ."files.\nThis requires an existing $MTP_PREAMBLE_FILENAME file."); - -&add_param('maxrun', 'integer', 6, '', '=i', - 'specify maximal number of pdflatex runs if problems are detected', - 'What should be the maximum number of runs for pdflatex (1-6)?', ""); - -&add_param('minrun', 'integer', 2, '', '=i', - 'specify minimal number of pdflatex runs if no problems are detected', - 'What should be the minimum number of runs for pdflatex (1-6)?', ""); - -&add_param('verbosity', 'integer', 5, '', '=i', - 'set the level of verbosity', - 'Which level of verbosity do you want (0-9)', - "Different people want different amounts of information about what the " - ."script\nactually does. Therefore you can adjust the verbosity to your " - ."personal needs\nby setting this parameter to a value from 0 to 9. 0 " - ."means no output at all\nand 9 means maximal output."); - -&add_param('pdftex_opts', 'text', '', '', '=s', - 'specify extra options for shell execution of pdflatex', - 'What additional options for pdflatex should be used?', - "Sometimes, people would like to pass some extra options over to pdflatex. " - ."This\nis the right place to do that. Everyone else can leave this empty."); - -&add_param('hyperref_args', 'text', '', '', '=s', - 'specify extra arguments for the hyperref package', - 'What additional arguments should be passed to the hyperref package?', - "Sometimes, people would like to pass some extra options over to hyperref. " - ."This\nis the right place to do that. Everyone else can leave this empty."); - -# the following parameter types should be set now: -# 'color' => \@VALUES, -# 'destination' => \@VALUES, -# 'paper' => \@VALUES, -# 'action' => undef, -# 'three' => undef, -# 'bool' => undef, -# 'integer' => undef, -# 'text' => undef, -# 'directory' => undef - -##### Functions ########################################### - -### handle a status report with a given priority level -# write it to the log file if log file if configuration is done -# write it to stdout if verbosity is set lower or equal -# -# The following priority levels exist: -# 1: minimal fatal error messages -# 2: additional information about fatal error -# 3: non-fatal error message -# 4: warning -# 5: major step of the process -# 6: minor step of the process -# 7: progress report of minor step -# 8: long status report from called applications -# 9: debug info -# -# parameter 1: priority level -# parameter 2: list of output strings -# return value: none - -sub report { - my $level; - my $verbosity; - my $log_verbosity; - my @output; - - if (@_ < 2 ) { - @output = ( "Oppss! Report function got only 1 argument!" ); - $level = 9; - } else { - ($level, @output) = @_; - } - - if($CONFIGURED) { - if( ¶m_value('debug') eq $NO ) { - $verbosity = ¶m_value('verbosity'); - $log_verbosity = $LOGFILE_VERBOSITY; - } else { - $verbosity = 9; - $log_verbosity = 9; - } - } else { - $verbosity = $PRE_CONFIG_VERBOSITY; - $log_verbosity = $LOGFILE_VERBOSITY; - } - - if ( $level <= $log_verbosity ) { - open LOGFILE, ">> $MYLOGFILE"; - print LOGFILE @output,"\n"; - close LOGFILE; - } - - if( $level <= $verbosity ) { - print @output,"\n"; - } -} - -### process system command and do the appropriate reports -# parameter 1: the system command to process -# parameter 2: flag - TRUE: abort on failure, FALSE: continue on failures -# parameter 3: priority level for output of system command -# parameter 4: specific failure message -# return value: TRUE - success, FALSE - failure - -sub system_command { - my $command = $_[0]; - my $fatal_failure= $_[1]; - my $output_priority = $_[2]; - my $fail_message = $_[3]; - my $system_out; - - $system_out = `$command 2>&1`; - - if ($?) { - if ($fatal_failure) { - &report(2, $system_out) if ($system_out); - &abort($fail_message.": $!"); - } else { - &report($output_priority, $system_out) if ($system_out); - &report(3, $fail_message.": $!"); - } - return $FALSE; - } - - return $TRUE; -} - -### Index of the first occurence of a string in an array -# parameter 1: text -# parameter 2: list -# return value: index or -1 if not element of the array - -sub array_index { - my ($text, @list) = @_; - - if(!defined($text)) { - &report(9, "Oppss! Cannot compare nothing."); - return -1; - } - - foreach (0..$#list) { - if ( $list[$_] eq $text ) { return $_; } - } - - return -1; -} - -### extract the last N lines of a text file -# abort on failures -# parameter 1: file to read -# parameter 2: N - number of lines to print (undef/0: all lines) -# return value: last N lines - -sub file_tail { - my $file_name = $_[0]; - my $no_of_lines = defined($_[1]) ? $_[1] : 0; - my @cache=(); - - &check_file($file_name); - open(TAIL_SOURCE, "<$file_name") - or &abort("Could not read file $file_name: $!"); - - if($no_of_lines == 0) { - # use entire file - while() { - if(!$_) { $_="\n"; } - push(@cache, $_); - } - } else { - # only last N lines - - # fill up cache - while(@cache < $no_of_lines and ) { - if(!$_) { $_="\n"; } - push(@cache, $_); - } - - # always cache the last N lines up to the end of the file - while() { - if(!$_) { $_="\n"; } - shift(@cache); - push(@cache, $_); - } - } - - close TAIL_SOURCE; - - return @cache; -} - -### return all lines of FILE which match match regexp EXPR -# parameter 1: FILE - file to read -# parameter 2: EXPR - regular expression to match -# parameter 3: true: exit on first occurence, otherwise get all (default: false) -# return value: array of matching lines - -sub grep_file { - my $file_name = $_[0]; - my $regexp = $_[1]; - my $first_only = $_[2] ? $TRUE : $FALSE; - my @result=(); - - ### open file and abort if not possible - &check_file($file_name); - open(GREP_SOURCE, "<$file_name") - or &abort("Could not read file $file_name: $!"); - - while() { - if(m#$regexp#) { - push(@result, $_); - if($first_only) { last; } - } - } - - close GREP_SOURCE; - return @result; -} - -### Removing all temporary files - -sub clean_up { - &report(6, "Removing temporary files ..."); - foreach (@TMPFILES) { - unlink($_) if(-f $_); - } - - foreach (@TMP_TEX_FILES) { - # make sure that we have a good tex file name in order - # to avoid unintended removals - if( $_ ne "" and -f $_.'.tex' ) { - unlink glob($_.".???"); - } else { - &report(3, "Bad file in temp tex files list: $_"); - } - } -} - -### Output of all temp files - -sub print_temp_files { - if (scalar @TMPFILES > 0) { - print "Stored the following explicit temporary files:\n"; - foreach (@TMPFILES) { - if (-f $_) { - print "> ".$_."\n"; - } else { - print "> ".$_." (does not exist)\n"; - } - } - print "\n"; - } - - if (scalar @TMP_TEX_FILES > 0) { - print "Stored the following temporary TeX base names:\n"; - foreach (@TMP_TEX_FILES) { - if( $_ ne "" and -f $_.'.tex' ) { - print "> ".$_.": "; - foreach my $file (glob($_.".???")) { - print basename($file)." "; - } - print "\n"; - } else { - print "> ".$_.": bad file for temp TeX file\n"; - } - } - print "\n"; - } -} - -### exit with an error message - -sub abort { - &report(1, @_); - if ( $CONFIGURED and ¶m_value('clean_on_abort') eq $YES - and ¶m_value('debug') eq $NO) { - &clean_up; - } else { - &print_temp_files; - } - &report(2, "Aborting ..."); - exit 1; -} - -### Check for required command with 'which'; abort if not found -# parameter $1: command to check -# parameter $2: remark if specified command is not found - -sub checkCommand { - my $command = $_[0]; - my $message = $_[1]; - my $which_output; - - $which_output = `which $command 2>&1`; - chomp $which_output; - $_ = $which_output; - s|^(.*/)?([^/]+)$|$2|; - - if ( $_ ne $command ) { - &report(2, "\n$which_output"); - &report(1, "\nRequired command '$command' seems not to be in your path."); - if ( defined($message) ) { - &report(2, "$message"); - } - &report(2, "Aborting ..."); - exit 1; - } -} - -###################### Generic configuration functions - -### interactively answer a question with yes or no -# parameter 1: question -# parameter 2: default value (not set means $NIL) -# parameter 3: yes: allow undefined as third value -# no : only yes/no allowed (default) -# return value: the given answer - -sub question_ynu { - my $user_input; - my $question = $_[0]; - my $default = defined($_[1]) ? $_[1] : $NIL; - my $undef_allowed = $_[2]; - my $response = undef; - - if (defined($undef_allowed) and $undef_allowed eq $YES) { - $undef_allowed = $TRUE; - } else { - $undef_allowed = $FALSE; - } - - if( $default =~ /^y(es)?/i ) { - $question .= ' [y]: '; - $default = $YES; - } elsif ( $default eq $NIL and $undef_allowed ) { - $question .= ' [u]: '; - $default = $NIL; - } else { - $question .= ' [n]: '; - $default = $NO; - } - while (! defined($response)) { - print $question; - $user_input = ; - chomp($user_input); - - if( $user_input =~ /^y(es)?/i ) { - $response=$YES; - } elsif ( $user_input =~ /^no?/i ) { - $response=$NO; - } elsif ( $user_input =~ /^u(ndef(ined)?)?/i and $undef_allowed ) { - $response=$NIL; - } elsif ( $user_input eq "" ) { - $response=$default; - } else { - print "Please respond with y(es)"; - print ", u(ndefined)" if($undef_allowed); - print " or n(o).\n"; - } - } - return $response; -} - -### interactively input a positive integer number -# parameter 1: question -# parameter 2: default value -# parameter 3: min value -# parameter 4: max value -# return value: the input number - -sub input_number { - my $question = $_[0]; - my $default = $_[1]; - my $min_limit = $_[2]; - my $max_limit = $_[3]; - my $response= undef; - - while (! defined($response)) { - print "$question [$default]: "; - my $user_input = ; - chomp($user_input); - - if ($user_input eq "") { - $response=$default; - } else { - $_ = $user_input; - if (s/^([0-9]+)$/$1/ and $_ >= $min_limit and $_ <= $max_limit ) { - $response = $_; - } else { - print "Invalid input. Please enter a positve integer from $min_limit to $max_limit.\n"; - } - } - } - return $response; -} - -### interactively choose between several given values -# parameter 1: question -# parameter 2: default value -# parameter 3: reference to an array of possible values arrays -# return value: the chosen value - -sub choose_value { - my ($question, $default, $enum_array_ref)=@_; - my $default_no=1; - my $chosen_no; - my @possible_values = @$enum_array_ref; - my @value_array; - my $value_key; - my $value_output; - - print "$question\n"; - foreach (0..$#possible_values) { - my $no = $_ + 1; - @value_array = @{$possible_values[$_]}; - $value_key = $value_array[0]; - $value_output = $value_array[1]; - - print "$no) " . $value_output . "\n"; - if ( $default eq $value_key ) { $default_no=$no; } - } - - $chosen_no=&input_number("Please enter the corresponding number", $default_no, 1, $#possible_values); - - @value_array = @{$possible_values[$chosen_no - 1]}; - $value_key = $value_array[0]; - return $value_key; -} - -### interactively answer a question -# parameter 1: question -# parameter 2: current value -# return value: the new value - -sub input_text { - my $question=$_[0]; - my $default=$_[1]; - my $response= undef; - - print "Suggested value: $default\n"; - if ( &question_ynu("Do you want to keep this value?", $YES) eq $YES ) { - $response= $default; - } else { - print "$question "; - my $user_input = ; - chomp($user_input); - - $response = $user_input; - } - return $response; -} - -##### Make sure that specified file exists and is readable; abort if missing -# parameter 1: file to check -# parameter 2: remark if check fails on specified file - -sub check_file { - my $file = $_[0]; - my $message = defined($_[1]) ? $_[1] : "Required file cannot be accessed!"; - - if ( ! -f $file ) { - &report(2, "\nSorry. I cannot find '$file'."); - &abort($message); - } elsif ( ! -r $file ) { - &report(2, "\nSorry. File '$file' exists, but is not readable."); - &abort($message); - } -} - -##### Make sure that specified directory exists and is writable -# parameter 1: directory to check -# parameter 2: remark if check fails on specified directory -# parameter 3: if yes, creation is allowed -# return value: $TRUE - ok; $FALSE - error - -sub check_dir { - my $directory = $_[0]; - my $message = defined($_[1]) ? $_[1] : "Not a valid path!"; - my $allow_creation = defined($_[2]) ? $_[2] : $NO; - - if ( index($directory, "/") != 0 ) { - &report(3, "\nSorry. '$directory' is not an absolute path."); - &report(3, $message); - return $FALSE; - } elsif ( ! -d $directory ) { - # dir does not exist - if ( $allow_creation eq $YES ) { - # creation allowed - &report(4, "\nI cannot find '$directory'. Try to create it."); - if ( mkdir($directory, 0755) ) { - &report(7, "Creation of '$directory' was successful."); - return $TRUE; - } else { - &report(3, "Creation of '$directory' failed."); - &report(3, $message); - return $FALSE; - } - } else { - # creation not allowed - &report(3, "\nSorry. Directory '$directory' does not exist."); - &report(3, $message); - return $FALSE; - } - } elsif ( ! -w $directory ) { - # dir not writable - &report(3, "\nSorry. Directory '$directory' exists, but is not writable."); - &report(3, $message); - return $FALSE; - } - return $TRUE; -} - -### interactively input a directory for data storage (absolute path) -# parameter 1: question -# parameter 2: default dir -# parameter 3: if 'yes' allow creation of directory -# return value: the specified directory - -sub input_dir { - my $question = $_[0]; - my $default_dir = $_[1]; - my $allow_creation = defined($_[2]) ? $_[2] : $NO; - my $user_input; - my $response = undef; - - if ( defined($default_dir) and index($default_dir, "/") == 0 - and ( (! -d $default_dir and $allow_creation eq $YES) - or (-d $default_dir and -w $default_dir) ) ) { - $question .= " [$default_dir]: "; - } else { - $default_dir = undef; - $question .= ": "; - } - - while (! defined($response)) { - print "$question"; - $user_input = ; - chomp($user_input); - - if( $user_input eq "" and defined($default_dir) ) { - # user has only pressed and thereby confirmed default value - if( ! &check_dir($default_dir,"Default value was not valid. Please, give different directory.", $allow_creation ) ) { - # default dir does not exist and cannot be created - $default_dir = undef; - $question = "$_[0]: "; - } else { - # valid default dir has already existed or has been created - $response = $default_dir; - } - } else { - # user has given a directory - if( &check_dir($user_input,"This is not a valid directory!", $allow_creation) ) { - $response = $user_input; - } - } - } - return $response; -} - -#### add a new parameter type with corresponding additional data argument -#### parameters types -# parameter 1: type key -# parameter 2: additonal data for the type -# e.g. for enum type: reference to list of arrays -# return value: none - -sub add_param_type { - - my ($type, $scalar_argument) = @_; - - $PARAMETER_TYPES{$type} = $scalar_argument; -} - -#### add a new parameter to the adminstrated parameters -#### -# parameter 1: key -# parameter 2: type -# parameter 3: default value -# parameter 4: alias for command line options -# parameter 5: specification for command line options -# parameter 6: short description for help -# parameter 7: question -# parameter 8: explanation -# return value: none - -sub add_param { - - my ($key, $type, $def_value, $opt_alias, $opt_spec, $description, $question, $explanation) = @_; - - $CONFIGURATION{$key} = $def_value; - - $PARAMETER_LIST{$key} = [ $type, $opt_alias, $opt_spec, $def_value, $description, $question, $explanation ]; - - push(@PARAMETER_ORDER, $key); - - if (! exists $PARAMETER_TYPES{$type}) { - $PARAMETER_TYPES{$type} = undef; - } -} - -### get the value of an existing parameter -# parameter 1: a parameter key -# return value: reference to the array of possible value entries -# (undef if not valid) - -sub type_enum_array { - my $key = $_[0]; - my $values_ref; - - if(! exists($PARAMETER_TYPES{$key})) { - &abort("unknown type: $key"); - } - - $values_ref = $PARAMETER_TYPES{$key}; - - if(ref $values_ref ne 'ARRAY') { - $values_ref = undef; - } - - return $values_ref; -} - -### get the value of an existing parameter -# parameter 1: a parameter key -# return value: parameter value - -sub param_value { - my $key = $_[0]; - my $current_value; - - exists($CONFIGURATION{$key}) - or &abort("unknown parameter: $key"); - $current_value = $CONFIGURATION{$key}; - - return $current_value; -} - -### get the type of an existing parameter -# parameter 1: a parameter key -# return value: parameter value - -sub param_type { - my $key = $_[0]; - my $def_ref; - my $type; - - exists($PARAMETER_LIST{$key}) - or &abort("unknown parameter: $key"); - $def_ref = $PARAMETER_LIST{$key}; - $type = @{$def_ref}[$TYPE]; - - exists($PARAMETER_TYPES{$type}) - or &abort("parameter has unknown type: $key (type: $type)"); - - return $type; -} - -### determine if the given parameter is a full one (instead of option only) -# parameter 1: a parameter key -# return value: $TRUE - full parameter; $FALSE otherwise - -sub full_param { - my $key = $_[0]; - my @param_def; - - exists($PARAMETER_LIST{$key}) - or &abort("unknown parameter: $key"); - @param_def = @{$PARAMETER_LIST{$key}}; - - if ($param_def[$TYPE] ne 'action' and defined ($param_def[$QUESTION])) { - return $TRUE; - } else { - return $FALSE; - } -} - -### get the output needed for configuration of this parameter -# parameter 1: a parameter key -# return value: array - (description, explanation, question) - -sub param_config_output { - my $key = $_[0]; - my @param_def; - my $description; - my $explanation; - my $question; - - exists($PARAMETER_LIST{$key}) - or &abort("unknown parameter: $key"); - @param_def = @{$PARAMETER_LIST{$key}}; - $description = $param_def[$DESCRIPTION]; - $explanation = $param_def[$EXPLANATION]; - $question = $param_def[$QUESTION]; - - return ($description, $explanation, $question); -} - -### set the value of an existing parameter -# parameter 1: a parameter key -# parameter 2: the new value -# return value: none - -sub set_param_value { - my $key = $_[0]; - my $new_value = $_[1]; - - exists($CONFIGURATION{$key}) - or &abort("unknown parameter: $key"); - $CONFIGURATION{$key}=$new_value; -} - -### get option specifier for getopts -# parameter 1: option key -# return value: string - option specifier - -sub option_specifier { - my $key = $_[0]; - my $spec; - my $def_ref; - - exists($PARAMETER_LIST{$key}) - or &abort("unknown parameter: $key"); - $def_ref = $PARAMETER_LIST{$key}; - $spec = $key . ${$def_ref}[$OPT_ALIAS] . ${$def_ref}[$OPT_SPEC]; - - return $spec; -} - -### handle an option -# parameter 1: a parameter/option key -# parameter 2: the option value -# return value: none - -sub handle_option { - my $key = $_[0]; - my $value = $_[1]; - my $type; - - $type = ¶m_type($key); - - if ($type eq 'action') { - &handle_action_opt($key, $value); - } elsif ( $type eq 'bool' or $type eq 'three') { - my $bool_value = $value ? $YES : $NO; - &set_param_value($key, $bool_value); - } elsif ( $type eq 'directory') { - if (! &check_dir($value)) { - &report(2, "$key requires an existing writable directory as an absolute path."); - &abort("Illegal value: $value"); - } - &set_param_value($key, $value); - } elsif (defined(&type_enum_array($type))){ - &set_enum_param($key, $value); - } else { - &set_param_value($key, $value); - } -} - -### handle all action options -# parameter 1: a option key -# parameter 2: the option value -# return value: none - -sub handle_action_opt { - my $key = $_[0]; - my $value = $_[1]; - - if ($key eq 'help') { - &print_help; - - } elsif ($key eq 'version') { - &print_version; - - } elsif ($key eq 'configure') { - if ( -f $RC_FILENAME ) { - &read_configuration($RC_FILENAME); - } - &configure; - &write_configuration($RC_FILENAME); - &print_configuration; - - } elsif ($key eq 'print_config') { - if ( -f $RC_FILENAME ) { - &read_configuration($RC_FILENAME); - } - &print_configuration; - - } else { - &print_usage; - exit 1; - } - exit 0; -} - -### set a variable by a command line option to a possible values; abort on error -# parameter 1: parameter key -# parameter 2: value - -sub set_enum_value { - my ($key, $value) = @_; - my $type; - my $enum_array_ref; - my @allowed_values=(); - - $type = ¶m_type($key); - $enum_array_ref = &type_enum_array($type); - &abort("Internal error: No value array for parameter $key.") - if(!defined($enum_array_ref)); - - ### find out if the given value is allowed - foreach my $value_array_ref (${$enum_array_ref}) { - if(${$value_array_ref}[0] eq $value) { - ### found it, so it is okay! - &set_param_value($key, $value); - return; - } - } - - ### value is not listed, so not allowed - ### make a list of all allowed values - foreach my $value_array_ref (${$enum_array_ref}) { - push(@allowed_values, ${$value_array_ref}[0]); - } - - &report(2, "\n$key allows: " . @allowed_values . ".\n"); - &abort("Illegal value: $value"); -} - -### configure an existing parameter interactively -# parameter 1: a parameter key -# return value: none - -sub config_param { - my $key = $_[0]; - my $type; - my $new_value; - my $current_value; - my $description; - my $explanation; - my $question; - - ### get required information about this parameter - $type = ¶m_type($key); - $current_value = ¶m_value($key); - ($description, $explanation, $question) = ¶m_config_output($key); - - ### tell the user the facts - print "\n\n--------------------------------------------\n"; - print "Parameter: ".$key."\n"; - print $description."\n\n"; - print $explanation."\n\n" if($explanation ne ""); - - ### ask him what he wants - if ($type eq 'bool') { - $new_value=&question_ynu($question, $current_value, $NO); - } elsif ($type eq 'three') { - $new_value=&question_ynu($question, $current_value, $YES); - } elsif ($type eq 'directory') { - $new_value=&input_dir($question, $current_value, $YES); - } elsif ($type eq 'text') { - $new_value=&input_text($question, $current_value); - } elsif ($type eq 'integer') { - $new_value=&input_number($question, $current_value, - $NUM_PARAM_MIN, $NUM_PARAM_MAX); - } else { - my $enum_array_ref; - - $enum_array_ref=&type_enum_array($type); - if (! defined($enum_array_ref)) { - &abort("Do not know how to configure this parameter: $key (type: $type)"); - } - - $new_value=&choose_value($question,$current_value,$enum_array_ref); - } - - ### store his choice - &set_param_value($key, $new_value); -} - -### save configuration in rc file -# parameter 1: file name -# return value: none - -sub write_configuration { - my $file_name = $_[0]; - my $date; - - open(RCFILE, ">$file_name") or - &abort("Could not open configuration file for writing ($file_name)"); - select RCFILE; - - $date = `date`; - chomp($date); - - print "# Configuration file for $MYNAME V$MYRELEASE\n"; - print "# Generated $date by $MYUSER on $MYHOSTNAME\n"; - print "$RCVERSION_STRING=$MYRCFILE_VERSION\n"; - - foreach my $key (@PARAMETER_ORDER) { - my $value = $CONFIGURATION{$key}; - if(&full_param($key)) { - print $key.'='.$value."\n"; - } - } - - print "# EOF\n"; - select STDOUT; - close RCFILE; -} - -### print the configuration parameters - -sub print_configuration { - print "\nConfiguration for $MYNAME V$MYRELEASE\n"; - - foreach my $key (@PARAMETER_ORDER) { - my $value = $CONFIGURATION{$key}; - if(&full_param($key)) { - print $key.'='.$value."\n"; - } - } - - print "\n"; -} - -### load parameters from rc file -# parameter 1: file name -# return value: version of read rc file or 0 if no version given - -sub read_configuration { - my $file_name = $_[0]; - my $file_version= 0; - - &check_file($file_name, "Could not access configuration file"); - open(RCFILE, "<$file_name") or - &abort("Could not open configuration file for reading ($file_name)"); - - while () { - chomp; - if( /^([^#=]+)=(.*)$/ ) { - if( exists $CONFIGURATION{$1} ) { - $CONFIGURATION{$1} = $2; - } elsif ( $1 eq $RCVERSION_STRING ) { - $file_version = $2; - } else { - print "Ignoring unknown parameter in RC file: $1=$2\n"; - } - } - } - close RCFILE; - - return $file_version; -} - -### print script version - -sub print_version { - print "\n$MYNAME Version $MYRELEASE\n"; -} - -###################### Specific functions (for use with this script only) - -### print usage of command - -sub print_usage { - print "\nUsage: $MYNAME [OPTIONS] DOCUMENT.lyx\n"; - print " $MYNAME [OPTIONS] DOCUMENT[.tex]\n\n"; - print " $MYNAME -c | --configure modify/set up configuration\n"; - print " $MYNAME -h | --help give a short help\n"; - print " $MYNAME -o | --print_config print current configuration\n"; - print " $MYNAME -v | --version print my version\n\n"; -} - -### print command help - -sub print_help { - &print_version; - &print_usage; - - foreach my $key (@PARAMETER_ORDER) { - my @param_def = @{$PARAMETER_LIST{$key}}; - my $description = $param_def[$DESCRIPTION]; - my $takes_value = $param_def[$OPT_SPEC] =~ /[=:]/ ? $TRUE : $FALSE; - my $negation = $param_def[$OPT_SPEC] eq '!' ? $TRUE : $FALSE; - my $alias = $param_def[$OPT_ALIAS]; - - $alias =~ s/\|(([a-zA-Z])(\||$))/ | -$1/g; - $alias =~ s/\|(([a-zA-Z][a-zA-Z0-9_]+)(\||$))/ | --$1/g; - - print "--"; - print "[no]" if($negation); - print $key.$alias; - print " VALUE" if ($takes_value); - print ":\n ".$description."\n\n"; - } - print "\n"; -} - -### configure all tex2pdf parameters interactively -# parameters: none -# return value: none - -sub configure { - - print "\n--------------------------------------------------------\n"; - print "\n***** Configuration for $MYNAME *****\n\n"; - print "The following answers are considered as defaults in later "; - print "executions\n"; - print "of $MYNAME. You can change these values by using the option "; - print "--configure \nagain."; - print "Additionally, all command-line options override these settings.\n"; - print "Many parameters can be set to '$NIL' or '$UNDEF'. This means that NO"; - print "\nvalue at all (not even an empty value) is passed over to the "; - print "called\napplication (e.g. latex package hyperref).\n"; - - $NUM_PARAM_MIN=1; - $NUM_PARAM_MAX=9; - - foreach my $key (@PARAMETER_ORDER) { - if(&full_param($key)) { - &config_param($key); - } - } - - print "\nConfiguration for $MYNAME finished.\n\n"; -} - -### check if the most important executables are installed on the system -# parameters: none - -sub check_commands { - my $exec_epstopdf; - ### check for which command - &checkCommand("which","You can switch off all command checks to fix this."); - - ### pdftex executables - # Homepage: http://tug.org/applications/pdftex - &checkCommand("pdflatex","See pdftex homepage for details: http://tug.org/applications/pdftex"); - &checkCommand("epstopdf","See pdftex homepage for details: http://tug.org/applications/pdftex"); - $exec_epstopdf = `which epstopdf`; - chomp $exec_epstopdf; - my $compat = "-dCompatibilityLevel=1\\.1"; - if (defined($ENV{'GS_OPTIONS'}) && $ENV{'GS_OPTIONS'} =~ /$compat/o) { - &report(9, "Good: ghostscript option '-dCompatibilityLevel=1.1' detected " - ."in\n'\$GS_OPTIONS'."); - } elsif (&grep_file($exec_epstopdf, $compat, $TRUE) > 0) { - &report(9, "Good: ghostscript option '-dCompatibilityLevel=1.1' detected " - ."in\n'$exec_epstopdf'."); - } else { - &report(4, "\nWARNING: no ghostscript option '-dCompatibilityLevel=1.1' " - ."in\n'$exec_epstopdf'.\n" - ."You might run into trouble with the conversions of bitmaps.\n" - ."Adjusting epstopdf or setting the environment variable GS_OPTIONS " - ."to \n".'"$GS_OPTIONS -dCompatibilityLevel=1.1" before calling this ' - ."script\nmight help in this case.\n"); - } - - if ( ¶m_value('thumbpdf') eq $YES ) { - &checkCommand("thumbpdf","You can switch off thumbpdf support to fix this."); - } - - if ( ¶m_value('ppower') eq $YES ) { - &checkCommand("ppower","You can switch off ppower support to fix this."); - } - - ### authorindex perl script - if ( ¶m_value('authorindex') eq $YES ) { - &checkCommand("authorindex","You can switch off authorindex support to fix this."); - } - - ### bibtex executable - if ( ¶m_value('bibtex') ne $NO or ¶m_value('gloss') ne $NO) { - &checkCommand("bibtex","You can switch off BibTeX support to fix this."); - } -} - -#### generate the tmp file name from the original tex filename -#### and make sure that they are not the same -# parameter 1: orignal filename (with or without a path or .tex) -# parameter 2: path for the tmp file (default: doc path) -# return value: tmp name - -sub reserve_tmp_texname { - my $original_name = $_[0]; - my $tmp_path = $_[1]; - my $tmp_base_suffix = ¶m_value('tmp_base_suffix'); - my $overwrite = ¶m_value('overwrite'); - my $original_path; - my $original_base; - my $suffix; - my $pathed_tmp_base; - my @existing_files; - - # separate path, base and suffix - ($original_base,$original_path,$suffix) = fileparse($original_name, '\.tex'); - - # set the path of the tmp file - if(!$tmp_path) { - $tmp_path=$original_path; - } else { - $tmp_path .= '/' if( $tmp_path ne "" and ! ($tmp_path =~ m#/$#) ); - } - - # abort if no absolute path is given - if( index($tmp_path, "/") != 0 ) { - &abort("Internal error: Illegal argument for reserve_tmp_texname:". - "Given file has no absolute path: $original_name"); - } - - # make sure that tmp_base_suffix is set correctly - if($tmp_base_suffix eq "") { - &abort("Temporary filename base suffix is empty."); - } - - $pathed_tmp_base = $tmp_path.$original_base.$tmp_base_suffix; - - # make sure no file with this base exists in this directory - @existing_files = glob "$pathed_tmp_base.*"; - if (@existing_files != 0) { - &report(3, "Problems detected while reserving temporay file name!\n", - "In this directory are already files with this basename.\n", - "A list of the conflicting, existing files:\n", - join("\n", @existing_files), "\n"); - if ($overwrite eq $YES) { - &report(4, "As you have activated the parameter 'overwrite' I will " - ."continue.\n", - "However, in order to protect the existing files I will not\n", - "delete any files with this basename at the final clean-up."); - } else { - &report(2, "You could activate the parameter 'overwrite' or remove ", - "the\n corresponding files in order to avoid these problems."); - &abort("No temporary name found for $original_name."); - } - } else { - push(@TMP_TEX_FILES, $pathed_tmp_base); - } - - return $pathed_tmp_base.$suffix; -} - -### generate LaTeX file from LyX document with LyX itself -# parameter ($1): Lyx document -# parameter ($2): Latex document - -sub generate_tex_file { - my $lyx_doc = $_[0]; - my $tex_doc = $_[1]; - my $lyx_dir; - my $lyx_output; - my $lyx_exec=¶m_value('lyx_exec'); - - $lyx_dir = ¶m_value('lyxrc_path'); - $lyx_dir .= '/' if( ! ($lyx_dir =~ m#/$#) ); - $lyx_dir .= '/' if( ! ($lyx_dir =~ m#/$#) ); - - ### Check if LyX file can be accessed - &check_file($lyx_doc,"Cannot read the specified LyX document!"); - - ### Check if LaTeX file exists and is newer than the LyX file - if ( -f $tex_doc and -M $tex_doc < -M $lyx_doc ) { - &report(4, "\nLaTeX file is newer than LyX document ($lyx_doc).\n", - "Using existing TeX file: $tex_doc\n", - "Remove it to force its new generation."); - } else { - ### export LaTeX file with LyX (needs a display!) - &checkCommand($lyx_exec, "Cannot generate LaTeX document without LyX!"); - &report(6, "\nExporting LaTeX file"); - - ### move some files out of the way that stop LyX from exporting - foreach my $file ($lyx_dir."lyxpipe.out",$lyx_dir."lyxpipe.in",$tex_doc) { - if ( -f $file ) { rename($file, $file.'~'); } - } - - $lyx_output = `$lyx_exec --export latex $lyx_doc 2>&1`; - - ### check if LaTeX file now really exists - if ( ! -f $tex_doc ) { - &report(2, "Lyx Output:\n$lyx_output"); - &report(2, "\nSorry. I cannot find '$tex_doc'."); - &abort("The LaTeX document was not generated by LyX!"); - } else { - &report(8, "Lyx Output:\n$lyx_output"); - } - } -} - -#### search TeX document for a certain text tag (e.g. author, title) -# parameter 1: file to parse -# parameter 2: full TeX tag name -# return value: list of the contents strings of all matching tags - -sub extract_tag_contents { - my $source=$_[0]; - my $tag_name=$_[1]; - my $contents; - my @results=(); - my $error_message="Could not read TeX document to extract $tag_name"; - - &check_file($source, $error_message.'.'); - open(EXTRACT_SOURCE, "<$source") or - &abort($error_message." ($source)."); - - - while() { - ### ignore comments - s/(^|[^\\])%.*/$1/; - # ignore \thanks{} - s/\\thanks\{.*?\}//g; - # change \and to and - s/\\and/ and/g; - - $contents .= $_; - } - - close EXTRACT_SOURCE; - - $_ = $contents; - - # add contents of all occurences of this tag in a line to result list - while ( /\\($tag_name)(\[[^]]*?\])*?{+([^{}]*?)}/s ) { - my $text = $3; - $_ = $'; - # remove newlines - $text =~ s/\n//g; - $text="" if (!defined($text)); - push(@results, $text); - } - - return @results; -} - -#### search for filenames in given TeX Tag in entire document -### skip all comments and duplicates while parsing -# parameter 1: file to parse -# parameter 2: full TeX tag name -# parameter 3: reference to a list of possible filename suffixes (without '.') -# parameter 4: regexp for suffix to ignore when specified in TeX file -# (undef if not used) -# return value: list of identified files - -sub identify_files { - my $source=$_[0]; - my $tag_name=$_[1]; - my @suffixes=@{$_[2]}; - my $ignore_suffix=$_[3]; - my @matched_tags; - my @found_files=(); - my $regexp_suffixes; - - # create one large regexp from given suffixes and escape dots in them - $regexp_suffixes= '.('.join('|', @suffixes).')'; - $regexp_suffixes =~ s/\./\\./g; - - @matched_tags = &extract_tag_contents($source, $tag_name); - - foreach my $tag_contents (@matched_tags) { - my $path; - my $base; - my $suffix; - my $kpse_result; - my $working_dir = cwd."/"; - - ($base,$path,$suffix) = fileparse($tag_contents, $regexp_suffixes); - - # if a suffix is specified in the tag_contents handle it as requested - # - # 1. $suffix: TRUE if $suffix is defined and not of zero length - # means: a valid suffix has been found in the filename - # 2. defined($ignore_suffix): TRUE if $ignore_suffix is defined - # means: a regexp for suffixes to be ignored has been specified as - # parameter4 - # 3. $suffix =~ /$ignore_suffix/: TRUE if $suffix matches the regexp - # means: the suffix in the filename is wanted to be ignored - # - # The IF statement will be executed when: - # a valid suffix has been found in the filename (1) - # AND regexp for suffixes to be ignored has NOT been specified (not 2) - # OR - # a valid suffix has been found in the filename (1) - # AND regexp for suffixes to be ignored has been specified (2) - # AND the suffix in the filename is NOT wanted to be ignored (not 3) - # - # The stuff that is executed if the entire IF statement is TRUE does the - # following: accept the found suffix and consider it as the only possible - # file name. - if($suffix and not (defined($ignore_suffix) and $suffix =~ /$ignore_suffix/)){ - $kpse_result=`kpsewhich $tag_contents`; - # print warning and skip this tag if kpsewhich could not find it - if (!$kpse_result) { - &report(4, "WARNING - Could not identify referenced file:\n", - " Ignoring '$tag_contents'."); - next; - } - } else { - # if there is a '.' in the basename assume that this is a reference - # to a file of another type and skip it - if( $base =~ /\./ ) { - &report(9, "Found an unknown extension. Ignoring '$tag_contents'."); - next; - } - - # search for all possible files with allowed suffixes - foreach my $allowed_suffix (@suffixes) { - if (not $allowed_suffix =~ /[\]\)\(\|\[\\]/ ) { - # suffix is not a regexp, but a real extension - my $possible_file= $path.$base.'.'.$allowed_suffix; - $kpse_result=`kpsewhich $possible_file`; - if ($kpse_result) { - last; - } - } - } - } - - # if kpsewhich could not find any file with an allowed suffix - # assume that this reference is of a different type and skip it - # quietly - if (!$kpse_result) { - &report(9, "No suitable file found. Ignoring '$tag_contents'."); - next; - } - - # expand '.' in kpsewhich output to the current path - $kpse_result =~ s#^\./#$working_dir#; - - # remove trailing newline - chomp($kpse_result); - - # add file to the found file list if it is not already on it - if( &array_index($kpse_result, @found_files) < 0 ) { - push(@found_files, $kpse_result); - } - } - - return @found_files; -} - -### Build a list of all files which are included from the root file. -# This function recurses, and is maybe smart enough to detect cycles. -# Be sure to set REF_DOCS to the empty string prior to calling this. -# parameter 1: tex file to start with -# no return value -# result is appended to global variable @REF_DOCS - -sub get_file_list { - my $source = $_[0]; - my @imports = (); - - # This is the cycle avoidance logic. - if ( &array_index($source, @REF_DOCS) < 0 ) { - # Make sure the file can be accessed - &check_file($source, "Included TeX file seems not to be available. Path problem?"); - - # Save the argument in the list of files. - push(@REF_DOCS, $source); - - # Get the list of files included by the argument. - @imports=&identify_files($source, 'include|input', ['tex']); - - # Recurse. - foreach my $file (@imports) { - if( ! ($file =~ /\.tex$/) ) { $file .= '.tex'; } - &get_file_list($file); - } - } -} - -### do the required modifications in the LaTeX preamble -# parameter 1: original preamble from the source file -# lines before \begin{document} tag (without this tag) -# parameter 2: reference to hyperref parameter list -# return value: adjusted preamble - -sub adjust_preamble { - my $preamble = $_[0]; - my $hyperref_params_ref = $_[1]; - my $extra_code; - my $result; - - $_ = $preamble; - - # protect pdflatex execution mode - s/^(\\batchmode)$/% $1/m; - - # insert a4paper in the documentclass when a4wide is used - # fixes problem that hyperref defaults to letter otherwise - if ( /^[^%]*\\usepackage(\[widemargins\])?\{(a4|a4wide)\}/m ) { - # check if package parameters with [] brackets are present - if ( not s/^(\\documentclass\[.*?)\]/$1,a4paper]/m ) { - s/^\\documentclass/$&\[a4paper\]/m; - } - } - - ### collect additional LaTeX code - - $extra_code = "\n" . '\usepackage{pslatex}' . "\n"; - - if ( ¶m_value('thumbpdf') eq $YES ) { - $extra_code .= '\usepackage{thumbpdf}' . "\n"; - } else { - $extra_code .= "% no thumbpdf support\n"; - } - -# if ( ¶m_value('ppower') eq $YES ) { -# $extra_code .= '\usepackage{mpmulti}' . "\n"; -# } else { -# $extra_code .= "% no ppower support\n"; -# } - - if ( ¶m_value('authorindex') eq $YES ) { - $extra_code .= '\usepackage[pages]{authorindex}' . "\n"; - $extra_code .= '\let\cite=\aicite' . "\n"; - } else { - $extra_code .= "% no authorindex support\n"; - } - - $extra_code .= '\makeatletter' . "\n"; - $extra_code .= '\usepackage[' . join(',', @$hyperref_params_ref) - . ']{hyperref}' . "\n"; - $extra_code .= '\makeatother' . "\n"; - - ### insert the extra LaTeX code directly after documentclass - m/^(\\documentclass)(\[[^]]*\])?(\{.*\})/m; - return $` . $& . $extra_code . $'; -} - -### adjust all filenames in the LaTeX code to the tmp files -# parameter 1: original LaTeX code from the source file -# return value: adjusted code - -sub adjust_filenames { - my $code = $_[0]; - my $tmp_suffix = ¶m_value('tmp_base_suffix'); - my $result; - - $_ = $code; - - # cut off the suffix of eps, ps, *.gz and pstex graphics - s/((\\includegraphics)(\[[^]]*?\])?(\{[^}]+?))\.(e?ps|pstex|e?ps\.gz)\n?\}/$1}/sg; - - # replace the suffix 'pstex_t' with 'pdf_t' - s/(\\input\{[^}]+?\.)pstex_t\n?\}/$1pdf_t}/sg; - - if ( ¶m_value('mtp_preamble') eq $NO ) { - # cut off the suffix of mmp graphics - s/(\\multiinclude(\[[^]]*?\])?\{[^}]+?)\.mmp\n?\}/$1}/sg; - } else { - # replace the suffix '.#' with '-mp.#' - s/(\\includegraphics(\[[^]]*?\])?\{[^}]+?)\.(\d+?)\n?\}/$1$MTP_TMP_BASESUFFIX\.$3}/sg; - - # replace the suffix '.#' with '-mp.#' - s/(\\convertMPtoPDF(\[[^]]*?\])?\{[^}]+?)\.(\d+?)\n?\}/$1$MTP_TMP_BASESUFFIX\.$3}/sg; - - # cut off optional suffix '.mmp' and append '-mp' in any case - s/(\\multiinclude(\[[^]]*?\])?\{[^}]+?)(\.mmp)?\n?\}/$1$MTP_TMP_BASESUFFIX}/sg; - } - - # insert the tmp_suffix in tex filenames - # I assume that files with no extension are TeX files as well; correct? - s#(\\(input|include)\{([^}]*?/)?[^}/.]+?)((\.tex)?\n?\})#$1$tmp_suffix$4#sg; - - return $_; -} - -### Convert given tex file to the temp tex file we need for pdftex -### major task is to change the reference in the tex files to the -### corresponding tmp files -# parameter 1: tex source file -# parameter 2: tex tmp file -# parameter 3: reference to hyperref parameter list or -# 'undef' if preamble should not be changed - -sub convert_tex2tmp { - my $source = $_[0]; - my $target = $_[1]; - my $hyperref_params_ref = $_[2]; - my $contents; - my $preamble; - my $body; - my $adjust_preamble = defined($hyperref_params_ref) ? $YES : $NO; - my $read_err_msg = "Could not read original TeX document to generate temporary document"; - - ### open source and target file - &check_file($source, $read_err_msg . '.'); - open(SOURCE_FILE, "<$source") or - &abort($read_err_msg . " ($source)."); - - ### read in the LaTeX source file - $contents = ""; - while() { - $contents .= $_; - } - - close SOURCE_FILE; - - ### prepare the LaTeX code for PDF generation - if ( $adjust_preamble eq $YES ) { - $contents =~ m/^ *\\begin\{document\} *$/m; - $preamble = $`; - $body = $&.$'; - $preamble = &adjust_preamble($preamble, $hyperref_params_ref); - $preamble = &adjust_filenames($preamble); - } else { - $preamble = ""; - $body = $contents; - } - - $body = &adjust_filenames($body); - - ### write the new LaTeX target file - open(TARGET_FILE, ">$target") or - &abort("Could not open file to write temporary TeX document ($target)."); - - print TARGET_FILE $preamble.$body; - - close TARGET_FILE; -} - -### Convert the given EPS image to PDF -# parameters $1: EPS image filename with absolute path -# return value: none - -sub convert_eps2pdf { - my $image = $_[0]; - my $image_path; - my $image_base; - my $image_name; - my $suffix; - my $image_target; - my $zipped = 0; - my $dummy; - - ($image_base,$image_path,$suffix) = fileparse($image, '\.eps', '\.ps', '\.pstex', '\.gz'); - if ($suffix eq "\.gz") { - $zipped = 1; - ($image_base,$dummy,$suffix) = fileparse($image_base, '\.eps', '\.ps', '\.pstex'); - } - $image_name = $image_base . $suffix; - $image_target = $image_path . $image_base . '.pdf'; - - #### check if image file really exists - #&check_file($image, "Could not convert referenced image."); - - ### return if image directory is not writeable - if (! -w $image_path) { - &report(4, "WARNING - Image directory not writable: $image_path\n", - " Skipping '$image_name', assume you have converted it manually."); - return; - } - - if ( ! -f $image_target or -M $image_target > -M $image ) { - &report(7, "Converting image $image_name to $image_target ...\n"); - if ($zipped > 0) { - &system_command("gunzip -c $image | epstopdf -f -outfile=$image_target", - $TRUE, 8, "epstopdf failed on $image_name"); - } else { - &system_command("epstopdf -outfile=$image_target $image", - $TRUE, 8, "epstopdf failed on $image_name"); - } - if (¶m_value('delete_pdf_images') eq $YES) { - push(@TMPFILES, $image_target); - } - } else { - &report(7, "$image_base.pdf newer than $image_name, conversion skipped..."); - } -} - -### Convert the given PSTEX_T file to PDF_T -# parameters 1: PSTEX_T filename with absolute path -# return value: none - -sub convert_pstex2pdf { - my $pstex_file = $_[0]; - my $pstex_path; - my $pstex_base; - my $pstex_name; - my $suffix; - my $pstex_target; - my @eps_images; - - ($pstex_base,$pstex_path,$suffix) = fileparse($pstex_file, ('\.pstex_t')); - $pstex_name = $pstex_base . $suffix; - $pstex_target = $pstex_path . $pstex_base . '.pdf_t'; - - #### check if image file really exists - #&check_file($pstex_file, "Could not convert referenced file."); - - ### return if directory is not writeable - if (! -w $pstex_path) { - &report(4, "WARNING - Directory not writable: $pstex_path\n", - " Skipping '$pstex_name', assume you have converted it manually."); - return; - } - - # descend into file - &report(7, "Converting file $pstex_name ...\n"); - - # find included EPS image(s) - @eps_images=&identify_files($pstex_file, 'includegraphics', - ['pstex', 'pstex\.gz']); - - # create .pdf_t file - &convert_tex2tmp($pstex_file, $pstex_target, undef); - - # put tmp file in the tmp file list - push(@TMPFILES, $pstex_target); - - # convert image(s) to pdf - foreach my $image (@eps_images) { - &convert_eps2pdf($image); - } -} - -### Convert the given MP image to PDF -# parameters $1: MP image filename with absolute path -# return value: none - -sub convert_mp2pdf { - my $image = $_[0]; - my $image_path; - my $image_base; - my $image_name; - my $suffix; - my $image_target; - my $image_src; - my @mps_fig=(); - my $mp_fig; - - ($image_base,$image_path,$suffix) = fileparse($image, '\.mp|\.mmp'); - $image_name = $image_base . $suffix; - $image_src=$image_path . $image_base . $suffix; - - @mps_fig= &grep_file($image_path.$image_name,'beginfig',$TRUE); - $_=$mps_fig[0]; - /(\d)/; - $mp_fig=$1; - if (¶m_value('mtp_preamble') eq $YES) { - $image_target = $image_path . $image_base . $MTP_TMP_BASESUFFIX . '.' . $mp_fig; - $image_name=$image_base.$MTP_TMP_BASESUFFIX.$suffix; - } else { - $image_target = $image_path . $image_base . '.' . $mp_fig; - } - - #### check if image file really exists - #&check_file($image, "Could not convert referenced image."); - - ### return if image directory is not writeable - if (! -w $image_path) { - &report(4, "$MYNAME: WARNING - Image directory not writable: $image_path\n", - " Skipping '$image_name', assume you have converted it manually."); - return; - } - - if ( ! -f $image_target - or (-M $image_target > -M $image_src) - or ( ( ¶m_value('mtp_preamble') eq $YES) - and (-M $image_target > -M $image_path.$MTP_PREAMBLE_FILENAME) ) ) { - &report(7, "Converting image $image_name ...\n"); - my $working_dir = cwd."/"; - chdir("$image_path") or &abort("cannot cd to $image_path($!)"); - if ( ¶m_value('mtp_preamble') eq $YES ) { - &modify_mp_file($image_base,$suffix); - } - &system_command("mpost $image_name", - $TRUE, 8, "mpost failed on $image_name"); - chdir("$working_dir") or &abort("cannot cd to $working_dir($!)"); - if (¶m_value('delete_pdf_images') eq $YES) { - push(@TMPFILES, $image_target); - } - } else { - if ( ¶m_value('mtp_preamble') eq $YES ) { - &report(7, "$image_base$MTP_TMP_BASESUFFIX.$mp_fig newer than $image_base$suffix, conversion skipped..."); - } else { - &report(7, "$image_base.$mp_fig newer than $image_base$suffix, conversion skipped..."); - } - } -} - -### Convert the given MP image to PDF -# parameters $1: MP image filename with absolute path -# return value: none - -sub modify_mp_file { - my $base=$_[0]; - my $suffix=$_[1]; - my $preamble_file=$MTP_PREAMBLE_FILENAME; - - my $mp_source=$base.$suffix; - my $mp_target=$base.$MTP_TMP_BASESUFFIX.$suffix; - - ### open source and target file - open(SOURCE_FILE, "<$mp_source") or - &abort("Could not open $mp_source to add $preamble_file ($mp_source)."); - - open(TARGET_FILE, ">$mp_target") or - &abort("Could not open $mp_target to add $preamble_file ($mp_source)."); - - open(PREAMBLE_FILE, "<$preamble_file") or - &abort("Could not open $preamble_file to be added to metapost files ($mp_source)."); - - ### set target file as stdout - select TARGET_FILE; - print 'verbatimtex' . "\n"; - print '%&latex' . "\n"; # This forces metapost to use latex in the compilation - print '\documentclass[english]{article}' . "\n"; # we have to decide if this sentence goes in preamble.cfg or here - # english must be added - # to preamble in order to - # make work mpost, why ??? - while() { - print $_ - } - print '\begin{document}' . "\n"; # we have to decide if this sentence goes in preamble.cfg or here - print 'etex' . "\n"; - while() { - print $_ - } - print 'verbatimtex' . "\n"; - print '\end{document}' . "\n"; - print 'etex' . "\n"; - - ### set STDOUT as stdout again - select STDOUT; - - ### close files - close SOURCE_FILE; - close TARGET_FILE; - close PREAMBLE_FILE; - -} - - -### Convert included images to pdf -# parameter 1: tex source file -# no return value - -sub convert_images { - my $tex_source=$_[0]; - my @pstex_file_list; - my @image_list; - my @mp_image_list; - my @mmp_image_list; - my @major_suffixes; - my $ignore_regexp; - - &report(6, "\nConverting images referenced in $tex_source."); - - ##### Get images of major type from the source file - @major_suffixes = (@BITMAP_SUFFIXES, $PDF_ORIG_SUFFIX, @EPS_SUFFIXES); - $ignore_regexp = '.('.join('|',@EPS_SUFFIXES).')'; - $ignore_regexp =~ s/\./\\./g; - - &report(6, "\nScanning for major image types (".join(', ',@major_suffixes)."):"); - @image_list = &identify_files($tex_source,'includegraphics', - \@major_suffixes, $ignore_regexp ); - - if ( @image_list > 0 ) { - &report(7, join("\n", @image_list)); - } else { - &report(7, "None."); - } - - ##### Get PSTEX_T files from the source file - &report(6, "\nScanning for PSTEX_T files (.pstex_t):"); - @pstex_file_list=&identify_files($tex_source, 'input', ['pstex_t']); - if ( @pstex_file_list > 0 ) { - &report(7, join("\n", @pstex_file_list)); - } else { - &report(7, "None."); - } - - ##### Get MP images from the source file - &report(6, "\nScanning for MP images (.mp):"); - @mp_image_list=&identify_files($tex_source, - 'convertMPtoPDF|includegraphics',['mp','(\d+)'],'\.(\d+)'); - # FIXME - # fixed for now by ignoring strange extension in identify_files - # - # the above could cause problems as identify_files is expecting a list of - # real extensions and not of regexps - # maybe the only way to fix this is to adjust identify_files to ignore - # invalid extension when testing them with kpsewhich - # ALTERNATIVE: design identify_files to use preffered_suffixes instead - # of ignore_suffixes - - if ( @mp_image_list > 0 ) { - &report(7, join("\n", @mp_image_list)); - } else { - &report(7, "None."); - } - - ##### Get MMP images from the source file - &report(6, "\nScanning for MMP images (.mmp):"); - @mmp_image_list=&identify_files($tex_source,'multiinclude',['mmp']); - if ( @mmp_image_list > 0 ) { - &report(7, join("\n", @mmp_image_list)); - } else { - &report(7, "None."); - } - - ### Convert EPS images to PDF, copy pdf.orig image files to pdf, - ### and simply ignore all other - if ( @image_list > 0) { - my $handled_suffixes; - - &report(6, "\nProcessing images of major types:"); - - # create one large regexp from suffixes and escape dots in them - $handled_suffixes = '.('.join('|',(@EPS_SUFFIXES, $PDF_ORIG_SUFFIX)).')'; - $handled_suffixes =~ s/\./\\./g; - - foreach my $image (@image_list) { - my $path; - my $base; - my $suffix; - ($base,$path,$suffix) = fileparse($image, $handled_suffixes); - if (not $suffix) { - &report(7, "No special handling required for image: $base$suffix"); - } elsif ($suffix eq ('.'.$PDF_ORIG_SUFFIX) ) { - my $image_target = $path.$base.'.pdf'; - - if ( ! -f $image_target or -M $image_target > -M $image ) { - &report(7, "Create temporary PDF file from original: $base$suffix"); - copy($image, $image_target) - or &abort("Could not create tmp file: $!"); - if (¶m_value('delete_pdf_images') eq $YES) { - push(@TMPFILES, $image_target); - } - } else { - &report(7, "$base.pdf newer than $base$suffix, copy skipped ..."); - } - } else { - &convert_eps2pdf($image); - } - } - } - - ### Convert all PSTEX_T files to PDF_T - if ( @pstex_file_list > 0 ) { - &report(6, "\nConverting pstex_t docs to pdf_t docs"); - foreach my $image (@pstex_file_list) { - &convert_pstex2pdf($image); - } - } - - ### Convert all MP images to PDF - if ( @mp_image_list > 0) { - &report(6, "\nConverting MP images to PDF"); - foreach my $image (@mp_image_list) { - &convert_mp2pdf($image); - } - } - - ### Convert all MMP images to PDF - if ( @mmp_image_list > 0) { - &report(6, "\nConverting MMP images to PDF"); - foreach my $image (@mmp_image_list) { - &convert_mp2pdf($image); - } - } - - &report(6, "\nFinished converting for ${tex_source}."); -} - -### run pdflatex -# parameter 1: LaTeX file without extension -# parameter 2: log-file where the full out put is stored -# return value: 0 - no errors (no rerun); 1 - errors (rerun required) - -sub run_pdflatex { - my $texfile=$_[0]; - my $logfile=$_[1]; - my @errors=(); - my $exit_status=0; - my $extra_options=¶m_value('pdftex_opts'); - - if( !defined($extra_options) or $extra_options eq $NIL ) { - $extra_options = ""; - } - - &report(7, "Running pdflatex. This may take a while.\n"); - system("pdflatex --interaction nonstopmode $extra_options $texfile > $logfile 2>&1"); - $exit_status=$?; - &report(7, "Pdflatex finished. Errors:"); - - ### extract all errors and warnings from the log file - @errors = &grep_file($logfile, '(Emergency stop|Error|Warning).*:'); - - ### make sure thumbpdf package does not spoil rerun detection - ### as it will be processed very last - if(grep(/Package thumbpdf/, @errors) == @errors) { @errors=(); } - - if ( @errors != 0 or $exit_status != 0 ) { - if ( grep(/Emergency stop/, @errors) != 0 ) { - &report(2, &file_tail($logfile,10)); - &report(2, "\nSee $logfile for details."); - &abort("Fatal error occured. I am lost."); - } - if( @errors != 0 ) { - &report(8, @errors); - } else { - &report(8, &file_tail($logfile,10)); - } - &report(7, "\nSee $logfile for details."); - return $FALSE; - } else { - &report(7, "None detected (log file: $logfile)."); - return $TRUE; - } -} - -#### run bibtex if BIBTEX=$YES or a bibliography tag is found -# included tex files are not parsed for a bibliography -# parameter 1: filename of the aux file without .aux suffix -# parameter 2: log-file where the full out put is stored - -sub handle_bibtex { - my $auxfile=$_[0]; - my $logfile=$_[1]; - my $run_bibtex=$FALSE; - my $bibtex_param=¶m_value('bibtex'); - - if ( $bibtex_param eq $YES ) { - $run_bibtex=$TRUE; - &report(7, "BibTeX parameter set to '$YES':"); - } else { - &report(7, "Checking for BibTeX bibliography in main document: "); - if( &grep_file($auxfile.'.tex', '^[^%]*\\\\bibliography{') != 0) { - $run_bibtex=$TRUE; - &report(7, "Bibliography detected."); - } else { - if ( @REF_DOCS > 0 ) { - &report(7, "Checking for BibTeX bibliography in included documents:"); - foreach my $file (@REF_DOCS) { - if( &grep_file($file, '^[^%]*\\\\bibliography{') != 0) { - $run_bibtex=$TRUE; - &report(7, "Bibliography detected."); - } else { - &report(7, "No bibliography detected in $file."); - } - } - } else { - &report(7, "No bibliography detected."); - } - } - } - - if ( $run_bibtex ) { - my @errors=(); - my $exit_status=0; - - &report(7, "Running bibtex. This may take a while.\n"); - system "bibtex $auxfile > $logfile"; - $exit_status=$?; - &report(7, "Bibtex finished. Errors:"); - - ### extract all errors and warnings from the log file - @errors=&grep_file($logfile, 'error message'); - - if ( @errors != 0 or $exit_status != 0 ) { - &report(4, &file_tail($logfile)); - &report(4, "\nYou can switch off BibTeX support by setting the bibtex parameter accordingly."); - } else { - &report(7, "None detected (log file: $logfile)."); - } - } -} - -#### run bibtex on file.gls if BIBTEX=$YES or a bibliography tag is found -# included tex files are not parsed for a bibliography -# parameter 1: filename of the aux file without .aux suffix -# parameter 2: log-file where the full out put is stored - -sub handle_gloss { - my $auxfile=$_[0]; - my $logfile=$_[1]; - my $run_gloss=$FALSE; - my $gloss_param=¶m_value('gloss'); - my $glsfile=$auxfile.'.gls'; - - if ( $gloss_param eq $YES ) { - $run_gloss=$TRUE; - &report(7, "Gloss parameter set to '$YES':"); - } else { - &report(7, "Checking for Gloss bibliography in main document: "); - if( &grep_file($auxfile.'.tex', '^[^%]*\\\\printgloss{') != 0) { - $run_gloss=$TRUE; - &report(7, "Gloss bibliography detected."); - } else { - if ( @REF_DOCS > 0 ) { - &report(7, "Checking for Gloss bibliography in included documents:"); - foreach my $file (@REF_DOCS) { - if( &grep_file($file, '^[^%]*\\\\printgloss') != 0) { - $run_gloss=$TRUE; - &report(7, "Gloss bibliography detected."); - } else { - &report(7, "No gloss database detected in $file."); - } - } - } else { - &report(7, "No gloss database detected."); - } - } - } - if ( $run_gloss ) { - my @errors=(); - my $exit_status=0; - - &report(7, "Running bibtex on $glsfile. This may take a while.\n"); - system "bibtex $glsfile > $logfile 2>&1"; - $exit_status=$?; - &report(7, "Bibtex finished. Errors:"); - - ### extract all errors and warnings from the log file - @errors=&grep_file($logfile, 'error message'); - - if ( @errors != 0 or $exit_status != 0 ) { - &report(4, &file_tail($logfile)); - &report(4, "\nYou can switch off Gloss support by setting the gloss parameter accordingly."); - } else { - &report(7, "None detected (log file: $logfile)."); - } - } -} - -#### run thumbpdf command to make thumbnails -# more informations: /usr/share/texmf/doc/pdftex/thumbpdf/readme.txt -# parameter 1: LaTeX file without extension -# parameter 2: log-file where the full out put is stored - -sub run_thumbpdf { - my $texfile=$_[0]; - my $logfile=$_[1]; - my $exit_status=0; - - &report(7, "\nCreating thumbnails with 'thumbpdf'\n"); - &system_command("thumbpdf $texfile", $FALSE, 8, - "thumbpdf failed.\n" - ."I will continue, but maybe there will not be thumbs in the PDF doc."); - - if ( -f 'thumbpdf.log' ) { - move('thumbpdf.log', $logfile); - &report(7, "\nSee $logfile for details."); - } - - ### store possible tmp files - push(@TMPFILES, glob 'thumb???.png'); - push(@TMPFILES, 'thumbpdf.pdf'); - push(@TMPFILES, 'thumbdta.tex'); - push(@TMPFILES, $texfile.'.tpt'); -} - - -#### run ppower command to make presentations -# more informations: -# parameter 1: LaTeX file without extension -# parameter 2: log-file where the full out put is stored - -sub run_ppower { - my $texfile=$_[0]; - my $logfile=$_[1]; - my $exit_status=0; - my $infile; - my $outfile; - my $texfile_base; - my $texfile_path; - my $texfile_suffix; - - ##### Getting document name, suffix and path - ($texfile_base,$texfile_path,$texfile_suffix) = fileparse($texfile,¶m_value('tmp_base_suffix')); - - $infile=$texfile_base.'.pdf'; - $outfile=$texfile_base.'_p4.pdf'; - - &report(7, "\nPostprocessing PDF file with 'ppower'\n"); - if(&system_command("ppower $infile $outfile", $FALSE, 8, - "ppower failed.\nI will continue, " - ."but maybe there will not be pause effects in the PDF doc.")) { - &report(7, "\nThe postprocessed pdf file is: $outfile\n"); - } - - if ( -f 'ppower.log' ) { - move('ppower.log', $logfile); - &report(7, "See $logfile for details."); - } -} - -#### run authorindex command to obtain an author index -# more informations: -# parameter 1: LaTeX file without extension -# parameter 2: log-file where the full out put is stored - -sub run_authorindex { - my $texfile=$_[0]; - my $logfile=$_[1]; - my $exit_status=0; - - &report(7, "\nProcessing file with 'authorindex'\n"); - &system_command("authorindex $texfile", $FALSE, 8, - "authorindex failed.\nI will continue, " - ."but maybe there will not be an author index in the PDF doc."); - - if ( -f 'authorindex.log' ) { - move('authorindex.log', $logfile); - &report(7, "\nSee $logfile for details."); - } - -} - - -##### read and analyse configuration and options and adjust basic variables -##### accordingly -#### The following sources are considered (last value overrides previous) -## 1. general configuration (global variables in the script) -## 2. private configuration (in user's RC file) -## 3. command line options -# parameters: none -# return value: given document argument - -sub adjust_configuration { - my $valid_rcfile = $FALSE; - my %opt_specs =(); - - ### Check number of arguments - if ( @ARGV == 0 ) { - &report(1, "\nI need at least one argument!"); - &print_usage; - exit 1; - } - - ##### command line options and private configuration files handling - - ### set parameters from rc file - if ( -f $RC_FILENAME ) { - my $rcfile_version; - $rcfile_version = &read_configuration($RC_FILENAME); - if( $rcfile_version == $MYRCFILE_VERSION ) { - $valid_rcfile = $TRUE; - } elsif ( $rcfile_version == 0 ) { - &report(4, "Could not determine version of read RC file."); - } else { - &report(4, "Version of read RC file ($rcfile_version) and ", - "this script ($MYRCFILE_VERSION) differs."); - } - } - - ### scan parameters - foreach (keys %PARAMETER_LIST) { - $opt_specs{&option_specifier($_)} = \&handle_option; - } - if(! GetOptions(%opt_specs)) { - &print_usage; - &abort("An error occured while processing command line options"); - } - - if( ! $valid_rcfile ) { - &report(3,"No valid configuration file found. Please run '$MYNAME " - ."--configure'.\nUsing default values for missing parameters in this " - ."session."); - } - - ### As the configuration process is done now, it is time to set the - # global configuration flag - $CONFIGURED = $TRUE; - - #### do some test in order to secure as good as possible that we will - #### succeed before to much work was done and maybe some data as damaged - - ### make sure that tmp_base_suffix is not empty - if ( ¶m_value('tmp_base_suffix') eq "" ) { - &report(2, "\nCAUTION: Empty tmp_base_suffix would destroy the original files!"); - &abort("Parameter tmp_base_suffix is not set."); - } - - ##### check for required commands - if (¶m_value('check_commands') ne $NO ) { - &check_commands; - } - - ### Check number of arguments - if ( @ARGV != 1 ) { - &report(1, "\nWrong number of arguments. I need exactly one file."); - &print_usage; - exit 1; - } - - return $ARGV[0]; -} - -#### prepare the logdir for the log files of the various called appplications - -sub prepare_logdir { - my $log_dir= ¶m_value('logdir'); - my $my_new_log; - - ##### Preparing the LOGDIR - if (! &check_dir($log_dir, "Could not create log directory", $YES)) { - &abort("Please, set a different path and restart"); - } - - # make sure there is a slash at the end of the path - $log_dir .= '/' if( ! ($log_dir =~ m#/$#) ); - - if( <$log_dir/*.log> and ¶m_value('clean_logs') eq $YES ) { - &report(6, "\nRemoving old log files ($log_dir)."); - unlink (<$log_dir/pdflatex-*.log>, <$log_dir/bibtex-*.log>, - <$log_dir/gloss-*.log>, <$log_dir/thumbpdf-*.log>, - <$log_dir/ppower-*.log>, <$log_dir/authorindex-*.log>, - <$log_dir/tex2pdf-*.log>); - } else { - &report(6, "\nAll log files will be stored in ($log_dir)."); - } - - ### move my pre-configuration log file to specified log directory - $my_new_log = "$log_dir/tex2pdf-$$.log"; - if ( move($MYLOGFILE, $my_new_log) ) { - $MYLOGFILE = $my_new_log; - } else { - &report(3, "Could not move '$MYLOGFILE' to logdir: $!"); - } -} - -##### analyse document argument -#### process the one and only argument (besides the options) which specifies -#### which LaTeX document the user wants to translate to PDF -#### a lyx file will be translated to LaTeX first -# parameter 1: argument - -sub process_doc_argument { - my $argument = $_[0]; - my $doc_base; - my $doc_path; - my $arg_suffix; - - ##### Getting document name, suffix and path - ($doc_base,$doc_path,$arg_suffix) = fileparse($argument, ('\.tex', '\.lyx')); - - if (! defined($arg_suffix) or $arg_suffix eq "") { - $arg_suffix = '.tex'; - } - - ###### change working directory to document directory - if ( $doc_path ne "" ) { - chdir $doc_path; - } - - ###### make DOCPATH an absolute path - $doc_path = cwd.'/'; - - ###### Cut off suffix and do lyx or tex specific stuff - if ( $arg_suffix eq '.lyx' ) { - # Lyx document argument: generate Latex document if required - &generate_tex_file($doc_base.'.lyx', $doc_base.'.tex'); - } else { - # LaTeX document argument: check access to given LaTeX document - &check_file($doc_base.'.tex', "Cannot read the specified LaTeX document!"); - } - - return $doc_path.$doc_base.'.tex'; -} - -#### handle the dir of the input path if the document has one and -# parameter 1: main tex doc -# return value: absolute input path - -sub process_inputpath { - my $texdoc = $_[0]; - my $doc_base; - my $doc_path; - my $doc_suffix; - my $input_path; - my @matches; - - ### Maybe the user has given us a different inputpath - $input_path = ¶m_value('input_path'); - if(defined($input_path) and $input_path ne "") { - &report(6, "Setting input path to specified directory: $input_path"); - - &report(7, "Change working directory to input path."); - chdir $input_path; - - return $input_path; - } - - ##### Getting document name, suffix and path - ($doc_base,$doc_path,$doc_suffix) = fileparse($texdoc, ('\.tex')); - - ###### change working directory to input_path if set - # When the files' path (images, included documents, etc.) in your document is - # relative to another directory than the PASSED document's directory. - # This is useful when the calling application (e.g. LyX) generates a - # temporary - # TeX file and calls the tex2pdf with it instead of the original file. - - @matches=&extract_tag_contents($texdoc, 'def\\\\input@path'); - $input_path=$matches[0]; - - ## check if input_path is ok - if ($input_path) { - &report(7, "Found an input path in the latex document: $input_path"); - if( &check_dir($input_path, 'The retrieved input@path seems not to be valid.', $NO)) { - &set_param_value('input_path', $input_path); - &report(7, "Change working directory to input path."); - chdir $input_path; - } else { - &abort ('I am lost.'); - } - } else { - &report(4, "No input path in the latex document found."); - &report(7, "Resources are expected to be relative to document's location: $doc_path"); - $input_path=$doc_path; - } - - return $input_path; -} - -#### set the working dir to the input path if the document has one and -#### and determine the path for the result -# parameter 1: main tex doc -# parameter 2: absolute input path -# return value: absolute path were the resulting pdf doc should be stored - -sub get_target_name { - my $texdoc = $_[0]; - my $input_path=$_[1]; - - my $doc_base; - my $doc_path; - my $doc_suffix; - my $destination; - my $pdf_path; - - ##### Getting document name, suffix and path - ($doc_base,$doc_path,$doc_suffix) = fileparse($texdoc, ('\.tex')); - - ##### set the directory where the final pdf will be stored - $destination=¶m_value('destination'); - $pdf_path=undef; - - if ($destination eq 'custom' ) { - $pdf_path=¶m_value('custom_path'); - } elsif ($destination eq 'input') { - $pdf_path=$input_path; - } else { - $pdf_path=$doc_path; - } - - if( ! defined($pdf_path) or $pdf_path eq "" or ! &check_dir($pdf_path, - 'The specified destination directory for the final PDF documents is not valid.', $NO)) { - &report(7, "Using document's instead of destination path: $doc_path"); - $pdf_path=$doc_path; - } - - # make sure there is a slash at the end of the path - $pdf_path .= '/' if( ! ($pdf_path =~ m#/$#) ); - - return $pdf_path.$doc_base.'.pdf'; -} - -### generate hyperref parameters from given settings -# parameter 1: main tex doc -# return_value: result - -sub generate_hyperref_params { - my $texdoc = $_[0]; - my $para; - my @params = ('pdftex'); - - ##### Set title and author from main LaTeX document or parameters - foreach my $info (('title', 'author')) { - my $value; - - $value=¶m_value("$info"); - if (! defined($value) ) { - my @matches=&extract_tag_contents($texdoc, $info); - $value= $matches[0]; - if (! defined($value) ) { - &report(4, "\nWARNING: Could not identify document's $info correctly."); - &report(7, "Maybe you have used a LaTeX tag inside the $info which confuses me.\n", - "Adjust the $info of the LaTeX file in order to avoid the problem or\n", - "you could set the $info parameter manually."); - $value= ¶m_value("default_$info"); - &report(7, "Using default-$info: $value"); - } - } - if (! defined($value) or $value eq $NIL ) { - &report(7, "$info field set to $NIL - no value will be passed."); - } else { - &report(7, "Document's $info: $value"); - push(@params, "pdf$info={$value}"); - } - } - - $para=¶m_value('paper'); - if ( $para ne $NIL ) { push(@params, $para); } - - $para=¶m_value('link_toc_page'); - if ( $para eq $YES ) { push(@params, 'linktocpage'); } - - $para=¶m_value('colorlinks'); - if ( $para ne $NIL ) { - $para= $para eq $YES ? 'true' : 'false'; - push(@params, "colorlinks=$para"); - } - - if ( $para ne 'false' ) { - foreach (('linkcolor', 'pagecolor', 'urlcolor', 'citecolor')) { - $para=¶m_value($_); - if ( $para ne $NIL ) { push(@params, "$_={$para}"); } - } - } - - $para=¶m_value('hyperref_args'); - if(defined($para) and $para ne "" and $para ne $NIL) { - push(@params, $para); - } - - return @params; -} - -#### Prepare the main document and all referenced ones for the generation -#### of the PDF document (including referenced images) -# parameter 1: top level tex document -# parameter 2: parameter list of hyperref parameters - -sub prepare_documents { - my ($main_tex_doc, $input_path, @hyperref_params) = @_; - @REF_DOCS=(); - - ## get a name for the tmp tex file - my $main_tmp_doc = &reserve_tmp_texname($main_tex_doc, $input_path); - - ## Get the list of imported files from the tex file - &get_file_list($main_tex_doc); - - ## remove main file from list (first element; needs special handling) - shift @REF_DOCS; - - ## tell user about the identified refereneced docs - if ( @REF_DOCS > 0 ) { - &report(7, "\nFound the following referenced TeX files:"); - foreach my $file (@REF_DOCS) { - &report(7, ">>>>> $file"); - } - } else { - &report(7, "\nFound no referenced TeX files."); - } - - ##### Generate adjusted temp tex files and convert all their images - ## main doc - &report(6, "\nGenerating main temporary LaTeX document: $main_tmp_doc"); - &convert_tex2tmp($main_tex_doc, $main_tmp_doc, \@hyperref_params); - &convert_images($main_tex_doc); - - ## referenced docs - foreach my $file (@REF_DOCS) { - my $tmp_file = &reserve_tmp_texname($file); - - ### Insert pdf conversation tags in tex file and write it to tmp_file - &report(7, "\nGenerating temporary LaTeX document: $tmp_file"); - &convert_tex2tmp($file, $tmp_file, undef); - &convert_images($file); - } - - return $main_tmp_doc; -} - -##### Generate the final PDF document -# parameter 1: filename of the source LaTeX document (with extension) - -sub generate_pdf_doc { - my $source = $_[0]; - my $runno=1; - my $rerun=$TRUE; - my $doc; - my $pdf_doc; - my $base; - my $path; - my $suffix; - - my $max_run_no= ¶m_value('maxrun'); - my $min_run_no= ¶m_value('minrun'); - my $log_dir= ¶m_value('logdir'); - $log_dir .= '/' if( ! ($log_dir =~ m#/$#) ); - my $makeindex_options=¶m_value('makeindex_opts'); - - # setting the log files for the output of pdflatex, bibtex, gloss, - # thumbpdf, ppower and authorindex - my $pdflog_base = $log_dir."pdflatex-$$-"; - my $bibtex_log = $log_dir."bibtex-$$.log"; - my $gloss_log = $log_dir."gloss-$$.log"; - my $thumbpdf_log = $log_dir."thumbpdf-$$.log"; - my $ppower_log = $log_dir."ppower-$$.log"; - my $authorindex_log = $log_dir."authorindex-$$.log"; - - ##### Getting document name, suffix and path - ($base,$path,$suffix) = fileparse($source, ('\.tex')); - $doc = $path.$base; - $pdf_doc = $base.'.pdf'; - - ### run pdflatex until no more errors are reported (max MAXRUNNO) - while ( $rerun and $runno <= $max_run_no ) - { - &report(6, "\n************ Pdflatex run no. $runno *************"); - if ( &run_pdflatex($doc, $pdflog_base.$runno.'.log') == $TRUE - and ( $min_run_no <= $runno )) { - # no errors detected and min. no. of runs are done - $rerun=$FALSE; - } else { - # errors appeared or max run no. has not been reached - $rerun=$TRUE; - } - - ### Execute BibTeX after first run if set (and required) - if ( $runno == 1 and ¶m_value('bibtex') ne $NO ) { - &report(6, "\n****************** BibTeX handling ***********************"); - &handle_bibtex($doc, $bibtex_log); - } - - ### Execute BibTeX on file.gls after first run if set (and required) - if ( $runno == 1 and ¶m_value('gloss') ne $NO ) { - &report(6, "\n****************** Gloss handling ***********************"); - &handle_gloss($doc, $gloss_log); - } - - ### generated index file exists - if ( $runno == 1 and -f $doc.'.idx' and ¶m_value('force_index') ne $NO ) { - if( !defined($makeindex_options) or $makeindex_options eq $NIL ) { - $makeindex_options = ""; - } - &report(6, "\n****************** Extra index generation ***************"); - &report(7, "Document seems to have an index. Generating ...\n"); - &system_command("makeindex $makeindex_options $doc.idx", $FALSE, 8, - "makeindex failed.\nI will continue, " - ."but maybe there will not be an index in the PDF doc."); - } - - $runno += 1; - } - - $rerun = $FALSE; - - ### if the authorindex option is switched on then run authorindex - if ( ¶m_value('authorindex') eq $YES ) { - &report(6, "\n****************** authorindex generation *****************"); - &run_authorindex($doc, $authorindex_log); - } - - ### generated index file exists - if ( -f $doc.'.idx' and ¶m_value('force_index') ne $NO ) { - if( !defined($makeindex_options) or $makeindex_options eq $NIL ) { - $makeindex_options = ""; - } - &report(6, "\n****************** Extra index generation ***************"); - &report(7, "Document seems to have an index. Generating ...\n"); - &system_command("makeindex $makeindex_options $doc.idx", $FALSE, 8, - "makeindex failed.\nI will continue, " - ."but maybe there will not be an index in the PDF doc."); - $rerun=$TRUE; - } - - ### if the thumbpdf option is switched on then make thumbnails - if ( ¶m_value('thumbpdf') eq $YES ) { - &report(6, "\n****************** Thumbnail generation *****************"); - &run_thumbpdf($doc, $thumbpdf_log); - $rerun=$TRUE; - } - - ### One final pdflatex run if requested - if ( $rerun ) { - &report(6, "\n************ One final pdflatex run no. $runno *************"); - &run_pdflatex($doc, $pdflog_base.$runno.'.log'); - } - - ### if the ppower option is switched on then run ppower - if ( ¶m_value('ppower') eq $YES ) { - &report(6, "\n****************** ppower postprocess *****************"); - &run_ppower($doc, $ppower_log); - } - - if ( ! -f $pdf_doc ) { - &abort("\nThe new PDF file could not be generated: ".$pdf_doc); - } - - return $pdf_doc; -} - -################## Lift off !!!! (main part) ################## - -my $texdoc; -my $doc_argument; -my $input_path; -my $target_name; -my @hyperref_params; -my $new_pdf_doc; -my $tmp_tex_doc; - -&report(5, "\nScript starts ($MYRELEASE)"); - -##### read and analyse configuration and options and adjust basic variables -##### accordingly -##### write RC file on config request -#### use the finished configuration to get all further settings before we -#### actually start doing something - -&report(5, "\nProcessing given parameters and arguments."); -$doc_argument = &adjust_configuration; - -#### prepare the script to write some information to specified log files - -&report(5, "\nPreparing directory for log files."); -&prepare_logdir; - -#### process the one and only argument (besides the options) which specifies -#### which LaTeX document the user wants to translate to PDF -#### a lyx file will be translated to LaTeX first - -&report(5, "\nAnalysing your document argument."); -$texdoc = &process_doc_argument($doc_argument); - -#### we would like to get some more information from the actual -#### main LaTeX document before we really start -#### parse the document and try to get the info - -## translate hyperref settings to the actual package parameters - -&report(5, "\nSetting up parameters for hyperref."); -@hyperref_params = &generate_hyperref_params($texdoc); - -## set the working dir to the input path if the document has one and - -&report(5, "\nProcessing input path for main tex document."); -$input_path = &process_inputpath($texdoc); - -## determine the name for the result - -&report(5, "\nSetting the correct name for the result."); -$target_name = &get_target_name($texdoc, $input_path); - -## as much as possible is prepared in advance at this point -## so hopefully we will succeed in generating the PDF document - -##### real work starts NOW - -##### Generate adjusted temp tex files and convert all their images - -&report(5, "\nPreparing all documents and images."); -$tmp_tex_doc = &prepare_documents($texdoc, $input_path, @hyperref_params); - -##### Generate the final PDF document - -&report(5, "\nProcessing the actual generation of the PDF document."); -$new_pdf_doc = &generate_pdf_doc($tmp_tex_doc); - -##### Finalize -move($new_pdf_doc, $target_name) or &abort("Could not move PDF file to final destination: $!"); - -if ( ¶m_value('debug') eq $NO ) { - &clean_up; -} else { - &print_temp_files; -} - -&report(5, "\nThe new pdf file is: $target_name\n"); - diff --git a/lustre/extN/.cvsignore b/lustre/extN/.cvsignore deleted file mode 100644 index 8a8af37..0000000 --- a/lustre/extN/.cvsignore +++ /dev/null @@ -1,19 +0,0 @@ -.Xrefs -Makefile -Makefile.in -.deps -TAGS -balloc.c -bitmap.c -dir.c -file.c -fsync.c -ialloc.c -inode.c -ioctl.c -namei.c -super.c -symlink.c -xattr.c -patch-stamp -sed-stamp diff --git a/lustre/extN/Makefile.am b/lustre/extN/Makefile.am deleted file mode 100644 index 2ff23b0..0000000 --- a/lustre/extN/Makefile.am +++ /dev/null @@ -1,146 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS=-DEXPORT_SYMTAB -MODULE = extN -modulefs_DATA = extN.o -EXTRA_PROGRAMS = extN - -# NOTE: If you are not using a RedHat 12.5 or later kernel, then you need to -# apply the "fixes" patch first, as it fixes a number of bugs in ext3. -# It will be applied automatically by the extN build process, or you -# can apply it to the source kernel tree and fix ext3 also. For chaos22 -# (or other RH < 12.5 kernels) use the "chaos22" patch instead. -EXTN_FIXES = ../patches/patch-2.4.18-chaos22 -#EXTN_FIXES = ext3-2.4.18-fixes.diff -EXTNP = htree-ext3-2.4.18.diff linux-2.4.18ea-0.8.26.diff -EXTNP+= ext3-2.4.18-ino_sb_macro.diff extN-misc-fixup.diff -EXTNC = balloc.c bitmap.c dir.c file.c fsync.c ialloc.c inode.c ioctl.c -EXTNC+= namei.c super.c symlink.c -EXTNI = extN_fs.h extN_fs_i.h extN_fs_sb.h extN_jbd.h quotaops.h -EXTN_EXTRA = include/linux/xattr.h include/linux/extN_xattr.h fs/extN/xattr.c -EXTN_EXTRA += include/linux/quotaops.h -extN_SOURCES = $(EXTNC) xattr.c # punch.c -extN_DEPENDENCIES = patch-stamp -EXTRA_DIST = $(EXTNP) $(EXTN_FIXES) \ - extN-2.4.18-ino_sb_fixup.diff extN-2.4.18-exports.diff \ - $(wildcard extN.patch-*) -DISTCLEANFILES = -r $(extN_SOURCES) sed-stamp patch-stamp *.orig *.rej -SUB=-e "s/ext3/extN/g" -e "s/EXT3/EXTN/g" -e "s/extern __inline__/static inline/" - -distclean: - cd .. && rm -f $(EXTN_EXTRA) - -include $(top_srcdir)/Rules - -# Following 2 vars are for buildind outside the source tree. -extN_orig = $(top_builddir)/$(subdir)/extN.orig -extN_include_orig = $(top_builddir)/$(subdir)/extN-include.orig - -# Create a fresh extN patch. -# This is for when the patch-stamp target fails for your kernel. -# Just edit the files until you like them, then do `make diff', and -# it will create a specialized patch for your particular kernel. -# Check it in, and the build should work for you without disrupting -# the other developers. -# Of course, the ideal is to merge changes so that the default patch -# set works for nearly everybody. This is mainly for damage control. - -diff: - $(RM) extN.patchT - l='$(EXTNC)'; for f in $$l; do \ - echo "$$f"; \ - (diff -u $(extN_orig)/$$f extN/$$f) >> extN.patchT; \ - test $$? -le 1 || exit 1; - done - l='$(EXTNI)'; for f in $$l; do \ - echo "$$f"; \ - (diff -u $(extN_include_orig)/$$f $(top_srcdir)/include/linux/$$f)>>extN.patchT;\ - test $$? -le 1 || exit 1; - done - l='$(EXTN_EXTRA)'; for f in $$l; do \ - f=`echo "$$f" | sed 's%^fs/%%'`; \ - echo "$$f"; \ - (cd $(top_srcdir) && \ - diff -u /dev/null $$f) >> extN.patchT; \ - test $$? -le 1 || exit 1; - done - mv -f extN.patchT $(top_builddir)/$(subdir)/extN.patch-$(RELEASE) - echo "Don't forget to add $(srcdir)/extN.patch-$(RELEASE) to CVS!" - - - -.PHONY: diff - -# Just do the SUB transformation on all our source files. - - -sed-stamp: - $(RM) $@ - rm -rf $(extN_orig) $(extN_include_orig) - mkdir $(extN_orig) $(extN_include_orig) - list='$(EXTNC)'; for f in $$list; do \ - echo "creating $(extN_orig)/$$f"; \ - sed $(SUB) $(LINUX)/fs/ext3/$$f > $(extN_orig)/$$f; \ - done - list='$(EXTNI)'; for i in $$list; do \ - s=`echo $$i | sed "s/extN/ext3/"`; \ - echo "creating $(extN_include_orig)/$$i"; \ - sed $(SUB) $(LINUX)/include/linux/$$s > $(extN_include_orig)/$$i; \ - done - echo timestamp > $@ - - -# Patch the kernel files with our ext3 patches. We need to go through some -# extra hoops because the include files are in a different tree and because -# patch likes to make local copies of files with (sym)links when it is patching -# them. To avoid this, we copy/patch in the source dir instead of the build -# dir (if they are different). -# We also want to preserve the pristine transformed files for the diff target. - - - -patch-stamp: sed-stamp $(EXTNP) - test -e $(top_builddir)/include/linux || mkdir -p $(top_builddir)/include/linux - cp -a $(extN_orig)/* $(top_builddir)/$(subdir) - cp -a $(extN_include_orig)/* $(top_builddir)/include/linux - test -e $(top_builddir)/fs || ln -s . $(top_builddir)/fs - list='$(EXTN_EXTRA)'; for f in $$list; do $(RM) $(top_builddir)/$$f; done - if [ -f $(srcdir)/extN.patch-$(RELEASE) ]; then \ - echo "applying patch $(srcdir)/extN.patch-$(RELEASE)"; \ - (cd $(top_builddir) && patch -p0) < $(srcdir)/extN.patch-$(RELEASE); \ - else \ - echo "If first patch fails, read NOTE in extN/Makefile.am"; \ - list='$(EXTNP)'; \ - sed '/i_version/q' $(extN_orig)/namei.c | tail -2 | \ - grep extN_mark_inode_dirty >/dev/null && list="$(EXTN_FIXES) $$list"; \ - for p in $$list; do \ - echo "applying patch $$p"; \ - sed $(SUB) $(srcdir)/$$p | \ - (cd $(top_builddir) && patch -p1) || exit $$?; \ - done; \ - echo "It is OK if the next patch says it is already applied"; \ - echo "applying patch $(srcdir)/extN-2.4.18-exports.diff"; \ - (cd $(top_builddir) && \ - patch -N -p1) < $(srcdir)/extN-2.4.18-exports.diff; \ - echo "applying patch $(srcdir)/extN-2.4.18-ino_sb_fix.diff"; \ - (cd $(top_builddir) && \ - patch -p1) < $(srcdir)/extN-2.4.18-ino_sb_fixup.diff || exit $$?; \ - fi - echo timestamp > $@ - - - - -$(extN_SOURCES) $(EXTNI) $(EXTN_EXTRA): patch-stamp - -# Don't distribute any patched files. -dist-hook: - $(RM) $(top_srcdir)/fs - list='$(EXTNC)'; for f in $$list; do $(RM) $(distdir)/$$f; done - list='$(EXTNI)'; for i in $$list; do \ - $(RM) $(distdir)/../include/linux/$$i; \ - done - list='$(EXTN_EXTRA)'; for f in $$list; do $(RM) $(distdir)/../$$f; done diff --git a/lustre/extN/ext3-2.4.18-fixes.diff b/lustre/extN/ext3-2.4.18-fixes.diff deleted file mode 100644 index 56e841e..0000000 --- a/lustre/extN/ext3-2.4.18-fixes.diff +++ /dev/null @@ -1,353 +0,0 @@ -diff -ru lum-2.4.18-um30/fs/ext3/balloc.c uml-2.4.18-12.5/fs/ext3/balloc.c ---- lum-2.4.18-um30/fs/ext3/balloc.c Mon Feb 25 12:38:08 2002 -+++ uml-2.4.18-12.5/fs/ext3/balloc.c Thu Sep 19 13:40:11 2002 -@@ -276,7 +276,8 @@ - } - lock_super (sb); - es = sb->u.ext3_sb.s_es; -- if (block < le32_to_cpu(es->s_first_data_block) || -+ if (block < le32_to_cpu(es->s_first_data_block) || -+ block + count < block || - (block + count) > le32_to_cpu(es->s_blocks_count)) { - ext3_error (sb, "ext3_free_blocks", - "Freeing blocks not in datazone - " -@@ -309,17 +310,6 @@ - if (!gdp) - goto error_return; - -- if (in_range (le32_to_cpu(gdp->bg_block_bitmap), block, count) || -- in_range (le32_to_cpu(gdp->bg_inode_bitmap), block, count) || -- in_range (block, le32_to_cpu(gdp->bg_inode_table), -- sb->u.ext3_sb.s_itb_per_group) || -- in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table), -- sb->u.ext3_sb.s_itb_per_group)) -- ext3_error (sb, "ext3_free_blocks", -- "Freeing blocks in system zones - " -- "Block = %lu, count = %lu", -- block, count); -- - /* - * We are about to start releasing blocks in the bitmap, - * so we need undo access. -@@ -345,14 +335,24 @@ - if (err) - goto error_return; - -- for (i = 0; i < count; i++) { -+ for (i = 0; i < count; i++, block++) { -+ if (block == le32_to_cpu(gdp->bg_block_bitmap) || -+ block == le32_to_cpu(gdp->bg_inode_bitmap) || -+ in_range(block, le32_to_cpu(gdp->bg_inode_table), -+ sb->u.ext2_sb.s_itb_per_group)) { -+ ext3_error(sb, __FUNCTION__, -+ "Freeing block in system zone - block = %lu", -+ block); -+ continue; -+ } -+ - /* - * An HJ special. This is expensive... - */ - #ifdef CONFIG_JBD_DEBUG - { - struct buffer_head *debug_bh; -- debug_bh = sb_get_hash_table(sb, block + i); -+ debug_bh = sb_get_hash_table(sb, block); - if (debug_bh) { - BUFFER_TRACE(debug_bh, "Deleted!"); - if (!bh2jh(bitmap_bh)->b_committed_data) -@@ -365,9 +365,8 @@ - #endif - BUFFER_TRACE(bitmap_bh, "clear bit"); - if (!ext3_clear_bit (bit + i, bitmap_bh->b_data)) { -- ext3_error (sb, __FUNCTION__, -- "bit already cleared for block %lu", -- block + i); -+ ext3_error(sb, __FUNCTION__, -+ "bit already cleared for block %lu", block); - BUFFER_TRACE(bitmap_bh, "bit already cleared"); - } else { - dquot_freed_blocks++; -@@ -415,7 +417,6 @@ - if (!err) err = ret; - - if (overflow && !err) { -- block += count; - count = overflow; - goto do_more; - } -@@ -542,6 +543,7 @@ - int i, j, k, tmp, alloctmp; - int bitmap_nr; - int fatal = 0, err; -+ int performed_allocation = 0; - struct super_block * sb; - struct ext3_group_desc * gdp; - struct ext3_super_block * es; -@@ -575,6 +577,7 @@ - - ext3_debug ("goal=%lu.\n", goal); - -+repeat: - /* - * First, test whether the goal block is free. - */ -@@ -644,8 +647,7 @@ - } - - /* No space left on the device */ -- unlock_super (sb); -- return 0; -+ goto out; - - search_back: - /* -@@ -684,16 +686,28 @@ - if (tmp == le32_to_cpu(gdp->bg_block_bitmap) || - tmp == le32_to_cpu(gdp->bg_inode_bitmap) || - in_range (tmp, le32_to_cpu(gdp->bg_inode_table), -- sb->u.ext3_sb.s_itb_per_group)) -- ext3_error (sb, "ext3_new_block", -- "Allocating block in system zone - " -- "block = %u", tmp); -+ EXT3_SB(sb)->s_itb_per_group)) { -+ ext3_error(sb, __FUNCTION__, -+ "Allocating block in system zone - block = %u", tmp); -+ -+ /* Note: This will potentially use up one of the handle's -+ * buffer credits. Normally we have way too many credits, -+ * so that is OK. In _very_ rare cases it might not be OK. -+ * We will trigger an assertion if we run out of credits, -+ * and we will have to do a full fsck of the filesystem - -+ * better than randomly corrupting filesystem metadata. -+ */ -+ ext3_set_bit(j, bh->b_data); -+ goto repeat; -+ } -+ - - /* The superblock lock should guard against anybody else beating - * us to this point! */ - J_ASSERT_BH(bh, !ext3_test_bit(j, bh->b_data)); - BUFFER_TRACE(bh, "setting bitmap bit"); - ext3_set_bit(j, bh->b_data); -+ performed_allocation = 1; - - #ifdef CONFIG_JBD_DEBUG - { -@@ -815,6 +829,11 @@ - ext3_std_error(sb, fatal); - } - unlock_super (sb); -+ /* -+ * Undo the block allocation -+ */ -+ if (!performed_allocation) -+ DQUOT_FREE_BLOCK(inode, 1); - return 0; - - } -diff -ru lum-2.4.18-um30/fs/ext3/file.c uml-2.4.18-12.5/fs/ext3/file.c ---- lum-2.4.18-um30/fs/ext3/file.c Thu Nov 15 14:37:55 2001 -+++ uml-2.4.18-12.5/fs/ext3/file.c Thu Sep 19 13:40:11 2002 -@@ -61,19 +61,52 @@ - static ssize_t - ext3_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) - { -+ int ret, err; - struct inode *inode = file->f_dentry->d_inode; - -- /* -- * Nasty: if the file is subject to synchronous writes then we need -- * to force generic_osync_inode() to call ext3_write_inode(). -- * We do that by marking the inode dirty. This adds much more -- * computational expense than we need, but we're going to sync -- * anyway. -- */ -- if (IS_SYNC(inode) || (file->f_flags & O_SYNC)) -- mark_inode_dirty(inode); -+ ret = generic_file_write(file, buf, count, ppos); - -- return generic_file_write(file, buf, count, ppos); -+ /* Skip file flushing code if there was an error, or if nothing -+ was written. */ -+ if (ret <= 0) -+ return ret; -+ -+ /* If the inode is IS_SYNC, or is O_SYNC and we are doing -+ data-journaling, then we need to make sure that we force the -+ transaction to disk to keep all metadata uptodate -+ synchronously. */ -+ -+ if (file->f_flags & O_SYNC) { -+ /* If we are non-data-journaled, then the dirty data has -+ already been flushed to backing store by -+ generic_osync_inode, and the inode has been flushed -+ too if there have been any modifications other than -+ mere timestamp updates. -+ -+ Open question --- do we care about flushing -+ timestamps too if the inode is IS_SYNC? */ -+ if (!ext3_should_journal_data(inode)) -+ return ret; -+ -+ goto force_commit; -+ } -+ -+ /* So we know that there has been no forced data flush. If the -+ inode is marked IS_SYNC, we need to force one ourselves. */ -+ if (!IS_SYNC(inode)) -+ return ret; -+ -+ /* Open question #2 --- should we force data to disk here too? -+ If we don't, the only impact is that data=writeback -+ filesystems won't flush data to disk automatically on -+ IS_SYNC, only metadata (but historically, that is what ext2 -+ has done.) */ -+ -+force_commit: -+ err = ext3_force_commit(inode->i_sb); -+ if (err) -+ return err; -+ return ret; - } - - struct file_operations ext3_file_operations = { -diff -ru lum-2.4.18-um30/fs/ext3/fsync.c uml-2.4.18-12.5/fs/ext3/fsync.c ---- lum-2.4.18-um30/fs/ext3/fsync.c Tue Nov 20 22:34:13 2001 -+++ uml-2.4.18-12.5/fs/ext3/fsync.c Thu Sep 19 13:40:11 2002 -@@ -62,7 +62,12 @@ - * we'll end up waiting on them in commit. - */ - ret = fsync_inode_buffers(inode); -- ret |= fsync_inode_data_buffers(inode); -+ -+ /* In writeback mode, we need to force out data buffers too. In -+ * the other modes, ext3_force_commit takes care of forcing out -+ * just the right data blocks. */ -+ if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) -+ ret |= fsync_inode_data_buffers(inode); - - ext3_force_commit(inode->i_sb); - -diff -ru lum-2.4.18-um30/fs/ext3/ialloc.c uml-2.4.18-12.5/fs/ext3/ialloc.c ---- lum-2.4.18-um30/fs/ext3/ialloc.c Mon Feb 25 12:38:08 2002 -+++ uml-2.4.18-12.5/fs/ext3/ialloc.c Thu Sep 19 13:40:11 2002 -@@ -392,7 +392,7 @@ - - err = -ENOSPC; - if (!gdp) -- goto fail; -+ goto out; - - err = -EIO; - bitmap_nr = load_inode_bitmap (sb, i); -@@ -523,9 +523,10 @@ - return inode; - - fail: -+ ext3_std_error(sb, err); -+out: - unlock_super(sb); - iput(inode); -- ext3_std_error(sb, err); - return ERR_PTR(err); - } - -diff -ru lum-2.4.18-um30/fs/ext3/inode.c uml-2.4.18-12.5/fs/ext3/inode.c ---- lum-2.4.18-um30/fs/ext3/inode.c Mon Feb 25 12:38:08 2002 -+++ uml-2.4.18-12.5/fs/ext3/inode.c Thu Sep 19 13:40:11 2002 -@@ -412,6 +412,7 @@ - return NULL; - - changed: -+ brelse(bh); - *err = -EAGAIN; - goto no_block; - failure: -@@ -581,8 +582,6 @@ - - parent = nr; - } -- if (IS_SYNC(inode)) -- handle->h_sync = 1; - } - if (n == num) - return 0; -@@ -1015,8 +1018,8 @@ - unsigned from, unsigned to) - { - struct inode *inode = page->mapping->host; -- handle_t *handle = ext3_journal_current_handle(); - int ret, needed_blocks = ext3_writepage_trans_blocks(inode); -+ handle_t *handle; - - lock_kernel(); - handle = ext3_journal_start(inode, needed_blocks); -diff -ru lum-2.4.18-um30/fs/ext3/namei.c uml-2.4.18-12.5/fs/ext3/namei.c ---- lum-2.4.18-um30/fs/ext3/namei.c Fri Nov 9 15:25:04 2001 -+++ uml-2.4.18-12.5/fs/ext3/namei.c Thu Sep 19 13:40:11 2002 -@@ -354,8 +355,8 @@ - */ - dir->i_mtime = dir->i_ctime = CURRENT_TIME; - dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -- ext3_mark_inode_dirty(handle, dir); - dir->i_version = ++event; -+ ext3_mark_inode_dirty(handle, dir); - BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); - ext3_journal_dirty_metadata(handle, bh); - brelse(bh); -@@ -464,8 +465,8 @@ - inode->i_op = &ext3_file_inode_operations; - inode->i_fop = &ext3_file_operations; - inode->i_mapping->a_ops = &ext3_aops; -- ext3_mark_inode_dirty(handle, inode); - err = ext3_add_nondir(handle, dentry, inode); -+ ext3_mark_inode_dirty(handle, inode); - } - ext3_journal_stop(handle, dir); - return err; -@@ -489,8 +490,8 @@ - err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - init_special_inode(inode, mode, rdev); -- ext3_mark_inode_dirty(handle, inode); - err = ext3_add_nondir(handle, dentry, inode); -+ ext3_mark_inode_dirty(handle, inode); - } - ext3_journal_stop(handle, dir); - return err; -@@ -933,8 +934,8 @@ - inode->i_size = l-1; - } - inode->u.ext3_i.i_disksize = inode->i_size; -- ext3_mark_inode_dirty(handle, inode); - err = ext3_add_nondir(handle, dentry, inode); -+ ext3_mark_inode_dirty(handle, inode); - out_stop: - ext3_journal_stop(handle, dir); - return err; -@@ -970,8 +971,8 @@ - ext3_inc_count(handle, inode); - atomic_inc(&inode->i_count); - -- ext3_mark_inode_dirty(handle, inode); - err = ext3_add_nondir(handle, dentry, inode); -+ ext3_mark_inode_dirty(handle, inode); - ext3_journal_stop(handle, dir); - return err; - } -diff -ru lum-2.4.18-um30/fs/ext3/super.c uml-2.4.18-12.5/fs/ext3/super.c ---- lum-2.4.18-um30/fs/ext3/super.c Fri Jul 12 17:59:37 2002 -+++ uml-2.4.18-12.5/fs/ext3/super.c Thu Sep 19 13:40:11 2002 -@@ -1589,8 +1589,10 @@ - journal_t *journal = EXT3_SB(sb)->s_journal; - - /* Now we set up the journal barrier. */ -+ unlock_super(sb); - journal_lock_updates(journal); - journal_flush(journal); -+ lock_super(sb); - - /* Journal blocked and flushed, clear needs_recovery flag. */ - EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); diff --git a/lustre/extN/ext3-2.4.18-ino_sb_macro.diff b/lustre/extN/ext3-2.4.18-ino_sb_macro.diff deleted file mode 100644 index a49d5da..0000000 --- a/lustre/extN/ext3-2.4.18-ino_sb_macro.diff +++ /dev/null @@ -1,1556 +0,0 @@ ---- ./fs/ext3/balloc.c.orig Fri Apr 12 10:27:49 2002 -+++ ./fs/ext3/balloc.c Tue May 7 15:35:59 2002 -@@ -46,18 +46,18 @@ struct ext3_group_desc * ext3_get_group_ - unsigned long desc; - struct ext3_group_desc * gdp; - -- if (block_group >= sb->u.ext3_sb.s_groups_count) { -+ if (block_group >= EXT3_SB(sb)->s_groups_count) { - ext3_error (sb, "ext3_get_group_desc", - "block_group >= groups_count - " - "block_group = %d, groups_count = %lu", -- block_group, sb->u.ext3_sb.s_groups_count); -+ block_group, EXT3_SB(sb)->s_groups_count); - - return NULL; - } - - group_desc = block_group / EXT3_DESC_PER_BLOCK(sb); - desc = block_group % EXT3_DESC_PER_BLOCK(sb); -- if (!sb->u.ext3_sb.s_group_desc[group_desc]) { -+ if (!EXT3_SB(sb)->s_group_desc[group_desc]) { - ext3_error (sb, "ext3_get_group_desc", - "Group descriptor not loaded - " - "block_group = %d, group_desc = %lu, desc = %lu", -@@ -66,9 +66,9 @@ struct ext3_group_desc * ext3_get_group_ - } - - gdp = (struct ext3_group_desc *) -- sb->u.ext3_sb.s_group_desc[group_desc]->b_data; -+ EXT3_SB(sb)->s_group_desc[group_desc]->b_data; - if (bh) -- *bh = sb->u.ext3_sb.s_group_desc[group_desc]; -+ *bh = EXT3_SB(sb)->s_group_desc[group_desc]; - return gdp + desc; - } - -@@ -104,8 +104,8 @@ static int read_block_bitmap (struct sup - * this group. The IO will be retried next time. - */ - error_out: -- sb->u.ext3_sb.s_block_bitmap_number[bitmap_nr] = block_group; -- sb->u.ext3_sb.s_block_bitmap[bitmap_nr] = bh; -+ EXT3_SB(sb)->s_block_bitmap_number[bitmap_nr] = block_group; -+ EXT3_SB(sb)->s_block_bitmap[bitmap_nr] = bh; - return retval; - } - -@@ -128,16 +128,17 @@ static int __load_block_bitmap (struct s - int i, j, retval = 0; - unsigned long block_bitmap_number; - struct buffer_head * block_bitmap; -+ struct ext3_sb_info *sbi = EXT3_SB(sb); - -- if (block_group >= sb->u.ext3_sb.s_groups_count) -+ if (block_group >= sbi->s_groups_count) - ext3_panic (sb, "load_block_bitmap", - "block_group >= groups_count - " - "block_group = %d, groups_count = %lu", -- block_group, sb->u.ext3_sb.s_groups_count); -+ block_group, EXT3_SB(sb)->s_groups_count); - -- if (sb->u.ext3_sb.s_groups_count <= EXT3_MAX_GROUP_LOADED) { -- if (sb->u.ext3_sb.s_block_bitmap[block_group]) { -- if (sb->u.ext3_sb.s_block_bitmap_number[block_group] == -+ if (sbi->s_groups_count <= EXT3_MAX_GROUP_LOADED) { -+ if (sbi->s_block_bitmap[block_group]) { -+ if (sbi->s_block_bitmap_number[block_group] == - block_group) - return block_group; - ext3_error (sb, "__load_block_bitmap", -@@ -149,21 +150,20 @@ static int __load_block_bitmap (struct s - return block_group; - } - -- for (i = 0; i < sb->u.ext3_sb.s_loaded_block_bitmaps && -- sb->u.ext3_sb.s_block_bitmap_number[i] != block_group; i++) -+ for (i = 0; i < sbi->s_loaded_block_bitmaps && -+ sbi->s_block_bitmap_number[i] != block_group; i++) - ; -- if (i < sb->u.ext3_sb.s_loaded_block_bitmaps && -- sb->u.ext3_sb.s_block_bitmap_number[i] == block_group) { -- block_bitmap_number = sb->u.ext3_sb.s_block_bitmap_number[i]; -- block_bitmap = sb->u.ext3_sb.s_block_bitmap[i]; -+ if (i < sbi->s_loaded_block_bitmaps && -+ sbi->s_block_bitmap_number[i] == block_group) { -+ block_bitmap_number = sbi->s_block_bitmap_number[i]; -+ block_bitmap = sbi->s_block_bitmap[i]; - for (j = i; j > 0; j--) { -- sb->u.ext3_sb.s_block_bitmap_number[j] = -- sb->u.ext3_sb.s_block_bitmap_number[j - 1]; -- sb->u.ext3_sb.s_block_bitmap[j] = -- sb->u.ext3_sb.s_block_bitmap[j - 1]; -+ sbi->s_block_bitmap_number[j] = -+ sbi->s_block_bitmap_number[j - 1]; -+ sbi->s_block_bitmap[j] = sbi->s_block_bitmap[j - 1]; - } -- sb->u.ext3_sb.s_block_bitmap_number[0] = block_bitmap_number; -- sb->u.ext3_sb.s_block_bitmap[0] = block_bitmap; -+ sbi->s_block_bitmap_number[0] = block_bitmap_number; -+ sbi->s_block_bitmap[0] = block_bitmap; - - /* - * There's still one special case here --- if block_bitmap == 0 -@@ -173,17 +173,14 @@ static int __load_block_bitmap (struct s - if (!block_bitmap) - retval = read_block_bitmap (sb, block_group, 0); - } else { -- if (sb->u.ext3_sb.s_loaded_block_bitmapsu.ext3_sb.s_loaded_block_bitmaps++; -+ if (sbi->s_loaded_block_bitmapss_loaded_block_bitmaps++; - else -- brelse (sb->u.ext3_sb.s_block_bitmap -- [EXT3_MAX_GROUP_LOADED - 1]); -- for (j = sb->u.ext3_sb.s_loaded_block_bitmaps - 1; -- j > 0; j--) { -- sb->u.ext3_sb.s_block_bitmap_number[j] = -- sb->u.ext3_sb.s_block_bitmap_number[j - 1]; -- sb->u.ext3_sb.s_block_bitmap[j] = -- sb->u.ext3_sb.s_block_bitmap[j - 1]; -+ brelse(sbi->s_block_bitmap[EXT3_MAX_GROUP_LOADED - 1]); -+ for (j = sbi->s_loaded_block_bitmaps - 1; j > 0; j--) { -+ sbi->s_block_bitmap_number[j] = -+ sbi->s_block_bitmap_number[j - 1]; -+ sbi->s_block_bitmap[j] = sbi->s_block_bitmap[j - 1]; - } - retval = read_block_bitmap (sb, block_group, 0); - } -@@ -206,24 +203,25 @@ static int __load_block_bitmap (struct s - static inline int load_block_bitmap (struct super_block * sb, - unsigned int block_group) - { -+ struct ext3_sb_info *sbi = EXT3_SB(sb); - int slot; -- -+ - /* - * Do the lookup for the slot. First of all, check if we're asking - * for the same slot as last time, and did we succeed that last time? - */ -- if (sb->u.ext3_sb.s_loaded_block_bitmaps > 0 && -- sb->u.ext3_sb.s_block_bitmap_number[0] == block_group && -- sb->u.ext3_sb.s_block_bitmap[0]) { -+ if (sbi->s_loaded_block_bitmaps > 0 && -+ sbi->s_block_bitmap_number[0] == block_group && -+ sbi->s_block_bitmap[0]) { - return 0; - } - /* - * Or can we do a fast lookup based on a loaded group on a filesystem - * small enough to be mapped directly into the superblock? - */ -- else if (sb->u.ext3_sb.s_groups_count <= EXT3_MAX_GROUP_LOADED && -- sb->u.ext3_sb.s_block_bitmap_number[block_group]==block_group -- && sb->u.ext3_sb.s_block_bitmap[block_group]) { -+ else if (sbi->s_groups_count <= EXT3_MAX_GROUP_LOADED && -+ sbi->s_block_bitmap_number[block_group] == block_group -+ && sbi->s_block_bitmap[block_group]) { - slot = block_group; - } - /* -@@ -243,7 +241,7 @@ static inline int load_block_bitmap (str - * If it's a valid slot, we may still have cached a previous IO error, - * in which case the bh in the superblock cache will be zero. - */ -- if (!sb->u.ext3_sb.s_block_bitmap[slot]) -+ if (!sbi->s_block_bitmap[slot]) - return -EIO; - - /* -@@ -275,7 +273,7 @@ void ext3_free_blocks (handle_t *handle, - return; - } - lock_super (sb); -- es = sb->u.ext3_sb.s_es; -+ es = EXT3_SB(sb)->s_es; - if (block < le32_to_cpu(es->s_first_data_block) || - block + count < block || - (block + count) > le32_to_cpu(es->s_blocks_count)) { -@@ -304,7 +302,7 @@ do_more: - if (bitmap_nr < 0) - goto error_return; - -- bitmap_bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr]; -+ bitmap_bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr]; - gdp = ext3_get_group_desc (sb, block_group, &gd_bh); - if (!gdp) - goto error_return; -@@ -330,8 +328,8 @@ do_more: - if (err) - goto error_return; - -- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access"); -- err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh); -+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); - if (err) - goto error_return; - -@@ -341,7 +339,7 @@ - if (block == le32_to_cpu(gdp->bg_block_bitmap) || - block == le32_to_cpu(gdp->bg_inode_bitmap) || - in_range(block, le32_to_cpu(gdp->bg_inode_table), -- sb->u.ext2_sb.s_itb_per_group)) { -+ EXT3_SB(sb)->s_itb_per_group)) { - ext3_error(sb, __FUNCTION__, - "Freeing block in system zone - block = %lu", - block); -@@ -410,8 +407,8 @@ do_more: - if (!err) err = ret; - - /* And the superblock */ -- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "dirtied superblock"); -- ret = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh); -+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "dirtied superblock"); -+ ret = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); - if (!err) err = ret; - - if (overflow && !err) { -@@ -564,12 +560,12 @@ int ext3_new_block (handle_t *handle, st - } - - lock_super (sb); -- es = sb->u.ext3_sb.s_es; -+ es = EXT3_SB(sb)->s_es; - if (le32_to_cpu(es->s_free_blocks_count) <= - le32_to_cpu(es->s_r_blocks_count) && -- ((sb->u.ext3_sb.s_resuid != current->fsuid) && -- (sb->u.ext3_sb.s_resgid == 0 || -- !in_group_p (sb->u.ext3_sb.s_resgid)) && -+ ((EXT3_SB(sb)->s_resuid != current->fsuid) && -+ (EXT3_SB(sb)->s_resgid == 0 || -+ !in_group_p (EXT3_SB(sb)->s_resgid)) && - !capable(CAP_SYS_RESOURCE))) - goto out; - -@@ -598,7 +595,7 @@ int ext3_new_block (handle_t *handle, st - if (bitmap_nr < 0) - goto io_error; - -- bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr]; -+ bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr]; - - ext3_debug ("goal is at %d:%d.\n", i, j); - -@@ -621,9 +618,9 @@ int ext3_new_block (handle_t *handle, st - * Now search the rest of the groups. We assume that - * i and gdp correctly point to the last group visited. - */ -- for (k = 0; k < sb->u.ext3_sb.s_groups_count; k++) { -+ for (k = 0; k < EXT3_SB(sb)->s_groups_count; k++) { - i++; -- if (i >= sb->u.ext3_sb.s_groups_count) -+ if (i >= EXT3_SB(sb)->s_groups_count) - i = 0; - gdp = ext3_get_group_desc (sb, i, &bh2); - if (!gdp) { -@@ -635,7 +632,7 @@ int ext3_new_block (handle_t *handle, st - if (bitmap_nr < 0) - goto io_error; - -- bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr]; -+ bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr]; - j = find_next_usable_block(-1, bh, - EXT3_BLOCKS_PER_GROUP(sb)); - if (j >= 0) -@@ -674,8 +671,8 @@ got_block: - fatal = ext3_journal_get_write_access(handle, bh2); - if (fatal) goto out; - -- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access"); -- fatal = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh); -+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access"); -+ fatal = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); - if (fatal) goto out; - - tmp = j + i * EXT3_BLOCKS_PER_GROUP(sb) -@@ -796,7 +804,7 @@ got_block: - if (!fatal) fatal = err; - - BUFFER_TRACE(bh, "journal_dirty_metadata for superblock"); -- err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh); -+ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); - if (!fatal) fatal = err; - - sb->s_dirt = 1; -@@ -829,11 +837,11 @@ unsigned long ext3_count_free_blocks (st - int i; - - lock_super (sb); -- es = sb->u.ext3_sb.s_es; -+ es = EXT3_SB(sb)->s_es; - desc_count = 0; - bitmap_count = 0; - gdp = NULL; -- for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) { -+ for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) { - gdp = ext3_get_group_desc (sb, i, NULL); - if (!gdp) - continue; -@@ -842,7 +850,7 @@ unsigned long ext3_count_free_blocks (st - if (bitmap_nr < 0) - continue; - -- x = ext3_count_free (sb->u.ext3_sb.s_block_bitmap[bitmap_nr], -+ x = ext3_count_free (EXT3_SB(sb)->s_block_bitmap[bitmap_nr], - sb->s_blocksize); - printk ("group %d: stored = %d, counted = %lu\n", - i, le16_to_cpu(gdp->bg_free_blocks_count), x); -@@ -853,7 +861,7 @@ unsigned long ext3_count_free_blocks (st - unlock_super (sb); - return bitmap_count; - #else -- return le32_to_cpu(sb->u.ext3_sb.s_es->s_free_blocks_count); -+ return le32_to_cpu(EXT3_SB(sb)->s_es->s_free_blocks_count); - #endif - } - -@@ -862,7 +870,7 @@ static inline int block_in_use (unsigned - unsigned char * map) - { - return ext3_test_bit ((block - -- le32_to_cpu(sb->u.ext3_sb.s_es->s_first_data_block)) % -+ le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) % - EXT3_BLOCKS_PER_GROUP(sb), map); - } - -@@ -930,11 +938,11 @@ void ext3_check_blocks_bitmap (struct su - struct ext3_group_desc * gdp; - int i; - -- es = sb->u.ext3_sb.s_es; -+ es = EXT3_SB(sb)->s_es; - desc_count = 0; - bitmap_count = 0; - gdp = NULL; -- for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) { -+ for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) { - gdp = ext3_get_group_desc (sb, i, NULL); - if (!gdp) - continue; -@@ -968,7 +976,7 @@ void ext3_check_blocks_bitmap (struct su - "Inode bitmap for group %d is marked free", - i); - -- for (j = 0; j < sb->u.ext3_sb.s_itb_per_group; j++) -+ for (j = 0; j < EXT3_SB(sb)->s_itb_per_group; j++) - if (!block_in_use (le32_to_cpu(gdp->bg_inode_table) + j, - sb, bh->b_data)) - ext3_error (sb, "ext3_check_blocks_bitmap", ---- ./fs/ext3/dir.c.orig Fri Apr 12 10:27:49 2002 -+++ ./fs/ext3/dir.c Tue May 7 14:54:13 2002 -@@ -52,7 +52,7 @@ int ext3_check_dir_entry (const char * f - else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize) - error_msg = "directory entry across blocks"; - else if (le32_to_cpu(de->inode) > -- le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count)) -+ le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count)) - error_msg = "inode out of bounds"; - - if (error_msg != NULL) ---- ./fs/ext3/ialloc.c.orig Fri Apr 12 10:27:49 2002 -+++ ./fs/ext3/ialloc.c Tue May 7 15:39:26 2002 -@@ -73,8 +73,8 @@ static int read_inode_bitmap (struct sup - * this group. The IO will be retried next time. - */ - error_out: -- sb->u.ext3_sb.s_inode_bitmap_number[bitmap_nr] = block_group; -- sb->u.ext3_sb.s_inode_bitmap[bitmap_nr] = bh; -+ EXT3_SB(sb)->s_inode_bitmap_number[bitmap_nr] = block_group; -+ EXT3_SB(sb)->s_inode_bitmap[bitmap_nr] = bh; - return retval; - } - -@@ -225,7 +225,7 @@ void ext3_free_inode (handle_t *handle, - clear_inode (inode); - - lock_super (sb); -- es = sb->u.ext3_sb.s_es; -+ es = EXT3_SB(sb)->s_es; - if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { - ext3_error (sb, "ext3_free_inode", - "reserved or nonexistent inode %lu", ino); -@@ -237,7 +237,7 @@ void ext3_free_inode (handle_t *handle, - if (bitmap_nr < 0) - goto error_return; - -- bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr]; -+ bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr]; - - BUFFER_TRACE(bh, "get_write_access"); - fatal = ext3_journal_get_write_access(handle, bh); -@@ -255,8 +255,8 @@ void ext3_free_inode (handle_t *handle, - fatal = ext3_journal_get_write_access(handle, bh2); - if (fatal) goto error_return; - -- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get write access"); -- fatal = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh); -+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get write access"); -+ fatal = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); - if (fatal) goto error_return; - - if (gdp) { -@@ -271,9 +271,9 @@ void ext3_free_inode (handle_t *handle, - if (!fatal) fatal = err; - es->s_free_inodes_count = - cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) + 1); -- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, -+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, - "call ext3_journal_dirty_metadata"); -- err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh); -+ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); - if (!fatal) fatal = err; - } - BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -@@ -305,6 +305,8 @@ struct inode * ext3_new_inode (handle_t - int i, j, avefreei; - struct inode * inode; - int bitmap_nr; -+ struct ext3_inode_info *ei; -+ struct ext3_sb_info *sbi; - struct ext3_group_desc * gdp; - struct ext3_group_desc * tmp; - struct ext3_super_block * es; -@@ -318,19 +320,21 @@ struct inode * ext3_new_inode (handle_t - inode = new_inode(sb); - if (!inode) - return ERR_PTR(-ENOMEM); -- init_rwsem(&inode->u.ext3_i.truncate_sem); -+ sbi = EXT3_SB(sb); -+ ei = EXT3_I(inode); -+ init_rwsem(&ei->truncate_sem); - - lock_super (sb); -- es = sb->u.ext3_sb.s_es; -+ es = sbi->s_es; - repeat: - gdp = NULL; - i = 0; - - if (S_ISDIR(mode)) { - avefreei = le32_to_cpu(es->s_free_inodes_count) / -- sb->u.ext3_sb.s_groups_count; -+ sbi->s_groups_count; - if (!gdp) { -- for (j = 0; j < sb->u.ext3_sb.s_groups_count; j++) { -+ for (j = 0; j < sbi->s_groups_count; j++) { - struct buffer_head *temp_buffer; - tmp = ext3_get_group_desc (sb, j, &temp_buffer); - if (tmp && -@@ -350,7 +354,7 @@ repeat: - /* - * Try to place the inode in its parent directory - */ -- i = dir->u.ext3_i.i_block_group; -+ i = EXT3_I(dir)->i_block_group; - tmp = ext3_get_group_desc (sb, i, &bh2); - if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) - gdp = tmp; -@@ -360,10 +364,10 @@ repeat: - * Use a quadratic hash to find a group with a - * free inode - */ -- for (j = 1; j < sb->u.ext3_sb.s_groups_count; j <<= 1) { -+ for (j = 1; j < sbi->s_groups_count; j <<= 1) { - i += j; -- if (i >= sb->u.ext3_sb.s_groups_count) -- i -= sb->u.ext3_sb.s_groups_count; -+ if (i >= sbi->s_groups_count) -+ i -= sbi->s_groups_count; - tmp = ext3_get_group_desc (sb, i, &bh2); - if (tmp && - le16_to_cpu(tmp->bg_free_inodes_count)) { -@@ -376,9 +380,9 @@ repeat: - /* - * That failed: try linear search for a free inode - */ -- i = dir->u.ext3_i.i_block_group + 1; -- for (j = 2; j < sb->u.ext3_sb.s_groups_count; j++) { -- if (++i >= sb->u.ext3_sb.s_groups_count) -+ i = EXT3_I(dir)->i_block_group + 1; -+ for (j = 2; j < sbi->s_groups_count; j++) { -+ if (++i >= sbi->s_groups_count) - i = 0; - tmp = ext3_get_group_desc (sb, i, &bh2); - if (tmp && -@@ -399,11 +403,11 @@ repeat: - if (bitmap_nr < 0) - goto fail; - -- bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr]; -+ bh = sbi->s_inode_bitmap[bitmap_nr]; - - if ((j = ext3_find_first_zero_bit ((unsigned long *) bh->b_data, -- EXT3_INODES_PER_GROUP(sb))) < -- EXT3_INODES_PER_GROUP(sb)) { -+ sbi->s_inodes_per_group)) < -+ sbi->s_inodes_per_group) { - BUFFER_TRACE(bh, "get_write_access"); - err = ext3_journal_get_write_access(handle, bh); - if (err) goto fail; -@@ -436,8 +440,8 @@ repeat: - } - goto repeat; - } -- j += i * EXT3_INODES_PER_GROUP(sb) + 1; -- if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) { -+ j += i * sbi->s_inodes_per_group + 1; -+ if (j < sbi->s_first_ino || j > le32_to_cpu(es->s_inodes_count)) { - ext3_error (sb, "ext3_new_inode", - "reserved inode or inode > inodes count - " - "block_group = %d,inode=%d", i, j); -@@ -457,13 +461,13 @@ repeat: - err = ext3_journal_dirty_metadata(handle, bh2); - if (err) goto fail; - -- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access"); -- err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh); -+ BUFFER_TRACE(sbi->s_sbh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, sbi->s_sbh); - if (err) goto fail; - es->s_free_inodes_count = - cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1); -- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "call ext3_journal_dirty_metadata"); -- err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh); -+ BUFFER_TRACE(sbi->s_sbh, "call ext3_journal_dirty_metadata"); -+ err = ext3_journal_dirty_metadata(handle, sbi->s_sbh); - sb->s_dirt = 1; - if (err) goto fail; - -@@ -483,31 +487,31 @@ repeat: - inode->i_blksize = PAGE_SIZE; - inode->i_blocks = 0; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; -- inode->u.ext3_i.i_flags = dir->u.ext3_i.i_flags & ~EXT3_INDEX_FL; -+ ei->i_flags = EXT3_I(dir)->i_flags & ~EXT3_INDEX_FL; - if (S_ISLNK(mode)) -- inode->u.ext3_i.i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL); -+ ei->i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL); - #ifdef EXT3_FRAGMENTS -- inode->u.ext3_i.i_faddr = 0; -- inode->u.ext3_i.i_frag_no = 0; -- inode->u.ext3_i.i_frag_size = 0; -+ ei->i_faddr = 0; -+ ei->i_frag_no = 0; -+ ei->i_frag_size = 0; - #endif -- inode->u.ext3_i.i_file_acl = 0; -- inode->u.ext3_i.i_dir_acl = 0; -- inode->u.ext3_i.i_dtime = 0; -- INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); -+ ei->i_file_acl = 0; -+ ei->i_dir_acl = 0; -+ ei->i_dtime = 0; -+ INIT_LIST_HEAD(&ei->i_orphan); - #ifdef EXT3_PREALLOCATE -- inode->u.ext3_i.i_prealloc_count = 0; -+ ei->i_prealloc_count = 0; - #endif -- inode->u.ext3_i.i_block_group = i; -+ ei->i_block_group = i; - -- if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) -+ if (ei->i_flags & EXT3_SYNC_FL) - inode->i_flags |= S_SYNC; - if (IS_SYNC(inode)) - handle->h_sync = 1; - insert_inode_hash(inode); -- inode->i_generation = sb->u.ext3_sb.s_next_generation++; -+ inode->i_generation = sbi->s_next_generation++; - -- inode->u.ext3_i.i_state = EXT3_STATE_NEW; -+ ei->i_state = EXT3_STATE_NEW; - err = ext3_mark_inode_dirty(handle, inode); - if (err) goto fail; - -@@ -585,19 +589,19 @@ struct inode *ext3_orphan_get (struct su - - unsigned long ext3_count_free_inodes (struct super_block * sb) - { -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ struct ext3_super_block *es = sbi->s_es; - #ifdef EXT3FS_DEBUG -- struct ext3_super_block * es; - unsigned long desc_count, bitmap_count, x; - int bitmap_nr; - struct ext3_group_desc * gdp; - int i; - - lock_super (sb); -- es = sb->u.ext3_sb.s_es; - desc_count = 0; - bitmap_count = 0; - gdp = NULL; -- for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) { -+ for (i = 0; i < sbi->s_groups_count; i++) { - gdp = ext3_get_group_desc (sb, i, NULL); - if (!gdp) - continue; -@@ -606,8 +610,8 @@ unsigned long ext3_count_free_inodes (st - if (bitmap_nr < 0) - continue; - -- x = ext3_count_free (sb->u.ext3_sb.s_inode_bitmap[bitmap_nr], -- EXT3_INODES_PER_GROUP(sb) / 8); -+ x = ext3_count_free(sbi->s_inode_bitmap[bitmap_nr], -+ sbi->s_inodes_per_group / 8); - printk ("group %d: stored = %d, counted = %lu\n", - i, le16_to_cpu(gdp->bg_free_inodes_count), x); - bitmap_count += x; -@@ -617,7 +621,7 @@ unsigned long ext3_count_free_inodes (st - unlock_super (sb); - return desc_count; - #else -- return le32_to_cpu(sb->u.ext3_sb.s_es->s_free_inodes_count); -+ return le32_to_cpu(es->s_free_inodes_count); - #endif - } - -@@ -626,16 +630,18 @@ unsigned long ext3_count_free_inodes (st - void ext3_check_inodes_bitmap (struct super_block * sb) - { - struct ext3_super_block * es; -+ struct ext3_sb_info *sbi; - unsigned long desc_count, bitmap_count, x; - int bitmap_nr; - struct ext3_group_desc * gdp; - int i; - -- es = sb->u.ext3_sb.s_es; -+ sbi = EXT3_SB(sb); -+ es = sbi->s_es; - desc_count = 0; - bitmap_count = 0; - gdp = NULL; -- for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) { -+ for (i = 0; i < sbi->s_groups_count; i++) { - gdp = ext3_get_group_desc (sb, i, NULL); - if (!gdp) - continue; -@@ -644,7 +650,7 @@ void ext3_check_inodes_bitmap (struct su - if (bitmap_nr < 0) - continue; - -- x = ext3_count_free (sb->u.ext3_sb.s_inode_bitmap[bitmap_nr], -+ x = ext3_count_free (sbi->s_inode_bitmap[bitmap_nr], - EXT3_INODES_PER_GROUP(sb) / 8); - if (le16_to_cpu(gdp->bg_free_inodes_count) != x) - ext3_error (sb, "ext3_check_inodes_bitmap", ---- ./fs/ext3/inode.c.orig Fri Apr 12 10:27:49 2002 -+++ ./fs/ext3/inode.c Tue May 7 15:41:23 2002 -@@ -196,7 +196,7 @@ void ext3_delete_inode (struct inode * i - * (Well, we could do this if we need to, but heck - it works) - */ - ext3_orphan_del(handle, inode); -- inode->u.ext3_i.i_dtime = CURRENT_TIME; -+ EXT3_I(inode)->i_dtime = CURRENT_TIME; - - /* - * One subtle ordering requirement: if anything has gone wrong -@@ -220,13 +220,14 @@ no_delete: - void ext3_discard_prealloc (struct inode * inode) - { - #ifdef EXT3_PREALLOCATE -+ struct ext3_inode_info *ei = EXT3_I(inode); - lock_kernel(); - /* Writer: ->i_prealloc* */ -- if (inode->u.ext3_i.i_prealloc_count) { -- unsigned short total = inode->u.ext3_i.i_prealloc_count; -- unsigned long block = inode->u.ext3_i.i_prealloc_block; -- inode->u.ext3_i.i_prealloc_count = 0; -- inode->u.ext3_i.i_prealloc_block = 0; -+ if (ei->i_prealloc_count) { -+ unsigned short total = ei->i_prealloc_count; -+ unsigned long block = ei->i_prealloc_block; -+ ei->i_prealloc_count = 0; -+ ei->i_prealloc_block = 0; - /* Writer: end */ - ext3_free_blocks (inode, block, total); - } -@@ -243,13 +244,15 @@ static int ext3_alloc_block (handle_t *h - unsigned long result; - - #ifdef EXT3_PREALLOCATE -+ struct ext3_inode_info *ei = EXT3_I(inode); -+ - /* Writer: ->i_prealloc* */ -- if (inode->u.ext3_i.i_prealloc_count && -- (goal == inode->u.ext3_i.i_prealloc_block || -- goal + 1 == inode->u.ext3_i.i_prealloc_block)) -+ if (ei->i_prealloc_count && -+ (goal == ei->i_prealloc_block || -+ goal + 1 == ei->i_prealloc_block)) - { -- result = inode->u.ext3_i.i_prealloc_block++; -- inode->u.ext3_i.i_prealloc_count--; -+ result = ei->i_prealloc_block++; -+ ei->i_prealloc_count--; - /* Writer: end */ - ext3_debug ("preallocation hit (%lu/%lu).\n", - ++alloc_hits, ++alloc_attempts); -@@ -259,8 +262,8 @@ static int ext3_alloc_block (handle_t *h - alloc_hits, ++alloc_attempts); - if (S_ISREG(inode->i_mode)) - result = ext3_new_block (inode, goal, -- &inode->u.ext3_i.i_prealloc_count, -- &inode->u.ext3_i.i_prealloc_block, err); -+ &ei->i_prealloc_count, -+ &ei->i_prealloc_block, err); - else - result = ext3_new_block (inode, goal, 0, 0, err); - /* -@@ -394,7 +397,7 @@ static Indirect *ext3_get_branch(struct - - *err = 0; - /* i_data is not going away, no lock needed */ -- add_chain (chain, NULL, inode->u.ext3_i.i_data + *offsets); -+ add_chain (chain, NULL, EXT3_I(inode)->i_data + *offsets); - if (!p->key) - goto no_block; - while (--depth) { -@@ -437,7 +440,8 @@ no_block: - - static inline unsigned long ext3_find_near(struct inode *inode, Indirect *ind) - { -- u32 *start = ind->bh ? (u32*) ind->bh->b_data : inode->u.ext3_i.i_data; -+ struct ext3_inode_info *ei = EXT3_I(inode); -+ u32 *start = ind->bh ? (u32*) ind->bh->b_data : ei->i_data; - u32 *p; - - /* Try to find previous block */ -@@ -453,9 +456,8 @@ static inline unsigned long ext3_find_ne - * It is going to be refered from inode itself? OK, just put it into - * the same cylinder group then. - */ -- return (inode->u.ext3_i.i_block_group * -- EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + -- le32_to_cpu(inode->i_sb->u.ext3_sb.s_es->s_first_data_block); -+ return (ei->i_block_group * EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + -+ le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); - } - - /** -@@ -474,14 +477,15 @@ - static int ext3_find_goal(struct inode *inode, long block, Indirect chain[4], - Indirect *partial, unsigned long *goal) - { -+ struct ext3_inode_info *ei = EXT3_I(inode); - /* Writer: ->i_next_alloc* */ -- if (block == inode->u.ext3_i.i_next_alloc_block + 1) { -- inode->u.ext3_i.i_next_alloc_block++; -- inode->u.ext3_i.i_next_alloc_goal++; -+ if (block == ei->i_next_alloc_block + 1) { -+ ei->i_next_alloc_block++; -+ ei->i_next_alloc_goal++; - } - #ifdef SEARCH_FROM_ZERO -- inode->u.ext3_i.i_next_alloc_block = 0; -- inode->u.ext3_i.i_next_alloc_goal = 0; -+ ei->i_next_alloc_block = 0; -+ ei->i_next_alloc_goal = 0; - #endif - /* Writer: end */ - /* Reader: pointers, ->i_next_alloc* */ -@@ -490,8 +493,8 @@ static int ext3_find_goal(struct inode * - * try the heuristic for sequential allocation, - * failing that at least try to get decent locality. - */ -- if (block == inode->u.ext3_i.i_next_alloc_block) -- *goal = inode->u.ext3_i.i_next_alloc_goal; -+ if (block == ei->i_next_alloc_block) -+ *goal = ei->i_next_alloc_goal; - if (!*goal) - *goal = ext3_find_near(inode, partial); - #ifdef SEARCH_FROM_ZERO -@@ -619,6 +621,7 @@ - { - int i; - int err = 0; -+ struct ext3_inode_info *ei = EXT3_I(inode); - - /* - * If we're splicing into a [td]indirect block (as opposed to the -@@ -641,11 +644,11 @@ static int ext3_splice_branch(handle_t * - /* That's it */ - - *where->p = where->key; -- inode->u.ext3_i.i_next_alloc_block = block; -- inode->u.ext3_i.i_next_alloc_goal = le32_to_cpu(where[num-1].key); -+ ei->i_next_alloc_block = block; -+ ei->i_next_alloc_goal = le32_to_cpu(where[num-1].key); - #ifdef SEARCH_FROM_ZERO -- inode->u.ext3_i.i_next_alloc_block = 0; -- inode->u.ext3_i.i_next_alloc_goal = 0; -+ ei->i_next_alloc_block = 0; -+ ei->i_next_alloc_goal = 0; - #endif - /* Writer: end */ - -@@ -729,6 +732,7 @@ - unsigned long goal; - int left; - int depth = ext3_block_to_path(inode, iblock, offsets); -+ struct ext3_inode_info *ei = EXT3_I(inode); - loff_t new_size; - - J_ASSERT(handle != NULL || create == 0); -@@ -782,7 +785,7 @@ out: - /* - * Block out ext3_truncate while we alter the tree - */ -- down_read(&inode->u.ext3_i.truncate_sem); -+ down_read(&ei->truncate_sem); - err = ext3_alloc_branch(handle, inode, left, goal, - offsets+(partial-chain), partial); - -@@ -794,7 +797,7 @@ out: - if (!err) - err = ext3_splice_branch(handle, inode, iblock, chain, - partial, left); -- up_read(&inode->u.ext3_i.truncate_sem); -+ up_read(&ei->truncate_sem); - if (err == -EAGAIN) - goto changed; - if (err) -@@ -807,8 +810,8 @@ out: - * truncate is in progress. It is racy between multiple parallel - * instances of get_block, but we have the BKL. - */ -- if (new_size > inode->u.ext3_i.i_disksize) -- inode->u.ext3_i.i_disksize = new_size; -+ if (new_size > ei->i_disksize) -+ ei->i_disksize = new_size; - - bh_result->b_state |= (1UL << BH_New); - goto got_it; -@@ -921,7 +924,7 @@ struct buffer_head *ext3_bread(handle_t - struct buffer_head *tmp_bh; - - for (i = 1; -- inode->u.ext3_i.i_prealloc_count && -+ EXT3_I(inode)->i_prealloc_count && - i < EXT3_SB(inode->i_sb)->s_es->s_prealloc_dir_blocks; - i++) { - /* -@@ -1131,8 +1134,8 @@ static int ext3_commit_write(struct file - kunmap(page); - } - } -- if (inode->i_size > inode->u.ext3_i.i_disksize) { -- inode->u.ext3_i.i_disksize = inode->i_size; -+ if (inode->i_size > EXT3_I(inode)->i_disksize) { -+ EXT3_I(inode)->i_disksize = inode->i_size; - ret2 = ext3_mark_inode_dirty(handle, inode); - if (!ret) - ret = ret2; -@@ -1832,7 +1835,8 @@ static void ext3_free_branches(handle_t - void ext3_truncate(struct inode * inode) - { - handle_t *handle; -- u32 *i_data = inode->u.ext3_i.i_data; -+ struct ext3_inode_info *ei = EXT3_I(inode); -+ u32 *i_data = EXT3_I(inode)->i_data; - int addr_per_block = EXT3_ADDR_PER_BLOCK(inode->i_sb); - int offsets[4]; - Indirect chain[4]; -@@ -1884,13 +1887,13 @@ void ext3_truncate(struct inode * inode) - * on-disk inode. We do this via i_disksize, which is the value which - * ext3 *really* writes onto the disk inode. - */ -- inode->u.ext3_i.i_disksize = inode->i_size; -+ ei->i_disksize = inode->i_size; - - /* - * From here we block out all ext3_get_block() callers who want to - * modify the block allocation tree. - */ -- down_write(&inode->u.ext3_i.truncate_sem); -+ down_write(&ei->truncate_sem); - - if (n == 1) { /* direct blocks */ - ext3_free_data(handle, inode, NULL, i_data+offsets[0], -@@ -1954,7 +1957,7 @@ do_indirects: - case EXT3_TIND_BLOCK: - ; - } -- up_write(&inode->u.ext3_i.truncate_sem); -+ up_write(&ei->truncate_sem); - inode->i_mtime = inode->i_ctime = CURRENT_TIME; - ext3_mark_inode_dirty(handle, inode); - -@@ -1983,6 +1986,8 @@ out_stop: - - int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc) - { -+ struct super_block *sb = inode->i_sb; -+ struct ext3_sb_info *sbi = EXT3_SB(sb); - struct buffer_head *bh = 0; - unsigned long block; - unsigned long block_group; -@@ -1997,23 +2010,19 @@ int ext3_get_inode_loc (struct inode *in - inode->i_ino != EXT3_JOURNAL_INO && -- inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) || -- inode->i_ino > le32_to_cpu( -- inode->i_sb->u.ext3_sb.s_es->s_inodes_count)) { -- ext3_error (inode->i_sb, "ext3_get_inode_loc", -- "bad inode number: %lu", inode->i_ino); -+ inode->i_ino < EXT3_FIRST_INO(sb)) || -+ inode->i_ino > le32_to_cpu(sbi->s_es->s_inodes_count)) { -+ ext3_error (sb, __FUNCTION__, "bad inode #%lu", inode->i_ino); - goto bad_inode; - } -- block_group = (inode->i_ino - 1) / EXT3_INODES_PER_GROUP(inode->i_sb); -- if (block_group >= inode->i_sb->u.ext3_sb.s_groups_count) { -- ext3_error (inode->i_sb, "ext3_get_inode_loc", -- "group >= groups count"); -+ block_group = (inode->i_ino - 1) / sbi->s_inodes_per_group; -+ if (block_group >= sbi->s_groups_count) { -+ ext3_error(sb, __FUNCTION__, "group >= groups count"); - goto bad_inode; - } -- group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(inode->i_sb); -- desc = block_group & (EXT3_DESC_PER_BLOCK(inode->i_sb) - 1); -- bh = inode->i_sb->u.ext3_sb.s_group_desc[group_desc]; -+ group_desc = block_group >> sbi->s_desc_per_block_bits; -+ desc = block_group & (sbi->s_desc_per_block - 1); -+ bh = sbi->s_group_desc[group_desc]; - if (!bh) { -- ext3_error (inode->i_sb, "ext3_get_inode_loc", -- "Descriptor not loaded"); -+ ext3_error(sb, __FUNCTION__, "Descriptor not loaded"); - goto bad_inode; - } - -@@ -2021,17 +2022,17 @@ int ext3_get_inode_loc (struct inode *in - /* - * Figure out the offset within the block group inode table - */ -- offset = ((inode->i_ino - 1) % EXT3_INODES_PER_GROUP(inode->i_sb)) * -- EXT3_INODE_SIZE(inode->i_sb); -+ offset = ((inode->i_ino - 1) % sbi->s_inodes_per_group) * -+ sbi->s_inode_size; - block = le32_to_cpu(gdp[desc].bg_inode_table) + -- (offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb)); -- if (!(bh = sb_bread(inode->i_sb, block))) { -- ext3_error (inode->i_sb, "ext3_get_inode_loc", -+ (offset >> EXT3_BLOCK_SIZE_BITS(sb)); -+ if (!(bh = sb_bread(sb, block))) { -+ ext3_error (sb, __FUNCTION__, - "unable to read inode block - " - "inode=%lu, block=%lu", inode->i_ino, block); - goto bad_inode; - } -- offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1); -+ offset &= (EXT3_BLOCK_SIZE(sb) - 1); - - iloc->bh = bh; - iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset); -@@ -2047,6 +2048,7 @@ void ext3_read_inode(struct inode * inod - { - struct ext3_iloc iloc; - struct ext3_inode *raw_inode; -+ struct ext3_inode_info *ei = EXT3_I(inode); - struct buffer_head *bh; - int block; - -@@ -2054,7 +2056,7 @@ void ext3_read_inode(struct inode * inod - goto bad_inode; - bh = iloc.bh; - raw_inode = iloc.raw_inode; -- init_rwsem(&inode->u.ext3_i.truncate_sem); -+ init_rwsem(&ei->truncate_sem); - inode->i_mode = le16_to_cpu(raw_inode->i_mode); - inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); - inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); -@@ -2067,7 +2069,7 @@ void ext3_read_inode(struct inode * inod - inode->i_atime = le32_to_cpu(raw_inode->i_atime); - inode->i_ctime = le32_to_cpu(raw_inode->i_ctime); - inode->i_mtime = le32_to_cpu(raw_inode->i_mtime); -- inode->u.ext3_i.i_dtime = le32_to_cpu(raw_inode->i_dtime); -+ ei->i_dtime = le32_to_cpu(raw_inode->i_dtime); - /* We now have enough fields to check if the inode was active or not. - * This is needed because nfsd might try to access dead inodes - * the test is that same one that e2fsck uses -@@ -2075,7 +2077,7 @@ void ext3_read_inode(struct inode * inod - */ - if (inode->i_nlink == 0) { - if (inode->i_mode == 0 || -- !(inode->i_sb->u.ext3_sb.s_mount_state & EXT3_ORPHAN_FS)) { -+ !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ORPHAN_FS)) { - /* this inode is deleted */ - brelse (bh); - goto bad_inode; -@@ -2090,33 +2092,33 @@ void ext3_read_inode(struct inode * inod - * size */ - inode->i_blocks = le32_to_cpu(raw_inode->i_blocks); - inode->i_version = ++event; -- inode->u.ext3_i.i_flags = le32_to_cpu(raw_inode->i_flags); -+ ei->i_flags = le32_to_cpu(raw_inode->i_flags); - #ifdef EXT3_FRAGMENTS -- inode->u.ext3_i.i_faddr = le32_to_cpu(raw_inode->i_faddr); -- inode->u.ext3_i.i_frag_no = raw_inode->i_frag; -- inode->u.ext3_i.i_frag_size = raw_inode->i_fsize; -+ ei->i_faddr = le32_to_cpu(raw_inode->i_faddr); -+ ei->i_frag_no = raw_inode->i_frag; -+ ei->i_frag_size = raw_inode->i_fsize; - #endif -- inode->u.ext3_i.i_file_acl = le32_to_cpu(raw_inode->i_file_acl); -+ ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl); - if (!S_ISREG(inode->i_mode)) { -- inode->u.ext3_i.i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl); -+ ei->i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl); - } else { - inode->i_size |= - ((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32; - } -- inode->u.ext3_i.i_disksize = inode->i_size; -+ ei->i_disksize = inode->i_size; - inode->i_generation = le32_to_cpu(raw_inode->i_generation); - #ifdef EXT3_PREALLOCATE -- inode->u.ext3_i.i_prealloc_count = 0; -+ ei->i_prealloc_count = 0; - #endif -- inode->u.ext3_i.i_block_group = iloc.block_group; -+ ei->i_block_group = iloc.block_group; - - /* - * NOTE! The in-memory inode i_data array is in little-endian order - * even on big-endian machines: we do NOT byteswap the block numbers! - */ - for (block = 0; block < EXT3_N_BLOCKS; block++) -- inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block]; -- INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); -+ ei->i_data[block] = iloc.raw_inode->i_block[block]; -+ INIT_LIST_HEAD(&ei->i_orphan); - - brelse (iloc.bh); - -@@ -2143,17 +2145,17 @@ void ext3_read_inode(struct inode * inod - /* inode->i_attr_flags = 0; unused */ -- if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) { -+ if (ei->i_flags & EXT3_SYNC_FL) { - /* inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS; unused */ - inode->i_flags |= S_SYNC; - } -- if (inode->u.ext3_i.i_flags & EXT3_APPEND_FL) { -+ if (ei->i_flags & EXT3_APPEND_FL) { - /* inode->i_attr_flags |= ATTR_FLAG_APPEND; unused */ - inode->i_flags |= S_APPEND; - } -- if (inode->u.ext3_i.i_flags & EXT3_IMMUTABLE_FL) { -+ if (ei->i_flags & EXT3_IMMUTABLE_FL) { - /* inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE; unused */ - inode->i_flags |= S_IMMUTABLE; - } -- if (inode->u.ext3_i.i_flags & EXT3_NOATIME_FL) { -+ if (ei->i_flags & EXT3_NOATIME_FL) { - /* inode->i_attr_flags |= ATTR_FLAG_NOATIME; unused */ - inode->i_flags |= S_NOATIME; - } -@@ -2175,6 +2177,7 @@ static int ext3_do_update_inode(handle_t - struct ext3_iloc *iloc) - { - struct ext3_inode *raw_inode = iloc->raw_inode; -+ struct ext3_inode_info *ei = EXT3_I(inode); - struct buffer_head *bh = iloc->bh; - int err = 0, rc, block; - -@@ -2192,7 +2195,7 @@ static int ext3_do_update_inode(handle_t - * Fix up interoperability with old kernels. Otherwise, old inodes get - * re-used with the upper 16 bits of the uid/gid intact - */ -- if(!inode->u.ext3_i.i_dtime) { -+ if(!ei->i_dtime) { - raw_inode->i_uid_high = - cpu_to_le16(high_16_bits(inode->i_uid)); - raw_inode->i_gid_high = -@@ -2210,34 +2213,33 @@ static int ext3_do_update_inode(handle_t - raw_inode->i_gid_high = 0; - } - raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); -- raw_inode->i_size = cpu_to_le32(inode->u.ext3_i.i_disksize); -+ raw_inode->i_size = cpu_to_le32(ei->i_disksize); - raw_inode->i_atime = cpu_to_le32(inode->i_atime); - raw_inode->i_ctime = cpu_to_le32(inode->i_ctime); - raw_inode->i_mtime = cpu_to_le32(inode->i_mtime); - raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); -- raw_inode->i_dtime = cpu_to_le32(inode->u.ext3_i.i_dtime); -- raw_inode->i_flags = cpu_to_le32(inode->u.ext3_i.i_flags); -+ raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); -+ raw_inode->i_flags = cpu_to_le32(ei->i_flags); - #ifdef EXT3_FRAGMENTS -- raw_inode->i_faddr = cpu_to_le32(inode->u.ext3_i.i_faddr); -- raw_inode->i_frag = inode->u.ext3_i.i_frag_no; -- raw_inode->i_fsize = inode->u.ext3_i.i_frag_size; -+ raw_inode->i_faddr = cpu_to_le32(ei->i_faddr); -+ raw_inode->i_frag = ei->i_frag_no; -+ raw_inode->i_fsize = ei->i_frag_size; - #else - /* If we are not tracking these fields in the in-memory inode, - * then preserve them on disk, but still initialise them to zero - * for new inodes. */ -- if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) { -+ if (ei->i_state & EXT3_STATE_NEW) { - raw_inode->i_faddr = 0; - raw_inode->i_frag = 0; - raw_inode->i_fsize = 0; - } - #endif -- raw_inode->i_file_acl = cpu_to_le32(inode->u.ext3_i.i_file_acl); -+ raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl); - if (!S_ISREG(inode->i_mode)) { -- raw_inode->i_dir_acl = cpu_to_le32(inode->u.ext3_i.i_dir_acl); -+ raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl); - } else { -- raw_inode->i_size_high = -- cpu_to_le32(inode->u.ext3_i.i_disksize >> 32); -- if (inode->u.ext3_i.i_disksize > 0x7fffffffULL) { -+ raw_inode->i_size_high = cpu_to_le32(ei->i_disksize >> 32); -+ if (ei->i_disksize > MAX_NON_LFS) { - struct super_block *sb = inode->i_sb; - if (!EXT3_HAS_RO_COMPAT_FEATURE(sb, - EXT3_FEATURE_RO_COMPAT_LARGE_FILE) || -@@ -2247,7 +2249,7 @@ static int ext3_do_update_inode(handle_t - * created, add a flag to the superblock. - */ - err = ext3_journal_get_write_access(handle, -- sb->u.ext3_sb.s_sbh); -+ EXT3_SB(sb)->s_sbh); - if (err) - goto out_brelse; - ext3_update_dynamic_rev(sb); -@@ -2256,7 +2258,7 @@ static int ext3_do_update_inode(handle_t - sb->s_dirt = 1; - handle->h_sync = 1; - err = ext3_journal_dirty_metadata(handle, -- sb->u.ext3_sb.s_sbh); -+ EXT3_SB(sb)->s_sbh); - } - } - } -@@ -2265,13 +2267,13 @@ static int ext3_do_update_inode(handle_t - raw_inode->i_block[0] = - cpu_to_le32(kdev_t_to_nr(inode->i_rdev)); - else for (block = 0; block < EXT3_N_BLOCKS; block++) -- raw_inode->i_block[block] = inode->u.ext3_i.i_data[block]; -+ raw_inode->i_block[block] = ei->i_data[block]; - - BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); - rc = ext3_journal_dirty_metadata(handle, bh); - if (!err) - err = rc; -- EXT3_I(inode)->i_state &= ~EXT3_STATE_NEW; -+ ei->i_state &= ~EXT3_STATE_NEW; - - out_brelse: - brelse (bh); -@@ -2379,7 +2381,7 @@ int ext3_setattr(struct dentry *dentry, - } - - error = ext3_orphan_add(handle, inode); -- inode->u.ext3_i.i_disksize = attr->ia_size; -+ EXT3_I(inode)->i_disksize = attr->ia_size; - rc = ext3_mark_inode_dirty(handle, inode); - if (!error) - error = rc; -@@ -2622,9 +2624,9 @@ int ext3_change_inode_journal_flag(struc - */ - - if (val) -- inode->u.ext3_i.i_flags |= EXT3_JOURNAL_DATA_FL; -+ EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL; - else -- inode->u.ext3_i.i_flags &= ~EXT3_JOURNAL_DATA_FL; -+ EXT3_I(inode)->i_flags &= ~EXT3_JOURNAL_DATA_FL; - - journal_unlock_updates(journal); - ---- ./fs/ext3/ioctl.c.orig Fri Apr 12 10:27:49 2002 -+++ ./fs/ext3/ioctl.c Tue May 7 15:20:52 2002 -@@ -18,13 +18,14 @@ - int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, - unsigned long arg) - { -+ struct ext3_inode_info *ei = EXT3_I(inode); - unsigned int flags; - - ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg); - - switch (cmd) { - case EXT3_IOC_GETFLAGS: -- flags = inode->u.ext3_i.i_flags & EXT3_FL_USER_VISIBLE; -+ flags = ei->i_flags & EXT3_FL_USER_VISIBLE; - return put_user(flags, (int *) arg); - case EXT3_IOC_SETFLAGS: { - handle_t *handle = NULL; -@@ -42,7 +42,7 @@ int ext3_ioctl (struct inode * inode, st - if (get_user(flags, (int *) arg)) - return -EFAULT; - -- oldflags = inode->u.ext3_i.i_flags; -+ oldflags = ei->i_flags; - - /* The JOURNAL_DATA flag is modifiable only by root */ - jflag = flags & EXT3_JOURNAL_DATA_FL; -@@ -79,7 +79,7 @@ int ext3_ioctl (struct inode * inode, st - - flags = flags & EXT3_FL_USER_MODIFIABLE; - flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE; -- inode->u.ext3_i.i_flags = flags; -+ ei->i_flags = flags; - - if (flags & EXT3_SYNC_FL) - inode->i_flags |= S_SYNC; -@@ -155,12 +155,12 @@ flags_err: - int ret = 0; - - set_current_state(TASK_INTERRUPTIBLE); -- add_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait); -- if (timer_pending(&sb->u.ext3_sb.turn_ro_timer)) { -+ add_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait); -+ if (timer_pending(&EXT3_SB(sb)->turn_ro_timer)) { - schedule(); - ret = 1; - } -- remove_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait); -+ remove_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait); - return ret; - } - #endif ---- ./fs/ext3/namei.c.orig Fri Apr 12 10:27:49 2002 -+++ ./fs/ext3/namei.c Tue May 7 16:05:51 2002 -@@ -636,7 +636,7 @@ static struct buffer_head * ext3_find_en - } - - nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb); -- start = dir->u.ext3_i.i_dir_start_lookup; -+ start = EXT3_I(dir)->i_dir_start_lookup; - if (start >= nblocks) - start = 0; - block = start; -@@ -677,7 +677,7 @@ restart: - i = search_dirblock(bh, dir, dentry, - block << EXT3_BLOCK_SIZE_BITS(sb), res_dir); - if (i == 1) { -- dir->u.ext3_i.i_dir_start_lookup = block; -+ EXT3_I(dir)->i_dir_start_lookup = block; - ret = bh; - goto cleanup_and_exit; - } else { -@@ -1419,7 +1419,7 @@ int ext3_orphan_add(handle_t *handle, st - int err = 0, rc; - - lock_super(sb); -- if (!list_empty(&inode->u.ext3_i.i_orphan)) -+ if (!list_empty(&EXT3_I(inode)->i_orphan)) - goto out_unlock; - - /* Orphan handling is only valid for files with data blocks -@@ -1430,8 +1430,8 @@ int ext3_orphan_add(handle_t *handle, st - J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); - -- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access"); -- err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh); -+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); - if (err) - goto out_unlock; - -@@ -1442,7 +1442,7 @@ int ext3_orphan_add(handle_t *handle, st - /* Insert this inode at the head of the on-disk orphan list... */ - NEXT_ORPHAN(inode) = le32_to_cpu(EXT3_SB(sb)->s_es->s_last_orphan); - EXT3_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino); -- err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh); -+ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); - rc = ext3_mark_iloc_dirty(handle, inode, &iloc); - if (!err) - err = rc; -@@ -1456,7 +1456,7 @@ int ext3_orphan_add(handle_t *handle, st - * This is safe: on error we're going to ignore the orphan list - * anyway on the next recovery. */ - if (!err) -- list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan); -+ list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan); - - jbd_debug(4, "superblock will point to %ld\n", inode->i_ino); - jbd_debug(4, "orphan inode %ld will point to %d\n", -@@ -714,25 +770,25 @@ - int ext3_orphan_del(handle_t *handle, struct inode *inode) - { - struct list_head *prev; -+ struct ext3_inode_info *ei = EXT3_I(inode); - struct ext3_sb_info *sbi; - ino_t ino_next; - struct ext3_iloc iloc; - int err = 0; - - lock_super(inode->i_sb); -- if (list_empty(&inode->u.ext3_i.i_orphan)) { -+ if (list_empty(&ei->i_orphan)) { - unlock_super(inode->i_sb); - return 0; - } - - ino_next = NEXT_ORPHAN(inode); -- prev = inode->u.ext3_i.i_orphan.prev; -+ prev = ei->i_orphan.prev; - sbi = EXT3_SB(inode->i_sb); - - jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino); - -- list_del(&inode->u.ext3_i.i_orphan); -- INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); -+ list_del_init(&ei->i_orphan); - - /* If we're on an error path, we may not have a valid - * transaction handle with which to update the orphan list on -@@ -1520,9 +1520,8 @@ int ext3_orphan_del(handle_t *handle, st - err = ext3_journal_dirty_metadata(handle, sbi->s_sbh); - } else { - struct ext3_iloc iloc2; -- struct inode *i_prev = -- list_entry(prev, struct inode, u.ext3_i.i_orphan); -- -+ struct inode *i_prev = orphan_list_entry(prev); -+ - jbd_debug(4, "orphan inode %ld will point to %ld\n", - i_prev->i_ino, ino_next); - err = ext3_reserve_inode_write(handle, i_prev, &iloc2); -@@ -1695,10 +1695,10 @@ static int ext3_symlink (struct inode * - goto out_no_entry; - } else { - inode->i_op = &ext3_fast_symlink_inode_operations; -- memcpy((char*)&inode->u.ext3_i.i_data,symname,l); -+ memcpy((char*)&EXT3_I(inode)->i_data,symname,l); - inode->i_size = l-1; - } -- inode->u.ext3_i.i_disksize = inode->i_size; -+ EXT3_I(inode)->i_disksize = inode->i_size; - err = ext3_add_nondir(handle, dentry, inode); - ext3_mark_inode_dirty(handle, inode); - out_stop: ---- ./fs/ext3/super.c.orig Fri Apr 12 10:27:49 2002 -+++ ./fs/ext3/super.c Tue May 7 16:05:44 2002 -@@ -121,7 +121,7 @@ static int ext3_error_behaviour(struct s - /* If no overrides were specified on the mount, then fall back - * to the default behaviour set in the filesystem's superblock - * on disk. */ -- switch (le16_to_cpu(sb->u.ext3_sb.s_es->s_errors)) { -+ switch (le16_to_cpu(EXT3_SB(sb)->s_es->s_errors)) { - case EXT3_ERRORS_PANIC: - return EXT3_ERRORS_PANIC; - case EXT3_ERRORS_RO: -@@ -269,9 +269,9 @@ void ext3_abort (struct super_block * sb - return; - - printk (KERN_CRIT "Remounting filesystem read-only\n"); -- sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS; -+ EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; - sb->s_flags |= MS_RDONLY; -- sb->u.ext3_sb.s_mount_opt |= EXT3_MOUNT_ABORT; -+ EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT; - journal_abort(EXT3_SB(sb)->s_journal, -EIO); - } - -@@ -377,8 +377,6 @@ static int ext3_blkdev_remove(struct ext3 - return ret; - } - --#define orphan_list_entry(l) list_entry((l), struct inode, u.ext3_i.i_orphan) -- - static void dump_orphan_list(struct super_block *sb, struct ext3_sb_info *sbi) - { - struct list_head *l; -@@ -818,7 +818,7 @@ static void ext3_orphan_cleanup (struct - sb->s_flags &= ~MS_RDONLY; - } - -- if (sb->u.ext3_sb.s_mount_state & EXT3_ERROR_FS) { -+ if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { - if (es->s_last_orphan) - jbd_debug(1, "Errors on filesystem, " - "clearing orphan list.\n"); -@@ -1463,12 +1463,14 @@ static void ext3_commit_super (struct su - struct ext3_super_block * es, - int sync) - { -+ struct buffer_head *sbh = EXT3_SB(sb)->s_sbh; -+ - es->s_wtime = cpu_to_le32(CURRENT_TIME); -- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "marking dirty"); -- mark_buffer_dirty(sb->u.ext3_sb.s_sbh); -+ BUFFER_TRACE(sbh, "marking dirty"); -+ mark_buffer_dirty(sbh); - if (sync) { -- ll_rw_block(WRITE, 1, &sb->u.ext3_sb.s_sbh); -- wait_on_buffer(sb->u.ext3_sb.s_sbh); -+ ll_rw_block(WRITE, 1, &sbh); -+ wait_on_buffer(sbh); - } - } - -@@ -1519,7 +1521,7 @@ static void ext3_clear_journal_err(struc - ext3_warning(sb, __FUNCTION__, "Marking fs in need of " - "filesystem check."); - -- sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS; -+ EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; - es->s_state |= cpu_to_le16(EXT3_ERROR_FS); - ext3_commit_super (sb, es, 1); - ---- ./fs/ext3/symlink.c.orig Fri Apr 12 10:27:49 2002 -+++ ./fs/ext3/symlink.c Tue May 7 15:25:39 2002 -@@ -23,13 +23,13 @@ - - static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen) - { -- char *s = (char *)dentry->d_inode->u.ext3_i.i_data; -- return vfs_readlink(dentry, buffer, buflen, s); -+ struct ext3_inode_info *ei = EXT3_I(dentry->d_inode); -+ return vfs_readlink(dentry, buffer, buflen, (char *)ei->i_data); - } - - static int ext3_follow_link(struct dentry *dentry, struct nameidata *nd) - { -- char *s = (char *)dentry->d_inode->u.ext3_i.i_data; -- return vfs_follow_link(nd, s); -+ struct ext3_inode_info *ei = EXT3_I(dentry->d_inode); -+ return vfs_follow_link(nd, (char*)ei->i_data); - } - ---- ./include/linux/ext3_fs.h.orig Tue Apr 16 14:27:25 2002 -+++ ./include/linux/ext3_fs.h Tue May 7 16:47:36 2002 -@@ -84,22 +84,25 @@ - #define EXT3_MIN_BLOCK_SIZE 1024 - #define EXT3_MAX_BLOCK_SIZE 4096 - #define EXT3_MIN_BLOCK_LOG_SIZE 10 -+ - #ifdef __KERNEL__ --# define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) --#else --# define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) --#endif --#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) --#ifdef __KERNEL__ --# define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) --#else --# define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) --#endif --#ifdef __KERNEL__ --#define EXT3_ADDR_PER_BLOCK_BITS(s) ((s)->u.ext3_sb.s_addr_per_block_bits) --#define EXT3_INODE_SIZE(s) ((s)->u.ext3_sb.s_inode_size) --#define EXT3_FIRST_INO(s) ((s)->u.ext3_sb.s_first_ino) -+#define EXT3_SB(sb) (&((sb)->u.ext3_sb)) -+#define EXT3_I(inode) (&((inode)->u.ext3_i)) -+ -+#define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) -+#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -+#define EXT3_ADDR_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_addr_per_block_bits) -+#define EXT3_INODE_SIZE(s) (EXT3_SB(s)->s_inode_size) -+#define EXT3_FIRST_INO(s) (EXT3_SB(s)->s_first_ino) - #else -+ -+/* Assume that user mode programs are passing in an ext3fs superblock, not -+ * a kernel struct super_block. This will allow us to call the feature-test -+ * macros from user land. */ -+#define EXT3_SB(sb) (sb) -+ -+#define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) -+#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) - #define EXT3_INODE_SIZE(s) (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \ - EXT3_GOOD_OLD_INODE_SIZE : \ - (s)->s_inode_size) -@@ -108,6 +110,7 @@ - EXT3_GOOD_OLD_FIRST_INO : \ - (s)->s_first_ino) - #endif -+#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) - - /* - * Macro-instructions used to manage fragments -@@ -116,8 +120,8 @@ - #define EXT3_MAX_FRAG_SIZE 4096 - #define EXT3_MIN_FRAG_LOG_SIZE 10 - #ifdef __KERNEL__ --# define EXT3_FRAG_SIZE(s) ((s)->u.ext3_sb.s_frag_size) --# define EXT3_FRAGS_PER_BLOCK(s) ((s)->u.ext3_sb.s_frags_per_block) -+# define EXT3_FRAG_SIZE(s) (EXT3_SB(s)->s_frag_size) -+# define EXT3_FRAGS_PER_BLOCK(s) (EXT3_SB(s)->s_frags_per_block) - #else - # define EXT3_FRAG_SIZE(s) (EXT3_MIN_FRAG_SIZE << (s)->s_log_frag_size) - # define EXT3_FRAGS_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / EXT3_FRAG_SIZE(s)) -@@ -163,15 +167,13 @@ - /* - * Macro-instructions used to manage group descriptors - */ -+# define EXT3_BLOCKS_PER_GROUP(s) (EXT3_SB(s)->s_blocks_per_group) -+# define EXT3_INODES_PER_GROUP(s) (EXT3_SB(s)->s_inodes_per_group) - #ifdef __KERNEL__ --# define EXT3_BLOCKS_PER_GROUP(s) ((s)->u.ext3_sb.s_blocks_per_group) --# define EXT3_DESC_PER_BLOCK(s) ((s)->u.ext3_sb.s_desc_per_block) --# define EXT3_INODES_PER_GROUP(s) ((s)->u.ext3_sb.s_inodes_per_group) --# define EXT3_DESC_PER_BLOCK_BITS(s) ((s)->u.ext3_sb.s_desc_per_block_bits) -+# define EXT3_DESC_PER_BLOCK(s) (EXT3_SB(s)->s_desc_per_block) -+# define EXT3_DESC_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_desc_per_block_bits) - #else --# define EXT3_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) - # define EXT3_DESC_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_group_desc)) --# define EXT3_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) - #endif - - /* -@@ -344,7 +347,7 @@ - #ifndef _LINUX_EXT2_FS_H - #define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt - #define set_opt(o, opt) o |= EXT3_MOUNT_##opt --#define test_opt(sb, opt) ((sb)->u.ext3_sb.s_mount_opt & \ -+#define test_opt(sb, opt) (EXT3_SB(sb)->s_mount_opt & \ - EXT3_MOUNT_##opt) - #else - #define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD -@@ -441,17 +443,11 @@ - /*EC*/ __u32 s_reserved[197]; /* Padding to the end of the block */ - }; - --#ifdef __KERNEL__ --#define EXT3_SB(sb) (&((sb)->u.ext3_sb)) --#define EXT3_I(inode) (&((inode)->u.ext3_i)) --#else --/* Assume that user mode programs are passing in an ext3fs superblock, not -- * a kernel struct super_block. This will allow us to call the feature-test -- * macros from user land. */ --#define EXT3_SB(sb) (sb) --#endif -- --#define NEXT_ORPHAN(inode) (inode)->u.ext3_i.i_dtime -+#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime -+static inline struct inode *orphan_list_entry(struct list_head *l) -+{ -+ return list_entry(l, struct inode, u.ext3_i.i_orphan); -+} - - /* - * Codes for operating systems ---- ./include/linux/ext3_jbd.h.orig Tue May 7 14:44:08 2002 -+++ ./include/linux/ext3_jbd.h Tue May 7 14:44:43 2002 -@@ -291,7 +291,7 @@ - return 1; - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) - return 1; -- if (inode->u.ext3_i.i_flags & EXT3_JOURNAL_DATA_FL) -+ if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) - return 1; - return 0; - } diff --git a/lustre/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 37fd692..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) -@@ -447,7 +447,9 @@ - #define NEXT_ORPHAN(inode) EXTN_I(inode)->i_dtime - static inline struct inode *orphan_list_entry(struct list_head *l) - { -- return list_entry(l, struct inode, u.extN_i.i_orphan); -+ return ((struct inode *)((char *)l - -+ (unsigned long)(offsetof(struct inode, u.generic_ip) + -+ offsetof(struct extN_inode_info, i_orphan)))); - } - - /* 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 de8bc8a..0000000 --- a/lustre/extN/htree-ext3-2.4.18.diff +++ /dev/null @@ -1,1213 +0,0 @@ ---- ./fs/ext3/super.c 2002/03/05 06:18:59 2.1 -+++ ./fs/ext3/super.c 2002/03/05 06:26:56 -@@ -529,6 +529,12 @@ - "EXT3 Check option not supported\n"); - #endif - } -+ else if (!strcmp (this_char, "index")) -+#ifdef CONFIG_EXT3_INDEX -+ set_opt (*mount_options, INDEX); -+#else -+ printk("EXT3 index option not supported\n"); -+#endif - else if (!strcmp (this_char, "debug")) - set_opt (*mount_options, DEBUG); - else if (!strcmp (this_char, "errors")) { -@@ -702,6 +708,12 @@ static int ext3_setup_super(struct super - es->s_mtime = cpu_to_le32(CURRENT_TIME); - ext3_update_dynamic_rev(sb); - EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); -+ -+ if (test_opt(sb, INDEX)) -+ EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX); -+ else if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) -+ set_opt (EXT3_SB(sb)->s_mount_opt, INDEX); -+ - ext3_commit_super (sb, es, 1); - if (test_opt (sb, DEBUG)) - printk (KERN_INFO ---- ./fs/ext3/namei.c 2002/03/05 06:18:59 2.1 -+++ ./fs/ext3/namei.c 2002/03/06 00:13:18 -@@ -16,6 +16,10 @@ - * David S. Miller (davem@caip.rutgers.edu), 1995 - * Directory entry file type support and forward compatibility hooks - * for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998 -+ * Hash Tree Directory indexing (c) -+ * Daniel Phillips, 2001 -+ * Hash Tree Directory indexing porting -+ * Christopher Li, 2002 - */ - - #include -@@ -33,7 +33,7 @@ - #include - #include - #include -- -+#include - - /* - * define how far ahead to read directories while searching them. -@@ -38,6 +42,433 @@ - #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) - #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b)) - -+static struct buffer_head *ext3_append(handle_t *handle, -+ struct inode *inode, -+ u32 *block, int *err) -+{ -+ struct buffer_head *bh; -+ -+ *block = inode->i_size >> inode->i_sb->s_blocksize_bits; -+ -+ if ((bh = ext3_bread(handle, inode, *block, 1, err))) { -+ inode->i_size += inode->i_sb->s_blocksize; -+ EXT3_I(inode)->i_disksize = inode->i_size; -+ ext3_journal_get_write_access(handle,bh); -+ } -+ return bh; -+} -+ -+#ifndef assert -+#define assert(test) J_ASSERT(test) -+#endif -+ -+#ifndef swap -+#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0) -+#endif -+ -+typedef struct { u32 v; } le_u32; -+typedef struct { u16 v; } le_u16; -+ -+#define dxtrace_on(command) command -+#define dxtrace_off(command) -+#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 dot; -+ char dot_name[4]; -+ struct fake_dirent dotdot; -+ char dotdot_name[4]; -+ struct dx_root_info -+ { -+ le_u32 reserved_zero; -+ u8 hash_version; /* 0 now, 1 at release */ -+ u8 info_length; /* 8 */ -+ u8 indirect_levels; -+ u8 unused_flags; -+ } -+ info; -+ struct dx_entry entries[0]; -+}; -+ -+struct dx_node -+{ -+ struct fake_dirent fake; -+ struct dx_entry entries[0]; -+}; -+ -+ -+struct dx_frame -+{ -+ struct buffer_head *bh; -+ struct dx_entry *entries; -+ struct dx_entry *at; -+}; -+ -+struct dx_map_entry -+{ -+ u32 hash; -+ u32 offs; -+}; -+ -+typedef struct ext3_dir_entry_2 ext3_dirent; -+static inline unsigned dx_get_block (struct dx_entry *entry); -+static void dx_set_block (struct dx_entry *entry, unsigned value); -+static inline unsigned dx_get_hash (struct dx_entry *entry); -+static void dx_set_hash (struct dx_entry *entry, unsigned value); -+static unsigned dx_get_count (struct dx_entry *entries); -+static unsigned dx_get_limit (struct dx_entry *entries); -+static void dx_set_count (struct dx_entry *entries, unsigned value); -+static void dx_set_limit (struct dx_entry *entries, unsigned value); -+static unsigned dx_root_limit (struct inode *dir, unsigned infosize); -+static unsigned dx_node_limit (struct inode *dir); -+static unsigned dx_hack_hash (const u8 *name, int len); -+static struct dx_frame *dx_probe (struct inode *dir, u32 hash, struct dx_frame *frame); -+static void dx_release (struct dx_frame *frames); -+static int dx_make_map (ext3_dirent *de, int size, struct dx_map_entry map[]); -+static void dx_sort_map(struct dx_map_entry *map, unsigned count); -+static ext3_dirent *dx_copy_dirents (char *from, char *to, -+ struct dx_map_entry *map, int count); -+static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); -+ -+ -+#ifdef CONFIG_EXT3_INDEX -+/* -+ * Future: use high four bits of block for coalesce-on-delete flags -+ * Mask them off for now. -+ */ -+ -+static inline unsigned dx_get_block (struct dx_entry *entry) -+{ -+ return le32_to_cpu(entry->block.v) & 0x00ffffff; -+} -+ -+static inline void dx_set_block (struct dx_entry *entry, unsigned value) -+{ -+ entry->block.v = cpu_to_le32(value); -+} -+ -+static inline unsigned dx_get_hash (struct dx_entry *entry) -+{ -+ return le32_to_cpu(entry->hash.v); -+} -+ -+static inline void dx_set_hash (struct dx_entry *entry, unsigned value) -+{ -+ entry->hash.v = cpu_to_le32(value); -+} -+ -+static inline unsigned dx_get_count (struct dx_entry *entries) -+{ -+ return le16_to_cpu(((struct dx_countlimit *) entries)->count.v); -+} -+ -+static inline unsigned dx_get_limit (struct dx_entry *entries) -+{ -+ return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v); -+} -+ -+static inline void dx_set_count (struct dx_entry *entries, unsigned value) -+{ -+ ((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value); -+} -+ -+static inline void dx_set_limit (struct dx_entry *entries, unsigned value) -+{ -+ ((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value); -+} -+ -+static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize) -+{ -+ unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) - -+ EXT3_DIR_REC_LEN(2) - infosize; -+ return 0? 20: entry_space / sizeof(struct dx_entry); -+} -+ -+static inline unsigned dx_node_limit (struct inode *dir) -+{ -+ unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0); -+ return 0? 22: entry_space / sizeof(struct dx_entry); -+} -+ -+/* Hash function - not bad, but still looking for an ideal default */ -+ -+static unsigned dx_hack_hash (const u8 *name, int len) -+{ -+ u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; -+ while (len--) -+ { -+ u32 hash = hash1 + (hash0 ^ (*name++ * 7152373)); -+ if (hash & 0x80000000) hash -= 0x7fffffff; -+ hash1 = hash0; -+ hash0 = hash; -+ } -+ return hash0; -+} -+ -+#define dx_hash(s,n) (dx_hack_hash(s,n) << 1) -+ -+/* -+ * Debug -+ */ -+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}; -+} -+ -+/* -+ * Probe for a directory leaf block to search -+ */ -+ -+static struct dx_frame * -+dx_probe(struct inode *dir, u32 hash, struct dx_frame *frame_in) -+{ -+ unsigned count, indirect; -+ struct dx_entry *at, *entries, *p, *q, *m; -+ struct dx_root *root; -+ struct buffer_head *bh; -+ struct dx_frame *frame = frame_in; -+ int err; -+ -+ frame->bh = NULL; -+ if (!(bh = ext3_bread(NULL, dir, 0, 0, &err))) -+ goto fail; -+ root = (struct dx_root *) bh->b_data; -+ if (root->info.hash_version > 0 || root->info.unused_flags & 1) { -+ brelse(bh); -+ goto fail; -+ } -+ if ((indirect = root->info.indirect_levels) > 1) { -+ brelse(bh); -+ goto fail; -+ } -+ entries = (struct dx_entry *) (((char *) &root->info) + root->info.info_length); -+ assert (dx_get_limit(entries) == dx_root_limit(dir, root->info.info_length)); -+ dxtrace (printk("Look up %x", hash)); -+ while (1) -+ { -+ count = dx_get_count(entries); -+ assert (count && count <= dx_get_limit(entries)); -+ p = entries + 1; -+ q = entries + count - 1; -+ while (p <= q) -+ { -+ m = p + (q - p)/2; -+ dxtrace(printk(".")); -+ if (dx_get_hash(m) > hash) -+ q = m - 1; -+ else -+ p = m + 1; -+ } -+ -+ if (0) // linear search cross check -+ { -+ unsigned n = count - 1; -+ at = entries; -+ while (n--) -+ { -+ dxtrace(printk(",")); -+ if (dx_get_hash(++at) > hash) -+ { -+ at--; -+ break; -+ } -+ } -+ assert (at == p - 1); -+ } -+ -+ at = p - 1; -+ dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at))); -+ frame->bh = bh; -+ frame->entries = entries; -+ frame->at = at; -+ if (!indirect--) return frame; -+ if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0,&err))) -+ goto fail2; -+ at = entries = ((struct dx_node *) bh->b_data)->entries; -+ assert (dx_get_limit(entries) == dx_node_limit (dir)); -+ frame++; -+ } -+fail2: -+ while (frame >= frame_in) { -+ brelse(frame->bh); -+ frame--; -+ } -+fail: -+ return NULL; -+} -+ -+static void dx_release (struct dx_frame *frames) -+{ -+ if (frames[0].bh == NULL) -+ return; -+ -+ if (((struct dx_root *)frames[0].bh->b_data)->info.indirect_levels) -+ brelse (frames[1].bh); -+ brelse (frames[0].bh); -+} -+ -+/* -+ * Directory block splitting, compacting -+ */ -+ -+static int dx_make_map (ext3_dirent *de, int size, struct dx_map_entry map[]) -+{ -+ int count = 0; -+ char *base = (char *) de; -+ while ((char *) de < base + size) { -+ if (de->name_len && de->inode) { -+ map[count].hash = dx_hash (de->name, de->name_len); -+ map[count].offs = (u32) ((char *) de - base); -+ count++; -+ } -+ de = (ext3_dirent *) ((char *) de + le16_to_cpu(de->rec_len)); -+ } -+ return count; -+} -+ -+static void dx_sort_map (struct dx_map_entry *map, unsigned count) -+{ -+ struct dx_map_entry *p, *q, *top = map + count - 1; -+ int more; -+ /* Combsort until bubble sort doesn't suck */ -+ while (count > 2) -+ { -+ count = count*10/13; -+ if (count - 9 < 2) /* 9, 10 -> 11 */ -+ count = 11; -+ for (p = top, q = p - count; q >= map; p--, q--) -+ if (p->hash < q->hash) -+ swap(*p, *q); -+ } -+ /* Garden variety bubble sort */ -+ do { -+ more = 0; -+ q = top; -+ while (q-- > map) -+ { -+ if (q[1].hash >= q[0].hash) -+ continue; -+ swap(*(q+1), *q); -+ more = 1; -+ } -+ } while(more); -+} -+ -+static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block) -+{ -+ struct dx_entry *entries = frame->entries; -+ struct dx_entry *old = frame->at, *new = old + 1; -+ int count = dx_get_count(entries); -+ -+ assert(count < dx_get_limit(entries)); -+ assert(old < entries + count); -+ memmove(new + 1, new, (char *)(entries + count) - (char *)(new)); -+ dx_set_hash(new, hash); -+ dx_set_block(new, block); -+ dx_set_count(entries, count + 1); -+} -+#endif -+ -+static void ext3_update_dx_flag(struct inode *inode) -+{ -+ if (!test_opt(inode->i_sb, INDEX)) -+ EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL; -+} -+ - /* - * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure. - * -@@ -95,6 +529,15 @@ - } - - /* -+ * p is at least 6 bytes before the end of page -+ */ -+static inline ext3_dirent *ext3_next_entry(ext3_dirent *p) -+{ -+ return (ext3_dirent *)((char*)p + le16_to_cpu(p->rec_len)); -+} -+ -+ -+/* - * ext3_find_entry() - * - * finds an entry in the specified directory with the wanted name. It -@@ -105,6 +548,8 @@ - * The returned buffer_head has ->b_count elevated. The caller is expected - * to brelse() it when appropriate. - */ -+ -+ - static struct buffer_head * ext3_find_entry (struct dentry *dentry, - struct ext3_dir_entry_2 ** res_dir) - { -@@ -119,10 +564,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 = (ext3_dirent *) bh->b_data; -+ top = (ext3_dirent *) ((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,92 @@ - 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; -+ char *data1 = (*bh)->b_data, *data2, *data3; -+ unsigned split; -+ ext3_dirent *de, *de2; -+ -+ bh2 = ext3_append (handle, dir, &newblock, error); -+ if (!(bh2)) -+ { -+ brelse(*bh); -+ *bh = NULL; -+ return (ext3_dirent *)bh2; -+ } -+ -+ BUFFER_TRACE(*bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, *bh); -+ BUFFER_TRACE(frame->bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, frame->bh); -+ -+ data2 = bh2->b_data; -+ -+ map = kmalloc(sizeof(*map) * MAX_DX_MAP, GFP_KERNEL); -+ if (!map) -+ panic("no memory for do_split\n"); -+ 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)); -+ kfree(map); -+ 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,281 @@ - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; - unsigned long offset; -- unsigned short rec_len; - struct buffer_head * bh; -- struct ext3_dir_entry_2 * de, * de1; -- struct super_block * sb; -+ ext3_dirent *de; -+ struct super_block * sb = dir->i_sb; - int retval; -+ unsigned short reclen = EXT3_DIR_REC_LEN(namelen); - -- sb = dir->i_sb; -+ unsigned blocksize = sb->s_blocksize; -+ unsigned nlen, rlen; -+ u32 block, blocks; -+ 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); -+ /* FIXME: do something if dx_probe() fails here */ -+ frame = dx_probe(dir, hash, frames); -+ entries = frame->entries; -+ at = frame->at; -+ -+ if (!(bh = ext3_bread(handle,dir, dx_get_block(at), 0,&retval))) -+ goto dxfail1; -+ -+ BUFFER_TRACE(bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, bh); -+ -+ data1 = bh->b_data; -+ de = (ext3_dirent *) data1; -+ top = data1 + (0? 200: blocksize); -+ while ((char *) de < top) -+ { -+ /* FIXME: check EEXIST and dir */ -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ if ((de->inode? rlen - nlen: rlen) >= reclen) -+ goto dx_add; -+ de = (ext3_dirent *) ((char *) de + rlen); -+ } -+ /* Block full, should compress but for now just split */ -+ dxtrace(printk("using %u of %u node entries\n", -+ dx_get_count(entries), dx_get_limit(entries))); -+ /* Need to split index? */ -+ if (dx_get_count(entries) == dx_get_limit(entries)) -+ { -+ u32 newblock; -+ unsigned icount = dx_get_count(entries); -+ int levels = frame - frames; -+ struct dx_entry *entries2; -+ struct dx_node *node2; -+ struct buffer_head *bh2; -+ if (levels && dx_get_count(frames->entries) == dx_get_limit(frames->entries)) -+ goto dxfull; -+ bh2 = ext3_append (handle, dir, &newblock, &retval); -+ if (!(bh2)) -+ goto dxfail2; -+ node2 = (struct dx_node *)(bh2->b_data); -+ entries2 = node2->entries; -+ node2->fake.rec_len = cpu_to_le16(blocksize); -+ node2->fake.inode = 0; -+ BUFFER_TRACE(frame->bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, frame->bh); -+ if (levels) -+ { -+ unsigned icount1 = icount/2, icount2 = icount - icount1; -+ unsigned hash2 = dx_get_hash(entries + icount1); -+ dxtrace(printk("Split index %i/%i\n", icount1, icount2)); -+ -+ BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */ -+ ext3_journal_get_write_access(handle, frames[0].bh); -+ -+ memcpy ((char *) entries2, (char *) (entries + icount1), -+ icount2 * sizeof(struct dx_entry)); -+ dx_set_count (entries, icount1); -+ dx_set_count (entries2, icount2); -+ dx_set_limit (entries2, dx_node_limit(dir)); -+ -+ /* Which index block gets the new entry? */ -+ if (at - entries >= icount1) { -+ frame->at = at = at - entries - icount1 + entries2; -+ frame->entries = entries = entries2; -+ swap(frame->bh, bh2); - } -- -- ext3_debug ("creating next block\n"); -- -- BUFFER_TRACE(bh, "get_write_access"); -- ext3_journal_get_write_access(handle, bh); -- de = (struct ext3_dir_entry_2 *) bh->b_data; -- de->inode = 0; -- de->rec_len = le16_to_cpu(sb->s_blocksize); -- dir->u.ext3_i.i_disksize = -- dir->i_size = offset + sb->s_blocksize; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -- ext3_mark_inode_dirty(handle, dir); -+ dx_insert_block (frames + 0, hash2, newblock); -+ dxtrace(dx_show_index ("node", frames[1].entries)); -+ dxtrace(dx_show_index ("node", -+ ((struct dx_node *) bh2->b_data)->entries)); -+ ext3_journal_dirty_metadata(handle, bh2); -+ brelse (bh2); - } else { -- -- ext3_debug ("skipping to next block\n"); -- -- de = (struct ext3_dir_entry_2 *) bh->b_data; -+ dxtrace(printk("Creating second level index...\n")); -+ memcpy((char *) entries2, (char *) entries, -+ icount * sizeof(struct dx_entry)); -+ dx_set_limit(entries2, dx_node_limit(dir)); -+ -+ /* Set up root */ -+ dx_set_count(entries, 1); -+ dx_set_block(entries + 0, newblock); -+ ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1; -+ -+ /* Add new access path frame */ -+ frame = frames + 1; -+ frame->at = at = at - entries + entries2; -+ frame->entries = entries = entries2; -+ frame->bh = bh2; -+ ext3_journal_get_write_access(handle, frame->bh); - } -+ ext3_journal_dirty_metadata(handle, frames[0].bh); - } -- if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh, -- offset)) { -- brelse (bh); -- return -ENOENT; -- } -- if (ext3_match (namelen, name, de)) { -+ de = do_split(handle, dir, &bh, frame, hash, &retval); -+ dx_release (frames); -+ if (!(de)) -+ goto fail; -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ goto add; -+ -+dx_add: -+ dx_release (frames); -+ goto add; -+ -+dxfull: -+ ext3_warning(sb, __FUNCTION__, "Directory index full!\n"); -+ retval = -ENOSPC; -+dxfail2: -+ brelse(bh); -+dxfail1: -+ dx_release (frames); -+ goto fail1; -+ } -+ -+ blocks = dir->i_size >> sb->s_blocksize_bits; -+ for (block = 0, offset = 0; block < blocks; block++) { -+ bh = ext3_bread(handle, dir, block, 0, &retval); -+ if(!bh) -+ return retval; -+ de = (ext3_dirent *)bh->b_data; -+ top = bh->b_data + blocksize - reclen; -+ while ((char *) de <= top) { -+ if (!ext3_check_dir_entry("ext3_add_entry", dir, de, -+ bh, offset)) { -+ brelse (bh); -+ return -EIO; -+ } -+ if (ext3_match (namelen, name, de)) { - brelse (bh); - return -EEXIST; -- } -- if ((le32_to_cpu(de->inode) == 0 && -- le16_to_cpu(de->rec_len) >= rec_len) || -- (le16_to_cpu(de->rec_len) >= -- EXT3_DIR_REC_LEN(de->name_len) + rec_len)) { -- BUFFER_TRACE(bh, "get_write_access"); -- ext3_journal_get_write_access(handle, bh); -- /* By now the buffer is marked for journaling */ -- offset += le16_to_cpu(de->rec_len); -- if (le32_to_cpu(de->inode)) { -- de1 = (struct ext3_dir_entry_2 *) ((char *) de + -- EXT3_DIR_REC_LEN(de->name_len)); -- de1->rec_len = -- cpu_to_le16(le16_to_cpu(de->rec_len) - -- EXT3_DIR_REC_LEN(de->name_len)); -- de->rec_len = cpu_to_le16( -- EXT3_DIR_REC_LEN(de->name_len)); -- de = de1; - } -- de->file_type = EXT3_FT_UNKNOWN; -- if (inode) { -- de->inode = cpu_to_le32(inode->i_ino); -- ext3_set_de_type(dir->i_sb, de, inode->i_mode); -- } else -- de->inode = 0; -- de->name_len = namelen; -- memcpy (de->name, name, namelen); -- /* -- * XXX shouldn't update any times until successful -- * completion of syscall, but too many callers depend -- * on this. -- * -- * XXX similarly, too many callers depend on -- * ext3_new_inode() setting the times, but error -- * recovery deletes the inode, so the worst that can -- * happen is that the times are slightly out of date -- * and/or different from the directory change time. -- */ -- dir->i_mtime = dir->i_ctime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -- dir->i_version = ++event; -- ext3_mark_inode_dirty(handle, dir); -- BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -- ext3_journal_dirty_metadata(handle, bh); -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ if ((de->inode? rlen - nlen: rlen) >= reclen) -+ goto add; -+ de = (ext3_dirent *)((char *)de + rlen); -+ offset += rlen; -+ } -+ if (ext3_dx && blocks == 1 && test_opt(sb, INDEX)) -+ goto dx_make_index; -+ brelse(bh); -+ } -+ bh = ext3_append(handle, dir, &block, &retval); -+ if (!bh) -+ return retval; -+ de = (ext3_dirent *) bh->b_data; -+ de->inode = 0; -+ de->rec_len = cpu_to_le16(rlen = blocksize); -+ nlen = 0; -+ goto add; -+ -+add: -+ BUFFER_TRACE(bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, bh); -+ /* By now the buffer is marked for journaling */ -+ if (de->inode) { -+ ext3_dirent *de1 = (ext3_dirent *)((char *)de + nlen); -+ de1->rec_len = cpu_to_le16(rlen - nlen); -+ de->rec_len = cpu_to_le16(nlen); -+ de = de1; -+ } -+ de->file_type = EXT3_FT_UNKNOWN; -+ if (inode) { -+ de->inode = cpu_to_le32(inode->i_ino); -+ ext3_set_de_type(dir->i_sb, de, inode->i_mode); -+ } else -+ de->inode = 0; -+ de->name_len = namelen; -+ memcpy (de->name, name, namelen); -+ /* -+ * XXX shouldn't update any times until successful -+ * completion of syscall, but too many callers depend -+ * on this. -+ * -+ * XXX similarly, too many callers depend on -+ * ext3_new_inode() setting the times, but error -+ * recovery deletes the inode, so the worst that can -+ * happen is that the times are slightly out of date -+ * and/or different from the directory change time. -+ */ -+ dir->i_mtime = dir->i_ctime = CURRENT_TIME; -+ ext3_update_dx_flag(dir); -+ dir->i_version = ++event; -+ ext3_mark_inode_dirty(handle, dir); -+ BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -+ ext3_journal_dirty_metadata(handle, bh); -+ brelse(bh); -+ return 0; -+ -+dx_make_index: -+ { -+ struct buffer_head *bh2; -+ struct dx_root *root; -+ struct dx_frame frames[2], *frame; -+ struct dx_entry *entries; -+ ext3_dirent *de2; -+ char *data1; -+ unsigned len; -+ u32 hash; -+ -+ dxtrace(printk("Creating index\n")); -+ ext3_journal_get_write_access(handle, bh); -+ root = (struct dx_root *) bh->b_data; -+ -+ EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; -+ bh2 = ext3_append (handle, dir, &block, &retval); -+ if (!(bh2)) -+ { - brelse(bh); -- return 0; -+ return retval; - } -- offset += le16_to_cpu(de->rec_len); -- de = (struct ext3_dir_entry_2 *) -- ((char *) de + le16_to_cpu(de->rec_len)); -+ data1 = bh2->b_data; -+ -+ /* The 0th block becomes the root, move the dirents out */ -+ de = (ext3_dirent *) &root->info; -+ len = ((char *) root) + 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->dotdot); -+ de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2)); -+ memset (&root->info, 0, sizeof(root->info)); -+ root->info.info_length = sizeof(root->info); -+ 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); - -@@ -550,7 +1320,7 @@ - if (err) - goto out_no_entry; - dir->i_nlink++; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); - d_instantiate(dentry, inode); - out_stop: -@@ -832,7 +1596,7 @@ - ext3_mark_inode_dirty(handle, inode); - dir->i_nlink--; - inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); - - end_rmdir: -@@ -878,7 +1642,7 @@ - if (retval) - goto end_unlink; - dir->i_ctime = dir->i_mtime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); - inode->i_nlink--; - if (!inode->i_nlink) -@@ -904,7 +1668,8 @@ - if (l > dir->i_sb->s_blocksize) - return -ENAMETOOLONG; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -959,7 +1724,8 @@ - if (inode->i_nlink >= EXT3_LINK_MAX) - return -EMLINK; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -995,7 +1761,8 @@ - - old_bh = new_bh = dir_bh = NULL; - -- handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2); -+ handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -1077,7 +1844,7 @@ - new_inode->i_ctime = CURRENT_TIME; - } - old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; -- old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(old_dir); - if (dir_bh) { - BUFFER_TRACE(dir_bh, "get_write_access"); - ext3_journal_get_write_access(handle, dir_bh); -@@ -1089,7 +1856,7 @@ - new_inode->i_nlink--; - } else { - new_dir->i_nlink++; -- new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(new_dir); - ext3_mark_inode_dirty(handle, new_dir); - } - } ---- ./include/linux/ext3_fs.h 2002/03/05 06:18:59 2.1 -+++ ./include/linux/ext3_fs.h 2002/03/05 06:26:56 -@@ -339,6 +339,7 @@ - #define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */ - #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ - #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ -+#define EXT3_MOUNT_INDEX 0x4000 /* Enable directory index */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -575,6 +576,24 @@ - #define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) - #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ - ~EXT3_DIR_ROUND) -+/* -+ * Hash Tree Directory indexing -+ * (c) Daniel Phillips, 2001 -+ */ -+ -+#define CONFIG_EXT3_INDEX -+ -+#ifdef CONFIG_EXT3_INDEX -+ enum {ext3_dx = 1}; -+ #define is_dx(dir) (EXT3_I(dir)->i_flags & EXT3_INDEX_FL) -+#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) -+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) -+#else -+ enum {ext3_dx = 0}; -+ #define is_dx(dir) 0 -+#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX) -+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2) -+#endif - - #ifdef __KERNEL__ - /* ---- ./include/linux/ext3_jbd.h 2002/03/05 06:18:59 2.1 -+++ ./include/linux/ext3_jbd.h 2002/03/05 06:33:54 -@@ -63,6 +63,8 @@ - - #define EXT3_RESERVE_TRANS_BLOCKS 12 - -+#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 -+ - int - ext3_mark_iloc_dirty(handle_t *handle, - struct inode *inode, diff --git a/lustre/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 15df90c..0000000 --- a/lustre/extN/linux-2.4.18ea-0.8.26.diff +++ /dev/null @@ -1,1787 +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/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,7 +2138,7 @@ - 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; -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 -@@ -465,6 +466,8 @@ - inode->i_fop = &extN_file_operations; - inode->i_mapping->a_ops = &ext3_aops; - err = ext3_add_nondir(handle, dentry, inode); -+ if (err) -+ ext3_xattr_drop_inode(handle, inode); - ext3_mark_inode_dirty(handle, inode); - } - ext3_journal_stop(handle, dir); -@@ -490,6 +493,8 @@ - if (!IS_ERR(inode)) { - init_special_inode(inode, mode, rdev); - err = ext3_add_nondir(handle, dentry, inode); -+ if (err) -+ ext3_xattr_drop_inode(handle, inode); - ext3_mark_inode_dirty(handle, inode); - } - ext3_journal_stop(handle, dir); -@@ -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,5 +919,5 @@ - goto out_stop; - -- if (l > sizeof (inode->u.ext3_i.i_data)) { -+ if (l > sizeof(EXT3_I(inode)->i_data)) { - inode->i_op = &page_symlink_inode_operations; - inode->i_mapping->a_ops = &ext3_aops; -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/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,1247 @@ -+/* -+ * 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 -+#include -+ -+/* These symbols may be needed by a module. */ -+EXPORT_SYMBOL(extN_xattr_register); -+EXPORT_SYMBOL(extN_xattr_unregister); -+EXPORT_SYMBOL(extN_xattr_get); -+EXPORT_SYMBOL(extN_xattr_list); -+EXPORT_SYMBOL(extN_xattr_set); -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) -+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1) -+#endif -+ -+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data)) -+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr)) -+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1) -+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) -+ -+#ifdef EXT3_XATTR_DEBUG -+# define ea_idebug(inode, f...) do { \ -+ printk(KERN_DEBUG "inode %s:%ld: ", \ -+ kdevname(inode->i_dev), inode->i_ino); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+# define ea_bdebug(bh, f...) do { \ -+ printk(KERN_DEBUG "block %s:%ld: ", \ -+ kdevname(bh->b_dev), bh->b_blocknr); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+#else -+# define ea_idebug(f...) -+# define ea_bdebug(f...) -+#endif -+ -+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *, -+ struct ext3_xattr_header *); -+ -+#ifdef CONFIG_EXT3_FS_XATTR_SHARING -+ -+static int ext3_xattr_cache_insert(struct buffer_head *); -+static struct buffer_head *ext3_xattr_cache_find(struct inode *, -+ struct ext3_xattr_header *); -+static void ext3_xattr_cache_remove(struct buffer_head *); -+static void ext3_xattr_rehash(struct ext3_xattr_header *, -+ struct ext3_xattr_entry *); -+ -+static struct mb_cache *ext3_xattr_cache; -+ -+#else -+# define ext3_xattr_cache_insert(bh) 0 -+# define ext3_xattr_cache_find(inode, header) NULL -+# define ext3_xattr_cache_remove(bh) do {} while(0) -+# define ext3_xattr_rehash(header, entry) do {} while(0) -+#endif -+ -+/* -+ * If a file system does not share extended attributes among inodes, -+ * we should not need the ext3_xattr_sem semaphore. However, the -+ * filesystem may still contain shared blocks, so we always take -+ * the lock. -+ */ -+ -+DECLARE_MUTEX(ext3_xattr_sem); -+ -+static inline void -+ext3_xattr_lock(void) -+{ -+ down(&ext3_xattr_sem); -+} -+ -+static inline void -+ext3_xattr_unlock(void) -+{ -+ up(&ext3_xattr_sem); -+} -+ -+static inline int -+ext3_xattr_new_block(handle_t *handle, struct inode *inode, -+ int * errp, int force) -+{ -+ struct super_block *sb = inode->i_sb; -+ int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + -+ EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb); -+ -+ /* How can we enforce the allocation? */ -+ int block = ext3_new_block(handle, inode, goal, 0, 0, errp); -+#ifdef OLD_QUOTAS -+ if (!*errp) -+ inode->i_blocks += inode->i_sb->s_blocksize >> 9; -+#endif -+ return block; -+} -+ -+static inline int -+ext3_xattr_quota_alloc(struct inode *inode, int force) -+{ -+ /* How can we enforce the allocation? */ -+#ifdef OLD_QUOTAS -+ int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1); -+ if (!error) -+ inode->i_blocks += inode->i_sb->s_blocksize >> 9; -+#else -+ int error = DQUOT_ALLOC_BLOCK(inode, 1); -+#endif -+ return error; -+} -+ -+#ifdef OLD_QUOTAS -+ -+static inline void -+ext3_xattr_quota_free(struct inode *inode) -+{ -+ DQUOT_FREE_BLOCK(inode->i_sb, inode, 1); -+ inode->i_blocks -= inode->i_sb->s_blocksize >> 9; -+} -+ -+static inline void -+ext3_xattr_free_block(handle_t *handle, struct inode * inode, -+ unsigned long block) -+{ -+ ext3_free_blocks(handle, inode, block, 1); -+ inode->i_blocks -= inode->i_sb->s_blocksize >> 9; -+} -+ -+#else -+# define ext3_xattr_quota_free(inode) \ -+ DQUOT_FREE_BLOCK(inode, 1) -+# define ext3_xattr_free_block(handle, inode, block) \ -+ ext3_free_blocks(handle, inode, block, 1) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) -+ -+static inline struct buffer_head * -+sb_bread(struct super_block *sb, int block) -+{ -+ return bread(sb->s_dev, block, sb->s_blocksize); -+} -+ -+static inline struct buffer_head * -+sb_getblk(struct super_block *sb, int block) -+{ -+ return getblk(sb->s_dev, block, sb->s_blocksize); -+} -+ -+#endif -+ -+struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX]; -+rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED; -+ -+int -+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler) -+{ -+ int error = -EINVAL; -+ -+ if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ if (!ext3_xattr_handlers[name_index-1]) { -+ ext3_xattr_handlers[name_index-1] = handler; -+ error = 0; -+ } -+ write_unlock(&ext3_handler_lock); -+ } -+ return error; -+} -+ -+void -+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler) -+{ -+ if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ ext3_xattr_handlers[name_index-1] = NULL; -+ write_unlock(&ext3_handler_lock); -+ } -+} -+ -+static inline const char * -+strcmp_prefix(const char *a, const char *a_prefix) -+{ -+ while (*a_prefix && *a == *a_prefix) { -+ a++; -+ a_prefix++; -+ } -+ return *a_prefix ? NULL : a; -+} -+ -+/* -+ * Decode the extended attribute name, and translate it into -+ * the name_index and name suffix. -+ */ -+static inline struct ext3_xattr_handler * -+ext3_xattr_resolve_name(const char **name) -+{ -+ struct ext3_xattr_handler *handler = NULL; -+ int i; -+ -+ if (!*name) -+ return NULL; -+ read_lock(&ext3_handler_lock); -+ for (i=0; 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; -+ (void)ext3_xattr_cache_insert(new_bh); -+ } else { -+ /* We need to allocate a new block */ -+ int force = EXT3_I(inode)->i_file_acl != 0; -+ int block = ext3_xattr_new_block(handle, inode, -+ &error, force); -+ if (error) -+ goto cleanup; -+ ea_idebug(inode, "creating block %d", block); -+ -+ new_bh = sb_getblk(sb, block); -+ if (!new_bh) { -+getblk_failed: ext3_xattr_free_block(handle, inode, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ lock_buffer(new_bh); -+ error = ext3_journal_get_create_access(handle, new_bh); -+ if (error) { -+ unlock_buffer(new_bh); -+ goto getblk_failed; -+ } -+ memcpy(new_bh->b_data, header, new_bh->b_size); -+ mark_buffer_uptodate(new_bh, 1); -+ unlock_buffer(new_bh); -+ (void)ext3_xattr_cache_insert(new_bh); -+ ext3_xattr_update_super_block(handle, sb); -+ } -+ error = ext3_journal_dirty_metadata(handle, new_bh); -+ if (error) -+ goto cleanup; -+ } -+ -+ /* Update the inode. */ -+ EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0; -+ inode->i_ctime = CURRENT_TIME; -+ ext3_mark_inode_dirty(handle, inode); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ -+ error = 0; -+ if (old_bh && old_bh != new_bh) { -+ /* -+ * If there was an old block, and we are not still using it, -+ * we now release the old block. -+ */ -+ unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount); -+ -+ error = ext3_journal_get_write_access(handle, old_bh); -+ if (error) -+ goto cleanup; -+ if (refcount == 1) { -+ /* Free the old block. */ -+ ea_bdebug(old_bh, "freeing"); -+ ext3_xattr_free_block(handle, inode, old_bh->b_blocknr); -+ -+ /* ext3_forget() calls bforget() for us, but we -+ let our caller release old_bh, so we need to -+ duplicate the handle before. */ -+ get_bh(old_bh); -+ ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr); -+ } else { -+ /* Decrement the refcount only. */ -+ refcount--; -+ HDR(old_bh)->h_refcount = cpu_to_le32(refcount); -+ ext3_xattr_quota_free(inode); -+ ext3_journal_dirty_metadata(handle, old_bh); -+ ea_bdebug(old_bh, "refcount now=%d", refcount); -+ } -+ } -+ -+cleanup: -+ if (old_bh != new_bh) -+ brelse(new_bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_drop_inode() -+ * -+ * Free extended attribute resources associated with this inode. This -+ * is called immediately before an inode is freed. -+ */ -+void -+ext3_xattr_drop_inode(handle_t *handle, struct inode *inode) -+{ -+ struct buffer_head *bh; -+ unsigned int block = EXT3_I(inode)->i_file_acl; -+ -+ if (!block) -+ return; -+ ext3_xattr_lock(); -+ -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_drop_inode", -+ "inode %ld: block %d read error", inode->i_ino, block); -+ goto cleanup; -+ } -+ ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count))); -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+ ext3_error(inode->i_sb, "ext3_xattr_drop_inode", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ goto cleanup; -+ } -+ ext3_journal_get_write_access(handle, bh); -+ ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ if (HDR(bh)->h_refcount == cpu_to_le32(1)) { -+ ext3_xattr_cache_remove(bh); -+ ext3_xattr_free_block(handle, inode, block); -+ ext3_forget(handle, 1, inode, bh, block); -+ bh = NULL; -+ } else { -+ HDR(bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ ext3_journal_dirty_metadata(handle, bh); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ ext3_xattr_quota_free(inode); -+ } -+ EXT3_I(inode)->i_file_acl = 0; -+ -+cleanup: -+ brelse(bh); -+ ext3_xattr_unlock(); -+} -+ -+/* -+ * ext3_xattr_put_super() -+ * -+ * This is called when a file system is unmounted. -+ */ -+void -+ext3_xattr_put_super(struct super_block *sb) -+{ -+#ifdef CONFIG_EXT3_FS_XATTR_SHARING -+ mb_cache_shrink(ext3_xattr_cache, sb->s_dev); -+#endif -+} -+ -+#ifdef CONFIG_EXT3_FS_XATTR_SHARING -+ -+/* -+ * ext3_xattr_cache_insert() -+ * -+ * Create a new entry in the extended attribute cache, and insert -+ * it unless such an entry is already in the cache. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+static int -+ext3_xattr_cache_insert(struct buffer_head *bh) -+{ -+ __u32 hash = le32_to_cpu(HDR(bh)->h_hash); -+ struct mb_cache_entry *ce; -+ int error; -+ -+ ce = mb_cache_entry_alloc(ext3_xattr_cache); -+ if (!ce) -+ return -ENOMEM; -+ error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash); -+ if (error) { -+ mb_cache_entry_free(ce); -+ if (error == -EBUSY) { -+ ea_bdebug(bh, "already in cache (%d cache entries)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ error = 0; -+ } -+ } else { -+ ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash, -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ mb_cache_entry_release(ce); -+ } -+ return error; -+} -+ -+/* -+ * ext3_xattr_cmp() -+ * -+ * Compare two extended attribute blocks for equality. -+ * -+ * Returns 0 if the blocks are equal, 1 if they differ, and -+ * a negative error number on errors. -+ */ -+static int -+ext3_xattr_cmp(struct ext3_xattr_header *header1, -+ struct ext3_xattr_header *header2) -+{ -+ struct ext3_xattr_entry *entry1, *entry2; -+ -+ entry1 = ENTRY(header1+1); -+ entry2 = ENTRY(header2+1); -+ while (!IS_LAST_ENTRY(entry1)) { -+ if (IS_LAST_ENTRY(entry2)) -+ return 1; -+ if (entry1->e_hash != entry2->e_hash || -+ entry1->e_name_len != entry2->e_name_len || -+ entry1->e_value_size != entry2->e_value_size || -+ memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len)) -+ return 1; -+ if (entry1->e_value_block != 0 || entry2->e_value_block != 0) -+ return -EIO; -+ if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), -+ (char *)header2 + le16_to_cpu(entry2->e_value_offs), -+ le32_to_cpu(entry1->e_value_size))) -+ return 1; -+ -+ entry1 = EXT3_XATTR_NEXT(entry1); -+ entry2 = EXT3_XATTR_NEXT(entry2); -+ } -+ if (!IS_LAST_ENTRY(entry2)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * ext3_xattr_cache_find() -+ * -+ * Find an identical extended attribute block. -+ * -+ * Returns a pointer to the block found, or NULL if such a block was -+ * not found or an error occurred. -+ */ -+static struct buffer_head * -+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header) -+{ -+ __u32 hash = le32_to_cpu(header->h_hash); -+ struct mb_cache_entry *ce; -+ -+ if (!header->h_hash) -+ return NULL; /* never share */ -+ ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); -+ ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash); -+ while (ce) { -+ struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block); -+ -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_cache_find", -+ "inode %ld: block %ld read error", -+ inode->i_ino, ce->e_block); -+ } else if (le32_to_cpu(HDR(bh)->h_refcount) > -+ EXT3_XATTR_REFCOUNT_MAX) { -+ ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block, -+ le32_to_cpu(HDR(bh)->h_refcount), -+ EXT3_XATTR_REFCOUNT_MAX); -+ } else if (!ext3_xattr_cmp(header, HDR(bh))) { -+ ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count))); -+ mb_cache_entry_release(ce); -+ return bh; -+ } -+ brelse(bh); -+ ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash); -+ } -+ return NULL; -+} -+ -+/* -+ * ext3_xattr_cache_remove() -+ * -+ * Remove the cache entry of a block from the cache. Called when a -+ * block becomes invalid. -+ */ -+static void -+ext3_xattr_cache_remove(struct buffer_head *bh) -+{ -+ struct mb_cache_entry *ce; -+ -+ ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr); -+ if (ce) { -+ ea_bdebug(bh, "removing (%d cache entries remaining)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)-1); -+ mb_cache_entry_free(ce); -+ } else -+ ea_bdebug(bh, "no cache entry"); -+} -+ -+#define NAME_HASH_SHIFT 5 -+#define VALUE_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_hash_entry() -+ * -+ * Compute the hash of an extended attribute. -+ */ -+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ __u32 hash = 0; -+ char *name = entry->e_name; -+ int n; -+ -+ for (n=0; n < entry->e_name_len; n++) { -+ hash = (hash << NAME_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ -+ *name++; -+ } -+ -+ if (entry->e_value_block == 0 && entry->e_value_size != 0) { -+ __u32 *value = (__u32 *)((char *)header + -+ le16_to_cpu(entry->e_value_offs)); -+ for (n = (le32_to_cpu(entry->e_value_size) + -+ EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) { -+ hash = (hash << VALUE_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ -+ le32_to_cpu(*value++); -+ } -+ } -+ entry->e_hash = cpu_to_le32(hash); -+} -+ -+#undef NAME_HASH_SHIFT -+#undef VALUE_HASH_SHIFT -+ -+#define BLOCK_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_rehash() -+ * -+ * Re-compute the extended attribute hash value after an entry has changed. -+ */ -+static void ext3_xattr_rehash(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ struct ext3_xattr_entry *here; -+ __u32 hash = 0; -+ -+ ext3_xattr_hash_entry(header, entry); -+ here = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(here)) { -+ if (!here->e_hash) { -+ /* Block is not shared if an entry's hash value == 0 */ -+ hash = 0; -+ break; -+ } -+ hash = (hash << BLOCK_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^ -+ le32_to_cpu(here->e_hash); -+ here = EXT3_XATTR_NEXT(here); -+ } -+ header->h_hash = cpu_to_le32(hash); -+} -+ -+#undef BLOCK_HASH_SHIFT -+ -+int __init -+init_ext3_xattr(void) -+{ -+ ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL, -+ sizeof(struct mb_cache_entry) + -+ sizeof(struct mb_cache_entry_index), 1, 61); -+ if (!ext3_xattr_cache) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+void -+exit_ext3_xattr(void) -+{ -+ if (ext3_xattr_cache) -+ mb_cache_destroy(ext3_xattr_cache); -+ ext3_xattr_cache = NULL; -+} -+ -+#else /* CONFIG_EXT3_FS_XATTR_SHARING */ -+ -+int __init -+init_ext3_xattr(void) -+{ -+ return 0; -+} -+ -+void -+exit_ext3_xattr(void) -+{ -+} -+ -+#endif /* CONFIG_EXT3_FS_XATTR_SHARING */ -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 *); - -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/.cvsignore b/lustre/include/.cvsignore deleted file mode 100644 index 864df96..0000000 --- a/lustre/include/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -.Xrefs -config.log -config.status -configure -config.h -stamp-h -stamp-h.in -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/include/config.h.in b/lustre/include/config.h.in deleted file mode 100644 index 14f0f3b..0000000 --- a/lustre/include/config.h.in +++ /dev/null @@ -1,10 +0,0 @@ -/* include/config.h.in. Generated automatically from configure.in by autoheader. */ - -/* Define if you have the `readline' library (-lreadline). */ -#undef HAVE_LIBREADLINE - -/* Name of package */ -#undef PACKAGE - -/* Version number of package */ -#undef VERSION diff --git a/lustre/include/linux/.cvsignore b/lustre/include/linux/.cvsignore deleted file mode 100644 index b731c89..0000000 --- a/lustre/include/linux/.cvsignore +++ /dev/null @@ -1,15 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS -extN_fs.h -extN_fs_i.h -extN_fs_sb.h -extN_jbd.h -extN_xattr.h -xattr.h -lustre_build_version.h diff --git a/lustre/include/linux/Makefile b/lustre/include/linux/Makefile deleted file mode 100644 index c263b40..0000000 --- a/lustre/include/linux/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -all .DEFAULT: - $(MAKE) -C ../.. $@ diff --git a/lustre/include/linux/lprocfs_status.h b/lustre/include/linux/lprocfs_status.h deleted file mode 100644 index e769f43..0000000 --- a/lustre/include/linux/lprocfs_status.h +++ /dev/null @@ -1,132 +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. - * - * Top level header file for LProc SNMP - * Author: Hariharan Thantry thantry@users.sourceforge.net - */ -#ifndef _LPROCFS_SNMP_H -#define _LPROCFS_SNMP_H - - -#ifndef LPROC_SNMP -#define LPROC_SNMP -#endif - -#include - -typedef enum { - E_LPROC_OK = 0 -} lproc_error_t; - -struct lprocfs_vars{ - - char* name; - read_proc_t* read_fptr; - write_proc_t* write_fptr; - void* data; -}; - -#ifdef LPROC_SNMP - -struct proc_dir_entry* lprocfs_mkdir(const char *dname, - struct proc_dir_entry *parent); -struct proc_dir_entry* lprocfs_srch(struct proc_dir_entry *head, - const char *name); -void lprocfs_remove_all(struct proc_dir_entry *root); -struct proc_dir_entry* lprocfs_new_dir(struct proc_dir_entry *root, - const char *string, - const char *tok); -int lprocfs_new_vars(struct proc_dir_entry *root, struct lprocfs_vars *list, - const char *tok, void *data); - -int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *var, - void *data); -int lprocfs_reg_obd(struct obd_device *device, struct lprocfs_vars *list, - void *data); -int lprocfs_dereg_obd(struct obd_device *device); -struct proc_dir_entry* lprocfs_reg_mnt(char *mnt_name); -int lprocfs_dereg_mnt(struct proc_dir_entry *root); - -int lprocfs_reg_class(struct obd_type *type, struct lprocfs_vars *list, - void *data); -int lprocfs_dereg_class(struct obd_type *class); -int lprocfs_reg_main(void); -int lprocfs_dereg_main(void); -int lprocfs_ll_rd(char *page, char **start, off_t off, int count, int *eof, - void *data); -#else - - -static inline int lprocfs_add_vars(struct proc_dir_entry *root, - struct lprocfs_vars *var, void *data) -{ - return 0; -} - -static inline int lprocfs_reg_obd(struct obd_device* device, - struct lprocfs_vars* list, void* data) -{ - return 0; -} - -static inline int lprocfs_dereg_obd(struct obd_device* device) -{ - return 0; -} - -static inline struct proc_dir_entry* lprocfs_reg_mnt(char *name) -{ - return NULL; -} - -static inline int lprocfs_dereg_mnt(struct proc_dir_entry* root) -{ - return 0; -} - -static inline int lprocfs_reg_class(struct obd_type* type, - struct lprocfs_vars* list, void* data) -{ - return 0; -} - -static inline int lprocfs_dereg_class(struct obd_type* class) -{ - return 0; -} - -static inline int lprocfs_reg_main(void) -{ - return 0; -} - -static inline int lprocfs_dereg_main(void) -{ - return 0; -} - -static inline int lprocfs_ll_rd(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} -#endif /* LPROC_SNMP */ - -#endif /* LPROCFS_SNMP_H */ diff --git a/lustre/include/linux/lustre_debug.h b/lustre/include/linux/lustre_debug.h deleted file mode 100644 index 756d32e..0000000 --- a/lustre/include/linux/lustre_debug.h +++ /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. - * - */ - -#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); -int page_debug_setup(void *addr, int len, __u64 off, __u64 id); -int page_debug_check(char *who, void *addr, int len, __u64 off, __u64 id); -#endif diff --git a/lustre/include/linux/lustre_dlm.h b/lustre/include/linux/lustre_dlm.h deleted file mode 100644 index 916db86..0000000 --- a/lustre/include/linux/lustre_dlm.h +++ /dev/null @@ -1,463 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * (visit-tags-table FILE) - * vim:expandtab:shiftwidth=8:tabstop=8: - */ - -#ifndef _LUSTRE_DLM_H__ -#define _LUSTRE_DLM_H__ - -#ifdef __KERNEL__ - -#include -#include -#include -#include - -struct obd_ops; -struct obd_device; - -#define OBD_LDLM_DEVICENAME "ldlm" - -typedef enum { - ELDLM_OK = 0, - - ELDLM_LOCK_CHANGED = 300, - ELDLM_LOCK_ABORTED = 301, - - ELDLM_NAMESPACE_EXISTS = 400, - ELDLM_BAD_NAMESPACE = 401 -} ldlm_error_t; - -#define LDLM_NAMESPACE_SERVER 0 -#define LDLM_NAMESPACE_CLIENT 1 - -#define LDLM_FL_LOCK_CHANGED (1 << 0) /* extent, mode, or resource changed */ - -/* If the server returns one of these flags, then the lock was put on that list. - * If the client sends one of these flags (during recovery ONLY!), it wants the - * lock added to the specified list, no questions asked. -p */ -#define LDLM_FL_BLOCK_GRANTED (1 << 1) -#define LDLM_FL_BLOCK_CONV (1 << 2) -#define LDLM_FL_BLOCK_WAIT (1 << 3) - -#define LDLM_FL_CBPENDING (1 << 4) // this lock is being destroyed -#define LDLM_FL_AST_SENT (1 << 5) // blocking or cancel packet was sent -#define LDLM_FL_WAIT_NOREPROC (1 << 6)// not a real lock flag,not saved in lock -#define LDLM_FL_CANCEL (1 << 7) // cancellation callback already run - -/* Lock is being replayed. This could probably be implied by the fact that one - * of BLOCK_{GRANTED,CONV,WAIT} is set, but that is pretty dangerous. */ -#define LDLM_FL_REPLAY (1 << 8) - -#define LDLM_FL_INTENT_ONLY (1 << 9) /* don't grant lock, just do intent */ -#define LDLM_FL_LOCAL_ONLY (1 << 10) /* see ldlm_cli_cancel_unused */ -#define LDLM_FL_NO_CALLBACK (1 << 11) /* see ldlm_cli_cancel_unused */ -#define LDLM_FL_HAS_INTENT (1 << 12) /* lock request has intent */ -#define LDLM_FL_CANCELING (1 << 13) /* lock cancel has already been sent */ - -/* The blocking callback is overloaded to perform two functions. These flags - * indicate which operation should be performed. */ -#define LDLM_CB_BLOCKING 1 -#define LDLM_CB_CANCELING 2 - -#define L2B(c) (1 << c) - -/* compatibility matrix */ -#define LCK_COMPAT_EX L2B(LCK_NL) -#define LCK_COMPAT_PW (LCK_COMPAT_EX | L2B(LCK_CR)) -#define LCK_COMPAT_PR (LCK_COMPAT_PW | L2B(LCK_PR)) -#define LCK_COMPAT_CW (LCK_COMPAT_PW | L2B(LCK_CW)) -#define LCK_COMPAT_CR (LCK_COMPAT_CW | L2B(LCK_PR) | L2B(LCK_PW)) -#define LCK_COMPAT_NL (LCK_COMPAT_CR | L2B(LCK_EX)) - -static ldlm_mode_t lck_compat_array[] = { - [LCK_EX] LCK_COMPAT_EX, - [LCK_PW] LCK_COMPAT_PW, - [LCK_PR] LCK_COMPAT_PR, - [LCK_CW] LCK_COMPAT_CW, - [LCK_CR] LCK_COMPAT_CR, - [LCK_NL] LCK_COMPAT_NL -}; - -static inline int lockmode_compat(ldlm_mode_t exist, ldlm_mode_t new) -{ - if (exist < LCK_EX || exist > LCK_NL) - LBUG(); - if (new < LCK_EX || new > LCK_NL) - LBUG(); - - return (lck_compat_array[exist] & L2B(new)); -} - -/* - * - * cluster name spaces - * - */ - -#define DLM_OST_NAMESPACE 1 -#define DLM_MDS_NAMESPACE 2 - -/* XXX - - do we just separate this by security domains and use a prefix for - multiple namespaces in the same domain? - - -*/ - -struct ldlm_namespace { - char *ns_name; - __u32 ns_client; /* is this a client-side lock tree? */ - struct list_head *ns_hash; /* hash table for ns */ - __u32 ns_refcount; /* count of resources in the hash */ - struct list_head ns_root_list; /* all root resources in ns */ - struct lustre_lock ns_lock; /* protects hash, refcount, list */ - struct list_head ns_list_chain; /* position in global NS list */ - /* - struct proc_dir_entry *ns_proc_dir; - */ - - struct list_head ns_unused_list; /* all root resources in ns */ - unsigned int ns_nr_unused; - unsigned int ns_max_unused; - - spinlock_t ns_counter_lock; - __u64 ns_locks; - __u64 ns_resources; -}; - -/* - * - * Resource hash table - * - */ - -#define RES_HASH_BITS 14 -#define RES_HASH_SIZE (1UL << RES_HASH_BITS) -#define RES_HASH_MASK (RES_HASH_SIZE - 1) - -struct ldlm_lock; - -typedef int (*ldlm_blocking_callback)(struct ldlm_lock *lock, - struct ldlm_lock_desc *new, void *data, - __u32 data_len, int flag); - -typedef int (*ldlm_completion_callback)(struct ldlm_lock *lock, int flags); - -struct ldlm_lock { - __u64 l_random; - atomic_t l_refc; - struct ldlm_resource *l_resource; - struct ldlm_lock *l_parent; - struct list_head l_children; - struct list_head l_childof; - struct list_head l_lru; - struct list_head l_res_link; /*position in one of three res lists*/ - struct list_head l_export_chain; /* per-export chain of locks */ - struct list_head l_pending_chain; /* locks with callbacks pending*/ - unsigned long l_callback_timeout; - - ldlm_mode_t l_req_mode; - ldlm_mode_t l_granted_mode; - - ldlm_completion_callback l_completion_ast; - ldlm_blocking_callback l_blocking_ast; - - struct obd_export *l_export; - struct lustre_handle *l_connh; - __u32 l_flags; - struct lustre_handle l_remote_handle; - void *l_data; - __u32 l_data_len; - struct ldlm_extent l_extent; - __u32 l_version[RES_VERSION_SIZE]; - - __u32 l_readers; - __u32 l_writers; - __u8 l_destroyed; - - /* If the lock is granted, a process sleeps on this waitq to learn when - * it's no longer in use. If the lock is not granted, a process sleeps - * on this waitq to learn when it becomes granted. */ - wait_queue_head_t l_waitq; -}; - -typedef int (*ldlm_res_compat)(struct ldlm_lock *child, struct ldlm_lock *new); -typedef int (*ldlm_res_policy)(struct ldlm_lock *lock, void *req_cookie, - ldlm_mode_t mode, int flags, void *data); - -#define LDLM_PLAIN 10 -#define LDLM_EXTENT 11 - -#define LDLM_MIN_TYPE 10 -#define LDLM_MAX_TYPE 11 - -extern ldlm_res_compat ldlm_res_compat_table []; -extern ldlm_res_policy ldlm_res_policy_table []; - -struct ldlm_resource { - struct ldlm_namespace *lr_namespace; - struct list_head lr_hash; - struct ldlm_resource *lr_parent; /* 0 for a root resource */ - struct list_head lr_children; /* list head for child resources */ - struct list_head lr_childof; /* part of ns_root_list if root res, - * part of lr_children if child */ - - struct list_head lr_granted; - struct list_head lr_converting; - struct list_head lr_waiting; - ldlm_mode_t lr_most_restr; - __u32 lr_type; /* LDLM_PLAIN or LDLM_EXTENT */ - struct ldlm_resource *lr_root; - __u64 lr_name[RES_NAME_SIZE]; - __u32 lr_version[RES_VERSION_SIZE]; - atomic_t lr_refcount; - void *lr_tmp; -}; - -struct ldlm_ast_work { - struct ldlm_lock *w_lock; - int w_blocking; - struct ldlm_lock_desc w_desc; - struct list_head w_list; - int w_flags; - void *w_data; - int w_datalen; -}; - -/* Per-export ldlm state. */ -struct ldlm_export_data { - struct list_head led_held_locks; - struct obd_import led_import; -}; - -static inline struct ldlm_extent *ldlm_res2extent(struct ldlm_resource *res) -{ - return (struct ldlm_extent *)(res->lr_name); -} - -extern struct obd_ops ldlm_obd_ops; - -extern char *ldlm_lockname[]; -extern char *ldlm_typename[]; -extern char *ldlm_it2str(int it); - -#define LDLM_DEBUG(lock, format, a...) \ -do { \ - if (lock->l_resource == NULL) { \ - CDEBUG(D_DLMTRACE, "### " format \ - " ns: \?\? lock: %p lrc: %d/%d,%d mode: %s/%s " \ - "res: \?\? rrc=\?\? type: \?\?\? remote: "LPX64")\n" \ - , ## a, lock, lock->l_refc, lock->l_readers, \ - lock->l_writers, \ - ldlm_lockname[lock->l_granted_mode], \ - ldlm_lockname[lock->l_req_mode], \ - lock->l_remote_handle.addr); \ - break; \ - } \ - if (lock->l_resource->lr_type == LDLM_EXTENT) { \ - CDEBUG(D_DLMTRACE, "### " format \ - " ns: %s lock: %p lrc: %d/%d,%d mode: %s/%s res: "LPU64 \ - "/"LPU64" rrc: %d type: %s ["LPU64"->"LPU64"] remote: " \ - LPX64"\n" , ## a, \ - lock->l_resource->lr_namespace->ns_name, lock, \ - lock->l_refc, lock->l_readers, lock->l_writers, \ - ldlm_lockname[lock->l_granted_mode], \ - ldlm_lockname[lock->l_req_mode], \ - lock->l_resource->lr_name[0], \ - lock->l_resource->lr_name[1], \ - atomic_read(&lock->l_resource->lr_refcount), \ - ldlm_typename[lock->l_resource->lr_type], \ - lock->l_extent.start, lock->l_extent.end, \ - lock->l_remote_handle.addr); \ - break; \ - } \ - { \ - CDEBUG(D_DLMTRACE, "### " format \ - " ns: %s lock: %p lrc: %d/%d,%d mode: %s/%s res: "LPU64 \ - "/"LPU64" rrc: %d type: %s remote: "LPX64"\n" , ## a, \ - lock->l_resource->lr_namespace->ns_name, lock, \ - lock->l_refc, lock->l_readers, lock->l_writers, \ - ldlm_lockname[lock->l_granted_mode], \ - ldlm_lockname[lock->l_req_mode], \ - lock->l_resource->lr_name[0], \ - lock->l_resource->lr_name[1], \ - atomic_read(&lock->l_resource->lr_refcount), \ - ldlm_typename[lock->l_resource->lr_type], \ - lock->l_remote_handle.addr); \ - } \ -} while (0) - -#define LDLM_DEBUG_NOLOCK(format, a...) \ - CDEBUG(D_DLMTRACE, "### " format "\n" , ## a) - -/* - * Iterators. - */ - -#define LDLM_ITER_CONTINUE 0 /* keep iterating */ -#define LDLM_ITER_STOP 1 /* stop iterating */ - -typedef int (*ldlm_iterator_t)(struct ldlm_lock *, void *); - -int ldlm_resource_foreach(struct ldlm_resource *res, ldlm_iterator_t iter, - void *closure); -int ldlm_namespace_foreach(struct ldlm_namespace *ns, ldlm_iterator_t iter, - void *closure); - -int ldlm_replay_locks(struct obd_import *imp); - -/* ldlm_extent.c */ -int ldlm_extent_compat(struct ldlm_lock *, struct ldlm_lock *); -int ldlm_extent_policy(struct ldlm_lock *, void *, ldlm_mode_t, int flags, - void *); - -/* ldlm_lockd.c */ -int ldlm_handle_enqueue(struct ptlrpc_request *req); -int ldlm_handle_convert(struct ptlrpc_request *req); -int ldlm_handle_cancel(struct ptlrpc_request *req); -int ldlm_del_waiting_lock(struct ldlm_lock *lock); - -/* ldlm_lock.c */ -void ldlm_register_intent(int (*arg)(struct ldlm_lock *lock, void *req_cookie, - ldlm_mode_t mode, int flags, void *data)); -void ldlm_unregister_intent(void); -void ldlm_lock2handle(struct ldlm_lock *lock, struct lustre_handle *lockh); -struct ldlm_lock *__ldlm_handle2lock(struct lustre_handle *, int strict, - int flags); -void ldlm_cancel_callback(struct ldlm_lock *); -int ldlm_lock_set_data(struct lustre_handle *, void *data, int datalen); -void ldlm_lock_remove_from_lru(struct ldlm_lock *); - -static inline struct ldlm_lock *ldlm_handle2lock(struct lustre_handle *h) -{ - return __ldlm_handle2lock(h, 1, 0); -} - -#define LDLM_LOCK_PUT(lock) \ -do { \ - /*LDLM_DEBUG(lock, "put");*/ \ - ldlm_lock_put(lock); \ -} while (0) - -#define LDLM_LOCK_GET(lock) \ -({ \ - ldlm_lock_get(lock); \ - /*LDLM_DEBUG(lock, "get");*/ \ - lock; \ -}) - -struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock); -void ldlm_lock_put(struct ldlm_lock *lock); -void ldlm_lock_destroy(struct ldlm_lock *lock); -void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc); -void ldlm_lock_addref(struct lustre_handle *lockh, __u32 mode); -void ldlm_lock_addref_internal(struct ldlm_lock *, __u32 mode); -void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode); -void ldlm_grant_lock(struct ldlm_lock *lock); -int ldlm_lock_match(struct ldlm_namespace *ns, __u64 *res_id, __u32 type, - void *cookie, int cookielen, ldlm_mode_t mode, - struct lustre_handle *lockh); -struct ldlm_lock * -ldlm_lock_create(struct ldlm_namespace *ns, - struct lustre_handle *parent_lock_handle, - __u64 *res_id, __u32 type, ldlm_mode_t mode, void *data, - __u32 data_len); -ldlm_error_t ldlm_lock_enqueue(struct ldlm_lock *lock, void *cookie, - int cookie_len, int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback blocking); -struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode, - int *flags); -void ldlm_lock_cancel(struct ldlm_lock *lock); -void ldlm_cancel_locks_for_export(struct obd_export *export); -void ldlm_run_ast_work(struct list_head *rpc_list); -void ldlm_reprocess_all(struct ldlm_resource *res); -void ldlm_lock_dump(struct ldlm_lock *lock); - -/* ldlm_test.c */ -int ldlm_test(struct obd_device *device, struct lustre_handle *connh); -int ldlm_regression_start(struct obd_device *obddev, - struct lustre_handle *connh, - unsigned int threads, unsigned int max_locks_in, - unsigned int num_resources_in, - unsigned int num_extents_in); -int ldlm_regression_stop(void); - - -/* resource.c */ -struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 local); -int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only); -int ldlm_namespace_free(struct ldlm_namespace *ns); -int ldlm_proc_setup(struct obd_device *obd); -void ldlm_proc_cleanup(struct obd_device *obd); - -/* resource.c - internal */ -struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns, - struct ldlm_resource *parent, - __u64 *name, __u32 type, int create); -struct ldlm_resource *ldlm_resource_getref(struct ldlm_resource *res); -int ldlm_resource_putref(struct ldlm_resource *res); -void ldlm_resource_add_lock(struct ldlm_resource *res, struct list_head *head, - struct ldlm_lock *lock); -void ldlm_resource_unlink_lock(struct ldlm_lock *lock); -void ldlm_res2desc(struct ldlm_resource *res, struct ldlm_resource_desc *desc); -void ldlm_dump_all_namespaces(void); -void ldlm_namespace_dump(struct ldlm_namespace *); -void ldlm_resource_dump(struct ldlm_resource *); -int ldlm_lock_change_resource(struct ldlm_lock *, __u64 new_resid[3]); - -/* ldlm_request.c */ -int ldlm_completion_ast(struct ldlm_lock *lock, int flags); -int ldlm_cli_enqueue(struct lustre_handle *conn, - struct ptlrpc_request *req, - struct ldlm_namespace *ns, - struct lustre_handle *parent_lock_handle, - __u64 *res_id, - __u32 type, - void *cookie, int cookielen, - ldlm_mode_t mode, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback callback, - void *data, - __u32 data_len, - struct lustre_handle *lockh); -int ldlm_match_or_enqueue(struct lustre_handle *connh, - struct ptlrpc_request *req, - struct ldlm_namespace *ns, - struct lustre_handle *parent_lock_handle, - __u64 *res_id, - __u32 type, - void *cookie, int cookielen, - ldlm_mode_t mode, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback callback, - void *data, - __u32 data_len, - struct lustre_handle *lockh); -int ldlm_server_ast(struct lustre_handle *lockh, struct ldlm_lock_desc *new, - void *data, __u32 data_len); -int ldlm_cli_convert(struct lustre_handle *, int new_mode, int *flags); -int ldlm_cli_cancel(struct lustre_handle *lockh); -int ldlm_cli_cancel_unused(struct ldlm_namespace *, __u64 *, int flags); -int ldlm_cancel_lru(struct ldlm_namespace *ns); - -/* mds/handler.c */ -/* This has to be here because recurisve inclusion sucks. */ -int mds_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, - void *data, __u32 data_len, int flag); - -#endif /* __KERNEL__ */ - -/* ioctls for trying requests */ -#define IOC_LDLM_TYPE 'f' -#define IOC_LDLM_MIN_NR 40 - -#define IOC_LDLM_TEST _IOWR('f', 40, long) -#define IOC_LDLM_DUMP _IOWR('f', 41, long) -#define IOC_LDLM_REGRESS_START _IOWR('f', 42, long) -#define IOC_LDLM_REGRESS_STOP _IOWR('f', 43, long) -#define IOC_LDLM_MAX_NR 43 - -#endif diff --git a/lustre/include/linux/lustre_export.h b/lustre/include/linux/lustre_export.h deleted file mode 100644 index dc2c0b5..0000000 --- a/lustre/include/linux/lustre_export.h +++ /dev/null @@ -1,45 +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 code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ - -#ifndef __EXPORT_H -#define __EXPORT_H - -#ifdef __KERNEL__ - -#include -#include -#include - -struct lov_export_data { - struct list_head led_open_head; -}; - -struct obd_export { - __u64 exp_cookie; - struct list_head exp_obd_chain; - struct list_head exp_conn_chain; - struct obd_device *exp_obd; - struct ptlrpc_connection *exp_connection; - struct ldlm_export_data exp_ldlm_data; - union { - struct mds_export_data eu_mds_data; - struct filter_export_data eu_filter_data; - struct lov_export_data eu_lov_data; - } u; -}; - -#define exp_mds_data u.eu_mds_data -#define exp_lov_data u.eu_lov_data -#define exp_filter_data u.eu_filter_data - -extern struct obd_export *class_conn2export(struct lustre_handle *conn); -extern struct obd_device *class_conn2obd(struct lustre_handle *conn); -#endif /* __KERNEL__ */ - -#endif /* __EXPORT_H */ diff --git a/lustre/include/linux/lustre_ha.h b/lustre/include/linux/lustre_ha.h deleted file mode 100644 index 1e6596b..0000000 --- a/lustre/include/linux/lustre_ha.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - */ - -#ifndef _LUSTRE_HA_H -#define _LUSTRE_HA_H - -#define LUSTRE_HA_NAME "ptlrpc" - -struct recovd_data; -struct recovd_obd; -struct obd_import; -struct ptlrpc_connection; - -/* rd_phase/rd_next_phase values */ -#define RD_IDLE 0 -#define RD_TROUBLED 1 -#define RD_PREPARING 2 -#define RD_PREPARED 3 -#define RD_RECOVERING 4 -#define RD_RECOVERED 5 -#define RD_FAILED 6 - -/* recovd_state values */ -#define RECOVD_READY 1 -#define RECOVD_STOPPING 2 /* how cleanup tells recovd to quit */ -#define RECOVD_STOPPED 4 /* after recovd has stopped */ - -#define PTLRPC_RECOVD_PHASE_PREPARE 1 -#define PTLRPC_RECOVD_PHASE_RECOVER 2 -#define PTLRPC_RECOVD_PHASE_FAILURE 3 - -typedef int (*ptlrpc_recovery_cb_t)(struct recovd_data *, int); - -struct recovd_data { - /* you must hold recovd->recovd_lock when touching rd_managed_chain */ - struct list_head rd_managed_chain; - ptlrpc_recovery_cb_t rd_recover; - struct recovd_obd *rd_recovd; - __u32 rd_phase; - __u32 rd_next_phase; - __u32 rd_flags; -}; - -void recovd_conn_fail(struct ptlrpc_connection *conn); -void recovd_conn_manage(struct ptlrpc_connection *conn, struct recovd_obd *mgr, - ptlrpc_recovery_cb_t recover); -void recovd_conn_unmanage(struct ptlrpc_connection *conn); -void recovd_conn_fixed(struct ptlrpc_connection *conn); -int recovd_setup(struct recovd_obd *mgr); -int recovd_cleanup(struct recovd_obd *mgr); - -extern struct recovd_obd *ptlrpc_recovd; - -int ptlrpc_run_recovery_upcall(struct ptlrpc_connection *conn); -int ptlrpc_reconnect_import(struct obd_import *imp, int rq_opc); -int ptlrpc_replay(struct obd_import *imp, int send_last_flag); -int ptlrpc_resend(struct obd_import *imp); -void ptlrpc_free_committed(struct obd_import *imp); -void ptlrpc_wake_delayed(struct obd_import *imp); -#endif diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h deleted file mode 100644 index ea75f08..0000000 --- a/lustre/include/linux/lustre_idl.h +++ /dev/null @@ -1,547 +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. - * - * (Un)packing of OST requests - */ - -#ifndef _LUSTRE_IDL_H_ -#define _LUSTRE_IDL_H_ - -#ifdef __KERNEL__ -# include -# include -# include -# include -#else -# define __KERNEL__ -# include -# include -# undef __KERNEL__ -# include -#endif -/* - * this file contains all data structures used in Lustre interfaces: - * - obdo and obd_request records - * - mds_request records - * - ldlm data - * - ioctl's - */ - -/* - * GENERAL STUFF - */ -typedef __u8 obd_uuid_t[37]; - -/* FOO_REQUEST_PORTAL is for incoming requests on the FOO - * FOO_REPLY_PORTAL is for incoming replies on the FOO - * FOO_BULK_PORTAL is for incoming bulk on the FOO - */ - -#define CONNMGR_REQUEST_PORTAL 1 -#define CONNMGR_REPLY_PORTAL 2 -#define OSC_REQUEST_PORTAL 3 -#define OSC_REPLY_PORTAL 4 -#define OSC_BULK_PORTAL 5 -#define OST_REQUEST_PORTAL 6 -#define OST_REPLY_PORTAL 7 -#define OST_BULK_PORTAL 8 -#define MDC_REQUEST_PORTAL 9 -#define MDC_REPLY_PORTAL 10 -#define MDC_BULK_PORTAL 11 -#define MDS_REQUEST_PORTAL 12 -#define MDS_REPLY_PORTAL 13 -#define MDS_BULK_PORTAL 14 -#define LDLM_CB_REQUEST_PORTAL 15 -#define LDLM_CB_REPLY_PORTAL 16 -#define LDLM_CANCEL_REQUEST_PORTAL 17 -#define LDLM_CANCEL_REPLY_PORTAL 18 - -#define SVC_KILLED 1 -#define SVC_EVENT 2 -#define SVC_SIGNAL 4 -#define SVC_RUNNING 8 -#define SVC_STOPPING 16 -#define SVC_STOPPED 32 - -#define LUSTRE_CONN_NEW 1 -#define LUSTRE_CONN_CON 2 -#define LUSTRE_CONN_RECOVD 3 -#define LUSTRE_CONN_FULL 4 - -/* packet types */ -#define PTL_RPC_MSG_REQUEST 4711 -#define PTL_RPC_MSG_ERR 4712 -#define PTL_RPC_MSG_REPLY 4713 - -#define PTLRPC_MSG_MAGIC (cpu_to_le32(0x0BD00BD0)) -#define PTLRPC_MSG_VERSION (cpu_to_le32(0x00040001)) - -struct lustre_handle { - __u64 addr; - __u64 cookie; -}; -#define DEAD_HANDLE_MAGIC 0xdeadbeefcafebabe - -static inline void ptlrpc_invalidate_handle(struct lustre_handle *hdl) -{ - hdl->addr = hdl->cookie = 0; /* XXX invalid enough? */ -} - -/* we depend on this structure to be 8-byte aligned */ -struct lustre_msg { - __u64 addr; - __u64 cookie; /* security token */ - __u32 magic; - __u32 type; - __u32 version; - __u32 opc; - __u64 last_xid; - __u64 last_committed; - __u64 transno; - __u32 status; - __u32 bufcount; - __u32 flags; - __u32 buflens[0]; -}; - -/* Flags that are operation-specific go in the top 16 bits. */ -#define MSG_OP_FLAG_MASK 0xffff0000 -#define MSG_OP_FLAG_SHIFT 16 - -/* Flags that apply to all requests are in the bottom 16 bits */ -#define MSG_GEN_FLAG_MASK 0x0000ffff -#define MSG_LAST_REPLAY 1 - -static inline int lustre_msg_get_flags(struct lustre_msg *msg) -{ - return (msg->flags & MSG_GEN_FLAG_MASK); -} - -static inline void lustre_msg_set_flags(struct lustre_msg *msg, int flags) -{ - msg->flags &= ~MSG_GEN_FLAG_MASK; - msg->flags |= MSG_GEN_FLAG_MASK & flags; -} - -static inline int lustre_msg_get_op_flags(struct lustre_msg *msg) -{ - return (msg->flags >> MSG_OP_FLAG_SHIFT); -} - -static inline void lustre_msg_set_op_flags(struct lustre_msg *msg, int flags) -{ - msg->flags &= ~MSG_OP_FLAG_MASK; - msg->flags |= ((flags & MSG_GEN_FLAG_MASK) << MSG_OP_FLAG_SHIFT); -} - -#define CONNMGR_REPLY 0 -#define CONNMGR_CONNECT 1 - -/* - * OST requests: OBDO & OBD request records - */ - -/* opcodes */ -#define OST_REPLY 0 /* reply ? */ -#define OST_GETATTR 1 -#define OST_SETATTR 2 -#define OST_READ 3 -#define OST_WRITE 4 -#define OST_CREATE 5 -#define OST_DESTROY 6 -#define OST_GET_INFO 7 -#define OST_CONNECT 8 -#define OST_DISCONNECT 9 -#define OST_PUNCH 10 -#define OST_OPEN 11 -#define OST_CLOSE 12 -#define OST_STATFS 13 - - -typedef uint64_t obd_id; -typedef uint64_t obd_gr; -typedef uint64_t obd_time; -typedef uint64_t obd_size; -typedef uint64_t obd_off; -typedef uint64_t obd_blocks; -typedef uint32_t obd_blksize; -typedef uint32_t obd_mode; -typedef uint32_t obd_uid; -typedef uint32_t obd_gid; -typedef uint64_t obd_rdev; -typedef uint32_t obd_flag; -typedef uint32_t obd_count; - -#define OBD_FL_INLINEDATA (0x00000001) -#define OBD_FL_OBDMDEXISTS (0x00000002) - -#define OBD_INLINESZ 60 - -/* Note: 64-bit types are 64-bit aligned in structure */ -struct obdo { - obd_id o_id; - obd_gr o_gr; - obd_time o_atime; - obd_time o_mtime; - obd_time o_ctime; - obd_size o_size; - obd_blocks o_blocks; - obd_rdev o_rdev; - obd_blksize o_blksize; - obd_mode o_mode; - obd_uid o_uid; - obd_gid o_gid; - obd_flag o_flags; - obd_count o_nlink; - obd_count o_generation; - obd_flag o_valid; /* hot fields in this obdo */ - obd_flag o_obdflags; - __u32 o_easize; - char o_inline[OBD_INLINESZ]; -}; - -struct lov_object_id { /* per-child structure */ - __u64 l_object_id; -}; - -#define LOV_MAGIC 0x0BD00BD0 - -struct lov_mds_md { - __u32 lmm_magic; - __u32 lmm_unused; /* was packed size of extended attribute */ - __u64 lmm_object_id; /* lov object id */ - __u32 lmm_stripe_offset; /* starting stripe offset in lmd_objects */ - __u32 lmm_stripe_count; /* number of stipes in use for this object */ - __u64 lmm_stripe_size; /* size of the stripe */ - __u32 lmm_ost_count; /* how many OST idx are in this LOV md */ - __u32 lmm_stripe_pattern; /* per-lov object stripe pattern */ - struct lov_object_id lmm_objects[0]; -}; - -#define OBD_MD_FLALL (0xffffffff) -#define OBD_MD_FLID (0x00000001) /* object ID */ -#define OBD_MD_FLATIME (0x00000002) /* access time */ -#define OBD_MD_FLMTIME (0x00000004) /* data modification time */ -#define OBD_MD_FLCTIME (0x00000008) /* change time */ -#define OBD_MD_FLSIZE (0x00000010) /* size */ -#define OBD_MD_FLBLOCKS (0x00000020) /* allocated blocks count */ -#define OBD_MD_FLBLKSZ (0x00000040) /* block size */ -#define OBD_MD_FLMODE (0x00000080) /* access bits (mode & ~S_IFMT) */ -#define OBD_MD_FLTYPE (0x00000100) /* object type (mode & S_IFMT) */ -#define OBD_MD_FLUID (0x00000200) /* user ID */ -#define OBD_MD_FLGID (0x00000400) /* group ID */ -#define OBD_MD_FLFLAGS (0x00000800) /* flags word */ -#define OBD_MD_FLOBDFLG (0x00001000) -#define OBD_MD_FLNLINK (0x00002000) /* link count */ -#define OBD_MD_FLGENER (0x00004000) /* generation number */ -#define OBD_MD_FLINLINE (0x00008000) /* inline data */ -#define OBD_MD_FLRDEV (0x00010000) /* device number */ -#define OBD_MD_FLEASIZE (0x00020000) /* extended attribute data */ -#define OBD_MD_LINKNAME (0x00040000) /* symbolic link target */ -#define OBD_MD_FLHANDLE (0x00080000) /* file handle */ -#define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS | OBD_MD_LINKNAME|\ - OBD_MD_FLEASIZE | OBD_MD_FLHANDLE)) - -struct obd_statfs { - __u64 os_type; - __u64 os_blocks; - __u64 os_bfree; - __u64 os_bavail; - __u64 os_files; - __u64 os_ffree; - __u8 os_fsid[40]; - __u32 os_bsize; - __u32 os_namelen; - __u32 os_spare[12]; -}; - -/* ost_body.data values for OST_BRW */ - -#define OBD_BRW_READ 0x1 -#define OBD_BRW_WRITE 0x2 -#define OBD_BRW_RWMASK (OBD_BRW_READ | OBD_BRW_WRITE) -#define OBD_BRW_CREATE 0x4 - -#define OBD_OBJECT_EOF 0xffffffffffffffffULL - -struct obd_ioobj { - obd_id ioo_id; - obd_gr ioo_gr; - /* struct lustre_handle ioo_handle; XXX in the future */ - __u32 ioo_type; - __u32 ioo_bufcnt; -}; - -struct niobuf_remote { - __u64 offset; - __u32 len; - __u32 xid; - __u32 flags; -}; - -#define CONNMGR_REPLY 0 -#define CONNMGR_CONNECT 1 - -struct connmgr_body { - __u64 conn; - __u64 conn_token; - __u32 generation; - obd_uuid_t conn_uuid; -}; - -/* request structure for OST's */ - -#define OST_REQ_HAS_OA1 0x1 - -struct ost_body { - struct obdo oa; -}; - -/* - * MDS REQ RECORDS - */ - -/* opcodes */ -#define MDS_GETATTR 1 -#define MDS_OPEN 2 -#define MDS_CLOSE 3 -#define MDS_REINT 4 -#define MDS_READPAGE 6 -#define MDS_CONNECT 7 -#define MDS_DISCONNECT 8 -#define MDS_GETSTATUS 9 -#define MDS_STATFS 10 -#define MDS_GETLOVINFO 11 - -#define REINT_SETATTR 1 -#define REINT_CREATE 2 -#define REINT_LINK 3 -#define REINT_UNLINK 4 -#define REINT_RENAME 5 -#define REINT_MAX 5 - -#define REINT_OPCODE_MASK 0xff /* opcodes must fit into this mask */ -#define REINT_REPLAYING 0x1000 /* masked into the opcode to indicate replay */ - -struct ll_fid { - __u64 id; - __u32 generation; - __u32 f_type; -}; - - -#define MDS_STATUS_CONN 1 -#define MDS_STATUS_LOV 2 - -struct mds_status_req { - __u32 flags; - __u32 repbuf; -}; - -struct mds_fileh_body { - struct ll_fid f_fid; - struct lustre_handle f_handle; -}; - -struct mds_conn_status { - struct ll_fid rootfid; - __u64 xid; - __u64 last_committed; - __u64 last_rcvd; - /* XXX preallocated quota & obj fields here */ -}; - -struct mds_body { - struct ll_fid fid1; - struct ll_fid fid2; - struct lustre_handle handle; - __u64 size; - __u32 ino; /* make this a __u64 */ - __u32 valid; - __u32 fsuid; - __u32 fsgid; - __u32 capability; - __u32 mode; - __u32 uid; - __u32 gid; - __u32 mtime; - __u32 ctime; - __u32 atime; - __u32 flags; - __u32 rdev; - __u32 nlink; - __u32 generation; -}; - -/* This is probably redundant with OBD_MD_FLEASIZE, but we need an audit */ -#define MDS_OPEN_HAS_EA 1 /* this open has an EA, for a delayed create*/ - -/* MDS update records */ - - -//struct mds_update_record_hdr { -// __u32 ur_opcode; -//}; - -struct mds_rec_setattr { - __u32 sa_opcode; - __u32 sa_fsuid; - __u32 sa_fsgid; - __u32 sa_cap; - __u32 sa_reserved; - __u32 sa_valid; - struct ll_fid sa_fid; - __u32 sa_mode; - __u32 sa_uid; - __u32 sa_gid; - __u32 sa_attr_flags; - __u64 sa_size; - __u64 sa_atime; - __u64 sa_mtime; - __u64 sa_ctime; -}; - -struct mds_rec_create { - __u32 cr_opcode; - __u32 cr_fsuid; - __u32 cr_fsgid; - __u32 cr_cap; - __u32 cr_reserved; - __u32 cr_mode; - struct ll_fid cr_fid; - struct ll_fid cr_replayfid; - __u32 cr_uid; - __u32 cr_gid; - __u64 cr_time; - __u64 cr_rdev; -}; - -struct mds_rec_link { - __u32 lk_opcode; - __u32 lk_fsuid; - __u32 lk_fsgid; - __u32 lk_cap; - struct ll_fid lk_fid1; - struct ll_fid lk_fid2; -}; - -struct mds_rec_unlink { - __u32 ul_opcode; - __u32 ul_fsuid; - __u32 ul_fsgid; - __u32 ul_cap; - __u32 ul_reserved; - __u32 ul_mode; - struct ll_fid ul_fid1; - struct ll_fid ul_fid2; -}; - -struct mds_rec_rename { - __u32 rn_opcode; - __u32 rn_fsuid; - __u32 rn_fsgid; - __u32 rn_cap; - struct ll_fid rn_fid1; - struct ll_fid rn_fid2; -}; - - -/* - * LOV data structures - */ - -#define LOV_RAID0 0 -#define LOV_RAIDRR 1 - -struct lov_desc { - __u32 ld_tgt_count; /* how many OBD's */ - __u32 ld_active_tgt_count; /* how many active */ - __u32 ld_default_stripe_count; /* how many objects are used */ - __u64 ld_default_stripe_size; /* in bytes */ - __u64 ld_default_stripe_offset; /* in bytes */ - __u32 ld_pattern; /* RAID 0,1 etc */ - obd_uuid_t ld_uuid; -}; - -/* - * LDLM requests: - */ -/* opcodes -- MUST be distinct from OST/MDS opcodes */ -#define LDLM_ENQUEUE 101 -#define LDLM_CONVERT 102 -#define LDLM_CANCEL 103 -#define LDLM_BL_CALLBACK 104 -#define LDLM_CP_CALLBACK 105 - -#define RES_NAME_SIZE 3 -#define RES_VERSION_SIZE 4 - -/* lock types */ -typedef enum { - LCK_EX = 1, - LCK_PW, - LCK_PR, - LCK_CW, - LCK_CR, - LCK_NL -} ldlm_mode_t; - -struct ldlm_extent { - __u64 start; - __u64 end; -}; - -struct ldlm_intent { - __u64 opc; -}; - -/* Note this unaligned structure; as long as it's only used in ldlm_request - * below, we're probably fine. */ -struct ldlm_resource_desc { - __u32 lr_type; - __u64 lr_name[RES_NAME_SIZE]; - __u32 lr_version[RES_VERSION_SIZE]; -}; - -struct ldlm_lock_desc { - struct ldlm_resource_desc l_resource; - ldlm_mode_t l_req_mode; - ldlm_mode_t l_granted_mode; - struct ldlm_extent l_extent; - __u32 l_version[RES_VERSION_SIZE]; -}; - -struct ldlm_request { - __u32 lock_flags; - struct ldlm_lock_desc lock_desc; - struct lustre_handle lock_handle1; - struct lustre_handle lock_handle2; -}; - -struct ldlm_reply { - __u32 lock_flags; - __u32 lock_mode; - __u64 lock_resource_name[RES_NAME_SIZE]; - struct lustre_handle lock_handle; - struct ldlm_extent lock_extent; /* XXX make this policy 1 &2 */ - __u64 lock_policy_res1; - __u64 lock_policy_res2; -}; -#endif diff --git a/lustre/include/linux/lustre_import.h b/lustre/include/linux/lustre_import.h deleted file mode 100644 index 0f0d67d..0000000 --- a/lustre/include/linux/lustre_import.h +++ /dev/null @@ -1,52 +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 code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ - -#ifndef __IMPORT_H -#define __IMPORT_H - -#ifdef __KERNEL__ - -#define IMP_INVALID 1 -#define IMP_REPLAYABLE 2 - -typedef int (*import_recover_t)(struct obd_import *imp, int phase); - -#include -struct obd_import { - import_recover_t imp_recover; - struct ptlrpc_connection *imp_connection; - struct ptlrpc_client *imp_client; - struct lustre_handle imp_handle; - struct list_head imp_chain; - - /* Lists of requests that are retained for replay, waiting for a reply, - * or waiting for recovery to complete, respectively. - */ - struct list_head imp_replay_list; - struct list_head imp_sending_list; - struct list_head imp_delayed_list; - - struct obd_device *imp_obd; - int imp_flags; - int imp_level; - __u64 imp_last_xid; - __u64 imp_max_transno; - __u64 imp_peer_last_xid; - __u64 imp_peer_committed_transno; - - /* Protects flags, level, *_xid, *_list */ - spinlock_t imp_lock; -}; - -extern struct obd_import *class_conn2cliimp(struct lustre_handle *); -extern struct obd_import *class_conn2ldlmimp(struct lustre_handle *); - -#endif /* __KERNEL__ */ - -#endif /* __IMPORT_H */ diff --git a/lustre/include/linux/lustre_lib.h b/lustre/include/linux/lustre_lib.h deleted file mode 100644 index da5cc81..0000000 --- a/lustre/include/linux/lustre_lib.h +++ /dev/null @@ -1,587 +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. - * - * Basic Lustre library routines. - * - */ - -#ifndef _LUSTRE_LIB_H -#define _LUSTRE_LIB_H - -#ifndef __KERNEL__ -# include -#else -# include -#endif -#include /* XXX just for LASSERT! */ -#include -#include - -#ifdef __KERNEL__ -/* l_net.c */ -struct ptlrpc_request; -struct obd_device; -struct recovd_data; -struct recovd_obd; -#include - -int target_handle_connect(struct ptlrpc_request *req); -int target_handle_disconnect(struct ptlrpc_request *req); -int client_obd_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover); -int client_obd_disconnect(struct lustre_handle *conn); -int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf); -int client_obd_cleanup(struct obd_device * obddev); -struct client_obd *client_conn2cli(struct lustre_handle *conn); - -int target_revoke_connection(struct recovd_data *rd, int phase); - -/* l_lock.c */ -struct lustre_lock { - int l_depth; - struct task_struct *l_owner; - struct semaphore l_sem; - spinlock_t l_spin; -}; - -void l_lock_init(struct lustre_lock *); -void l_lock(struct lustre_lock *); -void l_unlock(struct lustre_lock *); -int l_has_lock(struct lustre_lock *); - -#define CB_PHASE_START 12 -#define CB_PHASE_FINISH 13 - -/* This list head doesn't need to be locked, because it's only manipulated by - * one thread at a time. */ -struct obd_brw_set { - struct list_head brw_desc_head; /* list of ptlrpc_bulk_desc */ - wait_queue_head_t brw_waitq; - atomic_t brw_refcount; - int brw_flags; - - int (*brw_callback)(struct obd_brw_set *, int phase); -}; - -/* simple.c */ -struct obd_run_ctxt; -struct obd_ucred; -void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx, - struct obd_ucred *cred); -void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx, - struct obd_ucred *cred); -struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode); -struct dentry *simple_mknod(struct dentry *dir, char *name, int mode); -int lustre_fread(struct file *file, char *str, int len, loff_t *off); -int lustre_fwrite(struct file *file, const char *str, int len, loff_t *off); -int lustre_fsync(struct file *file); - -static inline void l_dput(struct dentry *de) -{ - if (!de || IS_ERR(de)) - return; - shrink_dcache_parent(de); - LASSERT(atomic_read(&de->d_count) > 0); - dput(de); -} - -static inline void ll_sleep(int t) -{ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(t * HZ); - set_current_state(TASK_RUNNING); -} -#endif - -/* FIXME: This needs to validate pointers and cookies */ -static inline void *lustre_handle2object(struct lustre_handle *handle) -{ - if (handle) - return (void *)(unsigned long)(handle->addr); - return NULL; -} - -static inline void ldlm_object2handle(void *object, struct lustre_handle *handle) -{ - handle->addr = (__u64)(unsigned long)object; -} - -struct obd_statfs; -struct statfs; -void statfs_pack(struct obd_statfs *osfs, struct statfs *sfs); -void statfs_unpack(struct statfs *sfs, struct obd_statfs *osfs); -void obd_statfs_pack(struct obd_statfs *tgt, struct obd_statfs *src); -static inline void -obd_statfs_unpack(struct obd_statfs *tgt, struct obd_statfs *src) -{ - obd_statfs_pack(tgt, src); -} - -#include - -/* - * OBD IOCTLS - */ -#define OBD_IOCTL_VERSION 0x00010001 - -struct obd_ioctl_data { - uint32_t ioc_len; - uint32_t ioc_version; - - uint64_t ioc_addr; - uint64_t ioc_cookie; - uint32_t ioc_conn1; - uint32_t ioc_conn2; - - struct obdo ioc_obdo1; - struct obdo ioc_obdo2; - - obd_size ioc_count; - obd_off ioc_offset; - uint32_t ioc_dev; - uint32_t ____padding; - - /* buffers the kernel will treat as user pointers */ - uint32_t ioc_plen1; - char *ioc_pbuf1; - uint32_t ioc_plen2; - char *ioc_pbuf2; - - /* two inline buffers */ - uint32_t ioc_inllen1; - char *ioc_inlbuf1; - uint32_t ioc_inllen2; - char *ioc_inlbuf2; - uint32_t ioc_inllen3; - char *ioc_inlbuf3; - - char ioc_bulk[0]; -}; - -struct obd_ioctl_hdr { - uint32_t ioc_len; - uint32_t ioc_version; -}; - -static inline int obd_ioctl_packlen(struct obd_ioctl_data *data) -{ - int len = size_round(sizeof(struct obd_ioctl_data)); - len += size_round(data->ioc_inllen1); - len += size_round(data->ioc_inllen2); - len += size_round(data->ioc_inllen3); - return len; -} - - -static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data) -{ - if (data->ioc_len > (1<<30)) { - printk("OBD ioctl: ioc_len larger than 1<<30\n"); - return 1; - } - if (data->ioc_inllen1 > (1<<30)) { - printk("OBD ioctl: ioc_inllen1 larger than 1<<30\n"); - return 1; - } - if (data->ioc_inllen2 > (1<<30)) { - printk("OBD ioctl: ioc_inllen2 larger than 1<<30\n"); - return 1; - } - - if (data->ioc_inllen3 > (1<<30)) { - printk("OBD ioctl: ioc_inllen3 larger than 1<<30\n"); - return 1; - } - if (data->ioc_inlbuf1 && !data->ioc_inllen1) { - printk("OBD ioctl: inlbuf1 pointer but 0 length\n"); - return 1; - } - if (data->ioc_inlbuf2 && !data->ioc_inllen2) { - printk("OBD ioctl: inlbuf2 pointer but 0 length\n"); - return 1; - } - if (data->ioc_inlbuf3 && !data->ioc_inllen3) { - printk("OBD ioctl: inlbuf3 pointer but 0 length\n"); - return 1; - } - if (data->ioc_pbuf1 && !data->ioc_plen1) { - printk("OBD ioctl: pbuf1 pointer but 0 length\n"); - return 1; - } - if (data->ioc_pbuf2 && !data->ioc_plen2) { - printk("OBD ioctl: pbuf2 pointer but 0 length\n"); - return 1; - } - /* - if (data->ioc_inllen1 && !data->ioc_inlbuf1) { - printk("OBD ioctl: inllen1 set but NULL pointer\n"); - return 1; - } - if (data->ioc_inllen2 && !data->ioc_inlbuf2) { - printk("OBD ioctl: inllen2 set but NULL pointer\n"); - return 1; - } - if (data->ioc_inllen3 && !data->ioc_inlbuf3) { - printk("OBD ioctl: inllen3 set but NULL pointer\n"); - return 1; - } - */ - if (data->ioc_plen1 && !data->ioc_pbuf1) { - printk("OBD ioctl: plen1 set but NULL pointer\n"); - return 1; - } - if (data->ioc_plen2 && !data->ioc_pbuf2) { - printk("OBD ioctl: plen2 set but NULL pointer\n"); - return 1; - } - if (obd_ioctl_packlen(data) != data->ioc_len ) { - printk("OBD ioctl: packlen exceeds ioc_len\n"); - return 1; - } -#if 0 - if (data->ioc_inllen1 && - data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') { - printk("OBD ioctl: inlbuf1 not 0 terminated\n"); - return 1; - } - if (data->ioc_inllen2 && - data->ioc_bulk[size_round(data->ioc_inllen1) + data->ioc_inllen2 - 1] != '\0') { - printk("OBD ioctl: inlbuf2 not 0 terminated\n"); - return 1; - } - if (data->ioc_inllen3 && - data->ioc_bulk[size_round(data->ioc_inllen1) + size_round(data->ioc_inllen2) - + data->ioc_inllen3 - 1] != '\0') { - printk("OBD ioctl: inlbuf3 not 0 terminated\n"); - return 1; - } -#endif - return 0; -} - -#ifndef __KERNEL__ -static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, - int max) -{ - char *ptr; - struct obd_ioctl_data *overlay; - data->ioc_len = obd_ioctl_packlen(data); - data->ioc_version = OBD_IOCTL_VERSION; - - if (*pbuf && data->ioc_len > max) - return 1; - if (*pbuf == NULL) { - *pbuf = malloc(data->ioc_len); - } - if (!*pbuf) - return 1; - overlay = (struct obd_ioctl_data *)*pbuf; - memcpy(*pbuf, data, sizeof(*data)); - - ptr = overlay->ioc_bulk; - if (data->ioc_inlbuf1) - LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr); - if (data->ioc_inlbuf2) - LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr); - if (data->ioc_inlbuf3) - LOGL(data->ioc_inlbuf3, data->ioc_inllen3, ptr); - if (obd_ioctl_is_invalid(overlay)) - return 1; - - return 0; -} - -static inline int obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, - int max) -{ - char *ptr; - struct obd_ioctl_data *overlay; - - if (!pbuf) - return 1; - overlay = (struct obd_ioctl_data *)pbuf; - - /* Preserve the caller's buffer pointers */ - overlay->ioc_inlbuf1 = data->ioc_inlbuf1; - overlay->ioc_inlbuf2 = data->ioc_inlbuf2; - overlay->ioc_inlbuf3 = data->ioc_inlbuf3; - - memcpy(data, pbuf, sizeof(*data)); - - ptr = overlay->ioc_bulk; - if (data->ioc_inlbuf1) - LOGU(data->ioc_inlbuf1, data->ioc_inllen1, ptr); - if (data->ioc_inlbuf2) - LOGU(data->ioc_inlbuf2, data->ioc_inllen2, ptr); - if (data->ioc_inlbuf3) - LOGU(data->ioc_inlbuf3, data->ioc_inllen3, ptr); - - return 0; -} -#else - -#include - -/* buffer MUST be at least the size of obd_ioctl_hdr */ -static inline int obd_ioctl_getdata(char **buf, int *len, void *arg) -{ - struct obd_ioctl_hdr hdr; - struct obd_ioctl_data *data; - int err; - ENTRY; - - err = copy_from_user(&hdr, (void *)arg, sizeof(hdr)); - if ( err ) { - EXIT; - return err; - } - - if (hdr.ioc_version != OBD_IOCTL_VERSION) { - printk("OBD: version mismatch kernel vs application\n"); - return -EINVAL; - } - - if (hdr.ioc_len > 8192) { - printk("OBD: user buffer exceeds 8192 max buffer\n"); - return -EINVAL; - } - - if (hdr.ioc_len < sizeof(struct obd_ioctl_data)) { - printk("OBD: user buffer too small for ioctl\n"); - return -EINVAL; - } - - OBD_ALLOC(*buf, hdr.ioc_len); - if (!*buf) { - CERROR("Cannot allocate control buffer of len %d\n", - hdr.ioc_len); - RETURN(-EINVAL); - } - *len = hdr.ioc_len; - data = (struct obd_ioctl_data *)*buf; - - err = copy_from_user(*buf, (void *)arg, hdr.ioc_len); - if ( err ) { - EXIT; - return err; - } - - if (obd_ioctl_is_invalid(data)) { - printk("OBD: ioctl not correctly formatted\n"); - return -EINVAL; - } - - if (data->ioc_inllen1) { - data->ioc_inlbuf1 = &data->ioc_bulk[0]; - } - - if (data->ioc_inllen2) { - data->ioc_inlbuf2 = &data->ioc_bulk[0] + size_round(data->ioc_inllen1); - } - - if (data->ioc_inllen3) { - data->ioc_inlbuf3 = &data->ioc_bulk[0] + size_round(data->ioc_inllen1) + - size_round(data->ioc_inllen2); - } - - EXIT; - return 0; -} -#endif - -#define OBD_IOC_CREATE _IOR ('f', 101, long) -#define OBD_IOC_SETUP _IOW ('f', 102, long) -#define OBD_IOC_CLEANUP _IO ('f', 103 ) -#define OBD_IOC_DESTROY _IOW ('f', 104, long) -#define OBD_IOC_PREALLOCATE _IOWR('f', 105, long) -#define OBD_IOC_DEC_USE_COUNT _IO ('f', 106 ) -#define OBD_IOC_SETATTR _IOW ('f', 107, long) -#define OBD_IOC_GETATTR _IOR ('f', 108, long) -#define OBD_IOC_READ _IOWR('f', 109, long) -#define OBD_IOC_WRITE _IOWR('f', 110, long) -#define OBD_IOC_CONNECT _IOR ('f', 111, long) -#define OBD_IOC_DISCONNECT _IOW ('f', 112, long) -#define OBD_IOC_STATFS _IOWR('f', 113, long) -#define OBD_IOC_SYNC _IOR ('f', 114, long) -#define OBD_IOC_READ2 _IOWR('f', 115, long) -#define OBD_IOC_FORMAT _IOWR('f', 116, long) -#define OBD_IOC_PARTITION _IOWR('f', 117, long) -#define OBD_IOC_ATTACH _IOWR('f', 118, long) -#define OBD_IOC_DETACH _IOWR('f', 119, long) -#define OBD_IOC_COPY _IOWR('f', 120, long) -#define OBD_IOC_MIGR _IOWR('f', 121, long) -#define OBD_IOC_PUNCH _IOWR('f', 122, long) -#define OBD_IOC_DEVICE _IOWR('f', 123, long) -#define OBD_IOC_MODULE_DEBUG _IOWR('f', 124, long) -#define OBD_IOC_BRW_READ _IOWR('f', 125, long) -#define OBD_IOC_BRW_WRITE _IOWR('f', 126, long) -#define OBD_IOC_NAME2DEV _IOWR('f', 127, long) -#define OBD_IOC_NEWDEV _IOWR('f', 128, long) -#define OBD_IOC_LIST _IOWR('f', 129, long) -#define OBD_IOC_UUID2DEV _IOWR('f', 130, long) - -#define OBD_IOC_RECOVD_NEWCONN _IOWR('f', 131, long) -#define OBD_IOC_LOV_SET_CONFIG _IOWR('f', 132, long) -#define OBD_IOC_LOV_GET_CONFIG _IOWR('f', 133, long) -#define OBD_IOC_LOV_CONFIG OBD_IOC_LOV_SET_CONFIG - -#define OBD_IOC_OPEN _IOWR('f', 134, long) -#define OBD_IOC_CLOSE _IOWR('f', 135, long) - -#define OBD_IOC_RECOVD_FAILCONN _IOWR('f', 136, long) - -#define OBD_IOC_DEC_FS_USE_COUNT _IO ('f', 139 ) - -#define OBD_GET_VERSION _IOWR ('f', 144, long) - -/* - * l_wait_event is a flexible sleeping function, permitting simple caller - * configuration of interrupt and timeout sensitivity along with actions to - * be performed in the event of either exception. - * - * Common usage looks like this: - * - * struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout, timeout_handler, - * intr_handler, callback_data); - * rc = l_wait_event(waitq, condition, &lwi); - * - * (LWI_TIMEOUT and LWI_INTR macros are available for timeout- and - * interrupt-only variants, respectively.) - * - * If a timeout is specified, the timeout_handler will be invoked in the event - * that the timeout expires before the process is awakened. (Note that any - * waking of the process will restart the timeout, even if the condition is - * not satisfied and the process immediately returns to sleep. This might be - * considered a bug.) If the timeout_handler returns non-zero, l_wait_event - * will return -ETIMEDOUT and the caller will continue. If the handler returns - * zero instead, the process will go back to sleep until it is awakened by the - * waitq or some similar mechanism, or an interrupt occurs (if the caller has - * asked for interrupts to be detected). The timeout will only fire once, so - * callers should take care that a timeout_handler which returns zero will take - * future steps to awaken the process. N.B. that these steps must include - * making the provided condition become true. - * - * If the interrupt flag (lwi_signals) is non-zero, then the process will be - * interruptible, and will be awakened by any "killable" signal (SIGTERM, - * SIGKILL or SIGINT). If a timeout is also specified, then the process will - * only become interruptible _after_ the timeout has expired, though it can be - * awakened by a signal that was delivered before the timeout and is still - * pending when the timeout expires. If a timeout is not specified, the process - * will be interruptible at all times during l_wait_event. - */ - -struct l_wait_info { - long lwi_timeout; - int (*lwi_on_timeout)(void *); - long lwi_signals; - int (*lwi_on_signal)(void *); /* XXX return is ignored for now */ - void *lwi_cb_data; -}; - -#define LWI_TIMEOUT(time, cb, data) \ -((struct l_wait_info) { \ - lwi_timeout: time, \ - lwi_on_timeout: cb, \ - lwi_cb_data: data \ -}) - -#define LWI_INTR(cb, data) \ -((struct l_wait_info) { \ - lwi_signals: 1, \ - lwi_on_signal: cb, \ - lwi_cb_data: data \ -}) - -#define LWI_TIMEOUT_INTR(time, time_cb, sig_cb, data) \ -((struct l_wait_info) { \ - lwi_timeout: time, \ - lwi_on_timeout: time_cb, \ - lwi_signals: 1, \ - lwi_on_signal: sig_cb, \ - lwi_cb_data: data \ -}) - -/* XXX this should be one mask-check */ -#define l_killable_pending(task) \ -(sigismember(&(task->pending.signal), SIGKILL) || \ - sigismember(&(task->pending.signal), SIGINT) || \ - sigismember(&(task->pending.signal), SIGTERM)) - -#define __l_wait_event(wq, condition, info, ret) \ -do { \ - wait_queue_t __wait; \ - long __state; \ - int __timed_out = 0; \ - init_waitqueue_entry(&__wait, current); \ - \ - add_wait_queue(&wq, &__wait); \ - if (info->lwi_signals && !info->lwi_timeout) \ - __state = TASK_INTERRUPTIBLE; \ - else \ - __state = TASK_UNINTERRUPTIBLE; \ - for (;;) { \ - set_current_state(__state); \ - if (condition) \ - break; \ - if (__state == TASK_INTERRUPTIBLE && l_killable_pending(current)) {\ - if (info->lwi_on_signal) \ - info->lwi_on_signal(info->lwi_cb_data); \ - ret = -EINTR; \ - break; \ - } \ - if (info->lwi_timeout && !__timed_out) { \ - if (schedule_timeout(info->lwi_timeout) == 0) { \ - __timed_out = 1; \ - if (!info->lwi_on_timeout || \ - info->lwi_on_timeout(info->lwi_cb_data)) { \ - ret = -ETIMEDOUT; \ - break; \ - } \ - /* We'll take signals after a timeout. */ \ - if (info->lwi_signals) { \ - __state = TASK_INTERRUPTIBLE; \ - /* Check for a pending interrupt. */ \ - if (info->lwi_signals && l_killable_pending(current)) {\ - if (info->lwi_on_signal) \ - info->lwi_on_signal(info->lwi_cb_data); \ - ret = -EINTR; \ - break; \ - } \ - } \ - } \ - } else { \ - schedule(); \ - } \ - } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ -} while(0) - -#define l_wait_event(wq, condition, info) \ -({ \ - int __ret = 0; \ - struct l_wait_info *__info = (info); \ - if (!(condition)) \ - __l_wait_event(wq, condition, __info, __ret); \ - __ret; \ -}) - -#endif /* _LUSTRE_LIB_H */ diff --git a/lustre/include/linux/lustre_lite.h b/lustre/include/linux/lustre_lite.h deleted file mode 100644 index 4da319d..0000000 --- a/lustre/include/linux/lustre_lite.h +++ /dev/null @@ -1,262 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre lite cluster file system - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copyright (C) 2002 Cluster File Systems, Inc. - */ - - - -#ifndef _LL_H -#define _LL_H - -#ifdef __KERNEL__ - -#include -#include -#include - -#include -#include -#include -#include - -extern kmem_cache_t *ll_file_data_slab; -struct ll_file_data { - struct lustre_handle fd_mdshandle; - struct lustre_handle fd_osthandle; - struct ptlrpc_request *fd_req; - __u32 fd_flags; -}; - -struct lustre_intent_data { - __u64 it_lock_handle[2]; - __u32 it_disposition; - __u32 it_status; - __u32 it_lock_mode; -}; - -struct ll_dentry_data { - struct semaphore lld_it_sem; -}; - -#define ll_d2d(dentry) ((struct ll_dentry_data*) dentry->d_fsdata) - -struct ll_read_inode2_cookie { - struct mds_body *lic_body; - struct lov_mds_md *lic_lmm; -}; - -#define LL_INLINESZ 60 -struct ll_inode_info { - struct lov_stripe_md *lli_smd; - char *lli_symlink_name; - struct semaphore lli_open_sem; - atomic_t lli_open_count; /* see ll_file_release */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) - struct inode lli_vfs_inode; -#endif -}; - - - -#define LL_SUPER_MAGIC 0x0BD00BD0 - -#define LL_COMMITCBD_STOPPING 0x1 -#define LL_COMMITCBD_STOPPED 0x2 -#define LL_COMMITCBD_RUNNING 0x4 - -#define LL_SBI_NOLCK 0x1 - -struct ll_sb_info { - obd_uuid_t ll_sb_uuid; - struct lustre_handle ll_mdc_conn; - struct lustre_handle ll_osc_conn; - struct proc_dir_entry* ll_proc_root; - obd_id ll_rootino; /* number of root inode */ - - int ll_flags; - wait_queue_head_t ll_commitcbd_waitq; - wait_queue_head_t ll_commitcbd_ctl_waitq; - int ll_commitcbd_flags; - struct task_struct *ll_commitcbd_thread; - time_t ll_commitcbd_waketime; - time_t ll_commitcbd_timeout; - spinlock_t ll_commitcbd_lock; - struct list_head ll_conn_chain; /* per-conn chain of SBs */ - - struct list_head ll_orphan_dentry_list; /*please don't ask -p*/ -}; - -static inline struct ll_sb_info *ll_s2sbi(struct super_block *sb) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) - return (struct ll_sb_info *)(sb->s_fs_info); -#else - return (struct ll_sb_info *)(sb->u.generic_sbp); -#endif -} - -static inline struct lustre_handle *ll_s2obdconn(struct super_block *sb) -{ - return &(ll_s2sbi(sb))->ll_osc_conn; -} - -static inline struct client_obd *sbi2mdc(struct ll_sb_info *sbi) -{ - struct obd_device *obd = class_conn2obd(&sbi->ll_mdc_conn); - if (obd == NULL) - LBUG(); - return &obd->u.cli; -} - -// FIXME: replace the name of this with LL_SB to conform to kernel stuff -static inline struct ll_sb_info *ll_i2sbi(struct inode *inode) -{ - return ll_s2sbi(inode->i_sb); -} - - -// FIXME: replace the name of this with LL_I to conform to kernel stuff -// static inline struct ll_inode_info *LL_I(struct inode *inode) -static inline struct ll_inode_info *ll_i2info(struct inode *inode) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) - return container_of(inode, struct ll_inode_info, lli_vfs_inode); -#else - return (struct ll_inode_info *)&(inode->u.generic_ip); -#endif -} - -static inline struct lustre_handle *ll_i2obdconn(struct inode *inode) -{ - return ll_s2obdconn(inode->i_sb); -} - -static inline void ll_ino2fid(struct ll_fid *fid, obd_id ino, __u32 generation, - int type) -{ - fid->id = ino; - fid->generation = generation; - fid->f_type = type; -} - -static inline void ll_inode2fid(struct ll_fid *fid, struct inode *inode) -{ - ll_ino2fid(fid, inode->i_ino, inode->i_generation, - inode->i_mode & S_IFMT); -} - -static inline int ll_mds_max_easize(struct super_block *sb) -{ - return sbi2mdc(ll_s2sbi(sb))->cl_max_mds_easize; -} - -/* namei.c */ -int ll_lock(struct inode *dir, struct dentry *dentry, - struct lookup_intent *it, struct lustre_handle *lockh); -int ll_unlock(__u32 mode, struct lustre_handle *lockh); - -typedef int (*intent_finish_cb)(int flag, struct ptlrpc_request *, - struct dentry **, struct lookup_intent *, - int offset, obd_id ino); -int ll_intent_lock(struct inode *parent, struct dentry **, - struct lookup_intent *, intent_finish_cb); - -/* dcache.c */ -void ll_intent_release(struct dentry *, struct lookup_intent *); -int ll_set_dd(struct dentry *de); - -/**** - -I originally implmented these as functions, then realized a macro -would be more helpful for debugging, so the CDEBUG messages show -the current calling function. The orignal functions are in llite/dcache.c - -int ll_save_intent(struct dentry * de, struct lookup_intent * it); -struct lookup_intent * ll_get_intent(struct dentry * de); -****/ - -#define IT_RELEASED_MAGIC 0xDEADCAFE - -#define LL_SAVE_INTENT(de, it) \ -do { \ - LASSERT(ll_d2d(de) != NULL); \ - \ - down(&ll_d2d(de)->lld_it_sem); \ - LASSERT(de->d_it == NULL); \ - de->d_it = it; \ - CDEBUG(D_DENTRY, "D_IT DOWN dentry %p fsdata %p intent: %s sem %d\n", \ - de, ll_d2d(de), ldlm_it2str(de->d_it->it_op), \ - atomic_read(&(ll_d2d(de)->lld_it_sem.count))); \ -} while(0) - -#define LL_GET_INTENT(de, it) \ -do { \ - it = de->d_it; \ - \ - LASSERT(ll_d2d(de) != NULL); \ - LASSERT(it); \ - LASSERT(it->it_op != IT_RELEASED_MAGIC); \ - \ - CDEBUG(D_DENTRY, "D_IT UP dentry %p fsdata %p intent: %s\n", \ - de, ll_d2d(de), ldlm_it2str(de->d_it->it_op)); \ - de->d_it = NULL; \ - it->it_op = IT_RELEASED_MAGIC; \ - up(&ll_d2d(de)->lld_it_sem); \ -} while(0) - - -/* dir.c */ -extern struct file_operations ll_dir_operations; -extern struct inode_operations ll_dir_inode_operations; - -/* file.c */ -extern struct file_operations ll_file_operations; -extern struct inode_operations ll_file_inode_operations; -struct ldlm_lock; -int ll_lock_callback(struct ldlm_lock *, struct ldlm_lock_desc *, void *data, - __u32 data_len, int flag); -int ll_size_lock(struct inode *, struct lov_stripe_md *, obd_off start, - int mode, struct lustre_handle **); -int ll_size_unlock(struct inode *, struct lov_stripe_md *, int mode, - struct lustre_handle *); -int ll_file_size(struct inode *inode, struct lov_stripe_md *md); -int ll_create_objects(struct super_block *sb, obd_id id, uid_t uid, - gid_t gid, struct lov_stripe_md **lsmp); - -/* rw.c */ -struct page *ll_getpage(struct inode *inode, unsigned long offset, - int create, int locked); -void ll_truncate(struct inode *inode); - -/* super.c */ -void ll_update_inode(struct inode *, struct mds_body *); - -/* symlink.c */ -extern struct inode_operations ll_fast_symlink_inode_operations; -extern struct inode_operations ll_symlink_inode_operations; - -/* sysctl.c */ -void ll_sysctl_init(void); -void ll_sysctl_clean(void); - -#endif /* __KERNEL__ */ - -#include - -#define LL_IOC_GETFLAGS _IOR ('f', 151, long) -#define LL_IOC_SETFLAGS _IOW ('f', 152, long) -#define LL_IOC_CLRFLAGS _IOW ('f', 153, long) -#define LL_IOC_LOV_SETSTRIPE _IOW ('f', 154, long) -#define LL_IOC_LOV_GETSTRIPE _IOW ('f', 155, long) - -#define O_LOV_DELAY_CREATE 0100000000 /* hopefully this does not conflict */ - -#define LL_FILE_IGNORE_LOCK 0x00000001 - -#endif diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h deleted file mode 100644 index 0260ac8..0000000 --- a/lustre/include/linux/lustre_mds.h +++ /dev/null @@ -1,250 +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. - * - * MDS data structures. - * See also lustre_idl.h for wire formats of requests. - * - */ - -#ifndef _LUSTRE_MDS_H -#define _LUSTRE_MDS_H - -#ifdef __KERNEL__ - -#include -#include - -struct ldlm_lock_desc; -struct mds_obd; -struct ptlrpc_connection; -struct ptlrpc_client; -struct obd_export; -struct ptlrpc_request; -struct obd_device; - -#define LUSTRE_MDS_NAME "mds" -#define LUSTRE_MDT_NAME "mdt" -#define LUSTRE_MDC_NAME "mdc" - -struct mds_update_record { - __u32 ur_fsuid; - __u32 ur_fsgid; - __u32 ur_cap; - __u32 ur_opcode; - struct ll_fid *ur_fid1; - struct ll_fid *ur_fid2; - int ur_namelen; - char *ur_name; - int ur_tgtlen; - char *ur_tgt; - struct iattr ur_iattr; - __u64 ur_rdev; - __u32 ur_mode; - __u32 ur_uid; - __u32 ur_gid; - __u64 ur_time; -}; - -#define MDS_LR_CLIENT 8192 -#define MDS_LR_SIZE 128 - -#define MDS_CLIENT_SLOTS 17 - -#define MDS_MOUNT_RECOV 2 - -/* Data stored per server at the head of the last_rcvd file. In le32 order. */ -struct mds_server_data { - __u8 msd_uuid[37]; /* server UUID */ - __u8 uuid_padding[3]; /* unused */ - __u64 msd_last_rcvd; /* last completed transaction ID */ - __u64 msd_mount_count; /* MDS incarnation number */ - __u8 padding[512 - 56]; -}; - -/* Data stored per client in the last_rcvd file. In le32 order. */ -struct mds_client_data { - __u8 mcd_uuid[37]; /* client UUID */ - __u8 uuid_padding[3]; /* unused */ - __u64 mcd_last_rcvd; /* last completed transaction ID */ - __u64 mcd_mount_count; /* MDS incarnation number */ - __u64 mcd_last_xid; /* client RPC xid for the last transaction */ - __u8 padding[MDS_LR_SIZE - 64]; -}; - -/* In-memory access to client data from MDS struct */ -struct mds_export_data { - struct list_head med_open_head; - spinlock_t med_open_lock; - struct mds_client_data *med_mcd; - int med_off; -}; - -/* file data for open files on MDS */ -struct mds_file_data { - struct list_head mfd_list; - struct lustre_handle mfd_clienthandle; - __u64 mfd_servercookie; - struct file *mfd_file; -}; - -/* mds/mds_reint.c */ -int mds_reint_rec(struct mds_update_record *r, int offset, - struct ptlrpc_request *req); - -/* lib/mds_updates.c */ -void mds_unpack_body(struct mds_body *b); -void mds_unpack_fid(struct ll_fid *fid); -void mds_pack_fid(struct ll_fid *fid); -void mds_pack_req_body(struct ptlrpc_request *); -void mds_pack_rep_body(struct ptlrpc_request *); -int mds_update_unpack(struct ptlrpc_request *, int offset, - struct mds_update_record *); - -void mds_readdir_pack(struct ptlrpc_request *req, __u64 offset, - obd_id ino, int type); -void mds_getattr_pack(struct ptlrpc_request *req, int offset, - struct inode *inode, const char *name, int namelen); -void mds_setattr_pack(struct ptlrpc_request *, int offset, struct inode *, - struct iattr *, const char *name, int namelen); -void mds_create_pack(struct ptlrpc_request *, int offset, struct inode *dir, - __u32 mode, __u64 rdev, __u32 uid, __u32 gid, __u64 time, - const char *name, int namelen, const void *data, - int datalen); -void mds_unlink_pack(struct ptlrpc_request *, int offset, struct inode *inode, - struct inode *child, __u32 mode, const char *name, - int namelen); -void mds_link_pack(struct ptlrpc_request *, int offset, struct inode *ino, - struct inode *dir, const char *name, int namelen); -void mds_rename_pack(struct ptlrpc_request *, int offset, struct inode *srcdir, - struct inode *tgtdir, const char *name, int namelen, - const char *tgt, int tgtlen); -void mds_pack_inode2fid(struct ll_fid *fid, struct inode *inode); -void mds_pack_inode2body(struct mds_body *body, struct inode *inode); - -/* mds/handler.c */ -struct dentry *mds_name2locked_dentry(struct obd_device *, struct dentry *dir, - struct vfsmount **mnt, char *name, - int namelen, int lock_mode, - struct lustre_handle *lockh, - int dir_lock_mode); -struct dentry *mds_fid2locked_dentry(struct obd_device *obd, struct ll_fid *fid, - struct vfsmount **mnt, int lock_mode, - struct lustre_handle *lockh); -struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, - struct vfsmount **mnt); -int mds_reint(struct ptlrpc_request *req, int offset); -int mds_pack_md(struct mds_obd *mds, struct ptlrpc_request *req, - int offset, struct mds_body *body, struct inode *inode); - -/* mdc/mdc_request.c */ -int mdc_enqueue(struct lustre_handle *conn, int lock_type, - struct lookup_intent *it, int lock_mode, struct inode *dir, - struct dentry *de, struct lustre_handle *lockh, char *tgt, - int tgtlen, void *data, int datalen); -int mdc_cancel_unused(struct lustre_handle *conn, struct inode *, int flags); -int mdc_getlovinfo(struct obd_device *obd, struct lustre_handle *mdc_connh, - struct ptlrpc_request **request); -int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid); -int mdc_getattr(struct lustre_handle *conn, - obd_id ino, int type, unsigned long valid, size_t ea_size, - struct ptlrpc_request **request); -int mdc_setattr(struct lustre_handle *conn, - struct inode *, struct iattr *iattr, struct ptlrpc_request **); -int mdc_open(struct lustre_handle *conn, obd_id ino, int type, int flags, - struct lov_mds_md *lmm, int lmm_size, struct lustre_handle *fh, - struct ptlrpc_request **); -int mdc_close(struct lustre_handle *conn, obd_id ino, int type, - struct lustre_handle *fh, struct ptlrpc_request **req); -int mdc_readpage(struct lustre_handle *conn, obd_id ino, - int type, __u64 offset, char *addr, struct ptlrpc_request **); -int mdc_create(struct lustre_handle *conn, - struct inode *dir, const char *name, int namelen, - const void *data, int datalen, int mode, __u32 uid, __u32 gid, - __u64 time, __u64 rdev, struct ptlrpc_request **); -int mdc_unlink(struct lustre_handle *, struct inode *dir, struct inode *child, - __u32 mode, const char *name, int namelen, - struct ptlrpc_request **); -int mdc_link(struct lustre_handle *conn, - struct dentry *src, struct inode *dir, const char *name, - int namelen, struct ptlrpc_request **); -int mdc_rename(struct lustre_handle *conn, - struct inode *src, struct inode *tgt, const char *old, - int oldlen, const char *new, int newlen, - struct ptlrpc_request **); -int mdc_create_client(obd_uuid_t uuid, struct ptlrpc_client *cl); - -/* Store the generation of a newly-created inode in |req| for replay. */ -void mdc_store_inode_generation(struct ptlrpc_request *req, int reqoff, - int repoff); - -int mds_client_add(struct mds_obd *mds, struct mds_export_data *med, - int cl_off); -int mds_client_free(struct obd_export *exp); - -/* mds/mds_fs.c */ -struct mds_fs_operations { - struct module *fs_owner; - void *(* fs_start)(struct inode *inode, int op); - 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, - struct lov_mds_md *md, int size); - int (* fs_get_md)(struct inode *inode, struct lov_mds_md *md, - int size); - ssize_t (* fs_readpage)(struct file *file, char *buf, size_t count, - loff_t *offset); - void (* fs_delete_inode)(struct inode *inode); - void (* cl_delete_inode)(struct inode *inode); - int (* fs_journal_data)(struct file *file); - int (* fs_set_last_rcvd)(struct mds_obd *mds, void *handle); - int (* fs_statfs)(struct super_block *sb, struct statfs *sfs); -}; - -extern int mds_register_fs_type(struct mds_fs_operations *op, const char *name); -extern void mds_unregister_fs_type(const char *name); -extern int mds_fs_setup(struct obd_device *obddev, struct vfsmount *mnt); -extern void mds_fs_cleanup(struct obd_device *obddev); - -#define MDS_FSOP_UNLINK 1 -#define MDS_FSOP_RMDIR 2 -#define MDS_FSOP_RENAME 3 -#define MDS_FSOP_CREATE 4 -#define MDS_FSOP_MKDIR 5 -#define MDS_FSOP_SYMLINK 6 -#define MDS_FSOP_MKNOD 7 -#define MDS_FSOP_SETATTR 8 -#define MDS_FSOP_LINK 9 - -#endif /* __KERNEL__ */ - -/* ioctls for trying requests */ -#define IOC_REQUEST_TYPE 'f' -#define IOC_REQUEST_MIN_NR 30 - -#define IOC_REQUEST_GETATTR _IOWR('f', 30, long) -#define IOC_REQUEST_READPAGE _IOWR('f', 31, long) -#define IOC_REQUEST_SETATTR _IOWR('f', 32, long) -#define IOC_REQUEST_CREATE _IOWR('f', 33, long) -#define IOC_REQUEST_OPEN _IOWR('f', 34, long) -#define IOC_REQUEST_CLOSE _IOWR('f', 35, long) -#define IOC_REQUEST_MAX_NR 35 - -#endif diff --git a/lustre/include/linux/lustre_net.h b/lustre/include/linux/lustre_net.h deleted file mode 100644 index 5c2ba75..0000000 --- a/lustre/include/linux/lustre_net.h +++ /dev/null @@ -1,363 +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_NET_H -#define _LUSTRE_NET_H - -#include -#include -// #include -#include -#include -#include -#include - -/* The following constants determine how much memory is devoted to - * buffering in the lustre services. - * - * ?_NEVENTS # event queue entries - * - * ?_NBUFS # request buffers - * ?_BUFSIZE # bytes in a single request buffer - * total memory = ?_NBUFS * ?_BUFSIZE - * - * ?_MAXREQSIZE # maximum request service will receive - * larger messages will get dropped. - * request buffers are auto-unlinked when less than ?_MAXREQSIZE - * is left in them. - */ - -#define LDLM_NUM_THREADS 4 -#define LDLM_NEVENTS 1024 -#define LDLM_NBUFS 10 -#define LDLM_BUFSIZE (64 * 1024) -#define LDLM_MAXREQSIZE 1024 - -#define MDT_NUM_THREADS 8 -#define MDS_NEVENTS 1024 -#define MDS_NBUFS 10 -#define MDS_BUFSIZE (64 * 1024) -#define MDS_MAXREQSIZE 1024 - -#define OST_NUM_THREADS 6 -#define OST_NEVENTS min(num_physpages / 16, 32768UL) -#define OST_NBUFS min(OST_NEVENTS / 128, 256UL) -#define OST_BUFSIZE ((OST_NEVENTS > 4096UL ? 128 : 64) * 1024) -#define OST_MAXREQSIZE (8 * 1024) - -#define CONN_INVALID 1 - -struct ptlrpc_connection { - struct list_head c_link; - struct lustre_peer c_peer; - __u8 c_local_uuid[37]; /* XXX do we need this? */ - __u8 c_remote_uuid[37]; - - __u32 c_generation; /* changes upon new connection */ - __u32 c_epoch; /* changes when peer changes */ - __u32 c_bootcount; /* peer's boot count */ - - spinlock_t c_lock; /* also protects req->rq_list */ - - atomic_t c_refcount; - __u64 c_token; - __u64 c_remote_conn; - __u64 c_remote_token; - - struct list_head c_delayed_head;/* delayed until post-recovery XXX imp? */ - struct recovd_data c_recovd_data; - - struct list_head c_imports; - struct list_head c_exports; - struct list_head c_sb_chain; - __u32 c_flags; // can we indicate INVALID elsewhere? -}; - -struct ptlrpc_client { - __u32 cli_request_portal; - __u32 cli_reply_portal; - - __u32 cli_target_devno; - - void *cli_data; - char *cli_name; -}; - -/* state flags of requests */ -#define PTL_RPC_FL_INTR (1 << 0) -#define PTL_RPC_FL_REPLIED (1 << 1) /* reply was received */ -#define PTL_RPC_FL_SENT (1 << 2) -#define PTL_BULK_FL_SENT (1 << 3) -#define PTL_BULK_FL_RCVD (1 << 4) -#define PTL_RPC_FL_ERR (1 << 5) -#define PTL_RPC_FL_TIMEOUT (1 << 6) -#define PTL_RPC_FL_RESEND (1 << 7) -#define PTL_RPC_FL_RESTART (1 << 8) /* operation must be restarted */ -#define PTL_RPC_FL_FINISHED (1 << 9) -#define PTL_RPC_FL_RETAIN (1 << 10) /* retain for replay after reply */ -#define PTL_RPC_FL_REPLAY (1 << 11) /* replay upon recovery */ -#define PTL_RPC_FL_ALLOCREP (1 << 12) /* reply buffer allocated */ - -struct ptlrpc_request { - int rq_type; /* one of PTL_RPC_MSG_* */ - struct list_head rq_list; - struct obd_device *rq_obd; - int rq_status; - int rq_flags; - atomic_t rq_refcount; - - int rq_request_portal; /* XXX FIXME bug 249 */ - int rq_reply_portal; /* XXX FIXME bug 249 */ - - int rq_reqlen; - struct lustre_msg *rq_reqmsg; - - int rq_replen; - struct lustre_msg *rq_repmsg; - __u64 rq_transno; - __u64 rq_xid; - - int rq_level; - time_t rq_timeout; - // void * rq_reply_handle; - wait_queue_head_t rq_wait_for_rep; - - /* incoming reply */ - ptl_md_t rq_reply_md; - ptl_handle_me_t rq_reply_me_h; - - /* outgoing req/rep */ - ptl_md_t rq_req_md; - - struct lustre_peer rq_peer; /* XXX see service.c can this be factored away? */ - struct obd_export *rq_export; - struct ptlrpc_connection *rq_connection; - struct obd_import *rq_import; - struct ptlrpc_service *rq_svc; - - void (*rq_replay_cb)(struct ptlrpc_request *); -}; - -#define DEBUG_REQ(level, req, fmt, args...) \ -do { \ -CDEBUG(level, \ - "@@@ " fmt " req x"LPD64"/t"LPD64" o%d->%s:%d lens %d/%d ref %d fl " \ - "%x\n" , ## args, req->rq_xid, req->rq_transno, \ - req->rq_reqmsg ? req->rq_reqmsg->opc : -1, \ - req->rq_connection ? (char *)req->rq_connection->c_remote_uuid : "", \ - (req->rq_import && req->rq_import->imp_client) ? \ - req->rq_import->imp_client->cli_request_portal : -1, \ - req->rq_reqlen, req->rq_replen, req->rq_refcount, req->rq_flags); \ -} while (0) - -struct ptlrpc_bulk_page { - struct ptlrpc_bulk_desc *bp_desc; - struct list_head bp_link; - void *bp_buf; - int bp_buflen; - struct page *bp_page; - __u32 bp_xid; - __u32 bp_flags; - struct dentry *bp_dentry; - int (*bp_cb)(struct ptlrpc_bulk_page *); -}; - - -struct ptlrpc_bulk_desc { - struct list_head bd_set_chain; /* entry in obd_brw_set */ - struct obd_brw_set *bd_brw_set; - int bd_flags; - struct ptlrpc_connection *bd_connection; - struct ptlrpc_client *bd_client; - __u32 bd_portal; - struct lustre_handle bd_conn; - void (*bd_ptl_ev_hdlr)(struct ptlrpc_bulk_desc *); - - wait_queue_head_t bd_waitq; - struct list_head bd_page_list; - __u32 bd_page_count; - atomic_t bd_refcount; - void *bd_desc_private; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) - struct work_struct bd_queue; -#else - struct tq_struct bd_queue; -#endif - - ptl_md_t bd_md; - ptl_handle_md_t bd_md_h; - ptl_handle_me_t bd_me_h; - - atomic_t bd_source_callback_count; - - struct iovec bd_iov[16]; /* self-sized pre-allocated iov */ -}; - -struct ptlrpc_thread { - struct list_head t_link; - - __u32 t_flags; - wait_queue_head_t t_ctl_waitq; -}; - -struct ptlrpc_request_buffer_desc { - struct list_head rqbd_list; - struct ptlrpc_service *rqbd_service; - ptl_handle_me_t rqbd_me_h; - atomic_t rqbd_refcount; - char *rqbd_buffer; -}; - -struct ptlrpc_service { - time_t srv_time; - time_t srv_timeout; - - /* incoming request buffers */ - /* FIXME: perhaps a list of EQs, if multiple NIs are used? */ - - __u32 srv_max_req_size; /* biggest request to receive */ - __u32 srv_buf_size; /* # bytes in a request buffer */ - struct list_head srv_rqbds; /* all the request buffer descriptors */ - __u32 srv_nrqbds; /* # request buffers */ - atomic_t srv_nrqbds_receiving; /* # request buffers posted for input */ - - __u32 srv_req_portal; - __u32 srv_rep_portal; - - __u32 srv_xid; - - /* event queue */ - ptl_handle_eq_t srv_eq_h; - - struct lustre_peer srv_self; - - wait_queue_head_t srv_waitq; /* all threads sleep on this */ - - spinlock_t srv_lock; - struct list_head srv_threads; - int (*srv_handler)(struct ptlrpc_request *req); - char *srv_name; /* only statically allocated strings here; we don't clean them */ -}; - -static inline void ptlrpc_hdl2req(struct ptlrpc_request *req, - struct lustre_handle *h) -{ - req->rq_reqmsg->addr = h->addr; - req->rq_reqmsg->cookie = h->cookie; -} - -typedef void (*bulk_callback_t)(struct ptlrpc_bulk_desc *, void *); - -typedef int (*svc_handler_t)(struct ptlrpc_request *req); - -/* rpc/connection.c */ -void ptlrpc_readdress_connection(struct ptlrpc_connection *, obd_uuid_t uuid); -struct ptlrpc_connection *ptlrpc_get_connection(struct lustre_peer *peer, - obd_uuid_t uuid); -int ptlrpc_put_connection(struct ptlrpc_connection *c); -struct ptlrpc_connection *ptlrpc_connection_addref(struct ptlrpc_connection *); -void ptlrpc_init_connection(void); -void ptlrpc_cleanup_connection(void); - -/* rpc/niobuf.c */ -int ptlrpc_check_bulk_sent(struct ptlrpc_bulk_desc *bulk); -int ptlrpc_check_bulk_received(struct ptlrpc_bulk_desc *bulk); -int ptlrpc_send_bulk(struct ptlrpc_bulk_desc *); -int ptlrpc_register_bulk(struct ptlrpc_bulk_desc *); -int ptlrpc_abort_bulk(struct ptlrpc_bulk_desc *bulk); -struct obd_brw_set *obd_brw_set_new(void); -void obd_brw_set_add(struct obd_brw_set *, struct ptlrpc_bulk_desc *); -void obd_brw_set_free(struct obd_brw_set *); - -int ptlrpc_reply(struct ptlrpc_service *svc, struct ptlrpc_request *req); -int ptlrpc_error(struct ptlrpc_service *svc, struct ptlrpc_request *req); -void ptlrpc_resend_req(struct ptlrpc_request *request); -int ptl_send_rpc(struct ptlrpc_request *request); -void ptlrpc_link_svc_me(struct ptlrpc_request_buffer_desc *rqbd); - -/* rpc/client.c */ -void ptlrpc_init_client(int req_portal, int rep_portal, char *name, - struct ptlrpc_client *); -void ptlrpc_cleanup_client(struct obd_import *imp); -__u8 *ptlrpc_req_to_uuid(struct ptlrpc_request *req); -struct ptlrpc_connection *ptlrpc_uuid_to_connection(obd_uuid_t uuid); - -int ll_brw_sync_wait(struct obd_brw_set *, int phase); - -int ptlrpc_queue_wait(struct ptlrpc_request *req); -void ptlrpc_continue_req(struct ptlrpc_request *req); -int ptlrpc_replay_req(struct ptlrpc_request *req); -void ptlrpc_restart_req(struct ptlrpc_request *req); - -struct ptlrpc_request *ptlrpc_prep_req(struct obd_import *imp, int opcode, - int count, int *lengths, char **bufs); -void ptlrpc_free_req(struct ptlrpc_request *request); -void ptlrpc_req_finished(struct ptlrpc_request *request); -struct ptlrpc_bulk_desc *ptlrpc_prep_bulk(struct ptlrpc_connection *); -void ptlrpc_free_bulk(struct ptlrpc_bulk_desc *bulk); -struct ptlrpc_bulk_page *ptlrpc_prep_bulk_page(struct ptlrpc_bulk_desc *desc); -void ptlrpc_free_bulk_page(struct ptlrpc_bulk_page *page); - -/* rpc/service.c */ -struct ptlrpc_service * -ptlrpc_init_svc(__u32 nevents, __u32 nbufs, __u32 bufsize, __u32 max_req_size, - int req_portal, int rep_portal, - obd_uuid_t uuid, svc_handler_t, char *name); -void ptlrpc_stop_all_threads(struct ptlrpc_service *svc); -int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc, - char *name); -int ptlrpc_unregister_service(struct ptlrpc_service *service); - -struct ptlrpc_svc_data { - char *name; - struct ptlrpc_service *svc; - struct ptlrpc_thread *thread; - struct obd_device *dev; -}; - -/* rpc/pack_generic.c */ -int lustre_pack_msg(int count, int *lens, char **bufs, int *len, - struct lustre_msg **msg); -int lustre_msg_size(int count, int *lengths); -int lustre_unpack_msg(struct lustre_msg *m, int len); -void *lustre_msg_buf(struct lustre_msg *m, int n); - -static inline void ptlrpc_bulk_decref(struct ptlrpc_bulk_desc *desc) -{ - if (atomic_dec_and_test(&desc->bd_refcount)) { - CDEBUG(D_PAGE, "Released last ref on %p, freeing\n", desc); - ptlrpc_free_bulk(desc); - } else { - CDEBUG(D_PAGE, "%p -> %d\n", desc, - atomic_read(&desc->bd_refcount)); - } -} - -static inline void ptlrpc_bulk_addref(struct ptlrpc_bulk_desc *desc) -{ - atomic_inc(&desc->bd_refcount); - CDEBUG(D_PAGE, "Set refcount of %p to %d\n", desc, - atomic_read(&desc->bd_refcount)); -} - -#endif diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h deleted file mode 100644 index cb72b5b..0000000 --- a/lustre/include/linux/obd.h +++ /dev/null @@ -1,420 +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 - */ - -#ifndef __OBD_H -#define __OBD_H - -struct lov_oinfo { /* per-child structure */ - __u64 loi_id; /* object ID on the target OST */ - struct lustre_handle *loi_handle; /* handle for object on OST */ - int loi_ost_idx; /* OST stripe index in lmd_objects array */ -}; - -struct lov_stripe_md { - __u32 lsm_magic; - __u64 lsm_object_id; /* lov object id */ - __u64 lsm_stripe_size; /* size of the stripe */ - __u32 lsm_stripe_pattern; /* per-lov object stripe pattern */ - int lsm_stripe_offset; /* offset of first stripe in lmd_objects */ - int lsm_stripe_count; /* how many objects are being striped on */ - struct lov_oinfo lsm_oinfo[0]; -}; - -#ifdef __KERNEL__ -# include -# include -# include -# include - -# include -# include -# include -# include - -struct obd_type { - struct list_head typ_chain; - struct obd_ops *typ_ops; - struct proc_dir_entry *typ_procroot; - char *typ_name; - int typ_refcnt; -}; - -struct brw_page { - struct page *pg; - obd_size count; - obd_off off; - obd_flag flag; -}; - -/* Individual type definitions */ - -struct ext2_obd { - struct super_block *e2_sb; - struct vfsmount *e2_vfsmnt; -}; - -struct obd_ucred { - __u32 ouc_fsuid; - __u32 ouc_fsgid; - __u32 ouc_cap; -}; - -#define OBD_RUN_CTXT_MAGIC 0xC0FFEEAA -#define OBD_CTXT_DEBUG /* development-only debugging */ -struct obd_run_ctxt { - struct vfsmount *pwdmnt; - struct dentry *pwd; - mm_segment_t fs; - __u32 fsuid; - __u32 fsgid; - __u32 cap; -#ifdef OBD_CTXT_DEBUG - __u32 magic; -#endif -}; - - -#ifdef OBD_CTXT_DEBUG -#define OBD_SET_CTXT_MAGIC(ctxt) (ctxt)->magic = OBD_RUN_CTXT_MAGIC -#else -#define OBD_SET_CTXT_MAGIC(ctxt) do {} while(0) -#endif - -struct filter_obd { - char *fo_fstype; - struct super_block *fo_sb; - struct vfsmount *fo_vfsmnt; - struct obd_run_ctxt fo_ctxt; - struct dentry *fo_dentry_O; - struct dentry *fo_dentry_O_mode[16]; - spinlock_t fo_objidlock; /* protects fo_lastobjid increment */ - __u64 fo_lastobjid; - struct file_operations *fo_fop; - struct inode_operations *fo_iop; - struct address_space_operations *fo_aops; - struct list_head fo_export_list; - spinlock_t fo_fddlock; /* protects setting dentry->d_fsdata */ -}; - -struct mds_server_data; - -struct client_obd { - struct obd_import cl_import; - struct semaphore cl_sem; - int cl_conn_count; - obd_uuid_t cl_target_uuid; /* XXX -> lustre_name */ - /* max_mds_easize is purely a performance thing so we don't have to - * call obd_size_wiremd() all the time. */ - int cl_max_mds_easize; - struct obd_device *cl_containing_lov; -}; - -#define IOC_OSC_TYPE 'h' -#define IOC_OSC_MIN_NR 20 -#define IOC_OSC_REGISTER_LOV _IOWR('h', 20, struct obd_device *) -#define IOC_OSC_MAX_NR 50 - -struct mds_obd { - struct ptlrpc_service *mds_service; - - char *mds_fstype; - struct super_block *mds_sb; - struct super_operations *mds_sop; - struct vfsmount *mds_vfsmnt; - struct obd_run_ctxt mds_ctxt; - struct file_operations *mds_fop; - struct inode_operations *mds_iop; - struct address_space_operations *mds_aops; - struct mds_fs_operations *mds_fsops; - - int mds_max_mdsize; - struct file *mds_rcvd_filp; - struct semaphore mds_transno_sem; - __u64 mds_last_committed; - __u64 mds_last_rcvd; - __u64 mds_mount_count; - struct ll_fid mds_rootfid; - struct mds_server_data *mds_server_data; - - wait_queue_head_t mds_next_transno_waitq; - __u64 mds_next_recovery_transno; - int mds_recoverable_clients; - struct list_head mds_recovery_queue; - struct list_head mds_delayed_reply_queue; - spinlock_t mds_processing_task_lock; - pid_t mds_processing_task; -}; - -struct ldlm_obd { - struct ptlrpc_service *ldlm_cb_service; - struct ptlrpc_service *ldlm_cancel_service; - struct ptlrpc_client *ldlm_client; - struct ptlrpc_connection *ldlm_server_conn; -}; - -struct echo_obd { - char *eo_fstype; - struct obdo oa; - spinlock_t eo_lock; - __u64 eo_lastino; - atomic_t eo_getattr; - atomic_t eo_setattr; - atomic_t eo_create; - atomic_t eo_destroy; - atomic_t eo_prep; - atomic_t eo_read; - atomic_t eo_write; -}; - -struct recovd_obd { - spinlock_t recovd_lock; - struct list_head recovd_managed_items; /* items managed */ - struct list_head recovd_troubled_items; /* items in recovery */ - - wait_queue_head_t recovd_recovery_waitq; - wait_queue_head_t recovd_ctl_waitq; - wait_queue_head_t recovd_waitq; - struct task_struct *recovd_thread; - __u32 recovd_state; -}; - -struct trace_obd { - struct obdtrace_opstats *stats; -}; - -#if 0 -struct snap_obd { - unsigned int snap_index; /* which snapshot index are we accessing */ - int snap_tableno; -}; - -#endif - -struct ost_obd { - struct ptlrpc_service *ost_service; - struct lustre_handle ost_conn; /* the local connection to the OBD */ -}; - -struct echo_client_obd { - struct lustre_handle conn; /* the local connection to osc/lov */ -}; - -struct lov_tgt_desc { - obd_uuid_t uuid; - struct lustre_handle conn; - int active; /* is this target available for requests, etc */ -}; - -struct lov_obd { - spinlock_t lov_lock; - struct obd_device *mdcobd; - struct lov_desc desc; - int bufsize; - int refcount; - struct lov_tgt_desc *tgts; -}; - -struct niobuf_local { - __u64 offset; - __u32 len; - __u32 xid; - __u32 flags; - void *addr; - struct page *page; - void *target_private; - struct dentry *dentry; -}; - -#define N_LOCAL_TEMP_PAGE 0x00000001 - -/* corresponds to one of the obd's */ -struct obd_device { - struct obd_type *obd_type; - - /* common and UUID name of this device */ - char *obd_name; - obd_uuid_t obd_uuid; - - int obd_minor; - int obd_flags; - struct proc_dir_entry *obd_proc_entry; - struct list_head obd_exports; - struct list_head obd_imports; - struct ldlm_namespace *obd_namespace; - struct ptlrpc_client obd_ldlm_client; /* XXX OST/MDS only */ - /* a spinlock is OK for what we do now, may need a semaphore later */ - spinlock_t obd_dev_lock; - union { - struct ext2_obd ext2; - struct filter_obd filter; - struct mds_obd mds; - struct client_obd cli; - struct ost_obd ost; - struct echo_client_obd echo_client;; - // struct osc_obd osc; - struct ldlm_obd ldlm; - struct echo_obd echo; - struct recovd_obd recovd; - struct trace_obd trace; - struct lov_obd lov; -#if 0 - struct snap_obd snap; -#endif - } u; - /* Fields used by LProcFS */ - unsigned int cntr_mem_size; - void* counters; -}; - -struct obd_ops { - int (*o_iocontrol)(unsigned int cmd, struct lustre_handle *, int len, - void *karg, void *uarg); - int (*o_get_info)(struct lustre_handle *, obd_count keylen, void *key, - obd_count *vallen, void **val); - int (*o_set_info)(struct lustre_handle *, obd_count keylen, void *key, - obd_count vallen, void *val); - int (*o_attach)(struct obd_device *dev, obd_count len, void *data); - int (*o_detach)(struct obd_device *dev); - int (*o_setup) (struct obd_device *dev, obd_count len, void *data); - int (*o_cleanup)(struct obd_device *dev); - int (*o_connect)(struct lustre_handle *conn, struct obd_device *src, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover); - int (*o_disconnect)(struct lustre_handle *conn); - - - int (*o_statfs)(struct lustre_handle *conn, struct obd_statfs *osfs); - int (*o_packmd)(struct lustre_handle *, struct lov_mds_md **wire_tgt, - struct lov_stripe_md *mem_src); - int (*o_unpackmd)(struct lustre_handle *, - struct lov_stripe_md **mem_tgt, - struct lov_mds_md *wire_src); - int (*o_preallocate)(struct lustre_handle *, obd_count *req, - obd_id *ids); - int (*o_create)(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md **ea); - int (*o_destroy)(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea); - int (*o_setattr)(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea); - int (*o_getattr)(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea); - int (*o_open)(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea); - int (*o_close)(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea); - int (*o_brw)(int rw, struct lustre_handle *conn, - struct lov_stripe_md *ea, obd_count oa_bufs, - struct brw_page *pgarr, struct obd_brw_set *); - int (*o_punch)(struct lustre_handle *conn, struct obdo *tgt, - struct lov_stripe_md *ea, obd_size count, - obd_off offset); - int (*o_sync)(struct lustre_handle *conn, struct obdo *tgt, - obd_size count, obd_off offset); - int (*o_migrate)(struct lustre_handle *conn, struct obdo *dst, - struct obdo *src, obd_size count, obd_off offset); - int (*o_copy)(struct lustre_handle *dstconn, struct obdo *dst, - struct lustre_handle *srconn, struct obdo *src, - obd_size count, obd_off offset); - int (*o_iterate)(struct lustre_handle *conn, - int (*)(obd_id, obd_gr, void *), - obd_id *startid, obd_gr group, void *data); - int (*o_preprw)(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_remote *remote, - struct niobuf_local *local, void **desc_private); - int (*o_commitrw)(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_local *local, - void *desc_private); - int (*o_enqueue)(struct lustre_handle *conn, struct lov_stripe_md *md, - struct lustre_handle *parent_lock, - __u32 type, void *cookie, int cookielen, __u32 mode, - int *flags, void *cb, void *data, int datalen, - struct lustre_handle *lockh); - int (*o_cancel)(struct lustre_handle *, struct lov_stripe_md *md, - __u32 mode, struct lustre_handle *); - int (*o_cancel_unused)(struct lustre_handle *, struct lov_stripe_md *, - int local_only); - -}; - -static inline void *mds_fs_start(struct mds_obd *mds, struct inode *inode, - int op) -{ - return mds->mds_fsops->fs_start(inode, op); -} - -static inline int mds_fs_commit(struct mds_obd *mds, struct inode *inode, - void *handle) -{ - return mds->mds_fsops->fs_commit(inode, handle); -} - -static inline int mds_fs_setattr(struct mds_obd *mds, 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 = mds->mds_fsops->fs_setattr(dentry, handle, iattr); - unlock_kernel(); - - return rc; -} - -static inline int mds_fs_set_md(struct mds_obd *mds, struct inode *inode, - void *handle, struct lov_mds_md *md, - int size) -{ - return mds->mds_fsops->fs_set_md(inode, handle, md, size); -} - -static inline int mds_fs_get_md(struct mds_obd *mds, struct inode *inode, - struct lov_mds_md *md, int size) -{ - return mds->mds_fsops->fs_get_md(inode, md, size); -} - -static inline ssize_t mds_fs_readpage(struct mds_obd *mds, struct file *file, - char *buf, size_t count, loff_t *offset) -{ - return mds->mds_fsops->fs_readpage(file, buf, count, offset); -} - -/* Set up callback to update mds->mds_last_committed with the current - * value of mds->mds_last_recieved when this transaction is on disk. - */ -static inline int mds_fs_set_last_rcvd(struct mds_obd *mds, void *handle) -{ - return mds->mds_fsops->fs_set_last_rcvd(mds, handle); -} - -/* Enable data journaling on the given file */ -static inline ssize_t mds_fs_journal_data(struct mds_obd *mds, - struct file *file) -{ - return mds->mds_fsops->fs_journal_data(file); -} - -static inline int mds_fs_statfs(struct mds_obd *mds, struct statfs *sfs) -{ - if (mds->mds_fsops->fs_statfs) - return mds->mds_fsops->fs_statfs(mds->mds_sb, sfs); - - return vfs_statfs(mds->mds_sb, sfs); -} -#endif /* __KERNEL */ -#endif /* __OBD_H */ diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h deleted file mode 100644 index 197de84..0000000 --- a/lustre/include/linux/obd_class.h +++ /dev/null @@ -1,879 +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. - * - */ - -#ifndef __LINUX_CLASS_OBD_H -#define __LINUX_CLASS_OBD_H - -#ifndef __KERNEL__ -# include -# define __KERNEL__ -# include -# undef __KERNEL__ -#else -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#endif - - -/* OBD Device Declarations */ -#define MAX_OBD_DEVICES 128 -extern struct obd_device obd_dev[MAX_OBD_DEVICES]; - -#define OBD_ATTACHED 0x1 -#define OBD_SET_UP 0x2 - -/* OBD Operations Declarations */ - -#ifdef __KERNEL__ -static inline int obd_check_conn(struct lustre_handle *conn) -{ - struct obd_device *obd; - if (!conn) { - CERROR("NULL conn\n"); - RETURN(-ENOTCONN); - } - obd = class_conn2obd(conn); - if (!obd) { - CERROR("NULL obd\n"); - RETURN(-ENODEV); - } - - if (!obd->obd_flags & OBD_ATTACHED ) { - CERROR("obd %d not attached\n", obd->obd_minor); - RETURN(-ENODEV); - } - - if (!obd->obd_flags & OBD_SET_UP) { - CERROR("obd %d not setup\n", obd->obd_minor); - RETURN(-ENODEV); - } - - if (!obd->obd_type) { - CERROR("obd %d not typed\n", obd->obd_minor); - RETURN(-ENODEV); - } - - if (!obd->obd_type->typ_ops) { - CERROR("obd_check_conn: obd %d no operations\n", - obd->obd_minor); - RETURN(-EOPNOTSUPP); - } - return 0; -} - - -#define OBT(dev) (dev)->obd_type -#define OBP(dev, op) (dev)->obd_type->typ_ops->o_ ## op - -#define OBD_CHECK_SETUP(conn, exp) \ -do { \ - if (!(conn)) { \ - CERROR("NULL connection\n"); \ - RETURN(-EINVAL); \ - } \ - \ - exp = class_conn2export(conn); \ - if (!(exp)) { \ - CERROR("No export\n"); \ - RETURN(-EINVAL); \ - } \ - \ - if (!((exp)->exp_obd->obd_flags & OBD_SET_UP)) { \ - CERROR("Device %d not setup\n", \ - (exp)->exp_obd->obd_minor); \ - RETURN(-EINVAL); \ - } \ -} while (0) - -#define OBD_CHECK_DEVSETUP(obd) \ -do { \ - if (!(obd)) { \ - CERROR("NULL device\n"); \ - RETURN(-EINVAL); \ - } \ - \ - if (!((obd)->obd_flags & OBD_SET_UP)) { \ - CERROR("Device %d not setup\n", \ - (obd)->obd_minor); \ - RETURN(-EINVAL); \ - } \ -} while (0) - -#define OBD_CHECK_OP(obd, op) \ -do { \ - if (!OBP((obd), op)) { \ - CERROR("obd_" #op ": dev %d no operation\n", \ - obd->obd_minor); \ - RETURN(-EOPNOTSUPP); \ - } \ -} while (0) - -static inline int obd_get_info(struct lustre_handle *conn, obd_count keylen, - void *key, obd_count *vallen, void **val) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, get_info); - - rc = OBP(exp->exp_obd, get_info)(conn, keylen, key, vallen, val); - RETURN(rc); -} - -static inline int obd_set_info(struct lustre_handle *conn, obd_count keylen, - void *key, obd_count vallen, void *val) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, set_info); - - rc = OBP(exp->exp_obd, set_info)(conn, keylen, key, vallen, val); - RETURN(rc); -} - -static inline int obd_setup(struct obd_device *obd, int datalen, void *data) -{ - int rc; - ENTRY; - - OBD_CHECK_OP(obd, setup); - - rc = OBP(obd, setup)(obd, datalen, data); - RETURN(rc); -} - -static inline int obd_cleanup(struct obd_device *obd) -{ - int rc; - ENTRY; - - OBD_CHECK_DEVSETUP(obd); - OBD_CHECK_OP(obd, cleanup); - - rc = OBP(obd, cleanup)(obd); - RETURN(rc); -} - -/* Pack an in-memory MD struct for sending to the MDS and/or disk. - * Returns +ve size of packed MD (0 for free), or -ve error. - * - * If @wire_tgt == NULL, MD size is returned (max size if @mem_src == NULL). - * If @*wire_tgt != NULL and @mem_src == NULL, @*wire_tgt will be freed. - * If @*wire_tgt == NULL, it will be allocated - */ -static inline int obd_packmd(struct lustre_handle *conn, - struct lov_mds_md **wire_tgt, - struct lov_stripe_md *mem_src) -{ - struct obd_export *exp; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, packmd); - - RETURN(OBP(exp->exp_obd, packmd)(conn, wire_tgt, mem_src)); -} - -static inline int obd_size_wiremd(struct lustre_handle *conn, - struct lov_stripe_md *mem_src) -{ - return obd_packmd(conn, NULL, mem_src); -} - -/* helper functions */ -static inline int obd_alloc_wiremd(struct lustre_handle *conn, - struct lov_mds_md **wire_tgt) -{ - LASSERT(wire_tgt); - LASSERT(*wire_tgt == NULL); - return obd_packmd(conn, wire_tgt, NULL); -} - -static inline int obd_free_wiremd(struct lustre_handle *conn, - struct lov_mds_md **wire_tgt) -{ - LASSERT(wire_tgt); - LASSERT(*wire_tgt); - return obd_packmd(conn, wire_tgt, NULL); -} - -/* Unpack an MD struct from the MDS and/or disk to in-memory format. - * Returns +ve size of unpacked MD (0 for free), or -ve error. - * - * If @mem_tgt == NULL, MD size is returned (max size if @wire_src == NULL). - * If @*mem_tgt != NULL and @wire_src == NULL, @*mem_tgt will be freed. - * If @*mem_tgt == NULL, it will be allocated - */ -static inline int obd_unpackmd(struct lustre_handle *conn, - struct lov_stripe_md **mem_tgt, - struct lov_mds_md *wire_src) -{ - struct obd_export *exp; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, unpackmd); - - RETURN(OBP(exp->exp_obd, unpackmd)(conn, mem_tgt, wire_src)); -} - -static inline int obd_size_memmd(struct lustre_handle *conn, - struct lov_mds_md *wire_src) -{ - return obd_unpackmd(conn, NULL, wire_src); -} - -/* helper functions */ -static inline int obd_alloc_memmd(struct lustre_handle *conn, - struct lov_stripe_md **mem_tgt) -{ - LASSERT(mem_tgt); - LASSERT(*mem_tgt == NULL); - return obd_unpackmd(conn, mem_tgt, NULL); -} - -static inline int obd_free_memmd(struct lustre_handle *conn, - struct lov_stripe_md **mem_tgt) -{ - LASSERT(mem_tgt); - LASSERT(*mem_tgt); - return obd_unpackmd(conn, mem_tgt, NULL); -} - -static inline int obd_create(struct lustre_handle *conn, struct obdo *obdo, - struct lov_stripe_md **ea) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, create); - - rc = OBP(exp->exp_obd, create)(conn, obdo, ea); - RETURN(rc); -} - -static inline int obd_destroy(struct lustre_handle *conn, struct obdo *obdo, - struct lov_stripe_md *ea) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, destroy); - - rc = OBP(exp->exp_obd, destroy)(conn, obdo, ea); - RETURN(rc); -} - -static inline int obd_getattr(struct lustre_handle *conn, struct obdo *obdo, - struct lov_stripe_md *ea) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, getattr); - - rc = OBP(exp->exp_obd, getattr)(conn, obdo, ea); - RETURN(rc); -} - -static inline int obd_close(struct lustre_handle *conn, struct obdo *obdo, - struct lov_stripe_md *ea) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, close); - - rc = OBP(exp->exp_obd, close)(conn, obdo, ea); - RETURN(rc); -} - -static inline int obd_open(struct lustre_handle *conn, struct obdo *obdo, - struct lov_stripe_md *ea) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, open); - - rc = OBP(exp->exp_obd, open)(conn, obdo, ea); - RETURN(rc); -} - -static inline int obd_setattr(struct lustre_handle *conn, struct obdo *obdo, - struct lov_stripe_md *ea) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, setattr); - - rc = OBP(exp->exp_obd, setattr)(conn, obdo, ea); - RETURN(rc); -} - -static inline int obd_connect(struct lustre_handle *conn, - struct obd_device *obd, obd_uuid_t cluuid, - struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - int rc; - ENTRY; - - OBD_CHECK_DEVSETUP(obd); - OBD_CHECK_OP(obd, connect); - - rc = OBP(obd, connect)(conn, obd, cluuid, recovd, recover); - RETURN(rc); -} - -static inline int obd_disconnect(struct lustre_handle *conn) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, disconnect); - - rc = OBP(exp->exp_obd, disconnect)(conn); - RETURN(rc); -} - -static inline int obd_statfs(struct lustre_handle *conn,struct obd_statfs *osfs) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, statfs); - - rc = OBP(exp->exp_obd, statfs)(conn, osfs); - RETURN(rc); -} - -static inline int obd_punch(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea, - obd_size start, obd_size end) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, punch); - - rc = OBP(exp->exp_obd, punch)(conn, oa, ea, start, end); - RETURN(rc); -} - -static inline int obd_brw(int cmd, struct lustre_handle *conn, - struct lov_stripe_md *ea, obd_count oa_bufs, - struct brw_page *pg, struct obd_brw_set *set) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, brw); - - if (!(cmd & OBD_BRW_RWMASK)) { - CERROR("obd_brw: cmd must be OBD_BRW_READ or OBD_BRW_WRITE\n"); - LBUG(); - } - - rc = OBP(exp->exp_obd, brw)(cmd, conn, ea, oa_bufs, pg, set); - RETURN(rc); -} - -static inline int obd_preprw(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_remote *remote, - struct niobuf_local *local, void **desc_private) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, preprw); - - rc = OBP(exp->exp_obd, preprw)(cmd, conn, objcount, obj, niocount, - remote, local, desc_private); - RETURN(rc); -} - -static inline int obd_commitrw(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_local *local, - void *desc_private) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, commitrw); - - rc = OBP(exp->exp_obd, commitrw)(cmd, conn, objcount, obj, niocount, - local, desc_private); - RETURN(rc); -} - -static inline int obd_iocontrol(unsigned int cmd, struct lustre_handle *conn, - int len, void *karg, void *uarg) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, iocontrol); - - rc = OBP(exp->exp_obd, iocontrol)(cmd, conn, len, karg, uarg); - RETURN(rc); -} - -static inline int obd_enqueue(struct lustre_handle *conn, - struct lov_stripe_md *ea, - struct lustre_handle *parent_lock, - __u32 type, void *cookie, int cookielen, - __u32 mode, int *flags, void *cb, void *data, - int datalen, struct lustre_handle *lockh) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, enqueue); - - rc = OBP(exp->exp_obd, enqueue)(conn, ea, parent_lock, type, - cookie, cookielen, mode, flags, cb, - data, datalen, lockh); - RETURN(rc); -} - -static inline int obd_cancel(struct lustre_handle *conn, - struct lov_stripe_md *ea, __u32 mode, - struct lustre_handle *lockh) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, cancel); - - rc = OBP(exp->exp_obd, cancel)(conn, ea, mode, lockh); - RETURN(rc); -} - -static inline int obd_cancel_unused(struct lustre_handle *conn, - struct lov_stripe_md *ea, int local) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, cancel_unused); - - rc = OBP(exp->exp_obd, cancel_unused)(conn, ea, local); - RETURN(rc); -} - -#endif - -/* OBD Metadata Support */ - -extern int obd_init_caches(void); -extern void obd_cleanup_caches(void); - -static inline struct lustre_handle *obdo_handle(struct obdo *oa) -{ - return (struct lustre_handle *)&oa->o_inline; -} - -static inline void obd_oa2handle(struct lustre_handle *handle, struct obdo *oa) -{ - if (oa->o_valid |= OBD_MD_FLHANDLE) { - struct lustre_handle *oa_handle = obdo_handle(oa); - memcpy(handle, oa_handle, sizeof(*handle)); - } -} - -static inline void obd_handle2oa(struct obdo *oa, struct lustre_handle *handle) -{ - if (handle->addr) { - struct lustre_handle *oa_handle = obdo_handle(oa); - memcpy(oa_handle, handle, sizeof(*handle)); - oa->o_valid |= OBD_MD_FLHANDLE; - } -} - -#ifdef __KERNEL__ -/* support routines */ -extern kmem_cache_t *obdo_cachep; -static inline struct obdo *obdo_alloc(void) -{ - struct obdo *oa; - - oa = kmem_cache_alloc(obdo_cachep, SLAB_KERNEL); - if (oa == NULL) - LBUG(); - memset(oa, 0, sizeof (*oa)); - - return oa; -} - -static inline void obdo_free(struct obdo *oa) -{ - if (!oa) - return; - kmem_cache_free(obdo_cachep, oa); -} - -static inline void obdo_from_iattr(struct obdo *oa, struct iattr *attr) -{ - unsigned int ia_valid = attr->ia_valid; - - if (ia_valid & ATTR_ATIME) { - oa->o_atime = attr->ia_atime; - oa->o_valid |= OBD_MD_FLATIME; - } - if (ia_valid & ATTR_MTIME) { - oa->o_mtime = attr->ia_mtime; - oa->o_valid |= OBD_MD_FLMTIME; - } - if (ia_valid & ATTR_CTIME) { - oa->o_ctime = attr->ia_ctime; - oa->o_valid |= OBD_MD_FLCTIME; - } - if (ia_valid & ATTR_SIZE) { - oa->o_size = attr->ia_size; - oa->o_valid |= OBD_MD_FLSIZE; - } - if (ia_valid & ATTR_MODE) { - oa->o_mode = attr->ia_mode; - oa->o_valid |= OBD_MD_FLTYPE | OBD_MD_FLMODE; - if (!in_group_p(oa->o_gid) && !capable(CAP_FSETID)) - oa->o_mode &= ~S_ISGID; - } - if (ia_valid & ATTR_UID) { - oa->o_uid = attr->ia_uid; - oa->o_valid |= OBD_MD_FLUID; - } - if (ia_valid & ATTR_GID) { - oa->o_gid = attr->ia_gid; - oa->o_valid |= OBD_MD_FLGID; - } -} - - -static inline void iattr_from_obdo(struct iattr *attr, struct obdo *oa, - obd_flag valid) -{ - memset(attr, 0, sizeof(*attr)); - if (valid & OBD_MD_FLATIME) { - attr->ia_atime = oa->o_atime; - attr->ia_valid |= ATTR_ATIME; - } - if (valid & OBD_MD_FLMTIME) { - attr->ia_mtime = oa->o_mtime; - attr->ia_valid |= ATTR_MTIME; - } - if (valid & OBD_MD_FLCTIME) { - attr->ia_ctime = oa->o_ctime; - attr->ia_valid |= ATTR_CTIME; - } - if (valid & OBD_MD_FLSIZE) { - attr->ia_size = oa->o_size; - attr->ia_valid |= ATTR_SIZE; - } - if (valid & OBD_MD_FLTYPE) { - attr->ia_mode = (attr->ia_mode & ~S_IFMT)|(oa->o_mode & S_IFMT); - attr->ia_valid |= ATTR_MODE; - } - if (valid & OBD_MD_FLMODE) { - attr->ia_mode = (attr->ia_mode & S_IFMT)|(oa->o_mode & ~S_IFMT); - attr->ia_valid |= ATTR_MODE; - if (!in_group_p(oa->o_gid) && !capable(CAP_FSETID)) - attr->ia_mode &= ~S_ISGID; - } - if (valid & OBD_MD_FLUID) - { - attr->ia_uid = oa->o_uid; - attr->ia_valid |= ATTR_UID; - } - if (valid & OBD_MD_FLGID) { - attr->ia_gid = oa->o_gid; - attr->ia_valid |= ATTR_GID; - } -} - - -/* WARNING: the file systems must take care not to tinker with - attributes they don't manage (such as blocks). */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#define to_kdev_t(dev) dev -#define kdev_t_to_nr(dev) dev -#endif - -static inline void obdo_from_inode(struct obdo *dst, struct inode *src, - obd_flag valid) -{ -// if (valid & OBD_MD_FLID) -// dst->o_id = src->i_ino; - if (valid & OBD_MD_FLATIME) - dst->o_atime = src->i_atime; - if (valid & OBD_MD_FLMTIME) - dst->o_mtime = src->i_mtime; - if (valid & OBD_MD_FLCTIME) - dst->o_ctime = src->i_ctime; - if (valid & OBD_MD_FLSIZE) - dst->o_size = src->i_size; - if (valid & OBD_MD_FLBLOCKS) /* allocation of space */ - dst->o_blocks = src->i_blocks; - if (valid & OBD_MD_FLBLKSZ) - dst->o_blksize = src->i_blksize; - if (valid & OBD_MD_FLTYPE) - dst->o_mode = (dst->o_mode & ~S_IFMT) | (src->i_mode & S_IFMT); - if (valid & OBD_MD_FLMODE) - dst->o_mode = (dst->o_mode & S_IFMT) | (src->i_mode & ~S_IFMT); - if (valid & OBD_MD_FLUID) - dst->o_uid = src->i_uid; - if (valid & OBD_MD_FLGID) - dst->o_gid = src->i_gid; - if (valid & OBD_MD_FLFLAGS) - dst->o_flags = src->i_flags; - if (valid & OBD_MD_FLNLINK) - dst->o_nlink = src->i_nlink; - if (valid & OBD_MD_FLGENER) - dst->o_generation = src->i_generation; - if (valid & OBD_MD_FLRDEV) - dst->o_rdev = (__u32)kdev_t_to_nr(src->i_rdev); - - dst->o_valid |= (valid & ~OBD_MD_FLID); -} - -static inline void obdo_to_inode(struct inode *dst, struct obdo *src, - obd_flag valid) -{ -// if (valid & OBD_MD_FLID) -// dst->i_ino = src->o_id; - if (valid & OBD_MD_FLATIME) - dst->i_atime = src->o_atime; - if (valid & OBD_MD_FLMTIME) - dst->i_mtime = src->o_mtime; - if (valid & OBD_MD_FLCTIME) - dst->i_ctime = src->o_ctime; - if (valid & OBD_MD_FLSIZE) - dst->i_size = src->o_size; - if (valid & OBD_MD_FLBLOCKS) /* allocation of space */ - dst->i_blocks = src->o_blocks; - if (valid & OBD_MD_FLBLKSZ) - dst->i_blksize = src->o_blksize; - if (valid & OBD_MD_FLTYPE) - dst->i_mode = (dst->i_mode & ~S_IFMT) | (src->o_mode & S_IFMT); - if (valid & OBD_MD_FLMODE) - dst->i_mode = (dst->i_mode & S_IFMT) | (src->o_mode & ~S_IFMT); - if (valid & OBD_MD_FLUID) - dst->i_uid = src->o_uid; - if (valid & OBD_MD_FLGID) - dst->i_gid = src->o_gid; - if (valid & OBD_MD_FLFLAGS) - dst->i_flags = src->o_flags; - if (valid & OBD_MD_FLNLINK) - dst->i_nlink = src->o_nlink; - if (valid & OBD_MD_FLGENER) - dst->i_generation = src->o_generation; - if (valid & OBD_MD_FLRDEV) - dst->i_rdev = to_kdev_t(src->o_rdev); -} -#endif - -static inline void obdo_cpy_md(struct obdo *dst, struct obdo *src, - obd_flag valid) -{ -#ifdef __KERNEL__ - CDEBUG(D_INODE, "src obdo %Ld valid 0x%x, dst obdo %Ld\n", - (unsigned long long)src->o_id, src->o_valid, - (unsigned long long)dst->o_id); -#endif - if (valid & OBD_MD_FLATIME) - dst->o_atime = src->o_atime; - if (valid & OBD_MD_FLMTIME) - dst->o_mtime = src->o_mtime; - if (valid & OBD_MD_FLCTIME) - dst->o_ctime = src->o_ctime; - if (valid & OBD_MD_FLSIZE) - dst->o_size = src->o_size; - if (valid & OBD_MD_FLBLOCKS) /* allocation of space */ - dst->o_blocks = src->o_blocks; - if (valid & OBD_MD_FLBLKSZ) - dst->o_blksize = src->o_blksize; - if (valid & OBD_MD_FLTYPE) - dst->o_mode = (dst->o_mode & ~S_IFMT) | (src->o_mode & S_IFMT); - if (valid & OBD_MD_FLMODE) - dst->o_mode = (dst->o_mode & S_IFMT) | (src->o_mode & ~S_IFMT); - if (valid & OBD_MD_FLUID) - dst->o_uid = src->o_uid; - if (valid & OBD_MD_FLGID) - dst->o_gid = src->o_gid; - if (valid & OBD_MD_FLFLAGS) - dst->o_flags = src->o_flags; - /* - if (valid & OBD_MD_FLOBDFLG) - dst->o_obdflags = src->o_obdflags; - */ - if (valid & OBD_MD_FLNLINK) - dst->o_nlink = src->o_nlink; - if (valid & OBD_MD_FLGENER) - dst->o_generation = src->o_generation; - if (valid & OBD_MD_FLRDEV) - dst->o_rdev = src->o_rdev; - if (valid & OBD_MD_FLINLINE && - src->o_obdflags & OBD_FL_INLINEDATA) { - memcpy(dst->o_inline, src->o_inline, sizeof(src->o_inline)); - dst->o_obdflags |= OBD_FL_INLINEDATA; - } - - dst->o_valid |= valid; -} - - -/* returns FALSE if comparison (by flags) is same, TRUE if changed */ -static inline int obdo_cmp_md(struct obdo *dst, struct obdo *src, - obd_flag compare) -{ - int res = 0; - - if ( compare & OBD_MD_FLATIME ) - res = (res || (dst->o_atime != src->o_atime)); - if ( compare & OBD_MD_FLMTIME ) - res = (res || (dst->o_mtime != src->o_mtime)); - if ( compare & OBD_MD_FLCTIME ) - res = (res || (dst->o_ctime != src->o_ctime)); - if ( compare & OBD_MD_FLSIZE ) - res = (res || (dst->o_size != src->o_size)); - if ( compare & OBD_MD_FLBLOCKS ) /* allocation of space */ - res = (res || (dst->o_blocks != src->o_blocks)); - if ( compare & OBD_MD_FLBLKSZ ) - res = (res || (dst->o_blksize != src->o_blksize)); - if ( compare & OBD_MD_FLTYPE ) - res = (res || (((dst->o_mode ^ src->o_mode) & S_IFMT) != 0)); - if ( compare & OBD_MD_FLMODE ) - res = (res || (((dst->o_mode ^ src->o_mode) & ~S_IFMT) != 0)); - if ( compare & OBD_MD_FLUID ) - res = (res || (dst->o_uid != src->o_uid)); - if ( compare & OBD_MD_FLGID ) - res = (res || (dst->o_gid != src->o_gid)); - if ( compare & OBD_MD_FLFLAGS ) - res = (res || (dst->o_flags != src->o_flags)); - if ( compare & OBD_MD_FLNLINK ) - res = (res || (dst->o_nlink != src->o_nlink)); - if ( compare & OBD_MD_FLGENER ) - res = (res || (dst->o_generation != src->o_generation)); - /* XXX Don't know if thses should be included here - wasn't previously - if ( compare & OBD_MD_FLINLINE ) - res = (res || memcmp(dst->o_inline, src->o_inline)); - */ - return res; -} - - -#ifdef __KERNEL__ -/* I'm as embarrassed about this as you are. - * - * // XXX do not look into _superhack with remaining eye - * // XXX if this were any uglier, I'd get my own show on MTV */ -extern int (*ptlrpc_put_connection_superhack)(struct ptlrpc_connection *c); - -int class_register_type(struct obd_ops *ops, struct lprocfs_vars* vars, - char *nm); -int class_unregister_type(char *nm); -int class_name2dev(char *name); -int class_uuid2dev(char *uuid); -struct obd_device *class_uuid2obd(char *uuid); -struct obd_export *class_new_export(struct obd_device *obddev); -struct obd_type *class_nm_to_type(char* name); -void class_destroy_export(struct obd_export *exp); -int class_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid); -int class_disconnect(struct lustre_handle *conn); -void class_disconnect_all(struct obd_device *obddev); - -/* generic operations shared by various OBD types */ -int class_multi_setup(struct obd_device *obddev, uint32_t len, void *data); -int class_multi_cleanup(struct obd_device *obddev); - -extern void (*class_signal_connection_failure)(struct ptlrpc_connection *); - -static inline struct ptlrpc_connection *class_rd2conn(struct recovd_data *rd) -{ - /* reuse list_entry's member-pointer offset stuff */ - return list_entry(rd, struct ptlrpc_connection, c_recovd_data); -} - -#endif - -/* sysctl.c */ -extern void obd_sysctl_init (void); -extern void obd_sysctl_clean (void); - -/* uuid.c */ -typedef __u8 class_uuid_t[16]; -//int class_uuid_parse(obd_uuid_t in, class_uuid_t out); -void class_uuid_unparse(class_uuid_t in, obd_uuid_t out); -#endif /* __LINUX_CLASS_OBD_H */ diff --git a/lustre/include/linux/obd_echo.h b/lustre/include/linux/obd_echo.h deleted file mode 100644 index 6bc32f2..0000000 --- a/lustre/include/linux/obd_echo.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _OBD_ECHO_H -#define _OBD_ECHO_H -/* - * Copyright (C) 2001 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ - -#define OBD_ECHO_DEVICENAME "obdecho" -#define OBD_ECHO_CLIENT_DEVICENAME "echo_client" - -#endif diff --git a/lustre/include/linux/obd_ext2.h b/lustre/include/linux/obd_ext2.h deleted file mode 100644 index 73b4b0b..0000000 --- a/lustre/include/linux/obd_ext2.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _OBD_EXT2 -#define _OBD_EXT2 -/* - * Copyright (C) 2001 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ - -#define OBD_EXT2_RUNIT _IOWR('f', 61, long) - -#ifndef OBD_EXT2_DEVICENAME -#define OBD_EXT2_DEVICENAME "obdext2" -#endif - -/* development definitions */ -extern struct obdfs_sb_info *obd_sbi; -extern struct file_operations *obd_fso; - -/* ext2_obd.c */ -extern struct obd_ops ext2_obd_ops; - -#include -#include - -/* super.c */ -#ifdef EXT2_OBD_DEBUG -# undef ext2_debug -# define ext2_debug(format, a...) CDEBUG(D_EXT2, format, ## a) -# define ext2_error ext2_warning -# define ext2_panic ext2_warning -# define ext2_warning(sb, func, format, a...) CDEBUG(D_WARNING, format, ## a) -#else -# undef ext2_debug -# define ext2_debug(format, a...) {} -# define ext2_error(sb, func, format, a...) printk(KERN_ERR "%s: " format, func, ## a) -# define ext2_panic(sb, func, format, a...) printk(KERN_CRIT "%s: " format, func, ## a) -# define ext2_warning(sb, func, format, a...) printk(KERN_WARNING "%s: " format, func, ## a) -#endif - -extern struct super_operations ext2_sops; -int obd_remount (struct super_block * sb, int * flags, char * data); -struct super_block * ext2_read_super (struct super_block * sb, void * data, - int silent); -/* punch.c */ -void ext2_truncate (struct inode * inode); -int ext2_punch (struct inode * inode, loff_t start, size_t count); - -#endif diff --git a/lustre/include/linux/obd_filter.h b/lustre/include/linux/obd_filter.h deleted file mode 100644 index fb3d1ff..0000000 --- a/lustre/include/linux/obd_filter.h +++ /dev/null @@ -1,50 +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 _OBD_FILTER_H -#define _OBD_FILTER_H - -#ifndef OBD_FILTER_DEVICENAME -#define OBD_FILTER_DEVICENAME "obdfilter" -#endif - -/* In-memory access to client data from OST struct */ -struct filter_export_data { - struct list_head fed_open_head; /* files to close on disconnect */ - spinlock_t fed_lock; /* protects fed_open_head */ -}; - -/* file data for open files on OST */ -struct filter_file_data { - struct list_head ffd_export_list; /* export open list - fed_lock */ - struct file *ffd_file; /* file handle */ - __u64 ffd_servercookie; /* cookie for lustre handle */ -}; - -struct filter_dentry_data { - atomic_t fdd_open_count; - int fdd_flags; -}; - -#define FILTER_FLAG_DESTROY 0x0001 /* destroy dentry on last file close */ - -#endif diff --git a/lustre/include/linux/obd_lov.h b/lustre/include/linux/obd_lov.h deleted file mode 100644 index acdac151..0000000 --- a/lustre/include/linux/obd_lov.h +++ /dev/null @@ -1,31 +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" - -void lov_unpackdesc(struct lov_desc *ld); -void lov_packdesc(struct lov_desc *ld); - -static inline int lov_stripe_md_size(int stripes) -{ - return sizeof(struct lov_stripe_md) + stripes*sizeof(struct lov_oinfo); -} -#endif - -static inline int lov_mds_md_size(int stripes) -{ - return sizeof(struct lov_mds_md) + stripes*sizeof(struct lov_object_id); -} - -#define IOC_LOV_TYPE 'g' -#define IOC_LOV_MIN_NR 50 -#define IOC_LOV_SET_OSC_ACTIVE _IOWR('g', 50, long) -#define IOC_LOV_MAX_NR 50 - -#endif diff --git a/lustre/include/linux/obd_ost.h b/lustre/include/linux/obd_ost.h deleted file mode 100644 index e999451..0000000 --- a/lustre/include/linux/obd_ost.h +++ /dev/null @@ -1,42 +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. - * - * Data structures for object storage targets and client: OST & OSC's - * - * See also lustre_idl.h for wire formats of requests. - * - */ - -#ifndef _LUSTRE_OST_H -#define _LUSTRE_OST_H - -#include - -#define LUSTRE_OST_NAME "ost" -#define LUSTRE_OSC_NAME "osc" - -/* ost/ost_pack.c */ -void ost_pack_niobuf(void **tmp, __u64 offset, __u32 len, __u32 flags, - __u32 xid); -void ost_unpack_niobuf(void **tmp, struct niobuf_remote **nbp); -void ost_pack_ioo(void **tmp, struct lov_stripe_md *oa, int bufcnt); -void ost_unpack_ioo(void **tmp, struct obd_ioobj **ioop); - -#endif diff --git a/lustre/include/linux/obd_snap.h b/lustre/include/linux/obd_snap.h deleted file mode 100644 index b7641d4..0000000 --- a/lustre/include/linux/obd_snap.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _OBD_SNAP -#define _OBD_SNAP -/* - * Copyright (C) 2001 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ - -#include - -#define OBD_SNAP_MAGIC 0xfffffff3 /* an unlikely block number */ - -#ifndef OBD_SNAP_DEVICENAME -#define OBD_SNAP_DEVICENAME "obdsnap" -#endif - -/* ioctls for manipulating snapshots 40 - 60 */ -#define OBD_SNAP_SETTABLE _IOWR('f', 40, long) -#define OBD_SNAP_PRINTTABLE _IOWR('f', 41, long) -#define OBD_SNAP_DELETE _IOWR('f', 42, long) -#define OBD_SNAP_RESTORE _IOWR('f', 43, long) - -void snap_use(int table_no, int snap_index) ; -void snap_unuse(int table_no, int snap_index) ; -int snap_is_used(int table_no, int snap_index) ; -int snap_table_attach(int tableno, int snap_index); - -#endif diff --git a/lustre/include/linux/obd_snap_support.h b/lustre/include/linux/obd_snap_support.h deleted file mode 100644 index fd8baa4..0000000 --- a/lustre/include/linux/obd_snap_support.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef __OBD_SNAP_SUPP_H -#define __OBD_SNAP_SUPP_H -/* - * Copyright (C) 2001 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ - -/* What we use to point to IDs in the obdmd data for snapshots. If we use - * obd_id (8 bytes) instead of ino_t (4 bytes), we halve the number of - * available snapshot slots (14 in 56 bytes vs. 7 in 56 bytes until we - * increase the size of OBD_OBDMDSZ). - */ -typedef obd_id snap_id; - -/* maximum number of snapshot tables we maintain in the kernel */ -#define SNAP_MAX_TABLES 8 - -/* maximum number of snapshots per device - must fit in "o_obdmd" area of struct obdo */ -#define SNAP_MAX ((OBD_OBDMDSZ - sizeof(uint32_t))/sizeof(snap_id)) - -struct snap_md { - uint32_t m_magic; - snap_id m_ids[SNAP_MAX]; /* id of snaps; slot 0 has current id */ -}; - - -/* if time is 0 this designates the "current" snapshot, i.e. - the head of the tree -*/ -struct snap { - time_t time; - int index; -}; - -/* snap ioctl data for attach: current always in first slot of this array */ -struct snap_obd_data { - int snap_dev; /* which device contains the data */ - unsigned int snap_index;/* which snapshot is ours */ - unsigned int snap_table;/* which table do we use */ -}; - - -/* snap ioctl data for table fiddling */ -struct snap_table_data { - int tblcmd_no; /* which table */ - unsigned int tblcmd_count; /* how many snaps */ - struct snap tblcmd_snaps[SNAP_MAX]; /* sorted times! */ -}; - - -struct snap_table { - spinlock_t tbl_lock; - unsigned int tbl_count; /* how many snapshots exist in this table*/ - int tbl_used; /* bitmap of snaps in use by a device */ - time_t tbl_times[SNAP_MAX]; - int tbl_index[SNAP_MAX]; -}; - -struct snap_iterdata { - struct lustre_handle *conn; - struct lustre_handle *ch_conn; - int index; - int previndex; - int currentindex; - int prevslot; - time_t prevtime; -}; - -inline struct lustre_handle *child_conn(struct lustre_handle *conn); -int snap_deleteobj(obd_id id, obd_gr group, void *data); -int snap_restoreobj(obd_id id, obd_gr group, void *data); -int snap_printobj(obd_id id, obd_gr group, void *data); -int snap_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len, void *karg, void *uarg); - -/* In the future, this function may have to deal with offsets into the obdmd. - * Currently, we assume we have the whole obdmd struct. - */ -static __inline__ struct snap_md *snap_obdmd(struct obdo *oa) -{ - return ((struct snap_md *)(&oa->o_obdmd)); -} -#endif diff --git a/lustre/include/linux/obd_support.h b/lustre/include/linux/obd_support.h deleted file mode 100644 index b95b266..0000000 --- a/lustre/include/linux/obd_support.h +++ /dev/null @@ -1,195 +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. - * - */ - -#ifndef _OBD_SUPPORT -#define _OBD_SUPPORT - -#include -#include -#include -#include -#include - -/* global variables */ -extern unsigned long obd_memory; -extern unsigned long obd_fail_loc; -extern unsigned long obd_timeout; -extern char obd_recovery_upcall[128]; - -#define OBD_FAIL_MDS 0x100 -#define OBD_FAIL_MDS_HANDLE_UNPACK 0x101 -#define OBD_FAIL_MDS_GETATTR_NET 0x102 -#define OBD_FAIL_MDS_GETATTR_PACK 0x103 -#define OBD_FAIL_MDS_READPAGE_NET 0x104 -#define OBD_FAIL_MDS_READPAGE_PACK 0x105 -#define OBD_FAIL_MDS_SENDPAGE 0x106 -#define OBD_FAIL_MDS_REINT_NET 0x107 -#define OBD_FAIL_MDS_REINT_UNPACK 0x108 -#define OBD_FAIL_MDS_REINT_SETATTR 0x109 -#define OBD_FAIL_MDS_REINT_SETATTR_WRITE 0x10a -#define OBD_FAIL_MDS_REINT_CREATE 0x10b -#define OBD_FAIL_MDS_REINT_CREATE_WRITE 0x10c -#define OBD_FAIL_MDS_REINT_UNLINK 0x10d -#define OBD_FAIL_MDS_REINT_UNLINK_WRITE 0x10e -#define OBD_FAIL_MDS_REINT_LINK 0x10f -#define OBD_FAIL_MDS_REINT_LINK_WRITE 0x110 -#define OBD_FAIL_MDS_REINT_RENAME 0x111 -#define OBD_FAIL_MDS_REINT_RENAME_WRITE 0x112 -#define OBD_FAIL_MDS_OPEN_NET 0x113 -#define OBD_FAIL_MDS_OPEN_PACK 0x114 -#define OBD_FAIL_MDS_CLOSE_NET 0x115 -#define OBD_FAIL_MDS_CLOSE_PACK 0x116 -#define OBD_FAIL_MDS_CONNECT_NET 0x117 -#define OBD_FAIL_MDS_CONNECT_PACK 0x118 -#define OBD_FAIL_MDS_REINT_NET_REP 0x119 -#define OBD_FAIL_MDS_DISCONNECT_NET 0x11a -#define OBD_FAIL_MDS_GETSTATUS_NET 0x11b -#define OBD_FAIL_MDS_GETSTATUS_PACK 0x11c -#define OBD_FAIL_MDS_STATFS_PACK 0x11d -#define OBD_FAIL_MDS_STATFS_NET 0x11e - -#define OBD_FAIL_OST 0x200 -#define OBD_FAIL_OST_CONNECT_NET 0x201 -#define OBD_FAIL_OST_DISCONNECT_NET 0x202 -#define OBD_FAIL_OST_GET_INFO_NET 0x203 -#define OBD_FAIL_OST_CREATE_NET 0x204 -#define OBD_FAIL_OST_DESTROY_NET 0x205 -#define OBD_FAIL_OST_GETATTR_NET 0x206 -#define OBD_FAIL_OST_SETATTR_NET 0x207 -#define OBD_FAIL_OST_OPEN_NET 0x208 -#define OBD_FAIL_OST_CLOSE_NET 0x209 -#define OBD_FAIL_OST_BRW_NET 0x20a -#define OBD_FAIL_OST_PUNCH_NET 0x20b -#define OBD_FAIL_OST_STATFS_NET 0x20c -#define OBD_FAIL_OST_HANDLE_UNPACK 0x20d -#define OBD_FAIL_OST_BRW_WRITE_BULK 0x20e -#define OBD_FAIL_OST_BRW_READ_BULK 0x20f - -#define OBD_FAIL_LDLM 0x300 -#define OBD_FAIL_LDLM_NAMESPACE_NEW 0x301 -#define OBD_FAIL_LDLM_ENQUEUE 0x302 -#define OBD_FAIL_LDLM_CONVERT 0x303 -#define OBD_FAIL_LDLM_CANCEL 0x304 -#define OBD_FAIL_LDLM_BL_CALLBACK 0x305 -#define OBD_FAIL_LDLM_CP_CALLBACK 0x306 - -#define OBD_FAIL_OSC 0x400 -#define OBD_FAIL_OSC_BRW_READ_BULK 0x401 -#define OBD_FAIL_OSC_BRW_WRITE_BULK 0x402 -#define OBD_FAIL_OSC_LOCK_BL_AST 0x403 -#define OBD_FAIL_OSC_LOCK_CP_AST 0x404 - -/* preparation for a more advanced failure testbed (not functional yet) */ -#define OBD_FAIL_MASK_SYS 0x0000FF00 -#define OBD_FAIL_MASK_LOC (0x000000FF | OBD_FAIL_MASK_SYS) -#define OBD_FAIL_ONCE 0x80000000 -#define OBD_FAILED 0x40000000 -#define OBD_FAIL_MDS_ALL_NET 0x01000000 -#define OBD_FAIL_OST_ALL_NET 0x02000000 - -#define OBD_FAIL_CHECK(id) ((obd_fail_loc & OBD_FAIL_MASK_LOC) == (id) && \ - ((obd_fail_loc & (OBD_FAILED | OBD_FAIL_ONCE))!=\ - (OBD_FAILED | OBD_FAIL_ONCE))) - -#define OBD_FAIL_RETURN(id, ret) \ -do { \ - if (OBD_FAIL_CHECK(id)) { \ - CERROR("obd_fail_loc=%x, fail operation rc=%d\n", id, ret); \ - obd_fail_loc |= OBD_FAILED; \ - if ((id) & OBD_FAIL_ONCE) \ - obd_fail_loc |= OBD_FAIL_ONCE; \ - RETURN(ret); \ - } \ -} while(0) - -#include -#include - -#define fixme() CDEBUG(D_OTHER, "FIXME\n"); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#define ll_bdevname(a) __bdevname((a)) -#define ll_lock_kernel lock_kernel() -#else -#define ll_lock_kernel -#define ll_bdevname(a) bdevname((a)) -#endif - -static inline void OBD_FAIL_WRITE(int id, kdev_t dev) -{ - if (OBD_FAIL_CHECK(id)) { -#ifdef CONFIG_DEV_RDONLY - CERROR("obd_fail_loc=%x, fail write operation on %s\n", - id, ll_bdevname(dev)); - dev_set_rdonly(dev, 2); -#else - CERROR("obd_fail_loc=%x, can't fail write operation on %s\n", - id, ll_bdevname(dev)); -#endif - /* We set FAIL_ONCE because we never "un-fail" a device */ - obd_fail_loc |= OBD_FAILED | OBD_FAIL_ONCE; - } -} - -#define OBD_ALLOC(ptr, size) \ -do { \ - void *lptr; \ - long s = (size); \ - (ptr) = lptr = kmalloc(s, GFP_KERNEL); \ - if (lptr == NULL) { \ - CERROR("kmalloc of '" #ptr "' (%ld bytes) failed " \ - "at %s:%d\n", s, __FILE__, __LINE__); \ - } else { \ - memset(lptr, 0, s); \ - obd_memory += s; \ - CDEBUG(D_MALLOC, "kmalloced '" #ptr "': %ld at " \ - "%p (tot %ld).\n", s, lptr, obd_memory); \ - } \ -} while (0) - -#ifdef CONFIG_DEBUG_SLAB -#define POISON(lptr, s) do {} while (0) -#else -#define POISON(lptr, s) memset(lptr, 0xb6, s) -#endif - -#define OBD_FREE(ptr, size) \ -do { \ - void *lptr = (ptr); \ - int s = (size); \ - LASSERT(lptr); \ - POISON(lptr, s); \ - kfree(lptr); \ - obd_memory -= s; \ - CDEBUG(D_MALLOC, "kfreed '" #ptr "': %d at %p (tot %ld).\n", \ - s, lptr, obd_memory); \ - (ptr) = (void *)0xdeadbeef; \ -} while (0) - -#ifdef CONFIG_HIGHMEM -extern void obd_kmap_get(int count, int server); -extern void obd_kmap_put(int count); -#else -#define obd_kmap_get(count, server) do {} while (0) -#define obd_kmap_put(count) do {} while (0) -#endif -#endif diff --git a/lustre/include/linux/obd_trace.h b/lustre/include/linux/obd_trace.h deleted file mode 100644 index 524889d..0000000 --- a/lustre/include/linux/obd_trace.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * obdtrace (header file) - is useful for tracing and performance - * debug of the Lustre obd protocol stack. obdtrace is a transparent - * logical obd driver that prints commands their in- and outbound - * parameters. obdtrace maintains statistics about number and latency - * of the obd commands that pass through it. As such it is also use - * for performance analysis. - * - * Copyright (c) 2001 Rumi Zahir - */ - -#ifndef __OBD_TRACE_H -#define __OBD_TRACE_H - -#include - -#endif diff --git a/lustre/install-sh b/lustre/install-sh deleted file mode 100755 index e9de238..0000000 --- a/lustre/install-sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/lustre/ldlm/.cvsignore b/lustre/ldlm/.cvsignore deleted file mode 100644 index e995588..0000000 --- a/lustre/ldlm/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.deps -Makefile -Makefile.in diff --git a/lustre/ldlm/Makefile.am b/lustre/ldlm/Makefile.am deleted file mode 100644 index ed5051a..0000000 --- a/lustre/ldlm/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= -MODULE = ldlm -modulefs_DATA = ldlm.o -EXTRA_PROGRAMS = ldlm - -ldlm_SOURCES = l_lock.c ldlm_lock.c ldlm_resource.c ldlm_test.c ldlm_lockd.c \ -ldlm_extent.c ldlm_request.c - -include $(top_srcdir)/Rules - diff --git a/lustre/ldlm/l_lock.c b/lustre/ldlm/l_lock.c deleted file mode 100644 index 680d4f0..0000000 --- a/lustre/ldlm/l_lock.c +++ /dev/null @@ -1,108 +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.sf.net/projects/lustre/ - * - * 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 -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_LDLM - -#include -#include - -/* invariants: - - only the owner of the lock changes l_owner/l_depth - - if a non-owner changes or checks the variables a spin lock is taken -*/ - -void l_lock_init(struct lustre_lock *lock) -{ - sema_init(&lock->l_sem, 1); - spin_lock_init(&lock->l_spin); -} - -void l_lock(struct lustre_lock *lock) -{ - int owner = 0; - - spin_lock(&lock->l_spin); - if (lock->l_owner == current) - owner = 1; - spin_unlock(&lock->l_spin); - - if (owner) { - ++lock->l_depth; - } else { - down(&lock->l_sem); - spin_lock(&lock->l_spin); - lock->l_owner = current; - lock->l_depth = 0; - spin_unlock(&lock->l_spin); - } -} - -void l_unlock(struct lustre_lock *lock) -{ - LASSERT(lock->l_owner == current); - LASSERT(lock->l_depth >= 0); - - spin_lock(&lock->l_spin); - if (--lock->l_depth < 0) { - lock->l_owner = NULL; - spin_unlock(&lock->l_spin); - up(&lock->l_sem); - return; - } - spin_unlock(&lock->l_spin); -} - -int l_has_lock(struct lustre_lock *lock) -{ - int depth = -1, owner = 0; - - spin_lock(&lock->l_spin); - if (lock->l_owner == current) { - depth = lock->l_depth; - owner = 1; - } - spin_unlock(&lock->l_spin); - - if (depth >= 0) - CDEBUG(D_INFO, "lock_depth: %d\n", depth); - return owner; -} diff --git a/lustre/ldlm/ldlm_extent.c b/lustre/ldlm/ldlm_extent.c deleted file mode 100644 index 468eb2b..0000000 --- a/lustre/ldlm/ldlm_extent.c +++ /dev/null @@ -1,97 +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 code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * by Cluster File Systems, Inc. - * authors, Peter Braam & - * Phil Schwan - */ - -#define DEBUG_SUBSYSTEM S_LDLM - -#include - -/* This function will be called to judge if the granted queue of another child - * (read: another extent) is conflicting and needs its granted queue walked to - * issue callbacks. - * - * This helps to find conflicts between read and write locks on overlapping - * extents. */ -int ldlm_extent_compat(struct ldlm_lock *a, struct ldlm_lock *b) -{ - if (MAX(a->l_extent.start, b->l_extent.start) <= - MIN(a->l_extent.end, b->l_extent.end)) - RETURN(0); - - RETURN(1); -} - -/* The purpose of this function is to return: - * - the maximum extent - * - containing the requested extent - * - and not overlapping existing extents outside the requested one - * - * An alternative policy is to not shrink the new extent when conflicts exist. - * - * To reconstruct our formulas, take a deep breath. */ -static void policy_internal(struct list_head *queue, struct ldlm_extent *req_ex, - struct ldlm_extent *new_ex, ldlm_mode_t mode) -{ - struct list_head *tmp; - - list_for_each(tmp, queue) { - struct ldlm_lock *lock; - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - - if (lock->l_extent.end < req_ex->start) - new_ex->start = MIN(lock->l_extent.end, new_ex->start); - else { - if (lock->l_extent.start < req_ex->start && - !lockmode_compat(lock->l_req_mode, mode)) - /* Policy: minimize conflict overlap */ - new_ex->start = req_ex->start; - } - if (lock->l_extent.start > req_ex->end) - new_ex->end = MAX(lock->l_extent.start, new_ex->end); - else { - if (lock->l_extent.end > req_ex->end && - !lockmode_compat(lock->l_req_mode, mode)) - /* Policy: minimize conflict overlap */ - new_ex->end = req_ex->end; - } - } -} - -/* apply the internal policy by walking all the lists */ -int ldlm_extent_policy(struct ldlm_lock *lock, void *req_cookie, - ldlm_mode_t mode, int flags, void *data) -{ - struct ldlm_resource *res = lock->l_resource; - struct ldlm_extent *req_ex = req_cookie; - struct ldlm_extent new_ex; - new_ex.start = 0; - new_ex.end = ~0; - - if (!res) - LBUG(); - - l_lock(&res->lr_namespace->ns_lock); - policy_internal(&res->lr_granted, req_ex, &new_ex, mode); - policy_internal(&res->lr_converting, req_ex, &new_ex, mode); - policy_internal(&res->lr_waiting, req_ex, &new_ex, mode); - l_unlock(&res->lr_namespace->ns_lock); - - memcpy(&lock->l_extent, &new_ex, sizeof(new_ex)); - - LDLM_DEBUG(lock, "new extent "LPU64" -> "LPU64, new_ex.start, - new_ex.end); - - if (new_ex.end != req_ex->end || new_ex.start != req_ex->start) - return ELDLM_LOCK_CHANGED; - else - return 0; -} diff --git a/lustre/ldlm/ldlm_lock.c b/lustre/ldlm/ldlm_lock.c deleted file mode 100644 index 83a6661..0000000 --- a/lustre/ldlm/ldlm_lock.c +++ /dev/null @@ -1,1061 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002 Cluster File Systems, Inc. - * Author: Peter Braam - * Author: Phil Schwan - * - * 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_LDLM - -#include -#include -#include -#include -#include -#include - -//struct lustre_lock ldlm_everything_lock; - -/* lock types */ -char *ldlm_lockname[] = { - [0] "--", - [LCK_EX] "EX", - [LCK_PW] "PW", - [LCK_PR] "PR", - [LCK_CW] "CW", - [LCK_CR] "CR", - [LCK_NL] "NL" -}; -char *ldlm_typename[] = { - [LDLM_PLAIN] "PLN", - [LDLM_EXTENT] "EXT", -}; - -char *ldlm_it2str(int it) -{ - switch (it) { - case IT_OPEN: - return "open"; - case IT_CREAT: - return "creat"; - case (IT_OPEN | IT_CREAT): - return "open|creat"; - case IT_MKDIR: - return "mkdir"; - case IT_LINK: - return "link"; - case IT_LINK2: - return "link2"; - case IT_SYMLINK: - return "symlink"; - case IT_UNLINK: - return "unlink"; - case IT_RMDIR: - return "rmdir"; - case IT_RENAME: - return "rename"; - case IT_RENAME2: - return "rename2"; - case IT_READDIR: - return "readdir"; - case IT_GETATTR: - return "getattr"; - case IT_SETATTR: - return "setattr"; - case IT_READLINK: - return "readlink"; - case IT_MKNOD: - return "mknod"; - case IT_LOOKUP: - return "lookup"; - default: - CERROR("Unknown intent %d\n", it); - return "UNKNOWN"; - } -} - -extern kmem_cache_t *ldlm_lock_slab; -struct lustre_lock ldlm_handle_lock; - -static int ldlm_plain_compat(struct ldlm_lock *a, struct ldlm_lock *b); - -ldlm_res_compat ldlm_res_compat_table[] = { - [LDLM_PLAIN] ldlm_plain_compat, - [LDLM_EXTENT] ldlm_extent_compat, -}; - -static ldlm_res_policy ldlm_intent_policy_func; - -static int ldlm_plain_policy(struct ldlm_lock *lock, void *req_cookie, - ldlm_mode_t mode, int flags, void *data) -{ - if ((flags & LDLM_FL_HAS_INTENT) && ldlm_intent_policy_func) { - return ldlm_intent_policy_func(lock, req_cookie, mode, flags, - data); - } - - return ELDLM_OK; -} - -ldlm_res_policy ldlm_res_policy_table[] = { - [LDLM_PLAIN] ldlm_plain_policy, - [LDLM_EXTENT] ldlm_extent_policy, -}; - -void ldlm_register_intent(ldlm_res_policy arg) -{ - ldlm_intent_policy_func = arg; -} - -void ldlm_unregister_intent(void) -{ - ldlm_intent_policy_func = NULL; -} - -/* - * REFCOUNTED LOCK OBJECTS - */ - - -/* - * Lock refcounts, during creation: - * - one special one for allocation, dec'd only once in destroy - * - one for being a lock that's in-use - * - one for the addref associated with a new lock - */ -struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock) -{ - l_lock(&lock->l_resource->lr_namespace->ns_lock); - atomic_inc(&lock->l_refc); - ldlm_resource_getref(lock->l_resource); - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - return lock; -} - -void ldlm_lock_put(struct ldlm_lock *lock) -{ - struct ldlm_namespace *ns = lock->l_resource->lr_namespace; - ENTRY; - - l_lock(&ns->ns_lock); - atomic_dec(&lock->l_refc); - LASSERT(atomic_read(&lock->l_refc) >= 0); - - if (ldlm_resource_putref(lock->l_resource)) { - LASSERT(atomic_read(&lock->l_refc) == 0); - lock->l_resource = NULL; - } - if (lock->l_parent) - LDLM_LOCK_PUT(lock->l_parent); - - if (atomic_read(&lock->l_refc) == 0) { - LASSERT(lock->l_destroyed); - l_unlock(&ns->ns_lock); - LDLM_DEBUG(lock, "final lock_put on destroyed lock, freeing"); - - spin_lock(&ns->ns_counter_lock); - ns->ns_locks--; - spin_unlock(&ns->ns_counter_lock); - - lock->l_resource = NULL; - lock->l_random = DEAD_HANDLE_MAGIC; - if (lock->l_export && lock->l_export->exp_connection) - ptlrpc_put_connection(lock->l_export->exp_connection); - memset(lock, 0x5a, sizeof(*lock)); - kmem_cache_free(ldlm_lock_slab, lock); - CDEBUG(D_MALLOC, "kfreed 'lock': %d at %p (tot 0).\n", - sizeof(*lock), lock); - } else - l_unlock(&ns->ns_lock); - - EXIT; -} - -void ldlm_lock_remove_from_lru(struct ldlm_lock *lock) -{ - ENTRY; - l_lock(&lock->l_resource->lr_namespace->ns_lock); - if (!list_empty(&lock->l_lru)) { - list_del_init(&lock->l_lru); - lock->l_resource->lr_namespace->ns_nr_unused--; - LASSERT(lock->l_resource->lr_namespace->ns_nr_unused >= 0); - } - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - EXIT; -} - -void ldlm_lock_destroy(struct ldlm_lock *lock) -{ - ENTRY; - l_lock(&lock->l_resource->lr_namespace->ns_lock); - - if (!list_empty(&lock->l_children)) { - LDLM_DEBUG(lock, "still has children (%p)!", - lock->l_children.next); - ldlm_lock_dump(lock); - LBUG(); - } - if (lock->l_readers || lock->l_writers) { - LDLM_DEBUG(lock, "lock still has references"); - ldlm_lock_dump(lock); - } - - if (!list_empty(&lock->l_res_link)) { - ldlm_lock_dump(lock); - LBUG(); - } - - if (lock->l_destroyed) { - LASSERT(list_empty(&lock->l_lru)); - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - EXIT; - return; - } - lock->l_destroyed = 1; - - list_del(&lock->l_export_chain); - lock->l_export = NULL; - ldlm_lock_remove_from_lru(lock); - - /* Wake anyone waiting for this lock */ - /* FIXME: I should probably add yet another flag, instead of using - * l_export to only call this on clients */ - if (lock->l_export && lock->l_completion_ast) - lock->l_completion_ast(lock, 0); - - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - LDLM_LOCK_PUT(lock); - EXIT; -} - -/* - usage: pass in a resource on which you have done get - pass in a parent lock on which you have done a get - do not put the resource or the parent - returns: lock with refcount 1 -*/ -static struct ldlm_lock *ldlm_lock_new(struct ldlm_lock *parent, - struct ldlm_resource *resource) -{ - struct ldlm_lock *lock; - ENTRY; - - if (resource == NULL) - LBUG(); - - lock = kmem_cache_alloc(ldlm_lock_slab, SLAB_KERNEL); - if (lock == NULL) - RETURN(NULL); - - memset(lock, 0, sizeof(*lock)); - get_random_bytes(&lock->l_random, sizeof(__u64)); - - lock->l_resource = resource; - /* this refcount matches the one of the resource passed - in which is not being put away */ - atomic_set(&lock->l_refc, 1); - INIT_LIST_HEAD(&lock->l_children); - INIT_LIST_HEAD(&lock->l_res_link); - INIT_LIST_HEAD(&lock->l_lru); - INIT_LIST_HEAD(&lock->l_export_chain); - INIT_LIST_HEAD(&lock->l_pending_chain); - init_waitqueue_head(&lock->l_waitq); - - spin_lock(&resource->lr_namespace->ns_counter_lock); - resource->lr_namespace->ns_locks++; - spin_unlock(&resource->lr_namespace->ns_counter_lock); - - if (parent != NULL) { - l_lock(&parent->l_resource->lr_namespace->ns_lock); - lock->l_parent = parent; - list_add(&lock->l_childof, &parent->l_children); - l_unlock(&parent->l_resource->lr_namespace->ns_lock); - } - - CDEBUG(D_MALLOC, "kmalloced 'lock': %d at " - "%p (tot %d).\n", sizeof(*lock), lock, 1); - /* this is the extra refcount, to prevent the lock from evaporating */ - LDLM_LOCK_GET(lock); - RETURN(lock); -} - -int ldlm_lock_change_resource(struct ldlm_lock *lock, __u64 new_resid[3]) -{ - struct ldlm_namespace *ns = lock->l_resource->lr_namespace; - struct ldlm_resource *oldres = lock->l_resource; - int i, refc; - ENTRY; - - l_lock(&ns->ns_lock); - if (memcmp(new_resid, lock->l_resource->lr_name, - sizeof(lock->l_resource->lr_name)) == 0) { - /* Nothing to do */ - l_unlock(&ns->ns_lock); - RETURN(0); - } - - LASSERT(new_resid[0] != 0); - - /* This function assumes that the lock isn't on any lists */ - LASSERT(list_empty(&lock->l_res_link)); - - lock->l_resource = ldlm_resource_get(ns, NULL, new_resid, - lock->l_resource->lr_type, 1); - if (lock->l_resource == NULL) { - LBUG(); - RETURN(-ENOMEM); - } - - /* move references over */ - refc = atomic_read(&lock->l_refc); - for (i = 0; i < refc; i++) { - int rc; - ldlm_resource_getref(lock->l_resource); - rc = ldlm_resource_putref(oldres); - if (rc == 1 && i != refc - 1) - LBUG(); - } - /* compensate for the initial get above.. */ - ldlm_resource_putref(lock->l_resource); - - l_unlock(&ns->ns_lock); - RETURN(0); -} - -/* - * HANDLES - */ - -void ldlm_lock2handle(struct ldlm_lock *lock, struct lustre_handle *lockh) -{ - lockh->addr = (__u64) (unsigned long)lock; - lockh->cookie = lock->l_random; -} - -/* - * if flags: atomically get the lock and set the flags. - * Return NULL if flag already set - */ - -struct ldlm_lock *__ldlm_handle2lock(struct lustre_handle *handle, int strict, - int flags) -{ - struct ldlm_lock *lock = NULL, *retval = NULL; - ENTRY; - - LASSERT(handle); - - if (!handle->addr) - RETURN(NULL); - - lock = (struct ldlm_lock *)(unsigned long)(handle->addr); - if (!kmem_cache_validate(ldlm_lock_slab, (void *)lock)) { - //CERROR("bogus lock %p\n", lock); - GOTO(out2, retval); - } - - if (lock->l_random != handle->cookie) { - //CERROR("bogus cookie: lock %p has "LPX64" vs. handle "LPX64 - // "\n", lock, lock->l_random, handle->cookie); - GOTO(out2, NULL); - } - if (!lock->l_resource) { - CERROR("trying to lock bogus resource: lock %p\n", lock); - //LDLM_DEBUG(lock, "ldlm_handle2lock(%p)", lock); - GOTO(out2, retval); - } - if (!lock->l_resource->lr_namespace) { - CERROR("trying to lock bogus namespace: lock %p\n", lock); - //LDLM_DEBUG(lock, "ldlm_handle2lock(%p)", lock); - GOTO(out2, retval); - } - - l_lock(&lock->l_resource->lr_namespace->ns_lock); - if (strict && lock->l_destroyed) { - CERROR("lock already destroyed: lock %p\n", lock); - //LDLM_DEBUG(lock, "ldlm_handle2lock(%p)", lock); - GOTO(out, NULL); - } - - if (flags && (lock->l_flags & flags)) - GOTO(out, NULL); - - if (flags) - lock->l_flags |= flags; - - retval = LDLM_LOCK_GET(lock); - if (!retval) - CERROR("lock disappeared below us!!! %p\n", lock); - EXIT; - out: - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - out2: - return retval; -} - -static int ldlm_plain_compat(struct ldlm_lock *a, struct ldlm_lock *b) -{ - return lockmode_compat(a->l_req_mode, b->l_req_mode); -} - -void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc) -{ - ldlm_res2desc(lock->l_resource, &desc->l_resource); - desc->l_req_mode = lock->l_req_mode; - desc->l_granted_mode = lock->l_granted_mode; - memcpy(&desc->l_extent, &lock->l_extent, sizeof(desc->l_extent)); - memcpy(desc->l_version, lock->l_version, sizeof(desc->l_version)); -} - -static void ldlm_add_ast_work_item(struct ldlm_lock *lock, - struct ldlm_lock *new) -{ - struct ldlm_ast_work *w; - ENTRY; - - l_lock(&lock->l_resource->lr_namespace->ns_lock); - if (new && (lock->l_flags & LDLM_FL_AST_SENT)) - GOTO(out, 0); - - OBD_ALLOC(w, sizeof(*w)); - if (!w) { - LBUG(); - GOTO(out, 0); - } - - if (new) { - lock->l_flags |= LDLM_FL_AST_SENT; - w->w_blocking = 1; - ldlm_lock2desc(new, &w->w_desc); - } - - w->w_lock = LDLM_LOCK_GET(lock); - list_add(&w->w_list, lock->l_resource->lr_tmp); - out: - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - return; -} - -void ldlm_lock_addref(struct lustre_handle *lockh, __u32 mode) -{ - struct ldlm_lock *lock; - - lock = ldlm_handle2lock(lockh); - ldlm_lock_addref_internal(lock, mode); - LDLM_LOCK_PUT(lock); -} - -/* only called for local locks */ -void ldlm_lock_addref_internal(struct ldlm_lock *lock, __u32 mode) -{ - l_lock(&lock->l_resource->lr_namespace->ns_lock); - ldlm_lock_remove_from_lru(lock); - if (mode == LCK_NL || mode == LCK_CR || mode == LCK_PR) - lock->l_readers++; - else - lock->l_writers++; - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - LDLM_LOCK_GET(lock); - LDLM_DEBUG(lock, "ldlm_lock_addref(%s)", ldlm_lockname[mode]); -} - -/* Args: unlocked lock */ -int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns, - __u64 *res_id, int flags); - -void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode) -{ - struct ldlm_lock *lock = __ldlm_handle2lock(lockh, 0, 0); - struct ldlm_namespace *ns; - ENTRY; - - if (lock == NULL) - LBUG(); - - LDLM_DEBUG(lock, "ldlm_lock_decref(%s)", ldlm_lockname[mode]); - ns = lock->l_resource->lr_namespace; - l_lock(&lock->l_resource->lr_namespace->ns_lock); - if (mode == LCK_NL || mode == LCK_CR || mode == LCK_PR) - lock->l_readers--; - else - lock->l_writers--; - - /* If we received a blocked AST and this was the last reference, - * run the callback. */ - if (!lock->l_readers && !lock->l_writers && - (lock->l_flags & LDLM_FL_CBPENDING)) { - if (!lock->l_resource->lr_namespace->ns_client && - lock->l_export) - CERROR("FL_CBPENDING set on non-local lock--just a " - "warning\n"); - - LDLM_DEBUG(lock, "final decref done on cbpending lock"); - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - - /* FIXME: need a real 'desc' here */ - lock->l_blocking_ast(lock, NULL, lock->l_data, - lock->l_data_len, LDLM_CB_BLOCKING); - } else if (ns->ns_client && !lock->l_readers && !lock->l_writers) { - LASSERT(list_empty(&lock->l_lru)); - LASSERT(ns->ns_nr_unused >= 0); - list_add_tail(&lock->l_lru, &ns->ns_unused_list); - ns->ns_nr_unused++; - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - ldlm_cancel_lru(ns); - } else - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - - LDLM_LOCK_PUT(lock); /* matches the ldlm_lock_get in addref */ - LDLM_LOCK_PUT(lock); /* matches the handle2lock above */ - - EXIT; -} - -static int ldlm_lock_compat_list(struct ldlm_lock *lock, int send_cbs, - struct list_head *queue) -{ - struct list_head *tmp, *pos; - int rc = 1; - - list_for_each_safe(tmp, pos, queue) { - struct ldlm_lock *child; - ldlm_res_compat compat; - - child = list_entry(tmp, struct ldlm_lock, l_res_link); - if (lock == child) - continue; - - compat = ldlm_res_compat_table[child->l_resource->lr_type]; - if (compat && compat(child, lock)) { - CDEBUG(D_OTHER, "compat function succeded, next.\n"); - continue; - } - if (lockmode_compat(child->l_granted_mode, lock->l_req_mode)) { - CDEBUG(D_OTHER, "lock modes are compatible, next.\n"); - continue; - } - - rc = 0; - - if (send_cbs && child->l_blocking_ast != NULL) { - CDEBUG(D_OTHER, "lock %p incompatible; sending " - "blocking AST.\n", child); - ldlm_add_ast_work_item(child, lock); - } - } - - return rc; -} - -static int ldlm_lock_compat(struct ldlm_lock *lock, int send_cbs) -{ - int rc; - ENTRY; - - l_lock(&lock->l_resource->lr_namespace->ns_lock); - rc = ldlm_lock_compat_list(lock, send_cbs, - &lock->l_resource->lr_granted); - /* FIXME: should we be sending ASTs to converting? */ - if (rc) - rc = ldlm_lock_compat_list - (lock, send_cbs, &lock->l_resource->lr_converting); - - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - RETURN(rc); -} - -/* NOTE: called by - - ldlm_handle_enqueuque - resource -*/ -void ldlm_grant_lock(struct ldlm_lock *lock) -{ - struct ldlm_resource *res = lock->l_resource; - ENTRY; - - l_lock(&lock->l_resource->lr_namespace->ns_lock); - ldlm_resource_add_lock(res, &res->lr_granted, lock); - lock->l_granted_mode = lock->l_req_mode; - - if (lock->l_granted_mode < res->lr_most_restr) - res->lr_most_restr = lock->l_granted_mode; - - if (lock->l_completion_ast) { - ldlm_add_ast_work_item(lock, NULL); - } - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - EXIT; -} - -/* returns a referenced lock or NULL */ -static struct ldlm_lock *search_queue(struct list_head *queue, ldlm_mode_t mode, - struct ldlm_extent *extent, - struct ldlm_lock *old_lock) -{ - struct ldlm_lock *lock; - struct list_head *tmp; - - list_for_each(tmp, queue) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - - if (lock == old_lock) - continue; - - if (lock->l_flags & LDLM_FL_CBPENDING) - continue; - - if (lock->l_req_mode != mode) - continue; - - if (lock->l_resource->lr_type == LDLM_EXTENT && - (lock->l_extent.start > extent->start || - lock->l_extent.end < extent->end)) - continue; - - if (lock->l_destroyed) - continue; - - ldlm_lock_addref_internal(lock, mode); - return lock; - } - - return NULL; -} - -/* Can be called in two ways: - * - * If 'ns' is NULL, then lockh describes an existing lock that we want to look - * for a duplicate of. - * - * Otherwise, all of the fields must be filled in, to match against. - * - * Returns 1 if it finds an already-existing lock that is compatible; in this - * case, lockh is filled in with a addref()ed lock - */ -int ldlm_lock_match(struct ldlm_namespace *ns, __u64 *res_id, __u32 type, - void *cookie, int cookielen, ldlm_mode_t mode, - struct lustre_handle *lockh) -{ - struct ldlm_resource *res; - struct ldlm_lock *lock, *old_lock = NULL; - int rc = 0; - ENTRY; - - if (ns == NULL) { - old_lock = ldlm_handle2lock(lockh); - LASSERT(old_lock); - - ns = old_lock->l_resource->lr_namespace; - res_id = old_lock->l_resource->lr_name; - type = old_lock->l_resource->lr_type; - mode = old_lock->l_req_mode; - } - - res = ldlm_resource_get(ns, NULL, res_id, type, 0); - if (res == NULL) { - LASSERT(old_lock == NULL); - RETURN(0); - } - - l_lock(&ns->ns_lock); - - if ((lock = search_queue(&res->lr_granted, mode, cookie, old_lock))) - GOTO(out, rc = 1); - if ((lock = search_queue(&res->lr_converting, mode, cookie, old_lock))) - GOTO(out, rc = 1); - if ((lock = search_queue(&res->lr_waiting, mode, cookie, old_lock))) - GOTO(out, rc = 1); - - EXIT; - out: - ldlm_resource_putref(res); - l_unlock(&ns->ns_lock); - - if (lock) { - ldlm_lock2handle(lock, lockh); - if (lock->l_completion_ast) - lock->l_completion_ast(lock, LDLM_FL_WAIT_NOREPROC); - } - if (rc) - LDLM_DEBUG(lock, "matched"); - else - LDLM_DEBUG_NOLOCK("not matched"); - - if (old_lock) - LDLM_LOCK_PUT(old_lock); - - return rc; -} - -/* Returns a referenced lock */ -struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns, - struct lustre_handle *parent_lock_handle, - __u64 * res_id, __u32 type, - ldlm_mode_t mode, void *data, __u32 data_len) -{ - struct ldlm_resource *res, *parent_res = NULL; - struct ldlm_lock *lock, *parent_lock = NULL; - - if (parent_lock_handle) { - parent_lock = ldlm_handle2lock(parent_lock_handle); - if (parent_lock) - parent_res = parent_lock->l_resource; - } - - res = ldlm_resource_get(ns, parent_res, res_id, type, 1); - if (res == NULL) - RETURN(NULL); - - lock = ldlm_lock_new(parent_lock, res); - if (lock == NULL) { - ldlm_resource_putref(res); - RETURN(NULL); - } - - lock->l_req_mode = mode; - lock->l_data = data; - lock->l_data_len = data_len; - - return lock; -} - -/* Must be called with lock->l_lock and lock->l_resource->lr_lock not held */ -ldlm_error_t ldlm_lock_enqueue(struct ldlm_lock * lock, - void *cookie, int cookie_len, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback blocking) -{ - struct ldlm_resource *res; - int local; - ldlm_res_policy policy; - ENTRY; - - res = lock->l_resource; - lock->l_blocking_ast = blocking; - - if (res->lr_type == LDLM_EXTENT) - memcpy(&lock->l_extent, cookie, sizeof(lock->l_extent)); - - /* policies are not executed on the client or during replay */ - local = res->lr_namespace->ns_client; - if (!local && !(*flags & LDLM_FL_REPLAY) && - (policy = ldlm_res_policy_table[res->lr_type])) { - int rc; - rc = policy(lock, cookie, lock->l_req_mode, *flags, NULL); - - if (rc == ELDLM_LOCK_CHANGED) { - res = lock->l_resource; - *flags |= LDLM_FL_LOCK_CHANGED; - } else if (rc == ELDLM_LOCK_ABORTED) { - ldlm_lock_destroy(lock); - RETURN(rc); - } - } - - l_lock(&res->lr_namespace->ns_lock); - if (local && lock->l_req_mode == lock->l_granted_mode) { - /* The server returned a blocked lock, but it was granted before - * we got a chance to actually enqueue it. We don't need to do - * anything else. */ - *flags &= ~(LDLM_FL_BLOCK_GRANTED | - LDLM_FL_BLOCK_CONV | LDLM_FL_BLOCK_WAIT); - GOTO(out, ELDLM_OK); - } - - /* This distinction between local lock trees is very important; a client - * namespace only has information about locks taken by that client, and - * thus doesn't have enough information to decide for itself if it can - * be granted (below). In this case, we do exactly what the server - * tells us to do, as dictated by the 'flags'. - * - * We do exactly the same thing during recovery, when the server is - * more or less trusting the clients not to lie. - * - * FIXME (bug 629283): Detect obvious lies by checking compatibility in - * granted/converting queues. */ - ldlm_resource_unlink_lock(lock); - if (local || (*flags & LDLM_FL_REPLAY)) { - if (*flags & LDLM_FL_BLOCK_CONV) - ldlm_resource_add_lock(res, res->lr_converting.prev, - lock); - else if (*flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED)) - ldlm_resource_add_lock(res, res->lr_waiting.prev, lock); - else - ldlm_grant_lock(lock); - GOTO(out, ELDLM_OK); - } - - /* FIXME: We may want to optimize by checking lr_most_restr */ - if (!list_empty(&res->lr_converting)) { - ldlm_resource_add_lock(res, res->lr_waiting.prev, lock); - *flags |= LDLM_FL_BLOCK_CONV; - GOTO(out, ELDLM_OK); - } - if (!list_empty(&res->lr_waiting)) { - ldlm_resource_add_lock(res, res->lr_waiting.prev, lock); - *flags |= LDLM_FL_BLOCK_WAIT; - GOTO(out, ELDLM_OK); - } - if (!ldlm_lock_compat(lock, 0)) { - ldlm_resource_add_lock(res, res->lr_waiting.prev, lock); - *flags |= LDLM_FL_BLOCK_GRANTED; - GOTO(out, ELDLM_OK); - } - - ldlm_grant_lock(lock); - EXIT; - out: - l_unlock(&res->lr_namespace->ns_lock); - /* Don't set 'completion_ast' until here so that if the lock is granted - * immediately we don't do an unnecessary completion call. */ - lock->l_completion_ast = completion; - return ELDLM_OK; -} - -/* Must be called with namespace taken: queue is waiting or converting. */ -static int ldlm_reprocess_queue(struct ldlm_resource *res, - struct list_head *queue) -{ - struct list_head *tmp, *pos; - ENTRY; - - list_for_each_safe(tmp, pos, queue) { - struct ldlm_lock *pending; - pending = list_entry(tmp, struct ldlm_lock, l_res_link); - - CDEBUG(D_INFO, "Reprocessing lock %p\n", pending); - - if (!ldlm_lock_compat(pending, 1)) - RETURN(1); - - list_del_init(&pending->l_res_link); - ldlm_grant_lock(pending); - } - - RETURN(0); -} - -void ldlm_run_ast_work(struct list_head *rpc_list) -{ - struct list_head *tmp, *pos; - int rc; - ENTRY; - - list_for_each_safe(tmp, pos, rpc_list) { - struct ldlm_ast_work *w = - list_entry(tmp, struct ldlm_ast_work, w_list); - - if (w->w_blocking) - rc = w->w_lock->l_blocking_ast - (w->w_lock, &w->w_desc, w->w_data, - w->w_datalen, LDLM_CB_BLOCKING); - else - rc = w->w_lock->l_completion_ast(w->w_lock, w->w_flags); - if (rc) - CERROR("Failed AST - should clean & disconnect " - "client\n"); - LDLM_LOCK_PUT(w->w_lock); - list_del(&w->w_list); - OBD_FREE(w, sizeof(*w)); - } - EXIT; -} - -/* Must be called with resource->lr_lock not taken. */ -void ldlm_reprocess_all(struct ldlm_resource *res) -{ - struct list_head rpc_list = LIST_HEAD_INIT(rpc_list); - ENTRY; - - /* Local lock trees don't get reprocessed. */ - if (res->lr_namespace->ns_client) { - EXIT; - return; - } - - l_lock(&res->lr_namespace->ns_lock); - res->lr_tmp = &rpc_list; - - ldlm_reprocess_queue(res, &res->lr_converting); - if (list_empty(&res->lr_converting)) - ldlm_reprocess_queue(res, &res->lr_waiting); - - res->lr_tmp = NULL; - l_unlock(&res->lr_namespace->ns_lock); - - ldlm_run_ast_work(&rpc_list); - EXIT; -} - -void ldlm_cancel_callback(struct ldlm_lock *lock) -{ - l_lock(&lock->l_resource->lr_namespace->ns_lock); - if (!(lock->l_flags & LDLM_FL_CANCEL)) { - lock->l_flags |= LDLM_FL_CANCEL; - if (lock->l_blocking_ast) - lock->l_blocking_ast(lock, NULL, lock->l_data, - lock->l_data_len, - LDLM_CB_CANCELING); - else - LDLM_DEBUG(lock, "no blocking ast"); - } - l_unlock(&lock->l_resource->lr_namespace->ns_lock); -} - -void ldlm_lock_cancel(struct ldlm_lock *lock) -{ - struct ldlm_resource *res; - struct ldlm_namespace *ns; - ENTRY; - - res = lock->l_resource; - ns = res->lr_namespace; - - l_lock(&ns->ns_lock); - if (lock->l_readers || lock->l_writers) - LDLM_DEBUG(lock, "lock still has references"); - - ldlm_cancel_callback(lock); - - ldlm_del_waiting_lock(lock); - ldlm_resource_unlink_lock(lock); - ldlm_lock_destroy(lock); - l_unlock(&ns->ns_lock); - EXIT; -} - -int ldlm_lock_set_data(struct lustre_handle *lockh, void *data, int datalen) -{ - struct ldlm_lock *lock = ldlm_handle2lock(lockh); - ENTRY; - - if (lock == NULL) - RETURN(-EINVAL); - - lock->l_data = data; - lock->l_data_len = datalen; - - LDLM_LOCK_PUT(lock); - - RETURN(0); -} - -void ldlm_cancel_locks_for_export(struct obd_export *exp) -{ - struct list_head *iter, *n; /* MUST BE CALLED "n"! */ - - list_for_each_safe(iter, n, &exp->exp_ldlm_data.led_held_locks) { - struct ldlm_lock *lock; - struct ldlm_resource *res; - lock = list_entry(iter, struct ldlm_lock, l_export_chain); - res = ldlm_resource_getref(lock->l_resource); - LDLM_DEBUG(lock, "export %p", exp); - ldlm_lock_cancel(lock); - ldlm_reprocess_all(res); - ldlm_resource_putref(res); - } -} - -struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode, - int *flags) -{ - struct list_head rpc_list = LIST_HEAD_INIT(rpc_list); - struct ldlm_resource *res; - struct ldlm_namespace *ns; - int granted = 0; - ENTRY; - - res = lock->l_resource; - ns = res->lr_namespace; - - l_lock(&ns->ns_lock); - - lock->l_req_mode = new_mode; - ldlm_resource_unlink_lock(lock); - - /* If this is a local resource, put it on the appropriate list. */ - if (res->lr_namespace->ns_client) { - if (*flags & (LDLM_FL_BLOCK_CONV | LDLM_FL_BLOCK_GRANTED)) - ldlm_resource_add_lock(res, res->lr_converting.prev, - lock); - else { - /* This should never happen, because of the way the - * server handles conversions. */ - LBUG(); - - res->lr_tmp = &rpc_list; - ldlm_grant_lock(lock); - res->lr_tmp = NULL; - granted = 1; - /* FIXME: completion handling not with ns_lock held ! */ - if (lock->l_completion_ast) - lock->l_completion_ast(lock, 0); - } - } else { - /* FIXME: We should try the conversion right away and possibly - * return success without the need for an extra AST */ - ldlm_resource_add_lock(res, res->lr_converting.prev, lock); - *flags |= LDLM_FL_BLOCK_CONV; - } - - l_unlock(&ns->ns_lock); - - if (granted) - ldlm_run_ast_work(&rpc_list); - RETURN(res); -} - -void ldlm_lock_dump(struct ldlm_lock *lock) -{ - char ver[128]; - - if (!(portal_debug & D_OTHER)) - return; - - if (RES_VERSION_SIZE != 4) - LBUG(); - - if (!lock) { - CDEBUG(D_OTHER, " NULL LDLM lock\n"); - return; - } - - snprintf(ver, sizeof(ver), "%x %x %x %x", - lock->l_version[0], lock->l_version[1], - lock->l_version[2], lock->l_version[3]); - - CDEBUG(D_OTHER, " -- Lock dump: %p (%s)\n", lock, ver); - if (lock->l_export && lock->l_export->exp_connection) - CDEBUG(D_OTHER, " Node: NID %x (rhandle: "LPX64")\n", - lock->l_export->exp_connection->c_peer.peer_nid, - lock->l_remote_handle.addr); - else - CDEBUG(D_OTHER, " Node: local\n"); - CDEBUG(D_OTHER, " Parent: %p\n", lock->l_parent); - CDEBUG(D_OTHER, " Resource: %p ("LPD64")\n", lock->l_resource, - lock->l_resource->lr_name[0]); - CDEBUG(D_OTHER, " Requested mode: %d, granted mode: %d\n", - (int)lock->l_req_mode, (int)lock->l_granted_mode); - CDEBUG(D_OTHER, " Readers: %u ; Writers; %u\n", - lock->l_readers, lock->l_writers); - if (lock->l_resource->lr_type == LDLM_EXTENT) - CDEBUG(D_OTHER, " Extent: %Lu -> %Lu\n", - (unsigned long long)lock->l_extent.start, - (unsigned long long)lock->l_extent.end); -} diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c deleted file mode 100644 index bd2dd09..0000000 --- a/lustre/ldlm/ldlm_lockd.c +++ /dev/null @@ -1,794 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Peter Braam - * Author: Phil Schwan - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_LDLM - -#include -#include -#include -#include -#include - -extern kmem_cache_t *ldlm_resource_slab; -extern kmem_cache_t *ldlm_lock_slab; -extern struct lustre_lock ldlm_handle_lock; -extern struct list_head ldlm_namespace_list; -extern int (*mds_reint_p)(int offset, struct ptlrpc_request *req); -extern int (*mds_getattr_name_p)(int offset, struct ptlrpc_request *req); - -inline unsigned long round_timeout(unsigned long timeout) -{ - return ((timeout / HZ) + 1) * HZ; -} - -static struct list_head waiting_locks_list; -static spinlock_t waiting_locks_spinlock; -static struct timer_list waiting_locks_timer; -static int ldlm_already_setup = 0; - -static void waiting_locks_callback(unsigned long unused) -{ - struct list_head *liter, *n; - - spin_lock_bh(&waiting_locks_spinlock); - list_for_each_safe(liter, n, &waiting_locks_list) { - struct ldlm_lock *l = list_entry(liter, struct ldlm_lock, - l_pending_chain); - if (l->l_callback_timeout > jiffies) - break; - LDLM_DEBUG(l, "timer expired, recovering exp %p on conn %p", - l->l_export, l->l_export->exp_connection); - recovd_conn_fail(l->l_export->exp_connection); - } - spin_unlock_bh(&waiting_locks_spinlock); -} - -/* - * Indicate that we're waiting for a client to call us back cancelling a given - * lock. We add it to the pending-callback chain, and schedule the lock-timeout - * timer to fire appropriately. (We round up to the next second, to avoid - * floods of timer firings during periods of high lock contention and traffic). - */ -static int ldlm_add_waiting_lock(struct ldlm_lock *lock) -{ - unsigned long timeout_rounded; - ENTRY; - - LASSERT(list_empty(&lock->l_pending_chain)); - - spin_lock_bh(&waiting_locks_spinlock); - lock->l_callback_timeout = jiffies + (obd_timeout * HZ / 2); - - timeout_rounded = round_timeout(lock->l_callback_timeout); - - if (timeout_rounded < waiting_locks_timer.expires || - !timer_pending(&waiting_locks_timer)) { - mod_timer(&waiting_locks_timer, timeout_rounded); - } - list_add_tail(&lock->l_pending_chain, &waiting_locks_list); /* FIFO */ - spin_unlock_bh(&waiting_locks_spinlock); - RETURN(1); -} - -/* - * Remove a lock from the pending list, likely because it had its cancellation - * callback arrive without incident. This adjusts the lock-timeout timer if - * needed. Returns 0 if the lock wasn't pending after all, 1 if it was. - */ -int ldlm_del_waiting_lock(struct ldlm_lock *lock) -{ - struct list_head *list_next; - - ENTRY; - - spin_lock_bh(&waiting_locks_spinlock); - - if (list_empty(&lock->l_pending_chain)) { - spin_unlock_bh(&waiting_locks_spinlock); - RETURN(0); - } - - list_next = lock->l_pending_chain.next; - if (lock->l_pending_chain.prev == &waiting_locks_list) { - /* Removing the head of the list, adjust timer. */ - if (list_next == &waiting_locks_list) { - /* No more, just cancel. */ - del_timer(&waiting_locks_timer); - } else { - struct ldlm_lock *next; - next = list_entry(list_next, struct ldlm_lock, - l_pending_chain); - mod_timer(&waiting_locks_timer, - round_timeout(next->l_callback_timeout)); - } - } - list_del_init(&lock->l_pending_chain); - spin_unlock_bh(&waiting_locks_spinlock); - RETURN(1); -} - -static int ldlm_server_blocking_ast(struct ldlm_lock *lock, - struct ldlm_lock_desc *desc, - void *data, __u32 data_len, int flag) -{ - struct ldlm_request *body; - struct ptlrpc_request *req; - int rc = 0, size = sizeof(*body); - ENTRY; - - if (flag == LDLM_CB_CANCELING) { - /* Don't need to do anything here. */ - RETURN(0); - } - - req = ptlrpc_prep_req(&lock->l_export->exp_ldlm_data.led_import, - LDLM_BL_CALLBACK, 1, &size, NULL); - if (!req) - RETURN(-ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - memcpy(&body->lock_handle1, &lock->l_remote_handle, - sizeof(body->lock_handle1)); - memcpy(&body->lock_desc, desc, sizeof(*desc)); - - LDLM_DEBUG(lock, "server preparing blocking AST"); - req->rq_replen = 0; /* no reply needed */ - - ldlm_add_waiting_lock(lock); - (void)ptl_send_rpc(req); - - /* not waiting for reply */ - ptlrpc_req_finished(req); - - RETURN(rc); -} - -static int ldlm_server_completion_ast(struct ldlm_lock *lock, int flags) -{ - struct ldlm_request *body; - struct ptlrpc_request *req; - int rc = 0, size = sizeof(*body); - ENTRY; - - if (lock == NULL) { - LBUG(); - RETURN(-EINVAL); - } - - req = ptlrpc_prep_req(&lock->l_export->exp_ldlm_data.led_import, - LDLM_CP_CALLBACK, 1, &size, NULL); - if (!req) - RETURN(-ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - memcpy(&body->lock_handle1, &lock->l_remote_handle, - sizeof(body->lock_handle1)); - body->lock_flags = flags; - ldlm_lock2desc(lock, &body->lock_desc); - - LDLM_DEBUG(lock, "server preparing completion AST"); - req->rq_replen = 0; /* no reply needed */ - - (void)ptl_send_rpc(req); - - /* not waiting for reply */ - ptlrpc_req_finished(req); - - RETURN(rc); -} - -int ldlm_handle_enqueue(struct ptlrpc_request *req) -{ - struct obd_device *obddev = req->rq_export->exp_obd; - struct ldlm_reply *dlm_rep; - struct ldlm_request *dlm_req; - int rc, size = sizeof(*dlm_rep), cookielen = 0; - __u32 flags; - ldlm_error_t err; - struct ldlm_lock *lock = NULL; - void *cookie = NULL; - ENTRY; - - LDLM_DEBUG_NOLOCK("server-side enqueue handler START"); - - dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); - flags = dlm_req->lock_flags; - if (dlm_req->lock_desc.l_resource.lr_type == LDLM_PLAIN && - (flags & LDLM_FL_HAS_INTENT)) { - /* In this case, the reply buffer is allocated deep in - * local_lock_enqueue by the policy function. */ - cookie = req; - cookielen = sizeof(*req); - } else { - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, - &req->rq_repmsg); - if (rc) { - CERROR("out of memory\n"); - RETURN(-ENOMEM); - } - if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT) { - cookie = &dlm_req->lock_desc.l_extent; - cookielen = sizeof(struct ldlm_extent); - } - } - - /* XXX notice that this lock has no callback data: of course the - export would be exactly what we may want to use here... */ - lock = ldlm_lock_create(obddev->obd_namespace, - &dlm_req->lock_handle2, - dlm_req->lock_desc.l_resource.lr_name, - dlm_req->lock_desc.l_resource.lr_type, - dlm_req->lock_desc.l_req_mode, NULL, 0); - if (!lock) - GOTO(out, err = -ENOMEM); - - memcpy(&lock->l_remote_handle, &dlm_req->lock_handle1, - sizeof(lock->l_remote_handle)); - LDLM_DEBUG(lock, "server-side enqueue handler, new lock created"); - - err = ldlm_lock_enqueue(lock, cookie, cookielen, &flags, - ldlm_server_completion_ast, - ldlm_server_blocking_ast); - if (err != ELDLM_OK) - GOTO(out, err); - - dlm_rep = lustre_msg_buf(req->rq_repmsg, 0); - dlm_rep->lock_flags = flags; - - ldlm_lock2handle(lock, &dlm_rep->lock_handle); - if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT) - memcpy(&dlm_rep->lock_extent, &lock->l_extent, - sizeof(lock->l_extent)); - if (dlm_rep->lock_flags & LDLM_FL_LOCK_CHANGED) { - memcpy(dlm_rep->lock_resource_name, lock->l_resource->lr_name, - sizeof(dlm_rep->lock_resource_name)); - dlm_rep->lock_mode = lock->l_req_mode; - } - - lock->l_export = req->rq_export; - if (lock->l_export) { - l_lock(&lock->l_resource->lr_namespace->ns_lock); - list_add(&lock->l_export_chain, - &lock->l_export->exp_ldlm_data.led_held_locks); - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - } - - EXIT; - out: - if (lock) - LDLM_DEBUG(lock, "server-side enqueue handler, sending reply" - "(err=%d)", err); - req->rq_status = err; - - if (lock) { - if (!err) - ldlm_reprocess_all(lock->l_resource); - LDLM_LOCK_PUT(lock); - } - LDLM_DEBUG_NOLOCK("server-side enqueue handler END (lock %p)", lock); - - return 0; -} - -int ldlm_handle_convert(struct ptlrpc_request *req) -{ - struct ldlm_request *dlm_req; - struct ldlm_reply *dlm_rep; - struct ldlm_lock *lock; - int rc, size = sizeof(*dlm_rep); - ENTRY; - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) { - CERROR("out of memory\n"); - RETURN(-ENOMEM); - } - dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); - dlm_rep = lustre_msg_buf(req->rq_repmsg, 0); - dlm_rep->lock_flags = dlm_req->lock_flags; - - lock = ldlm_handle2lock(&dlm_req->lock_handle1); - if (!lock) { - req->rq_status = EINVAL; - } else { - LDLM_DEBUG(lock, "server-side convert handler START"); - ldlm_lock_convert(lock, dlm_req->lock_desc.l_req_mode, - &dlm_rep->lock_flags); - if (ldlm_del_waiting_lock(lock)) - CDEBUG(D_DLMTRACE, "converted waiting lock %p\n", lock); - req->rq_status = 0; - } - - if (lock) { - ldlm_reprocess_all(lock->l_resource); - LDLM_DEBUG(lock, "server-side convert handler END"); - LDLM_LOCK_PUT(lock); - } else - LDLM_DEBUG_NOLOCK("server-side convert handler END"); - - RETURN(0); -} - -int ldlm_handle_cancel(struct ptlrpc_request *req) -{ - struct ldlm_request *dlm_req; - struct ldlm_lock *lock; - int rc; - ENTRY; - - rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) { - CERROR("out of memory\n"); - RETURN(-ENOMEM); - } - dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); - if (!dlm_req) { - CERROR("bad request buffer for cancel\n"); - RETURN(-EINVAL); - } - - lock = ldlm_handle2lock(&dlm_req->lock_handle1); - if (!lock) { - LDLM_DEBUG_NOLOCK("server-side cancel handler stale lock (lock " - "%p)", (void *)(unsigned long) - dlm_req->lock_handle1.addr); - req->rq_status = ESTALE; - } else { - LDLM_DEBUG(lock, "server-side cancel handler START"); - ldlm_lock_cancel(lock); - if (ldlm_del_waiting_lock(lock)) - CDEBUG(D_DLMTRACE, "cancelled waiting lock %p\n", lock); - req->rq_status = 0; - } - - if (ptlrpc_reply(req->rq_svc, req) != 0) - LBUG(); - - if (lock) { - ldlm_reprocess_all(lock->l_resource); - LDLM_DEBUG(lock, "server-side cancel handler END"); - LDLM_LOCK_PUT(lock); - } - - RETURN(0); -} - -static int ldlm_handle_bl_callback(struct ptlrpc_request *req) -{ - struct ldlm_request *dlm_req; - struct ldlm_lock *lock; - int do_ast; - ENTRY; - - OBD_FAIL_RETURN(OBD_FAIL_OSC_LOCK_BL_AST, 0); - - dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); - - lock = ldlm_handle2lock(&dlm_req->lock_handle1); - if (!lock) { - CERROR("blocking callback on lock "LPX64" - lock disappeared\n", - dlm_req->lock_handle1.addr); - RETURN(0); - } - - LDLM_DEBUG(lock, "client blocking AST callback handler START"); - - l_lock(&lock->l_resource->lr_namespace->ns_lock); - lock->l_flags |= LDLM_FL_CBPENDING; - do_ast = (!lock->l_readers && !lock->l_writers); - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - - if (do_ast) { - LDLM_DEBUG(lock, "already unused, calling " - "callback (%p)", lock->l_blocking_ast); - if (lock->l_blocking_ast != NULL) { - lock->l_blocking_ast(lock, &dlm_req->lock_desc, - lock->l_data, lock->l_data_len, - LDLM_CB_BLOCKING); - } - } else - LDLM_DEBUG(lock, "Lock still has references, will be" - " cancelled later"); - - LDLM_DEBUG(lock, "client blocking callback handler END"); - LDLM_LOCK_PUT(lock); - RETURN(0); -} - -static int ldlm_handle_cp_callback(struct ptlrpc_request *req) -{ - struct list_head ast_list = LIST_HEAD_INIT(ast_list); - struct ldlm_request *dlm_req; - struct ldlm_lock *lock; - ENTRY; - - OBD_FAIL_RETURN(OBD_FAIL_OSC_LOCK_CP_AST, 0); - - dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); - - lock = ldlm_handle2lock(&dlm_req->lock_handle1); - if (!lock) { - CERROR("completion callback on lock "LPX64" - lock " - "disappeared\n", dlm_req->lock_handle1.addr); - RETURN(0); - } - - LDLM_DEBUG(lock, "client completion callback handler START"); - - l_lock(&lock->l_resource->lr_namespace->ns_lock); - - /* If we receive the completion AST before the actual enqueue returned, - * then we might need to switch lock modes, resources, or extents. */ - if (dlm_req->lock_desc.l_granted_mode != lock->l_req_mode) { - lock->l_req_mode = dlm_req->lock_desc.l_granted_mode; - LDLM_DEBUG(lock, "completion AST, new lock mode"); - } - if (lock->l_resource->lr_type == LDLM_EXTENT) - memcpy(&lock->l_extent, &dlm_req->lock_desc.l_extent, - sizeof(lock->l_extent)); - ldlm_resource_unlink_lock(lock); - if (memcmp(dlm_req->lock_desc.l_resource.lr_name, - lock->l_resource->lr_name, - sizeof(__u64) * RES_NAME_SIZE) != 0) { - ldlm_lock_change_resource(lock, - dlm_req->lock_desc.l_resource.lr_name); - LDLM_DEBUG(lock, "completion AST, new resource"); - } - lock->l_resource->lr_tmp = &ast_list; - ldlm_grant_lock(lock); - lock->l_resource->lr_tmp = NULL; - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - LDLM_DEBUG(lock, "callback handler finished, about to run_ast_work"); - LDLM_LOCK_PUT(lock); - - ldlm_run_ast_work(&ast_list); - - LDLM_DEBUG_NOLOCK("client completion callback handler END (lock %p)", - lock); - RETURN(0); -} - -static int ldlm_callback_handler(struct ptlrpc_request *req) -{ - int rc; - ENTRY; - - rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); - if (rc) { - CERROR("lustre_ldlm: Invalid request: %d\n", rc); - RETURN(rc); - } - - if (req->rq_export == NULL) { - CERROR("operation %d with bad export (ptl req %d/rep %d)\n", - req->rq_reqmsg->opc, req->rq_request_portal, - req->rq_reply_portal); - CERROR("--> export addr: "LPX64", cookie: "LPX64"\n", - req->rq_reqmsg->addr, req->rq_reqmsg->cookie); - CERROR("--> ignoring this error as a temporary workaround! " - "beware!\n"); - //RETURN(-ENOTCONN); - } - - switch (req->rq_reqmsg->opc) { - case LDLM_BL_CALLBACK: - CDEBUG(D_INODE, "blocking ast\n"); - OBD_FAIL_RETURN(OBD_FAIL_LDLM_BL_CALLBACK, 0); - rc = ldlm_handle_bl_callback(req); - RETURN(rc); - case LDLM_CP_CALLBACK: - CDEBUG(D_INODE, "completion ast\n"); - OBD_FAIL_RETURN(OBD_FAIL_LDLM_CP_CALLBACK, 0); - rc = ldlm_handle_cp_callback(req); - RETURN(rc); - - default: - CERROR("invalid opcode %d\n", req->rq_reqmsg->opc); - RETURN(-EINVAL); - } - - RETURN(0); -} - - -static int ldlm_cancel_handler(struct ptlrpc_request *req) -{ - int rc; - ENTRY; - - rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); - if (rc) { - CERROR("lustre_ldlm: Invalid request: %d\n", rc); - RETURN(rc); - } - - if (req->rq_export == NULL) { - CERROR("operation %d with bad export (ptl req %d/rep %d)\n", - req->rq_reqmsg->opc, req->rq_request_portal, - req->rq_reply_portal); - CERROR("--> export addr: "LPX64", cookie: "LPX64"\n", - req->rq_reqmsg->addr, req->rq_reqmsg->cookie); - CERROR("--> ignoring this error as a temporary workaround! " - "beware!\n"); - //RETURN(-ENOTCONN); - } - - switch (req->rq_reqmsg->opc) { - - /* XXX FIXME move this back to mds/handler.c, bug 625069 */ - case LDLM_CANCEL: - CDEBUG(D_INODE, "cancel\n"); - OBD_FAIL_RETURN(OBD_FAIL_LDLM_CANCEL, 0); - rc = ldlm_handle_cancel(req); - if (rc) - break; - RETURN(0); - - default: - CERROR("invalid opcode %d\n", req->rq_reqmsg->opc); - RETURN(-EINVAL); - } - - RETURN(0); -} - - -static int ldlm_iocontrol(long cmd, struct lustre_handle *conn, int len, - void *karg, void *uarg) -{ - struct obd_device *obddev = class_conn2obd(conn); - struct ptlrpc_connection *connection; - int err = 0; - ENTRY; - - if (_IOC_TYPE(cmd) != IOC_LDLM_TYPE || _IOC_NR(cmd) < IOC_LDLM_MIN_NR || - _IOC_NR(cmd) > IOC_LDLM_MAX_NR) { - CDEBUG(D_IOCTL, "invalid ioctl (type %ld, nr %ld, size %ld)\n", - _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd)); - RETURN(-EINVAL); - } - - OBD_ALLOC(obddev->u.ldlm.ldlm_client, - sizeof(*obddev->u.ldlm.ldlm_client)); - connection = ptlrpc_uuid_to_connection("ldlm"); - if (!connection) - CERROR("No LDLM UUID found: assuming ldlm is local.\n"); - - switch (cmd) { - case IOC_LDLM_TEST: - err = ldlm_test(obddev, conn); - CERROR("-- done err %d\n", err); - GOTO(out, err); - case IOC_LDLM_DUMP: - ldlm_dump_all_namespaces(); - GOTO(out, err); - default: - GOTO(out, err = -EINVAL); - } - - out: - if (connection) - ptlrpc_put_connection(connection); - OBD_FREE(obddev->u.ldlm.ldlm_client, - sizeof(*obddev->u.ldlm.ldlm_client)); - return err; -} - -static int ldlm_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct ldlm_obd *ldlm = &obddev->u.ldlm; - int rc, i; - ENTRY; - - if (ldlm_already_setup) - RETURN(-EALREADY); - - MOD_INC_USE_COUNT; - - rc = ldlm_proc_setup(obddev); - if (rc != 0) - GOTO(out_dec, rc); - - ldlm->ldlm_cb_service = - ptlrpc_init_svc(LDLM_NEVENTS, LDLM_NBUFS, LDLM_BUFSIZE, - LDLM_MAXREQSIZE, LDLM_CB_REQUEST_PORTAL, - LDLM_CB_REPLY_PORTAL, "self", - ldlm_callback_handler, "ldlm_cbd"); - - if (!ldlm->ldlm_cb_service) { - CERROR("failed to start service\n"); - GOTO(out_proc, rc = -ENOMEM); - } - - ldlm->ldlm_cancel_service = - ptlrpc_init_svc(LDLM_NEVENTS, LDLM_NBUFS, LDLM_BUFSIZE, - LDLM_MAXREQSIZE, LDLM_CANCEL_REQUEST_PORTAL, - LDLM_CANCEL_REPLY_PORTAL, "self", - ldlm_cancel_handler, "ldlm_canceld"); - - if (!ldlm->ldlm_cancel_service) { - CERROR("failed to start service\n"); - GOTO(out_proc, rc = -ENOMEM); - } - - for (i = 0; i < LDLM_NUM_THREADS; i++) { - char name[32]; - sprintf(name, "ldlm_cn_%02d", i); - rc = ptlrpc_start_thread(obddev, ldlm->ldlm_cancel_service, - name); - if (rc) { - CERROR("cannot start LDLM thread #%d: rc %d\n", i, rc); - LBUG(); - GOTO(out_thread, rc); - } - } - - for (i = 0; i < LDLM_NUM_THREADS; i++) { - char name[32]; - sprintf(name, "ldlm_cb_%02d", i); - rc = ptlrpc_start_thread(obddev, ldlm->ldlm_cb_service, name); - if (rc) { - CERROR("cannot start LDLM thread #%d: rc %d\n", i, rc); - LBUG(); - GOTO(out_thread, rc); - } - } - - INIT_LIST_HEAD(&waiting_locks_list); - spin_lock_init(&waiting_locks_spinlock); - waiting_locks_timer.function = waiting_locks_callback; - waiting_locks_timer.data = 0; - init_timer(&waiting_locks_timer); - - ldlm_already_setup = 1; - - RETURN(0); - - out_thread: - ptlrpc_stop_all_threads(ldlm->ldlm_cancel_service); - ptlrpc_unregister_service(ldlm->ldlm_cancel_service); - ptlrpc_stop_all_threads(ldlm->ldlm_cb_service); - ptlrpc_unregister_service(ldlm->ldlm_cb_service); - - out_proc: - ldlm_proc_cleanup(obddev); - - out_dec: - MOD_DEC_USE_COUNT; - return rc; -} - -static int ldlm_cleanup(struct obd_device *obddev) -{ - struct ldlm_obd *ldlm = &obddev->u.ldlm; - ENTRY; - - if (!list_empty(&ldlm_namespace_list)) { - CERROR("ldlm still has namespaces; clean these up first.\n"); - RETURN(-EBUSY); - } - - ptlrpc_stop_all_threads(ldlm->ldlm_cb_service); - ptlrpc_unregister_service(ldlm->ldlm_cb_service); - ptlrpc_stop_all_threads(ldlm->ldlm_cancel_service); - ptlrpc_unregister_service(ldlm->ldlm_cancel_service); - ldlm_proc_cleanup(obddev); - - ldlm_already_setup = 0; - MOD_DEC_USE_COUNT; - RETURN(0); -} - -static int ldlm_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); -} - -struct obd_ops ldlm_obd_ops = { - o_iocontrol: ldlm_iocontrol, - o_setup: ldlm_setup, - o_cleanup: ldlm_cleanup, - o_connect: ldlm_connect, - o_disconnect: class_disconnect -}; - -static int __init ldlm_init(void) -{ - int rc = class_register_type(&ldlm_obd_ops, 0, OBD_LDLM_DEVICENAME); - if (rc != 0) - return rc; - - ldlm_resource_slab = kmem_cache_create("ldlm_resources", - sizeof(struct ldlm_resource), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); - if (ldlm_resource_slab == NULL) - return -ENOMEM; - - ldlm_lock_slab = kmem_cache_create("ldlm_locks", - sizeof(struct ldlm_lock), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); - if (ldlm_lock_slab == NULL) { - kmem_cache_destroy(ldlm_resource_slab); - return -ENOMEM; - } - - l_lock_init(&ldlm_handle_lock); - - return 0; -} - -static void __exit ldlm_exit(void) -{ - class_unregister_type(OBD_LDLM_DEVICENAME); - if (kmem_cache_destroy(ldlm_resource_slab) != 0) - CERROR("couldn't free ldlm resource slab\n"); - if (kmem_cache_destroy(ldlm_lock_slab) != 0) - CERROR("couldn't free ldlm lock slab\n"); -} - -EXPORT_SYMBOL(ldlm_completion_ast); -EXPORT_SYMBOL(ldlm_handle_enqueue); -EXPORT_SYMBOL(ldlm_handle_cancel); -EXPORT_SYMBOL(ldlm_handle_convert); -EXPORT_SYMBOL(ldlm_register_intent); -EXPORT_SYMBOL(ldlm_unregister_intent); -EXPORT_SYMBOL(ldlm_lockname); -EXPORT_SYMBOL(ldlm_typename); -EXPORT_SYMBOL(__ldlm_handle2lock); -EXPORT_SYMBOL(ldlm_lock2handle); -EXPORT_SYMBOL(ldlm_lock_put); -EXPORT_SYMBOL(ldlm_lock_match); -EXPORT_SYMBOL(ldlm_lock_addref); -EXPORT_SYMBOL(ldlm_lock_decref); -EXPORT_SYMBOL(ldlm_lock_change_resource); -EXPORT_SYMBOL(ldlm_lock_set_data); -EXPORT_SYMBOL(ldlm_cli_convert); -EXPORT_SYMBOL(ldlm_cli_enqueue); -EXPORT_SYMBOL(ldlm_cli_cancel); -EXPORT_SYMBOL(ldlm_cli_cancel_unused); -EXPORT_SYMBOL(ldlm_match_or_enqueue); -EXPORT_SYMBOL(ldlm_it2str); -EXPORT_SYMBOL(ldlm_test); -EXPORT_SYMBOL(ldlm_regression_start); -EXPORT_SYMBOL(ldlm_regression_stop); -EXPORT_SYMBOL(ldlm_lock_dump); -EXPORT_SYMBOL(ldlm_namespace_new); -EXPORT_SYMBOL(ldlm_namespace_cleanup); -EXPORT_SYMBOL(ldlm_namespace_free); -EXPORT_SYMBOL(ldlm_namespace_dump); -EXPORT_SYMBOL(ldlm_cancel_locks_for_export); -EXPORT_SYMBOL(ldlm_replay_locks); -EXPORT_SYMBOL(ldlm_resource_foreach); -EXPORT_SYMBOL(ldlm_namespace_foreach); -EXPORT_SYMBOL(l_lock); -EXPORT_SYMBOL(l_unlock); - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Lock Management Module v0.1"); -MODULE_LICENSE("GPL"); - -module_init(ldlm_init); -module_exit(ldlm_exit); diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c deleted file mode 100644 index 7d449ef..0000000 --- a/lustre/ldlm/ldlm_request.c +++ /dev/null @@ -1,797 +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_LDLM - -#include -#include -#include - -static int interrupted_completion_wait(void *data) -{ - RETURN(1); -} - -static int expired_completion_wait(void *data) -{ - struct ldlm_lock *lock = data; - struct ptlrpc_connection *conn; - struct obd_device *obd; - - if (!lock) - CERROR("NULL lock\n"); - else if (!lock->l_connh) - CERROR("lock %p has NULL connh\n", lock); - else if (!(obd = class_conn2obd(lock->l_connh))) - CERROR("lock %p has NULL obd\n", lock); - else if (!(conn = obd->u.cli.cl_import.imp_connection)) - CERROR("lock %p has NULL connection\n", lock); - else - class_signal_connection_failure(conn); - RETURN(0); -} - -int ldlm_completion_ast(struct ldlm_lock *lock, int flags) -{ - struct l_wait_info lwi = - LWI_TIMEOUT_INTR(obd_timeout * HZ, expired_completion_wait, - interrupted_completion_wait, lock); - int rc = 0; - ENTRY; - - if (flags == LDLM_FL_WAIT_NOREPROC) - goto noreproc; - - if (flags == 0) { - wake_up(&lock->l_waitq); - RETURN(0); - } - - if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED | - LDLM_FL_BLOCK_CONV))) - RETURN(0); - - LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, " - "sleeping"); - ldlm_lock_dump(lock); - ldlm_reprocess_all(lock->l_resource); - - noreproc: - /* Go to sleep until the lock is granted or cancelled. */ - rc = l_wait_event(lock->l_waitq, - ((lock->l_req_mode == lock->l_granted_mode) || - lock->l_destroyed), &lwi); - - if (lock->l_destroyed) { - LDLM_DEBUG(lock, "client-side enqueue waking up: destroyed"); - RETURN(-EIO); - } - - if (rc) { - LDLM_DEBUG(lock, "client-side enqueue waking up: failed (%d)", - rc); - RETURN(rc); - } - - LDLM_DEBUG(lock, "client-side enqueue waking up: granted"); - RETURN(0); -} - -static int ldlm_cli_enqueue_local(struct ldlm_namespace *ns, - struct lustre_handle *parent_lockh, - __u64 *res_id, - __u32 type, - void *cookie, int cookielen, - ldlm_mode_t mode, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback blocking, - void *data, - __u32 data_len, - struct lustre_handle *lockh) -{ - struct ldlm_lock *lock; - int err; - ENTRY; - - if (ns->ns_client) { - CERROR("Trying to enqueue local lock in a shadow namespace\n"); - LBUG(); - } - - lock = ldlm_lock_create(ns, parent_lockh, res_id, type, mode, data, - data_len); - if (!lock) - GOTO(out_nolock, err = -ENOMEM); - LDLM_DEBUG(lock, "client-side local enqueue handler, new lock created"); - - ldlm_lock_addref_internal(lock, mode); - ldlm_lock2handle(lock, lockh); - lock->l_connh = NULL; - - err = ldlm_lock_enqueue(lock, cookie, cookielen, flags, completion, - blocking); - if (err != ELDLM_OK) - GOTO(out, err); - - if (type == LDLM_EXTENT) - memcpy(cookie, &lock->l_extent, sizeof(lock->l_extent)); - if ((*flags) & LDLM_FL_LOCK_CHANGED) - memcpy(res_id, lock->l_resource->lr_name, sizeof(*res_id)); - - LDLM_DEBUG_NOLOCK("client-side local enqueue handler END (lock %p)", - lock); - - if (lock->l_completion_ast) - lock->l_completion_ast(lock, *flags); - - LDLM_DEBUG(lock, "client-side local enqueue END"); - EXIT; - out: - LDLM_LOCK_PUT(lock); - out_nolock: - return err; -} - -int ldlm_cli_enqueue(struct lustre_handle *connh, - struct ptlrpc_request *req, - struct ldlm_namespace *ns, - struct lustre_handle *parent_lock_handle, - __u64 *res_id, - __u32 type, - void *cookie, int cookielen, - ldlm_mode_t mode, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback blocking, - void *data, - __u32 data_len, - struct lustre_handle *lockh) -{ - struct ldlm_lock *lock; - struct ldlm_request *body; - struct ldlm_reply *reply; - int rc, size = sizeof(*body), req_passed_in = 1, is_replay; - ENTRY; - - is_replay = *flags & LDLM_FL_REPLAY; - LASSERT(connh != NULL || !is_replay); - - if (connh == NULL) - return ldlm_cli_enqueue_local(ns, parent_lock_handle, res_id, - type, cookie, cookielen, mode, - flags, completion, blocking, data, - data_len, lockh); - - /* If we're replaying this lock, just check some invariants. - * If we're creating a new lock, get everything all setup nice. */ - if (is_replay) { - lock = ldlm_handle2lock(lockh); - LDLM_DEBUG(lock, "client-side enqueue START"); - LASSERT(connh == lock->l_connh); - } else { - lock = ldlm_lock_create(ns, parent_lock_handle, res_id, type, - mode, data, data_len); - if (lock == NULL) - GOTO(out_nolock, rc = -ENOMEM); - LDLM_DEBUG(lock, "client-side enqueue START"); - /* for the local lock, add the reference */ - ldlm_lock_addref_internal(lock, mode); - ldlm_lock2handle(lock, lockh); - if (type == LDLM_EXTENT) - memcpy(&lock->l_extent, cookie, - sizeof(body->lock_desc.l_extent)); - } - - if (req == NULL) { - req = ptlrpc_prep_req(class_conn2cliimp(connh), LDLM_ENQUEUE, 1, - &size, NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - req_passed_in = 0; - } else if (req->rq_reqmsg->buflens[0] != sizeof(*body)) - LBUG(); - - /* Dump lock data into the request buffer */ - body = lustre_msg_buf(req->rq_reqmsg, 0); - ldlm_lock2desc(lock, &body->lock_desc); - body->lock_flags = *flags; - - memcpy(&body->lock_handle1, lockh, sizeof(*lockh)); - if (parent_lock_handle) - memcpy(&body->lock_handle2, parent_lock_handle, - sizeof(body->lock_handle2)); - - /* Continue as normal. */ - if (!req_passed_in) { - size = sizeof(*reply); - req->rq_replen = lustre_msg_size(1, &size); - } - lock->l_connh = connh; - lock->l_export = NULL; - - LDLM_DEBUG(lock, "sending request"); - rc = ptlrpc_queue_wait(req); - - if (rc != ELDLM_OK) { - LASSERT(!is_replay); - LDLM_DEBUG(lock, "client-side enqueue END (%s)", - rc == ELDLM_LOCK_ABORTED ? "ABORTED" : "FAILED"); - ldlm_lock_decref(lockh, mode); - /* FIXME: if we've already received a completion AST, this will - * LBUG! */ - ldlm_lock_destroy(lock); - GOTO(out, rc); - } - - reply = lustre_msg_buf(req->rq_repmsg, 0); - memcpy(&lock->l_remote_handle, &reply->lock_handle, - sizeof(lock->l_remote_handle)); - *flags = reply->lock_flags; - - CDEBUG(D_INFO, "local: %p, remote: %p, flags: %d\n", lock, - (void *)(unsigned long)reply->lock_handle.addr, *flags); - if (type == LDLM_EXTENT) { - CDEBUG(D_INFO, "requested extent: "LPU64" -> "LPU64", got " - "extent "LPU64" -> "LPU64"\n", - body->lock_desc.l_extent.start, - body->lock_desc.l_extent.end, - reply->lock_extent.start, reply->lock_extent.end); - cookie = &reply->lock_extent; /* FIXME bug 267 */ - cookielen = sizeof(reply->lock_extent); - } - - /* If enqueue returned a blocked lock but the completion handler has - * already run, then it fixed up the resource and we don't need to do it - * again. */ - if ((*flags) & LDLM_FL_LOCK_CHANGED) { - int newmode = reply->lock_mode; - LASSERT(!is_replay); - if (newmode && newmode != lock->l_req_mode) { - LDLM_DEBUG(lock, "server returned different mode %s", - ldlm_lockname[newmode]); - lock->l_req_mode = newmode; - } - - if (reply->lock_resource_name[0] != - lock->l_resource->lr_name[0]) { - CDEBUG(D_INFO, "remote intent success, locking %ld " - "instead of %ld\n", - (long)reply->lock_resource_name[0], - (long)lock->l_resource->lr_name[0]); - - ldlm_lock_change_resource(lock, - reply->lock_resource_name); - if (lock->l_resource == NULL) { - LBUG(); - RETURN(-ENOMEM); - } - LDLM_DEBUG(lock, "client-side enqueue, new resource"); - } - } - - if (!is_replay) { - rc = ldlm_lock_enqueue(lock, cookie, cookielen, flags, - completion, blocking); - if (lock->l_completion_ast) - lock->l_completion_ast(lock, *flags); - } - - if (!req_passed_in) - ptlrpc_req_finished(req); - - LDLM_DEBUG(lock, "client-side enqueue END"); - EXIT; - out: - LDLM_LOCK_PUT(lock); - out_nolock: - return rc; -} - -int ldlm_match_or_enqueue(struct lustre_handle *connh, - struct ptlrpc_request *req, - struct ldlm_namespace *ns, - struct lustre_handle *parent_lock_handle, - __u64 *res_id, - __u32 type, - void *cookie, int cookielen, - ldlm_mode_t mode, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback blocking, - void *data, - __u32 data_len, - struct lustre_handle *lockh) -{ - int rc; - ENTRY; - rc = ldlm_lock_match(ns, res_id, type, cookie, cookielen, mode, lockh); - if (rc == 0) { - rc = ldlm_cli_enqueue(connh, req, ns, - parent_lock_handle, res_id, type, cookie, - cookielen, mode, flags, completion, - blocking, data, data_len, lockh); - if (rc != ELDLM_OK) - CERROR("ldlm_cli_enqueue: err: %d\n", rc); - RETURN(rc); - } else - RETURN(0); -} - -int ldlm_cli_replay_enqueue(struct ldlm_lock *lock) -{ - struct lustre_handle lockh; - int flags = LDLM_FL_REPLAY; - ldlm_lock2handle(lock, &lockh); - return ldlm_cli_enqueue(lock->l_connh, NULL, NULL, NULL, NULL, - lock->l_resource->lr_type, NULL, 0, -1, &flags, - NULL, NULL, NULL, 0, &lockh); -} - -static int ldlm_cli_convert_local(struct ldlm_lock *lock, int new_mode, - int *flags) -{ - ENTRY; - if (lock->l_resource->lr_namespace->ns_client) { - CERROR("Trying to cancel local lock\n"); - LBUG(); - } - LDLM_DEBUG(lock, "client-side local convert"); - - ldlm_lock_convert(lock, new_mode, flags); - ldlm_reprocess_all(lock->l_resource); - - LDLM_DEBUG(lock, "client-side local convert handler END"); - LDLM_LOCK_PUT(lock); - RETURN(0); -} - -/* FIXME: one of ldlm_cli_convert or the server side should reject attempted - * conversion of locks which are on the waiting or converting queue */ -int ldlm_cli_convert(struct lustre_handle *lockh, int new_mode, int *flags) -{ - struct ldlm_request *body; - struct lustre_handle *connh; - struct ldlm_reply *reply; - struct ldlm_lock *lock; - struct ldlm_resource *res; - struct ptlrpc_request *req; - int rc, size = sizeof(*body); - ENTRY; - - lock = ldlm_handle2lock(lockh); - if (!lock) { - LBUG(); - RETURN(-EINVAL); - } - *flags = 0; - connh = lock->l_connh; - - if (!connh) - RETURN(ldlm_cli_convert_local(lock, new_mode, flags)); - - LDLM_DEBUG(lock, "client-side convert"); - - req = ptlrpc_prep_req(class_conn2cliimp(connh), LDLM_CONVERT, 1, &size, - NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - memcpy(&body->lock_handle1, &lock->l_remote_handle, - sizeof(body->lock_handle1)); - - body->lock_desc.l_req_mode = new_mode; - body->lock_flags = *flags; - - size = sizeof(*reply); - req->rq_replen = lustre_msg_size(1, &size); - - rc = ptlrpc_queue_wait(req); - if (rc != ELDLM_OK) - GOTO(out, rc); - - reply = lustre_msg_buf(req->rq_repmsg, 0); - res = ldlm_lock_convert(lock, new_mode, &reply->lock_flags); - if (res != NULL) - ldlm_reprocess_all(res); - /* Go to sleep until the lock is granted. */ - /* FIXME: or cancelled. */ - if (lock->l_completion_ast) - lock->l_completion_ast(lock, LDLM_FL_WAIT_NOREPROC); - EXIT; - out: - LDLM_LOCK_PUT(lock); - ptlrpc_req_finished(req); - return rc; -} - -int ldlm_cli_cancel(struct lustre_handle *lockh) -{ - struct ptlrpc_request *req; - struct ldlm_lock *lock; - struct ldlm_request *body; - int rc = 0, size = sizeof(*body); - ENTRY; - - /* concurrent cancels on the same handle can happen */ - lock = __ldlm_handle2lock(lockh, 0, LDLM_FL_CANCELING); - if (lock == NULL) - RETURN(0); - - if (lock->l_connh) { - LDLM_DEBUG(lock, "client-side cancel"); - /* Set this flag to prevent others from getting new references*/ - l_lock(&lock->l_resource->lr_namespace->ns_lock); - lock->l_flags |= LDLM_FL_CBPENDING; - ldlm_cancel_callback(lock); - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - - req = ptlrpc_prep_req(class_conn2cliimp(lock->l_connh), - LDLM_CANCEL, 1, &size, NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - - /* XXX FIXME bug 249 */ - req->rq_request_portal = LDLM_CANCEL_REQUEST_PORTAL; - req->rq_reply_portal = LDLM_CANCEL_REPLY_PORTAL; - - body = lustre_msg_buf(req->rq_reqmsg, 0); - memcpy(&body->lock_handle1, &lock->l_remote_handle, - sizeof(body->lock_handle1)); - - req->rq_replen = lustre_msg_size(0, NULL); - - rc = ptlrpc_queue_wait(req); - ptlrpc_req_finished(req); - if (rc != ELDLM_OK) - GOTO(out, rc); - - ldlm_lock_cancel(lock); - } else { - LDLM_DEBUG(lock, "client-side local cancel"); - if (lock->l_resource->lr_namespace->ns_client) { - CERROR("Trying to cancel local lock\n"); - LBUG(); - } - ldlm_lock_cancel(lock); - ldlm_reprocess_all(lock->l_resource); - LDLM_DEBUG(lock, "client-side local cancel handler END"); - } - - lock->l_flags |= LDLM_FL_CANCELING; - - EXIT; - out: - LDLM_LOCK_PUT(lock); - return rc; -} - -int ldlm_cancel_lru(struct ldlm_namespace *ns) -{ - struct list_head *tmp, *next, list = LIST_HEAD_INIT(list); - int count, rc = 0; - struct ldlm_ast_work *w; - ENTRY; - - l_lock(&ns->ns_lock); - count = ns->ns_nr_unused - ns->ns_max_unused; - - if (count <= 0) { - l_unlock(&ns->ns_lock); - RETURN(0); - } - - list_for_each_safe(tmp, next, &ns->ns_unused_list) { - struct ldlm_lock *lock; - lock = list_entry(tmp, struct ldlm_lock, l_lru); - - LASSERT(!lock->l_readers && !lock->l_writers); - - /* Setting the CBPENDING flag is a little misleading, but - * prevents an important race; namely, once CBPENDING is set, - * the lock can accumulate no more readers/writers. Since - * readers and writers are already zero here, ldlm_lock_decref - * won't see this flag and call l_blocking_ast */ - lock->l_flags |= LDLM_FL_CBPENDING; - - OBD_ALLOC(w, sizeof(*w)); - LASSERT(w); - - w->w_lock = LDLM_LOCK_GET(lock); - list_add(&w->w_list, &list); - ldlm_lock_remove_from_lru(lock); - - if (--count == 0) - break; - } - l_unlock(&ns->ns_lock); - - list_for_each_safe(tmp, next, &list) { - struct lustre_handle lockh; - int rc; - w = list_entry(tmp, struct ldlm_ast_work, w_list); - - ldlm_lock2handle(w->w_lock, &lockh); - rc = ldlm_cli_cancel(&lockh); - if (rc != ELDLM_OK) - CDEBUG(D_INFO, "ldlm_cli_cancel: %d\n", rc); - - list_del(&w->w_list); - LDLM_LOCK_PUT(w->w_lock); - OBD_FREE(w, sizeof(*w)); - } - - RETURN(rc); -} - -int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns, - __u64 *res_id, int flags) -{ - struct ldlm_resource *res; - struct list_head *tmp, *next, list = LIST_HEAD_INIT(list); - struct ldlm_ast_work *w; - ENTRY; - - res = ldlm_resource_get(ns, NULL, res_id, 0, 0); - if (res == NULL) { - /* This is not a problem. */ - CDEBUG(D_INFO, "No resource "LPU64"\n", res_id[0]); - RETURN(0); - } - - l_lock(&ns->ns_lock); - list_for_each(tmp, &res->lr_granted) { - struct ldlm_lock *lock; - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - - if (lock->l_readers || lock->l_writers) - continue; - - /* See CBPENDING comment in ldlm_cancel_lru */ - lock->l_flags |= LDLM_FL_CBPENDING; - - OBD_ALLOC(w, sizeof(*w)); - LASSERT(w); - - w->w_lock = LDLM_LOCK_GET(lock); - list_add(&w->w_list, &list); - } - l_unlock(&ns->ns_lock); - - list_for_each_safe(tmp, next, &list) { - struct lustre_handle lockh; - int rc; - w = list_entry(tmp, struct ldlm_ast_work, w_list); - - /* Prevent the cancel callback from being called by setting - * LDLM_FL_CANCEL in the lock. Very sneaky. -p */ - if (flags & LDLM_FL_NO_CALLBACK) - w->w_lock->l_flags |= LDLM_FL_CANCEL; - - if (flags & LDLM_FL_LOCAL_ONLY) { - ldlm_lock_cancel(w->w_lock); - } else { - ldlm_lock2handle(w->w_lock, &lockh); - rc = ldlm_cli_cancel(&lockh); - if (rc != ELDLM_OK) - CERROR("ldlm_cli_cancel: %d\n", rc); - } - list_del(&w->w_list); - LDLM_LOCK_PUT(w->w_lock); - OBD_FREE(w, sizeof(*w)); - } - - ldlm_resource_putref(res); - - RETURN(0); -} - -/* Cancel all locks on a namespace (or a specific resource, if given) that have - * 0 readers/writers. - * - * If 'local_only' is true, throw the locks away without trying to notify the - * server. */ -int ldlm_cli_cancel_unused(struct ldlm_namespace *ns, __u64 *res_id, - int flags) -{ - int i; - ENTRY; - - if (res_id) - RETURN(ldlm_cli_cancel_unused_resource(ns, res_id, flags)); - - l_lock(&ns->ns_lock); - for (i = 0; i < RES_HASH_SIZE; i++) { - struct list_head *tmp, *pos; - list_for_each_safe(tmp, pos, &(ns->ns_hash[i])) { - int rc; - struct ldlm_resource *res; - res = list_entry(tmp, struct ldlm_resource, lr_hash); - ldlm_resource_getref(res); - - rc = ldlm_cli_cancel_unused_resource(ns, res->lr_name, - flags); - - if (rc) - CERROR("cancel_unused_res ("LPU64"): %d\n", - res->lr_name[0], rc); - ldlm_resource_putref(res); - } - } - l_unlock(&ns->ns_lock); - - RETURN(ELDLM_OK); -} - -/* Lock iterators. */ - -int ldlm_resource_foreach(struct ldlm_resource *res, ldlm_iterator_t iter, - void *closure) -{ - struct list_head *tmp, *next; - struct ldlm_lock *lock; - int rc = LDLM_ITER_CONTINUE; - struct ldlm_namespace *ns = res->lr_namespace; - - ENTRY; - - if (!res) - RETURN(LDLM_ITER_CONTINUE); - - l_lock(&ns->ns_lock); - list_for_each_safe(tmp, next, &res->lr_granted) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - - if (iter(lock, closure) == LDLM_ITER_STOP) - GOTO(out, rc = LDLM_ITER_STOP); - } - - list_for_each_safe(tmp, next, &res->lr_converting) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - - if (iter(lock, closure) == LDLM_ITER_STOP) - GOTO(out, rc = LDLM_ITER_STOP); - } - - list_for_each_safe(tmp, next, &res->lr_waiting) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - - if (iter(lock, closure) == LDLM_ITER_STOP) - GOTO(out, rc = LDLM_ITER_STOP); - } - out: - l_unlock(&ns->ns_lock); - RETURN(rc); -} - -struct iter_helper_data { - ldlm_iterator_t iter; - void *closure; -}; - -static int ldlm_iter_helper(struct ldlm_lock *lock, void *closure) -{ - struct iter_helper_data *helper = closure; - return helper->iter(lock, helper->closure); -} - -int ldlm_namespace_foreach(struct ldlm_namespace *ns, ldlm_iterator_t iter, - void *closure) -{ - int i, rc = LDLM_ITER_CONTINUE; - struct iter_helper_data helper = { iter: iter, closure: closure }; - - l_lock(&ns->ns_lock); - for (i = 0; i < RES_HASH_SIZE; i++) { - struct list_head *tmp, *next; - list_for_each_safe(tmp, next, &(ns->ns_hash[i])) { - struct ldlm_resource *res = - list_entry(tmp, struct ldlm_resource, lr_hash); - - ldlm_resource_getref(res); - rc = ldlm_resource_foreach(res, ldlm_iter_helper, - &helper); - ldlm_resource_putref(res); - if (rc == LDLM_ITER_STOP) - GOTO(out, rc); - } - } - out: - l_unlock(&ns->ns_lock); - RETURN(rc); -} - -/* Lock replay */ - -static int ldlm_chain_lock_for_replay(struct ldlm_lock *lock, void *closure) -{ - struct list_head *list = closure; - - /* we use l_pending_chain here, because it's unused on clients. */ - list_add(&lock->l_pending_chain, list); - return LDLM_ITER_CONTINUE; -} - -static int replay_one_lock(struct obd_import *imp, struct ldlm_lock *lock, - int last) -{ - struct ptlrpc_request *req; - struct ldlm_request *body; - struct ldlm_reply *reply; - int rc, size; - int flags = LDLM_FL_REPLAY; - - flags |= lock->l_flags & - (LDLM_FL_BLOCK_GRANTED|LDLM_FL_BLOCK_CONV|LDLM_FL_BLOCK_WAIT); - - size = sizeof(*body); - req = ptlrpc_prep_req(imp, LDLM_ENQUEUE, 1, &size, NULL); - if (!req) - RETURN(-ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - ldlm_lock2desc(lock, &body->lock_desc); - body->lock_flags = flags; - - ldlm_lock2handle(lock, &body->lock_handle1); - size = sizeof(*reply); - req->rq_replen = lustre_msg_size(1, &size); - - if (last) - req->rq_reqmsg->flags |= MSG_LAST_REPLAY; - - LDLM_DEBUG(lock, "replaying lock:"); - rc = ptlrpc_queue_wait(req); - if (rc != ELDLM_OK) - GOTO(out, rc); - - reply = lustre_msg_buf(req->rq_repmsg, 0); - memcpy(&lock->l_remote_handle, &reply->lock_handle, - sizeof(lock->l_remote_handle)); - LDLM_DEBUG(lock, "replayed lock:"); - out: - ptlrpc_req_finished(req); - RETURN(rc); -} - -int ldlm_replay_locks(struct obd_import *imp) -{ - struct ldlm_namespace *ns = imp->imp_obd->obd_namespace; - struct list_head list, *pos, *next; - struct ldlm_lock *lock; - int rc = 0; - - ENTRY; - INIT_LIST_HEAD(&list); - - l_lock(&ns->ns_lock); - (void)ldlm_namespace_foreach(ns, ldlm_chain_lock_for_replay, &list); - - list_for_each_safe(pos, next, &list) { - lock = list_entry(pos, struct ldlm_lock, l_pending_chain); - rc = replay_one_lock(imp, lock, (next == &list)); - if (rc) - break; /* or try to do the rest? */ - } - l_unlock(&ns->ns_lock); - RETURN(rc); -} diff --git a/lustre/ldlm/ldlm_resource.c b/lustre/ldlm/ldlm_resource.c deleted file mode 100644 index 64ec591..0000000 --- a/lustre/ldlm/ldlm_resource.c +++ /dev/null @@ -1,522 +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 code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * by Cluster File Systems, Inc. - */ - -#define DEBUG_SUBSYSTEM S_LDLM - -#include -#include - -kmem_cache_t *ldlm_resource_slab, *ldlm_lock_slab; - -spinlock_t ldlm_namespace_lock = SPIN_LOCK_UNLOCKED; -struct list_head ldlm_namespace_list = LIST_HEAD_INIT(ldlm_namespace_list); -static struct proc_dir_entry *ldlm_ns_proc_dir = NULL; - -int ldlm_proc_setup(struct obd_device *obd) -{ - ENTRY; - LASSERT(ldlm_ns_proc_dir == NULL); - ldlm_ns_proc_dir=obd->obd_type->typ_procroot; - RETURN(0); -} - -void ldlm_proc_cleanup(struct obd_device *obd) -{ - ldlm_ns_proc_dir = NULL; -} - -#define MAX_STRING_SIZE 100 -void ldlm_proc_namespace(struct ldlm_namespace *ns) -{ - struct lprocfs_vars lock_vars[2]; - char lock_names[MAX_STRING_SIZE+1]; - - memset(lock_vars, 0, sizeof(lock_vars)); - snprintf(lock_names, MAX_STRING_SIZE, "%s/resource_count", ns->ns_name); - lock_names[MAX_STRING_SIZE] = '\0'; - lock_vars[0].name = lock_names; - lock_vars[0].read_fptr = lprocfs_ll_rd; - lock_vars[0].write_fptr = NULL; - lock_vars[0].data = &ns->ns_resources; - lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0); - - memset(lock_vars, 0, sizeof(lock_vars)); - snprintf(lock_names, MAX_STRING_SIZE, "%s/lock_count", ns->ns_name); - lock_names[MAX_STRING_SIZE] = '\0'; - lock_vars[0].name = lock_names; - lock_vars[0].read_fptr = lprocfs_ll_rd; - lock_vars[0].write_fptr = NULL; - lock_vars[0].data = &ns->ns_locks; - lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0); - -} -#undef MAX_STRING_SIZE - -#define LDLM_MAX_UNUSED 20 -struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 client) -{ - struct ldlm_namespace *ns = NULL; - struct list_head *bucket; - ENTRY; - - OBD_ALLOC(ns, sizeof(*ns)); - if (!ns) { - LBUG(); - GOTO(out, NULL); - } - - ns->ns_hash = vmalloc(sizeof(*ns->ns_hash) * RES_HASH_SIZE); - if (!ns->ns_hash) { - LBUG(); - GOTO(out, ns); - } - obd_memory += sizeof(*ns->ns_hash) * RES_HASH_SIZE; - - OBD_ALLOC(ns->ns_name, strlen(name) + 1); - if (!ns->ns_name) { - LBUG(); - GOTO(out, ns); - } - strcpy(ns->ns_name, name); - - INIT_LIST_HEAD(&ns->ns_root_list); - l_lock_init(&ns->ns_lock); - ns->ns_refcount = 0; - ns->ns_client = client; - spin_lock_init(&ns->ns_counter_lock); - ns->ns_locks = 0; - ns->ns_resources = 0; - - for (bucket = ns->ns_hash + RES_HASH_SIZE - 1; bucket >= ns->ns_hash; - bucket--) - INIT_LIST_HEAD(bucket); - - INIT_LIST_HEAD(&ns->ns_unused_list); - ns->ns_nr_unused = 0; - ns->ns_max_unused = LDLM_MAX_UNUSED; - - spin_lock(&ldlm_namespace_lock); - list_add(&ns->ns_list_chain, &ldlm_namespace_list); - spin_unlock(&ldlm_namespace_lock); - ldlm_proc_namespace(ns); - RETURN(ns); - - out: - if (ns && ns->ns_hash) { - memset(ns->ns_hash, 0x5a, sizeof(*ns->ns_hash) * RES_HASH_SIZE); - vfree(ns->ns_hash); - obd_memory -= sizeof(*ns->ns_hash) * RES_HASH_SIZE; - } - if (ns && ns->ns_name) - OBD_FREE(ns->ns_name, strlen(name) + 1); - if (ns) - OBD_FREE(ns, sizeof(*ns)); - return NULL; -} - -extern struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock); - -/* If 'local_only' is true, don't try to tell the server, just cleanup. */ -static void cleanup_resource(struct ldlm_resource *res, struct list_head *q, - int local_only) -{ - struct list_head *tmp, *pos; - int rc = 0, client = res->lr_namespace->ns_client; - ENTRY; - - list_for_each_safe(tmp, pos, q) { - struct ldlm_lock *lock; - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - LDLM_LOCK_GET(lock); - - /* At shutdown time, don't call the cancellation callback */ - lock->l_flags |= LDLM_FL_CANCEL; - - if (client) { - struct lustre_handle lockh; - ldlm_lock2handle(lock, &lockh); - if (!local_only) { - rc = ldlm_cli_cancel(&lockh); - if (rc) - CERROR("ldlm_cli_cancel: %d\n", rc); - } - /* Force local cleanup on errors, too. */ - if (local_only || rc != ELDLM_OK) - ldlm_lock_cancel(lock); - } else { - LDLM_DEBUG(lock, "Freeing a lock still held by a " - "client node.\n"); - - ldlm_resource_unlink_lock(lock); - ldlm_lock_destroy(lock); - } - LDLM_LOCK_PUT(lock); - } -} - -int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only) -{ - int i; - - l_lock(&ns->ns_lock); - for (i = 0; i < RES_HASH_SIZE; i++) { - struct list_head *tmp, *pos; - list_for_each_safe(tmp, pos, &(ns->ns_hash[i])) { - struct ldlm_resource *res; - res = list_entry(tmp, struct ldlm_resource, lr_hash); - ldlm_resource_getref(res); - - cleanup_resource(res, &res->lr_granted, local_only); - cleanup_resource(res, &res->lr_converting, local_only); - cleanup_resource(res, &res->lr_waiting, local_only); - - /* XXX what a mess: don't force cleanup if we're - * local_only (which is only used by recovery). In that - * case, we probably still have outstanding lock refs - * which reference these resources. -phil */ - if (!ldlm_resource_putref(res) && !local_only) { - CERROR("Resource refcount nonzero (%d) after " - "lock cleanup; forcing cleanup.\n", - atomic_read(&res->lr_refcount)); - ldlm_resource_dump(res); - atomic_set(&res->lr_refcount, 1); - ldlm_resource_putref(res); - } - } - } - l_unlock(&ns->ns_lock); - - return ELDLM_OK; -} - -/* Cleanup, but also free, the namespace */ -int ldlm_namespace_free(struct ldlm_namespace *ns) -{ - if (!ns) - RETURN(ELDLM_OK); - - spin_lock(&ldlm_namespace_lock); - list_del(&ns->ns_list_chain); - - spin_unlock(&ldlm_namespace_lock); - - ldlm_namespace_cleanup(ns, 0); - - memset(ns->ns_hash, 0x5a, sizeof(*ns->ns_hash) * RES_HASH_SIZE); - vfree(ns->ns_hash /* , sizeof(*ns->ns_hash) * RES_HASH_SIZE */); - obd_memory -= sizeof(*ns->ns_hash) * RES_HASH_SIZE; - OBD_FREE(ns->ns_name, strlen(ns->ns_name) + 1); - OBD_FREE(ns, sizeof(*ns)); - - return ELDLM_OK; -} - -int ldlm_client_free(struct obd_export *exp) -{ - struct ldlm_export_data *led = &exp->exp_ldlm_data; - ptlrpc_cleanup_client(&led->led_import); - RETURN(0); -} - -static __u32 ldlm_hash_fn(struct ldlm_resource *parent, __u64 *name) -{ - __u32 hash = 0; - int i; - - for (i = 0; i < RES_NAME_SIZE; i++) - hash += name[i]; - - hash += (__u32)((unsigned long)parent >> 4); - - return (hash & RES_HASH_MASK); -} - -static struct ldlm_resource *ldlm_resource_new(void) -{ - struct ldlm_resource *res; - - res = kmem_cache_alloc(ldlm_resource_slab, SLAB_KERNEL); - if (res == NULL) { - LBUG(); - return NULL; - } - memset(res, 0, sizeof(*res)); - - INIT_LIST_HEAD(&res->lr_children); - INIT_LIST_HEAD(&res->lr_childof); - INIT_LIST_HEAD(&res->lr_granted); - INIT_LIST_HEAD(&res->lr_converting); - INIT_LIST_HEAD(&res->lr_waiting); - - atomic_set(&res->lr_refcount, 1); - - return res; -} - -/* Args: locked namespace - * Returns: newly-allocated, referenced, unlocked resource */ -static struct ldlm_resource *ldlm_resource_add(struct ldlm_namespace *ns, - struct ldlm_resource *parent, - __u64 *name, __u32 type) -{ - struct list_head *bucket; - struct ldlm_resource *res; - ENTRY; - - if (type < LDLM_MIN_TYPE || type > LDLM_MAX_TYPE) { - LBUG(); - RETURN(NULL); - } - - res = ldlm_resource_new(); - if (!res) { - LBUG(); - RETURN(NULL); - } - - spin_lock(&ns->ns_counter_lock); - ns->ns_resources++; - spin_unlock(&ns->ns_counter_lock); - - l_lock(&ns->ns_lock); - memcpy(res->lr_name, name, sizeof(res->lr_name)); - res->lr_namespace = ns; - ns->ns_refcount++; - - res->lr_type = type; - res->lr_most_restr = LCK_NL; - - bucket = ns->ns_hash + ldlm_hash_fn(parent, name); - list_add(&res->lr_hash, bucket); - - if (parent == NULL) { - list_add(&res->lr_childof, &ns->ns_root_list); - } else { - res->lr_parent = parent; - list_add(&res->lr_childof, &parent->lr_children); - } - l_unlock(&ns->ns_lock); - - RETURN(res); -} - -/* Args: unlocked namespace - * Locks: takes and releases ns->ns_lock and res->lr_lock - * Returns: referenced, unlocked ldlm_resource or NULL */ -struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns, - struct ldlm_resource *parent, - __u64 *name, __u32 type, int create) -{ - struct list_head *bucket; - struct list_head *tmp = bucket; - struct ldlm_resource *res = NULL; - ENTRY; - - if (ns == NULL || ns->ns_hash == NULL) { - LBUG(); - RETURN(NULL); - } - - l_lock(&ns->ns_lock); - bucket = ns->ns_hash + ldlm_hash_fn(parent, name); - - list_for_each(tmp, bucket) { - struct ldlm_resource *chk; - chk = list_entry(tmp, struct ldlm_resource, lr_hash); - - if (memcmp(chk->lr_name, name, sizeof(chk->lr_name)) == 0) { - res = chk; - atomic_inc(&res->lr_refcount); - l_unlock(&ns->ns_lock); - RETURN(res); - } - } - - if (create) - res = ldlm_resource_add(ns, parent, name, type); - l_unlock(&ns->ns_lock); - - RETURN(res); -} - -struct ldlm_resource *ldlm_resource_getref(struct ldlm_resource *res) -{ - atomic_inc(&res->lr_refcount); - CDEBUG(D_INFO, "getref res: %p count: %d\n", res, - atomic_read(&res->lr_refcount)); - return res; -} - -/* Returns 1 if the resource was freed, 0 if it remains. */ -int ldlm_resource_putref(struct ldlm_resource *res) -{ - int rc = 0; - - if (atomic_dec_and_test(&res->lr_refcount)) { - struct ldlm_namespace *ns = res->lr_namespace; - ENTRY; - CDEBUG(D_INFO, "putref res: %p count: %d\n", res, - atomic_read(&res->lr_refcount)); - - l_lock(&ns->ns_lock); - - if (atomic_read(&res->lr_refcount) != 0) { - /* We lost the race. */ - l_unlock(&ns->ns_lock); - RETURN(rc); - } - - if (!list_empty(&res->lr_granted)) { - ldlm_resource_dump(res); - LBUG(); - } - - if (!list_empty(&res->lr_converting)) { - ldlm_resource_dump(res); - LBUG(); - } - - if (!list_empty(&res->lr_waiting)) { - ldlm_resource_dump(res); - LBUG(); - } - - if (!list_empty(&res->lr_children)) { - ldlm_resource_dump(res); - LBUG(); - } - - ns->ns_refcount--; - list_del(&res->lr_hash); - list_del(&res->lr_childof); - - memset(res, 0x5a, sizeof(*res)); - kmem_cache_free(ldlm_resource_slab, res); - l_unlock(&ns->ns_lock); - - spin_lock(&ns->ns_counter_lock); - ns->ns_resources--; - spin_unlock(&ns->ns_counter_lock); - - rc = 1; - } else { - ENTRY; - CDEBUG(D_INFO, "putref res: %p count: %d\n", res, - atomic_read(&res->lr_refcount)); - out: - LASSERT(atomic_read(&res->lr_refcount) >= 0); - } - - RETURN(rc); -} - -void ldlm_resource_add_lock(struct ldlm_resource *res, struct list_head *head, - struct ldlm_lock *lock) -{ - l_lock(&res->lr_namespace->ns_lock); - - ldlm_resource_dump(res); - ldlm_lock_dump(lock); - - LASSERT(list_empty(&lock->l_res_link)); - - list_add(&lock->l_res_link, head); - l_unlock(&res->lr_namespace->ns_lock); -} - -void ldlm_resource_unlink_lock(struct ldlm_lock *lock) -{ - l_lock(&lock->l_resource->lr_namespace->ns_lock); - list_del_init(&lock->l_res_link); - l_unlock(&lock->l_resource->lr_namespace->ns_lock); -} - -void ldlm_res2desc(struct ldlm_resource *res, struct ldlm_resource_desc *desc) -{ - desc->lr_type = res->lr_type; - memcpy(desc->lr_name, res->lr_name, sizeof(desc->lr_name)); - memcpy(desc->lr_version, res->lr_version, sizeof(desc->lr_version)); -} - -void ldlm_dump_all_namespaces(void) -{ - struct list_head *tmp; - - spin_lock(&ldlm_namespace_lock); - - list_for_each(tmp, &ldlm_namespace_list) { - struct ldlm_namespace *ns; - ns = list_entry(tmp, struct ldlm_namespace, ns_list_chain); - ldlm_namespace_dump(ns); - } - - spin_unlock(&ldlm_namespace_lock); -} - -void ldlm_namespace_dump(struct ldlm_namespace *ns) -{ - struct list_head *tmp; - - l_lock(&ns->ns_lock); - CDEBUG(D_OTHER, "--- Namespace: %s (rc: %d, client: %d)\n", ns->ns_name, - ns->ns_refcount, ns->ns_client); - - list_for_each(tmp, &ns->ns_root_list) { - struct ldlm_resource *res; - res = list_entry(tmp, struct ldlm_resource, lr_childof); - - /* Once we have resources with children, this should really dump - * them recursively. */ - ldlm_resource_dump(res); - } - l_unlock(&ns->ns_lock); -} - -void ldlm_resource_dump(struct ldlm_resource *res) -{ - struct list_head *tmp; - char name[256]; - - if (RES_NAME_SIZE != 3) - LBUG(); - - snprintf(name, sizeof(name), "%Lx %Lx %Lx", - (unsigned long long)res->lr_name[0], - (unsigned long long)res->lr_name[1], - (unsigned long long)res->lr_name[2]); - - CDEBUG(D_OTHER, "--- Resource: %p (%s) (rc: %d)\n", res, name, - atomic_read(&res->lr_refcount)); - CDEBUG(D_OTHER, "Namespace: %p (%s)\n", res->lr_namespace, - res->lr_namespace->ns_name); - CDEBUG(D_OTHER, "Parent: %p, root: %p\n", res->lr_parent, res->lr_root); - - CDEBUG(D_OTHER, "Granted locks:\n"); - list_for_each(tmp, &res->lr_granted) { - struct ldlm_lock *lock; - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - ldlm_lock_dump(lock); - } - - CDEBUG(D_OTHER, "Converting locks:\n"); - list_for_each(tmp, &res->lr_converting) { - struct ldlm_lock *lock; - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - ldlm_lock_dump(lock); - } - - CDEBUG(D_OTHER, "Waiting locks:\n"); - list_for_each(tmp, &res->lr_waiting) { - struct ldlm_lock *lock; - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - ldlm_lock_dump(lock); - } -} diff --git a/lustre/ldlm/ldlm_test.c b/lustre/ldlm/ldlm_test.c deleted file mode 100644 index ce7a73d..0000000 --- a/lustre/ldlm/ldlm_test.c +++ /dev/null @@ -1,646 +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. - * Copyright (c) 2002 Lawrence Livermore National Laboratory - * Author: James Newsome - * - * 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_LDLM - -#include -#include -#include - -#include -#include - -struct ldlm_test_thread { - struct obd_device *obddev; - struct ldlm_namespace *t_ns; - struct list_head t_link; - __u32 t_flags; - wait_queue_head_t t_ctl_waitq; -}; - -struct ldlm_test_lock { - struct list_head l_link; - struct lustre_handle l_lockh; -}; - -static unsigned int max_locks; -static unsigned int num_resources; -static unsigned int num_extents; - -static spinlock_t ctl_lock = SPIN_LOCK_UNLOCKED; -/* protect these with the ctl_lock */ -static LIST_HEAD(ctl_threads); -static int regression_running = 0; -static LIST_HEAD(lock_list); -static int num_locks = 0; - -/* cumulative stats for regression test */ -static atomic_t locks_requested = ATOMIC_INIT(0); -static atomic_t converts_requested = ATOMIC_INIT(0); -static atomic_t locks_granted = ATOMIC_INIT(0); -static atomic_t locks_matched = ATOMIC_INIT(0); - -/* making this a global avoids the problem of having pointers - * to garbage after the test exits. - */ -static struct lustre_handle regress_connh; - -static int ldlm_do_decrement(void); -static int ldlm_do_enqueue(struct ldlm_test_thread *thread); -static int ldlm_do_convert(void); - -/* - * blocking ast for regression test. - * Just cancels lock - */ -static int ldlm_test_blocking_ast(struct ldlm_lock *lock, - struct ldlm_lock_desc *new, - void *data, __u32 data_len, int flag) -{ - int rc; - struct lustre_handle lockh; - ENTRY; - - switch (flag) { - case LDLM_CB_BLOCKING: - LDLM_DEBUG(lock, "We're blocking. Cancelling lock"); - ldlm_lock2handle(lock, &lockh); - rc = ldlm_cli_cancel(&lockh); - if (rc < 0) { - CERROR("ldlm_cli_cancel: %d\n", rc); - LBUG(); - } - break; - case LDLM_CB_CANCELING: - LDLM_DEBUG(lock, "this lock is being cancelled"); - break; - default: - LBUG(); - } - - RETURN(0); -} - -/* blocking ast for basic tests. noop */ -static int ldlm_blocking_ast(struct ldlm_lock *lock, - struct ldlm_lock_desc *new, - void *data, __u32 data_len, int flag) -{ - ENTRY; - CERROR("ldlm_blocking_ast: lock=%p, new=%p, flag=%d\n", lock, new, - flag); - RETURN(0); -} - -/* Completion ast for regression test. - * Does not sleep when blocked. - */ -static int ldlm_test_completion_ast(struct ldlm_lock *lock, int flags) -{ - struct ldlm_test_lock *lock_info; - ENTRY; - - if (flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED | - LDLM_FL_BLOCK_CONV)) { - LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock"); - RETURN(0); - } - - if (lock->l_granted_mode != lock->l_req_mode) - CERROR("completion ast called with non-granted lock\n"); - - /* add to list of granted locks */ - - if (flags & LDLM_FL_WAIT_NOREPROC) { - atomic_inc(&locks_matched); - LDLM_DEBUG(lock, "lock matched"); - } else { - atomic_inc(&locks_granted); - LDLM_DEBUG(lock, "lock granted"); - } - - OBD_ALLOC(lock_info, sizeof(*lock_info)); - if (lock_info == NULL) { - LBUG(); - RETURN(-ENOMEM); - } - - ldlm_lock2handle(lock, &lock_info->l_lockh); - - spin_lock(&ctl_lock); - list_add_tail(&lock_info->l_link, &lock_list); - num_locks++; - spin_unlock(&ctl_lock); - - RETURN(0); -} - -int ldlm_test_basics(struct obd_device *obddev) -{ - struct ldlm_namespace *ns; - struct ldlm_resource *res; - __u64 res_id[RES_NAME_SIZE] = {1, 2, 3}; - ldlm_error_t err; - struct ldlm_lock *lock1, *lock; - int flags; - ENTRY; - - ns = ldlm_namespace_new("test_server", LDLM_NAMESPACE_SERVER); - if (ns == NULL) - LBUG(); - - lock1 = ldlm_lock_create(ns, NULL, res_id, LDLM_PLAIN, LCK_CR, NULL, 0); - if (lock1 == NULL) - LBUG(); - err = ldlm_lock_enqueue(lock1, NULL, 0, &flags, - ldlm_completion_ast, ldlm_blocking_ast); - if (err != ELDLM_OK) - LBUG(); - - lock = ldlm_lock_create(ns, NULL, res_id, LDLM_PLAIN, LCK_EX, NULL, 0); - if (lock == NULL) - LBUG(); - err = ldlm_lock_enqueue(lock, NULL, 0, &flags, - ldlm_completion_ast, ldlm_blocking_ast); - if (err != ELDLM_OK) - LBUG(); - if (!(flags & LDLM_FL_BLOCK_GRANTED)) - LBUG(); - - res = ldlm_resource_get(ns, NULL, res_id, LDLM_PLAIN, 1); - if (res == NULL) - LBUG(); - ldlm_resource_dump(res); - - res = ldlm_lock_convert(lock1, LCK_NL, &flags); - if (res != NULL) - ldlm_reprocess_all(res); - - ldlm_resource_dump(res); - ldlm_namespace_free(ns); - - RETURN(0); -} - -int ldlm_test_extents(struct obd_device *obddev) -{ - struct ldlm_namespace *ns; - struct ldlm_resource *res; - struct ldlm_lock *lock, *lock1, *lock2; - __u64 res_id[RES_NAME_SIZE] = {0, 0, 0}; - struct ldlm_extent ext1 = {4, 6}, ext2 = {6, 9}, ext3 = {10, 11}; - ldlm_error_t err; - int flags; - ENTRY; - - ns = ldlm_namespace_new("test_server", LDLM_NAMESPACE_SERVER); - if (ns == NULL) - LBUG(); - - flags = 0; - lock1 = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_PR, NULL, - 0); - if (lock1 == NULL) - LBUG(); - err = ldlm_lock_enqueue(lock1, &ext1, sizeof(ext1), &flags, NULL, NULL); - if (err != ELDLM_OK) - LBUG(); - if (!(flags & LDLM_FL_LOCK_CHANGED)) - LBUG(); - - flags = 0; - lock2 = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_PR, - NULL, 0); - err = ldlm_lock_enqueue(lock2, &ext2, sizeof(ext2), &flags, NULL, NULL); - if (err != ELDLM_OK) - LBUG(); - if (!(flags & LDLM_FL_LOCK_CHANGED)) - LBUG(); - - flags = 0; - lock = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_EX, NULL, 0); - if (lock == NULL) - LBUG(); - err = ldlm_lock_enqueue(lock, &ext3, sizeof(ext3), &flags, - NULL, NULL); - if (err != ELDLM_OK) - LBUG(); - if (!(flags & LDLM_FL_BLOCK_GRANTED)) - LBUG(); - if (flags & LDLM_FL_LOCK_CHANGED) - LBUG(); - - /* Convert/cancel blocking locks */ - flags = 0; - res = ldlm_lock_convert(lock1, LCK_NL, &flags); - if (res != NULL) - ldlm_reprocess_all(res); - - ldlm_lock_cancel(lock2); - if (res != NULL) - ldlm_reprocess_all(res); - - /* Dump the results */ - res = ldlm_resource_get(ns, NULL, res_id, LDLM_EXTENT, 0); - if (res == NULL) - LBUG(); - ldlm_resource_dump(res); - ldlm_namespace_free(ns); - - RETURN(0); -} - -static int ldlm_test_network(struct obd_device *obddev, - struct lustre_handle *connh) -{ - - __u64 res_id[RES_NAME_SIZE] = {1, 2, 3}; - struct ldlm_extent ext = {4, 6}; - struct lustre_handle lockh1; - struct ldlm_lock *lock; - int flags = 0; - ldlm_error_t err; - ENTRY; - - err = ldlm_cli_enqueue(connh, NULL, obddev->obd_namespace, NULL, res_id, - LDLM_EXTENT, &ext, sizeof(ext), LCK_PR, &flags, - ldlm_completion_ast, NULL, NULL, 0, &lockh1); - - CERROR("ldlm_cli_enqueue: %d\n", err); - - flags = 0; - err = ldlm_cli_convert(&lockh1, LCK_EX, &flags); - CERROR("ldlm_cli_convert: %d\n", err); - - lock = ldlm_handle2lock(&lockh1); - ldlm_lock_dump(lock); - ldlm_lock_put(lock); - - /* Need to decrement old mode. Don't bother incrementing new - * mode since the test is done. - */ - if (err == ELDLM_OK) - ldlm_lock_decref(&lockh1, LCK_PR); - - RETURN(err); -} - -static int ldlm_do_decrement(void) -{ - struct ldlm_test_lock *lock_info; - struct ldlm_lock *lock; - int rc = 0; - ENTRY; - - spin_lock(&ctl_lock); - if(list_empty(&lock_list)) { - CERROR("lock_list is empty\n"); - spin_unlock(&ctl_lock); - RETURN(0); - } - - /* delete from list */ - lock_info = list_entry(lock_list.next, - struct ldlm_test_lock, l_link); - list_del(lock_list.next); - num_locks--; - spin_unlock(&ctl_lock); - - /* decrement and free the info */ - lock = ldlm_handle2lock(&lock_info->l_lockh); - ldlm_lock_decref(&lock_info->l_lockh, lock->l_granted_mode); - ldlm_lock_put(lock); - - OBD_FREE(lock_info, sizeof(*lock_info)); - - RETURN(rc); -} - -static int ldlm_do_enqueue(struct ldlm_test_thread *thread) -{ - struct lustre_handle lockh; - __u64 res_id[3] = {0}; - __u32 lock_mode; - struct ldlm_extent ext; - unsigned char random; - int flags = 0, rc = 0; - ENTRY; - - /* Pick a random resource from 1 to num_resources */ - get_random_bytes(&random, sizeof(random)); - res_id[0] = random % num_resources; - - /* Pick a random lock mode */ - get_random_bytes(&random, sizeof(random)); - lock_mode = random % LCK_NL + 1; - - /* Pick a random extent */ - get_random_bytes(&random, sizeof(random)); - ext.start = random % num_extents; - get_random_bytes(&random, sizeof(random)); - ext.end = random % - (num_extents - (int)ext.start) + ext.start; - - LDLM_DEBUG_NOLOCK("about to enqueue with resource "LPX64", mode %d," - " extent "LPX64" -> "LPX64, res_id[0], lock_mode, - ext.start, ext.end); - - rc = ldlm_match_or_enqueue(®ress_connh, NULL, - thread->obddev->obd_namespace, - NULL, res_id, LDLM_EXTENT, &ext, - sizeof(ext), lock_mode, &flags, - ldlm_test_completion_ast, - ldlm_test_blocking_ast, - NULL, 0, &lockh); - - atomic_inc(&locks_requested); - - if (rc < 0) { - CERROR("ldlm_cli_enqueue: %d\n", rc); - LBUG(); - } - - RETURN(rc); -} - -static int ldlm_do_convert(void) -{ - __u32 lock_mode; - unsigned char random; - int flags = 0, rc = 0; - struct ldlm_test_lock *lock_info; - struct ldlm_lock *lock; - ENTRY; - - /* delete from list */ - spin_lock(&ctl_lock); - lock_info = list_entry(lock_list.next, struct ldlm_test_lock, l_link); - list_del(lock_list.next); - num_locks--; - spin_unlock(&ctl_lock); - - /* Pick a random lock mode */ - get_random_bytes(&random, sizeof(random)); - lock_mode = random % LCK_NL + 1; - - /* do the conversion */ - rc = ldlm_cli_convert(&lock_info->l_lockh , lock_mode, &flags); - atomic_inc(&converts_requested); - - if (rc < 0) { - CERROR("ldlm_cli_convert: %d\n", rc); - LBUG(); - } - - /* - * Adjust reference counts. - * FIXME: This is technically a bit... wrong, - * since we don't know when/if the convert succeeded - */ - ldlm_lock_addref(&lock_info->l_lockh, lock_mode); - lock = ldlm_handle2lock(&lock_info->l_lockh); - ldlm_lock_decref(&lock_info->l_lockh, lock->l_granted_mode); - ldlm_lock_put(lock); - - OBD_FREE(lock_info, sizeof(*lock_info)); - - RETURN(rc); -} - - - -static int ldlm_test_main(void *data) -{ - struct ldlm_test_thread *thread = data; - ENTRY; - - lock_kernel(); - daemonize(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - sigfillset(¤t->blocked); - recalc_sigpending(); -#else - spin_lock_irq(¤t->sigmask_lock); - sigfillset(¤t->blocked); - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); -#endif - - sprintf(current->comm, "ldlm_test"); - unlock_kernel(); - - /* Record that the thread is running */ - thread->t_flags |= SVC_RUNNING; - wake_up(&thread->t_ctl_waitq); - - while (!(thread->t_flags & SVC_STOPPING)) { - unsigned char random; - unsigned char dec_chance, con_chance; - unsigned char chance_left = 100; - - spin_lock(&ctl_lock); - /* probability of decrementing increases linearly - * as more locks are held. - */ - dec_chance = chance_left * num_locks / max_locks; - chance_left -= dec_chance; - - /* FIXME: conversions temporarily disabled - * until they are working correctly. - */ - /* con_chance = chance_left * num_locks / max_locks; */ - con_chance = 0; - chance_left -= con_chance; - spin_unlock(&ctl_lock); - - get_random_bytes(&random, sizeof(random)); - - random = random % 100; - if (random < dec_chance) - ldlm_do_decrement(); - else if (random < (dec_chance + con_chance)) - ldlm_do_convert(); - else - ldlm_do_enqueue(thread); - - LDLM_DEBUG_NOLOCK("locks requested: %d, " - "conversions requested %d", - atomic_read(&locks_requested), - atomic_read(&converts_requested)); - LDLM_DEBUG_NOLOCK("locks granted: %d, " - "locks matched: %d", - atomic_read(&locks_granted), - atomic_read(&locks_matched)); - - spin_lock(&ctl_lock); - LDLM_DEBUG_NOLOCK("lock references currently held: %d, ", - num_locks); - spin_unlock(&ctl_lock); - - /* - * We don't sleep after a lock being blocked, so let's - * make sure other things can run. - */ - schedule(); - } - - thread->t_flags |= SVC_STOPPED; - wake_up(&thread->t_ctl_waitq); - - RETURN(0); -} - -static int ldlm_start_thread(struct obd_device *obddev, - struct lustre_handle *connh) -{ - struct ldlm_test_thread *test; - int rc; - ENTRY; - - OBD_ALLOC(test, sizeof(*test)); - if (test == NULL) { - LBUG(); - RETURN(-ENOMEM); - } - init_waitqueue_head(&test->t_ctl_waitq); - - test->obddev = obddev; - - spin_lock(&ctl_lock); - list_add(&test->t_link, &ctl_threads); - spin_unlock(&ctl_lock); - - rc = kernel_thread(ldlm_test_main, (void *)test, - CLONE_VM | CLONE_FS | CLONE_FILES); - if (rc < 0) { - CERROR("cannot start thread\n"); - RETURN(-EINVAL); - } - wait_event(test->t_ctl_waitq, test->t_flags & SVC_RUNNING); - - RETURN(0); -} - -int ldlm_regression_start(struct obd_device *obddev, - struct lustre_handle *connh, - unsigned int threads, unsigned int max_locks_in, - unsigned int num_resources_in, - unsigned int num_extents_in) -{ - int i, rc = 0; - ENTRY; - - spin_lock(&ctl_lock); - if (regression_running) { - CERROR("You can't start the ldlm regression twice.\n"); - spin_unlock(&ctl_lock); - RETURN(-EINVAL); - } - regression_running = 1; - spin_unlock(&ctl_lock); - - regress_connh = *connh; - max_locks = max_locks_in; - num_resources = num_resources_in; - num_extents = num_extents_in; - - LDLM_DEBUG_NOLOCK("regression test started: threads: %d, max_locks: " - "%d, num_res: %d, num_ext: %d\n", - threads, max_locks_in, num_resources_in, - num_extents_in); - - for (i = 0; i < threads; i++) { - rc = ldlm_start_thread(obddev, connh); - if (rc < 0) - GOTO(cleanup, rc); - } - - cleanup: - if (rc < 0) - ldlm_regression_stop(); - RETURN(rc); -} - -int ldlm_regression_stop(void) -{ - ENTRY; - - spin_lock(&ctl_lock); - if (!regression_running) { - CERROR("The ldlm regression isn't started.\n"); - spin_unlock(&ctl_lock); - RETURN(-EINVAL); - } - - while (!list_empty(&ctl_threads)) { - struct ldlm_test_thread *thread; - thread = list_entry(ctl_threads.next, struct ldlm_test_thread, - t_link); - - thread->t_flags |= SVC_STOPPING; - - spin_unlock(&ctl_lock); - wake_up(&thread->t_ctl_waitq); - wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_STOPPED); - spin_lock(&ctl_lock); - - list_del(&thread->t_link); - OBD_FREE(thread, sizeof(*thread)); - } - - /* decrement all held locks */ - while (!list_empty(&lock_list)) { - struct ldlm_lock *lock; - struct ldlm_test_lock *lock_info = - list_entry(lock_list.next, struct ldlm_test_lock, - l_link); - list_del(lock_list.next); - num_locks--; - - lock = ldlm_handle2lock(&lock_info->l_lockh); - ldlm_lock_decref(&lock_info->l_lockh, lock->l_granted_mode); - ldlm_lock_put(lock); - - OBD_FREE(lock_info, sizeof(*lock_info)); - } - - regression_running = 0; - spin_unlock(&ctl_lock); - - RETURN(0); -} - -int ldlm_test(struct obd_device *obddev, struct lustre_handle *connh) -{ - int rc; - rc = ldlm_test_basics(obddev); - if (rc) - RETURN(rc); - - rc = ldlm_test_extents(obddev); - if (rc) - RETURN(rc); - - rc = ldlm_test_network(obddev, connh); - RETURN(rc); -} diff --git a/lustre/lib/.cvsignore b/lustre/lib/.cvsignore deleted file mode 100644 index e530020..0000000 --- a/lustre/lib/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/lib/Makefile.am b/lustre/lib/Makefile.am deleted file mode 100644 index da31808..0000000 --- a/lustre/lib/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -EXTRA_DIST = mds_updates.c obd_pack.c ll_pack.c simple.c -EXTRA_DIST += client.c target.c - -include $(top_srcdir)/Rules diff --git a/lustre/lib/client.c b/lustre/lib/client.c deleted file mode 100644 index c75b399..0000000 --- a/lustre/lib/client.c +++ /dev/null @@ -1,267 +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. - * Author: Peter J. Braam - * Author: Phil Schwan - * Author: Mike Shaver - * - * 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. - * - * Client-common OBD method implementations and utility functions. - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_OST /* XXX WRONG */ - -#include -#include -#include -#include - -struct client_obd *client_conn2cli(struct lustre_handle *conn) -{ - struct obd_export *export = class_conn2export(conn); - if (!export) - LBUG(); - return &export->exp_obd->u.cli; -} - -int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct obd_ioctl_data* data = buf; - int rq_portal, rp_portal; - char *name; - struct client_obd *cli = &obddev->u.cli; - struct obd_import *imp = &cli->cl_import; - obd_uuid_t server_uuid; - ENTRY; - - if (obddev->obd_type->typ_ops->o_brw) { - rq_portal = OST_REQUEST_PORTAL; - rp_portal = OSC_REPLY_PORTAL; - name = "osc"; - } else { - rq_portal = MDS_REQUEST_PORTAL; - rp_portal = MDC_REPLY_PORTAL; - name = "mdc"; - } - - if (data->ioc_inllen1 < 1) { - CERROR("requires a TARGET UUID\n"); - RETURN(-EINVAL); - } - - if (data->ioc_inllen1 > 37) { - CERROR("client UUID must be less than 38 characters\n"); - RETURN(-EINVAL); - } - - if (data->ioc_inllen2 < 1) { - CERROR("setup requires a SERVER UUID\n"); - RETURN(-EINVAL); - } - - if (data->ioc_inllen2 > 37) { - CERROR("target UUID must be less than 38 characters\n"); - RETURN(-EINVAL); - } - - sema_init(&cli->cl_sem, 1); - cli->cl_conn_count = 0; - memcpy(cli->cl_target_uuid, data->ioc_inlbuf1, data->ioc_inllen1); - memcpy(server_uuid, data->ioc_inlbuf2, MIN(data->ioc_inllen2, - sizeof(server_uuid))); - - imp->imp_connection = ptlrpc_uuid_to_connection(server_uuid); - if (!imp->imp_connection) - RETURN(-ENOENT); - - INIT_LIST_HEAD(&imp->imp_replay_list); - INIT_LIST_HEAD(&imp->imp_sending_list); - INIT_LIST_HEAD(&imp->imp_delayed_list); - spin_lock_init(&imp->imp_lock); - - ptlrpc_init_client(rq_portal, rp_portal, name, - &obddev->obd_ldlm_client); - imp->imp_client = &obddev->obd_ldlm_client; - imp->imp_obd = obddev; - - cli->cl_max_mds_easize = sizeof(struct lov_mds_md); - - MOD_INC_USE_COUNT; - RETURN(0); -} - -int client_obd_cleanup(struct obd_device * obddev) -{ - struct client_obd *obd = &obddev->u.cli; - - ptlrpc_cleanup_client(&obd->cl_import); - ptlrpc_put_connection(obd->cl_import.imp_connection); - - MOD_DEC_USE_COUNT; - return 0; -} - -int client_obd_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct client_obd *cli = &obd->u.cli; - struct ptlrpc_request *request; - int rc, size[] = {sizeof(cli->cl_target_uuid), - sizeof(obd->obd_uuid) }; - char *tmp[] = {cli->cl_target_uuid, obd->obd_uuid}; - int rq_opc = (obd->obd_type->typ_ops->o_brw) ? OST_CONNECT :MDS_CONNECT; - struct ptlrpc_connection *c; - struct obd_import *imp = &cli->cl_import; - - ENTRY; - down(&cli->cl_sem); - MOD_INC_USE_COUNT; - rc = class_connect(conn, obd, cluuid); - if (rc) { - MOD_DEC_USE_COUNT; - GOTO(out_sem, rc); - } - cli->cl_conn_count++; - if (cli->cl_conn_count > 1) - GOTO(out_sem, rc); - - if (obd->obd_namespace != NULL) - CERROR("already have namespace!\n"); - obd->obd_namespace = ldlm_namespace_new(obd->obd_name, - LDLM_NAMESPACE_CLIENT); - if (obd->obd_namespace == NULL) - GOTO(out_disco, rc = -ENOMEM); - - INIT_LIST_HEAD(&imp->imp_chain); - imp->imp_last_xid = 0; - imp->imp_max_transno = 0; - imp->imp_peer_last_xid = 0; - imp->imp_peer_committed_transno = 0; - - request = ptlrpc_prep_req(&cli->cl_import, rq_opc, 2, size, tmp); - if (!request) - GOTO(out_ldlm, rc = -ENOMEM); - - request->rq_level = LUSTRE_CONN_NEW; - request->rq_replen = lustre_msg_size(0, NULL); - request->rq_reqmsg->addr = conn->addr; - request->rq_reqmsg->cookie = conn->cookie; - c = class_conn2export(conn)->exp_connection = - ptlrpc_connection_addref(request->rq_connection); - list_add(&imp->imp_chain, &c->c_imports); - recovd_conn_manage(c, recovd, recover); - - imp->imp_level = LUSTRE_CONN_CON; - rc = ptlrpc_queue_wait(request); - if (rc) - GOTO(out_req, rc); - - if (rq_opc == MDS_CONNECT) - imp->imp_flags |= IMP_REPLAYABLE; - imp->imp_level = LUSTRE_CONN_FULL; - imp->imp_handle.addr = request->rq_repmsg->addr; - imp->imp_handle.cookie = request->rq_repmsg->cookie; - - EXIT; -out_req: - ptlrpc_req_finished(request); - if (rc) { -out_ldlm: - ldlm_namespace_free(obd->obd_namespace); - obd->obd_namespace = NULL; - if (rq_opc == MDS_CONNECT) { - /* Don't class_disconnect OSCs, because the LOV - * cares about them even if they can't connect to the - * OST. - * - * This is leak-bait, but without either a way to - * operate on the osc without an export or separate - * methods for connect-to-osc and connect-osc-to-ost - * it's not clear what else to do. - */ -out_disco: - cli->cl_conn_count--; - class_disconnect(conn); - MOD_DEC_USE_COUNT; - } - } -out_sem: - up(&cli->cl_sem); - return rc; -} - -int client_obd_disconnect(struct lustre_handle *conn) -{ - struct obd_device *obd = class_conn2obd(conn); - struct client_obd *cli = &obd->u.cli; - int rq_opc; - struct ptlrpc_request *request = NULL; - int rc, err; - ENTRY; - - if (!obd) { - CERROR("invalid connection for disconnect: addr "LPX64 - ", cookie "LPX64"\n", conn ? conn->addr : -1UL, - conn ? conn->cookie : -1UL); - RETURN(-EINVAL); - } - - rq_opc = obd->obd_type->typ_ops->o_brw ? OST_DISCONNECT:MDS_DISCONNECT; - down(&cli->cl_sem); - if (!cli->cl_conn_count) { - CERROR("disconnecting disconnected device (%s)\n", - obd->obd_name); - GOTO(out_sem, rc = -EINVAL); - } - - cli->cl_conn_count--; - if (cli->cl_conn_count) - GOTO(out_disco, rc = 0); - - ldlm_namespace_free(obd->obd_namespace); - obd->obd_namespace = NULL; - request = ptlrpc_prep_req(&cli->cl_import, rq_opc, 0, NULL, - NULL); - if (!request) - GOTO(out_disco, rc = -ENOMEM); - - request->rq_replen = lustre_msg_size(0, NULL); - - /* Process disconnects even if we're waiting for recovery. */ - request->rq_level = LUSTRE_CONN_RECOVD; - - rc = ptlrpc_queue_wait(request); - if (rc) - GOTO(out_req, rc); - - EXIT; - out_req: - if (request) - ptlrpc_req_finished(request); - out_disco: - err = class_disconnect(conn); - if (!rc && err) - rc = err; - list_del_init(&cli->cl_import.imp_chain); - MOD_DEC_USE_COUNT; - out_sem: - up(&cli->cl_sem); - RETURN(rc); -} diff --git a/lustre/lib/ll_pack.c b/lustre/lib/ll_pack.c deleted file mode 100644 index 184c2c1..0000000 --- a/lustre/lib/ll_pack.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. - * - * (Un)packing of OST/MDS requests - * - */ - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include - -void obd_statfs_pack(struct obd_statfs *tgt, struct obd_statfs *src) -{ - tgt->os_type = HTON__u64(src->os_type); - tgt->os_blocks = HTON__u64(src->os_blocks); - tgt->os_bfree = HTON__u64(src->os_bfree); - tgt->os_bavail = HTON__u64(src->os_bavail); - tgt->os_files = HTON__u64(src->os_files); - tgt->os_ffree = HTON__u64(src->os_ffree); - tgt->os_bsize = HTON__u32(src->os_bsize); - tgt->os_namelen = HTON__u32(src->os_namelen); -} - -#define obd_statfs_unpack(tgt, src) obd_statfs_pack(tgt, src) - -void statfs_pack(struct obd_statfs *osfs, struct statfs *sfs) -{ - osfs->os_type = sfs->f_type; - osfs->os_blocks = sfs->f_blocks; - osfs->os_bfree = sfs->f_bfree; - osfs->os_bavail = sfs->f_bavail; - osfs->os_files = sfs->f_files; - osfs->os_ffree = sfs->f_ffree; - osfs->os_bsize = sfs->f_bsize; - osfs->os_namelen = sfs->f_namelen; -} - -void statfs_unpack(struct statfs *sfs, struct obd_statfs *osfs) -{ - sfs->f_type = osfs->os_type; - sfs->f_blocks = osfs->os_blocks; - sfs->f_bfree = osfs->os_bfree; - sfs->f_bavail = osfs->os_bavail; - sfs->f_files = osfs->os_files; - sfs->f_ffree = osfs->os_ffree; - sfs->f_bsize = osfs->os_bsize; - sfs->f_namelen = osfs->os_namelen; -} - diff --git a/lustre/lib/mds_updates.c b/lustre/lib/mds_updates.c deleted file mode 100644 index 6a53cb6..0000000 --- a/lustre/lib/mds_updates.c +++ /dev/null @@ -1,478 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copryright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.sf.net/projects/lustre/ - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Lustre Lite Update Records - */ - -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#include // for wait_on_buffer -#else -#include // for wait_on_buffer -#endif -#include - -#include -#include - -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_MDS - -#include -#include -#include -#include - -void mds_pack_inode2fid(struct ll_fid *fid, struct inode *inode) -{ - fid->id = HTON__u64(inode->i_ino); - fid->generation = HTON__u32(inode->i_generation); - fid->f_type = HTON__u32(S_IFMT & inode->i_mode); -} - - -void mds_pack_inode2body(struct mds_body *b, struct inode *inode) -{ - b->valid = OBD_MD_FLID | OBD_MD_FLATIME | OBD_MD_FLMTIME | - OBD_MD_FLCTIME | OBD_MD_FLSIZE | OBD_MD_FLUID | OBD_MD_FLGID | - OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLNLINK | OBD_MD_FLGENER; - b->ino = HTON__u32(inode->i_ino); - b->atime = HTON__u32(inode->i_atime); - b->mtime = HTON__u32(inode->i_mtime); - b->ctime = HTON__u32(inode->i_ctime); - b->mode = HTON__u32(inode->i_mode); - b->size = HTON__u64(inode->i_size); - b->uid = HTON__u32(inode->i_uid); - b->gid = HTON__u32(inode->i_gid); - b->flags = HTON__u32(inode->i_flags); - b->rdev = HTON__u32(b->rdev); - b->nlink = HTON__u32(inode->i_nlink); - b->generation = HTON__u32(inode->i_generation); -} - - -void mds_pack_fid(struct ll_fid *fid) -{ - fid->id = HTON__u64(fid->id); - fid->generation = HTON__u32(fid->generation); - fid->f_type = HTON__u32(fid->f_type); -} - -static void mds_pack_body(struct mds_body *b) -{ - if (b == NULL) - LBUG(); - - b->fsuid = HTON__u32(current->fsuid); - b->fsgid = HTON__u32(current->fsgid); - b->capability = HTON__u32(current->cap_effective); - - mds_pack_fid(&b->fid1); - mds_pack_fid(&b->fid2); - b->size = HTON__u64(b->size); - b->ino = HTON__u32(b->ino); - b->valid = HTON__u32(b->valid); - b->mode = HTON__u32(b->mode); - b->uid = HTON__u32(b->uid); - b->gid = HTON__u32(b->gid); - b->mtime = HTON__u32(b->mtime); - b->ctime = HTON__u32(b->ctime); - b->atime = HTON__u32(b->atime); - b->flags = HTON__u32(b->flags); - b->rdev = HTON__u32(b->rdev); - b->nlink = HTON__u32(b->nlink); - b->generation = HTON__u32(b->generation); -} - -void mds_getattr_pack(struct ptlrpc_request *req, int offset, - struct inode *inode, - const char *name, int namelen) -{ - struct mds_body *b; - b = lustre_msg_buf(req->rq_reqmsg, offset); - - b->fsuid = HTON__u32(current->fsuid); - b->fsgid = HTON__u32(current->fsgid); - b->capability = HTON__u32(current->cap_effective); - - ll_inode2fid(&b->fid1, inode); - if (name) { - char *tmp; - tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); - LOGL0(name, namelen, tmp); - } -} - -void mds_readdir_pack(struct ptlrpc_request *req, __u64 offset, - obd_id ino, int type) -{ - struct mds_body *b; - - b = lustre_msg_buf(req->rq_reqmsg, 0); - b->fsuid = HTON__u32(current->fsuid); - b->fsgid = HTON__u32(current->fsgid); - b->capability = HTON__u32(current->cap_effective); - b->fid1.id = HTON__u64(ino); - b->fid1.f_type = HTON__u32(type); - b->size = HTON__u64(offset); -} - - -void mds_pack_req_body(struct ptlrpc_request *req) -{ - struct mds_body *b = lustre_msg_buf(req->rq_reqmsg, 0); - mds_pack_body(b); -} - -void mds_pack_rep_body(struct ptlrpc_request *req) -{ - struct mds_body *b = lustre_msg_buf(req->rq_repmsg, 0); - mds_pack_body(b); -} - - -/* packing of MDS records */ -void mds_create_pack(struct ptlrpc_request *req, int offset, struct inode *dir, - __u32 mode, __u64 rdev, __u32 uid, __u32 gid, __u64 time, - const char *name, int namelen, - const void *data, int datalen) -{ - struct mds_rec_create *rec; - char *tmp; - rec = lustre_msg_buf(req->rq_reqmsg, offset); - - /* XXX do something about time, uid, gid */ - rec->cr_opcode = HTON__u32(REINT_CREATE); - rec->cr_fsuid = HTON__u32(current->fsuid); - rec->cr_fsgid = HTON__u32(current->fsgid); - rec->cr_cap = HTON__u32(current->cap_effective); - ll_inode2fid(&rec->cr_fid, dir); - memset(&rec->cr_replayfid, 0, sizeof(rec->cr_replayfid)); - rec->cr_mode = HTON__u32(mode); - rec->cr_rdev = HTON__u64(rdev); - rec->cr_uid = HTON__u32(uid); - rec->cr_gid = HTON__u32(gid); - rec->cr_time = HTON__u64(time); - - tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); - LOGL0(name, namelen, tmp); - - if (data) { - tmp = lustre_msg_buf(req->rq_reqmsg, offset + 2); - LOGL0(data, datalen, tmp); - } -} - -void mds_setattr_pack(struct ptlrpc_request *req, int offset, - struct inode *inode, struct iattr *iattr, - const char *name, int namelen) -{ - struct mds_rec_setattr *rec; - rec = lustre_msg_buf(req->rq_reqmsg, offset); - - rec->sa_opcode = HTON__u32(REINT_SETATTR); - rec->sa_fsuid = HTON__u32(current->fsuid); - rec->sa_fsgid = HTON__u32(current->fsgid); - rec->sa_cap = HTON__u32(current->cap_effective); - ll_inode2fid(&rec->sa_fid, inode); - rec->sa_valid = HTON__u32(iattr->ia_valid); - rec->sa_mode = HTON__u32(iattr->ia_mode); - rec->sa_uid = HTON__u32(iattr->ia_uid); - rec->sa_gid = HTON__u32(iattr->ia_gid); - rec->sa_size = HTON__u64(iattr->ia_size); - rec->sa_atime = HTON__u64(iattr->ia_atime); - rec->sa_mtime = HTON__u64(iattr->ia_mtime); - rec->sa_ctime = HTON__u64(iattr->ia_ctime); - rec->sa_attr_flags = HTON__u32(iattr->ia_attr_flags); - - if (namelen) { - char *tmp; - tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); - LOGL0(name, namelen, tmp); - } -} - -void mds_unlink_pack(struct ptlrpc_request *req, int offset, - struct inode *inode, struct inode *child, __u32 mode, - const char *name, int namelen) -{ - struct mds_rec_unlink *rec; - char *tmp; - - rec = lustre_msg_buf(req->rq_reqmsg, offset); - - rec->ul_opcode = HTON__u32(REINT_UNLINK); - rec->ul_fsuid = HTON__u32(current->fsuid); - rec->ul_fsgid = HTON__u32(current->fsgid); - rec->ul_cap = HTON__u32(current->cap_effective); - rec->ul_mode = HTON__u32(mode); - ll_inode2fid(&rec->ul_fid1, inode); - if (child) - ll_inode2fid(&rec->ul_fid2, child); - - tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); - LOGL0(name, namelen, tmp); -} - -void mds_link_pack(struct ptlrpc_request *req, int offset, - struct inode *inode, struct inode *dir, - const char *name, int namelen) -{ - struct mds_rec_link *rec; - char *tmp; - - rec = lustre_msg_buf(req->rq_reqmsg, offset); - - rec->lk_opcode = HTON__u32(REINT_LINK); - rec->lk_fsuid = HTON__u32(current->fsuid); - rec->lk_fsgid = HTON__u32(current->fsgid); - rec->lk_cap = HTON__u32(current->cap_effective); - ll_inode2fid(&rec->lk_fid1, inode); - ll_inode2fid(&rec->lk_fid2, dir); - - tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); - LOGL0(name, namelen, tmp); -} - -void mds_rename_pack(struct ptlrpc_request *req, int offset, - struct inode *srcdir, struct inode *tgtdir, - const char *old, int oldlen, const char *new, int newlen) -{ - struct mds_rec_rename *rec; - char *tmp; - - rec = lustre_msg_buf(req->rq_reqmsg, offset); - - /* XXX do something about time, uid, gid */ - rec->rn_opcode = HTON__u32(REINT_RENAME); - rec->rn_fsuid = HTON__u32(current->fsuid); - rec->rn_fsgid = HTON__u32(current->fsgid); - rec->rn_cap = HTON__u32(current->cap_effective); - ll_inode2fid(&rec->rn_fid1, srcdir); - ll_inode2fid(&rec->rn_fid2, tgtdir); - - tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); - LOGL0(old, oldlen, tmp); - - if (new) { - tmp = lustre_msg_buf(req->rq_reqmsg, offset + 2); - LOGL0(new, newlen, tmp); - } -} - -/* unpacking */ -void mds_unpack_fid(struct ll_fid *fid) -{ - fid->id = NTOH__u64(fid->id); - fid->generation = NTOH__u32(fid->generation); - fid->f_type = NTOH__u32(fid->f_type); -} - -void mds_unpack_body(struct mds_body *b) -{ - if (b == NULL) - LBUG(); - - mds_unpack_fid(&b->fid1); - mds_unpack_fid(&b->fid2); - b->size = NTOH__u64(b->size); - b->valid = NTOH__u32(b->valid); - b->fsuid = NTOH__u32(b->fsuid); - b->fsgid = NTOH__u32(b->fsgid); - b->capability = NTOH__u32(b->capability); - b->ino = NTOH__u32(b->ino); - b->mode = NTOH__u32(b->mode); - b->uid = NTOH__u32(b->uid); - b->gid = NTOH__u32(b->gid); - b->mtime = NTOH__u32(b->mtime); - b->ctime = NTOH__u32(b->ctime); - b->atime = NTOH__u32(b->atime); - b->flags = NTOH__u32(b->flags); - b->rdev = NTOH__u32(b->rdev); - b->nlink = NTOH__u32(b->nlink); - b->generation = NTOH__u32(b->generation); -} - -static int mds_setattr_unpack(struct ptlrpc_request *req, int offset, - struct mds_update_record *r) -{ - struct iattr *attr = &r->ur_iattr; - struct mds_rec_setattr *rec = lustre_msg_buf(req->rq_reqmsg, offset); - ENTRY; - - if (req->rq_reqmsg->bufcount < offset + 1 || - req->rq_reqmsg->buflens[offset] != sizeof(*rec)) - RETURN(-EFAULT); - - r->ur_fsuid = NTOH__u32(rec->sa_fsuid); - r->ur_fsgid = NTOH__u32(rec->sa_fsgid); - r->ur_cap = NTOH__u32(rec->sa_cap); - r->ur_fid1 = &rec->sa_fid; - attr->ia_valid = NTOH__u32(rec->sa_valid); - attr->ia_mode = NTOH__u32(rec->sa_mode); - attr->ia_uid = NTOH__u32(rec->sa_uid); - attr->ia_gid = NTOH__u32(rec->sa_gid); - attr->ia_size = NTOH__u64(rec->sa_size); - attr->ia_atime = NTOH__u64(rec->sa_atime); - attr->ia_mtime = NTOH__u64(rec->sa_mtime); - attr->ia_ctime = NTOH__u64(rec->sa_ctime); - attr->ia_attr_flags = NTOH__u32(rec->sa_attr_flags); - - if (req->rq_reqmsg->bufcount == offset + 2) { - r->ur_namelen = req->rq_reqmsg->buflens[offset + 1]; - r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1); - } else - r->ur_namelen = 0; - - RETURN(0); -} - -static int mds_create_unpack(struct ptlrpc_request *req, int offset, - struct mds_update_record *r) -{ - struct mds_rec_create *rec = lustre_msg_buf(req->rq_reqmsg, offset); - ENTRY; - - if (req->rq_reqmsg->bufcount < offset + 2 || - req->rq_reqmsg->buflens[offset] != sizeof(*rec)) - RETURN(-EFAULT); - - r->ur_fsuid = NTOH__u32(rec->cr_fsuid); - r->ur_fsgid = NTOH__u32(rec->cr_fsgid); - r->ur_cap = NTOH__u32(rec->cr_cap); - r->ur_fid1 = &rec->cr_fid; - r->ur_fid2 = &rec->cr_replayfid; - r->ur_mode = NTOH__u32(rec->cr_mode); - r->ur_rdev = NTOH__u64(rec->cr_rdev); - r->ur_uid = NTOH__u32(rec->cr_uid); - r->ur_gid = NTOH__u32(rec->cr_gid); - r->ur_time = NTOH__u64(rec->cr_time); - - r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1); - r->ur_namelen = req->rq_reqmsg->buflens[offset + 1]; - - if (req->rq_reqmsg->bufcount == offset + 3) { - r->ur_tgt = lustre_msg_buf(req->rq_reqmsg, offset + 2); - r->ur_tgtlen = req->rq_reqmsg->buflens[offset + 2]; - } else { - r->ur_tgt = NULL; - r->ur_tgtlen = 0; - } - RETURN(0); -} - -static int mds_link_unpack(struct ptlrpc_request *req, int offset, - struct mds_update_record *r) -{ - struct mds_rec_link *rec = lustre_msg_buf(req->rq_reqmsg, offset); - ENTRY; - - if (req->rq_reqmsg->bufcount != offset + 2 || - req->rq_reqmsg->buflens[offset] != sizeof(*rec)) - RETURN(-EFAULT); - - r->ur_fsuid = NTOH__u32(rec->lk_fsuid); - r->ur_fsgid = NTOH__u32(rec->lk_fsgid); - r->ur_cap = NTOH__u32(rec->lk_cap); - r->ur_fid1 = &rec->lk_fid1; - r->ur_fid2 = &rec->lk_fid2; - - r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1); - r->ur_namelen = req->rq_reqmsg->buflens[offset + 1]; - RETURN(0); -} - -static int mds_unlink_unpack(struct ptlrpc_request *req, int offset, - struct mds_update_record *r) -{ - struct mds_rec_unlink *rec = lustre_msg_buf(req->rq_reqmsg, offset); - ENTRY; - - if (req->rq_reqmsg->bufcount != offset + 2 || - req->rq_reqmsg->buflens[offset] != sizeof(*rec)) - RETURN(-EFAULT); - - r->ur_fsuid = NTOH__u32(rec->ul_fsuid); - r->ur_fsgid = NTOH__u32(rec->ul_fsgid); - r->ur_cap = NTOH__u32(rec->ul_cap); - r->ur_mode = NTOH__u32(rec->ul_mode); - r->ur_fid1 = &rec->ul_fid1; - r->ur_fid2 = &rec->ul_fid2; - - r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1); - r->ur_namelen = req->rq_reqmsg->buflens[offset + 1]; - RETURN(0); -} - -static int mds_rename_unpack(struct ptlrpc_request *req, int offset, - struct mds_update_record *r) -{ - struct mds_rec_rename *rec = lustre_msg_buf(req->rq_reqmsg, offset); - ENTRY; - - if (req->rq_reqmsg->bufcount != offset + 3 || - req->rq_reqmsg->buflens[offset] != sizeof(*rec)) - RETURN(-EFAULT); - - r->ur_fsuid = NTOH__u32(rec->rn_fsuid); - r->ur_fsgid = NTOH__u32(rec->rn_fsgid); - r->ur_cap = NTOH__u32(rec->rn_cap); - r->ur_fid1 = &rec->rn_fid1; - r->ur_fid2 = &rec->rn_fid2; - - r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1); - r->ur_namelen = req->rq_reqmsg->buflens[offset + 1]; - - r->ur_tgt = lustre_msg_buf(req->rq_reqmsg, offset + 2); - r->ur_tgtlen = req->rq_reqmsg->buflens[offset + 2]; - RETURN(0); -} - -typedef int (*update_unpacker)(struct ptlrpc_request *req, int offset, - struct mds_update_record *r); - -static update_unpacker mds_unpackers[REINT_MAX + 1] = { - [REINT_SETATTR] mds_setattr_unpack, - [REINT_CREATE] mds_create_unpack, - [REINT_LINK] mds_link_unpack, - [REINT_UNLINK] mds_unlink_unpack, - [REINT_RENAME] mds_rename_unpack, -}; - -int mds_update_unpack(struct ptlrpc_request *req, int offset, - struct mds_update_record *rec) -{ - __u32 *opcode = lustre_msg_buf(req->rq_reqmsg, offset); - int rc, realop; - ENTRY; - - if (!opcode || req->rq_reqmsg->buflens[offset] < sizeof(*opcode)) - RETURN(-EFAULT); - - realop = rec->ur_opcode = NTOH__u32(*opcode); - realop &= REINT_OPCODE_MASK; - - if (realop < 0 || realop > REINT_MAX) - RETURN(-EFAULT); - - rc = mds_unpackers[realop](req, offset, rec); - RETURN(rc); -} diff --git a/lustre/lib/obd_pack.c b/lustre/lib/obd_pack.c deleted file mode 100644 index 8b3c33a..0000000 --- a/lustre/lib/obd_pack.c +++ /dev/null @@ -1,80 +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. - * - * (Un)packing of OST requests - * - */ - -#define DEBUG_SUBSYSTEM S_OST - -#include -#include - -void ost_pack_ioo(void **tmp, struct lov_stripe_md *lsm, int bufcnt) -{ - struct obd_ioobj *ioo = *tmp; - char *c = *tmp; - - ioo->ioo_id = HTON__u64(lsm->lsm_object_id); - ioo->ioo_gr = HTON__u64(0); - ioo->ioo_type = HTON__u32(S_IFREG); - ioo->ioo_bufcnt = HTON__u32(bufcnt); - *tmp = c + sizeof(*ioo); -} - -void ost_unpack_ioo(void **tmp, struct obd_ioobj **ioop) -{ - char *c = *tmp; - struct obd_ioobj *ioo = *tmp; - *ioop = *tmp; - - ioo->ioo_id = NTOH__u64(ioo->ioo_id); - ioo->ioo_gr = NTOH__u64(ioo->ioo_gr); - ioo->ioo_type = NTOH__u32(ioo->ioo_type); - ioo->ioo_bufcnt = NTOH__u32(ioo->ioo_bufcnt); - *tmp = c + sizeof(*ioo); -} - -void ost_pack_niobuf(void **tmp, __u64 offset, __u32 len, __u32 flags, - __u32 xid) -{ - struct niobuf_remote *nb = *tmp; - char *c = *tmp; - - nb->offset = HTON__u64(offset); - nb->len = HTON__u32(len); - nb->flags = HTON__u32(flags); - nb->xid = HTON__u32(xid); - *tmp = c + sizeof(*nb); -} - -void ost_unpack_niobuf(void **tmp, struct niobuf_remote **nbp) -{ - char *c = *tmp; - struct niobuf_remote *nb = *tmp; - - *nbp = *tmp; - - nb->offset = NTOH__u64(nb->offset); - nb->len = NTOH__u32(nb->len); - nb->flags = NTOH__u32(nb->flags); - - *tmp = c + sizeof(*nb); -} diff --git a/lustre/lib/simple.c b/lustre/lib/simple.c deleted file mode 100644 index 4b423d4..0000000 --- a/lustre/lib/simple.c +++ /dev/null @@ -1,236 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lib/simple.c - * - * 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 Peter Braam - * and Andreas Dilger - */ - -#define EXPORT_SYMTAB - -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_FILTER - -#include -#include -#include -#include -#include - -#ifdef OBD_CTXT_DEBUG -/* Debugging check only needed during development */ -#define ASSERT_CTXT_MAGIC(magic) do { if ((magic) != OBD_RUN_CTXT_MAGIC) { \ - CERROR("bad ctxt magic\n"); LBUG(); } } while(0) -#define ASSERT_NOT_KERNEL_CTXT(msg) do { if (segment_eq(get_fs(), get_ds())) { \ - CERROR(msg); LBUG(); } } while(0) -#define ASSERT_KERNEL_CTXT(msg) do { if (!segment_eq(get_fs(), get_ds())) { \ - CERROR(msg); LBUG(); } } while(0) -#else -#define ASSERT_CTXT_MAGIC(magic) do {} while(0) -#define ASSERT_NOT_KERNEL_CTXT(msg) do {} while(0) -#define ASSERT_KERNEL_CTXT(msg) do {} while(0) -#endif - -/* push / pop to root of obd store */ -void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx, - struct obd_ucred *uc) -{ - //ASSERT_NOT_KERNEL_CTXT("already in kernel context!\n"); - ASSERT_CTXT_MAGIC(new_ctx->magic); - OBD_SET_CTXT_MAGIC(save); - - /* - CDEBUG(D_INFO, "== push %p->%p == cur fs %p pwd %p (%*s), pwdmnt %p\n", - save, current, current->fs, current->fs->pwd, - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt); - */ - - save->fs = get_fs(); - save->pwd = dget(current->fs->pwd); - save->pwdmnt = mntget(current->fs->pwdmnt); - - LASSERT(save->pwd); - LASSERT(save->pwdmnt); - LASSERT(new_ctx->pwd); - LASSERT(new_ctx->pwdmnt); - - if (uc) { - save->fsuid = current->fsuid; - save->fsgid = current->fsgid; - save->cap = current->cap_effective; - - current->fsuid = uc->ouc_fsuid; - current->fsgid = uc->ouc_fsgid; - current->cap_effective = uc->ouc_cap; - } - set_fs(new_ctx->fs); - set_fs_pwd(current->fs, new_ctx->pwdmnt, new_ctx->pwd); - - /* - CDEBUG(D_INFO, "== push %p==%p == cur fs %p pwd %p (%*s), pwdmnt %p\n", - new_ctx, current, current->fs, current->fs->pwd, - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt); - */ -} - -void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx, - struct obd_ucred *uc) -{ - //printk("pc0"); - ASSERT_CTXT_MAGIC(saved->magic); - //printk("pc1"); - ASSERT_KERNEL_CTXT("popping non-kernel context!\n"); - - /* - CDEBUG(D_INFO, " == pop %p==%p == cur %p pwd %p (%*s), pwdmnt %p\n", - new_ctx, current, current->fs, current->fs->pwd, - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt); - */ - - LASSERT(current->fs->pwd == new_ctx->pwd); - LASSERT(current->fs->pwdmnt == new_ctx->pwdmnt); - - //printk("pc2"); - set_fs(saved->fs); - //printk("pc3\n"); - set_fs_pwd(current->fs, saved->pwdmnt, saved->pwd); - //printk("pc4"); - - dput(saved->pwd); - //printk("pc5"); - mntput(saved->pwdmnt); - //printk("pc6\n"); - if (uc) { - current->fsuid = saved->fsuid; - current->fsgid = saved->fsgid; - current->cap_effective = saved->cap; - } - - /* - CDEBUG(D_INFO, "== pop %p->%p == cur fs %p pwd %p (%*s), pwdmnt %p\n", - saved, current, current->fs, current->fs->pwd, - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt); - */ -} - -/* utility to make a file */ -struct dentry *simple_mknod(struct dentry *dir, char *name, int mode) -{ - struct dentry *dchild; - int err = 0; - ENTRY; - - ASSERT_KERNEL_CTXT("kernel doing mknod outside kernel context\n"); - CDEBUG(D_INODE, "creating file %*s\n", (int)strlen(name), name); - - down(&dir->d_inode->i_sem); - dchild = lookup_one_len(name, dir, strlen(name)); - if (IS_ERR(dchild)) - GOTO(out, PTR_ERR(dchild)); - - if (dchild->d_inode) { - if ((dchild->d_inode->i_mode & S_IFMT) != S_IFREG) - GOTO(out, err = -EEXIST); - - GOTO(out, dchild); - } - - err = vfs_create(dir->d_inode, dchild, (mode & ~S_IFMT) | S_IFREG); - EXIT; -out: - up(&dir->d_inode->i_sem); - if (err) { - dput(dchild); - RETURN(ERR_PTR(err)); - } - - RETURN(dchild); -} - -/* utility to make a directory */ -struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode) -{ - struct dentry *dchild; - int err = 0; - ENTRY; - - ASSERT_KERNEL_CTXT("kernel doing mkdir outside kernel context\n"); - CDEBUG(D_INODE, "creating directory %*s\n", (int)strlen(name), name); - down(&dir->d_inode->i_sem); - dchild = lookup_one_len(name, dir, strlen(name)); - if (IS_ERR(dchild)) - GOTO(out, PTR_ERR(dchild)); - - if (dchild->d_inode) { - if (!S_ISDIR(dchild->d_inode->i_mode)) - GOTO(out, err = -ENOTDIR); - - GOTO(out, dchild); - } - - err = vfs_mkdir(dir->d_inode, dchild, mode); - EXIT; -out: - up(&dir->d_inode->i_sem); - if (err) { - dput(dchild); - RETURN(ERR_PTR(err)); - } - - RETURN(dchild); -} - -/* - * Read a file from within kernel context. Prior to calling this - * function we should already have done a push_ctxt(). - */ -int lustre_fread(struct file *file, char *str, int len, loff_t *off) -{ - ASSERT_KERNEL_CTXT("kernel doing read outside kernel context\n"); - if (!file || !file->f_op || !file->f_op->read || !off) - RETURN(-ENOSYS); - - return file->f_op->read(file, str, len, off); -} - -/* - * Write a file from within kernel context. Prior to calling this - * function we should already have done a push_ctxt(). - */ -int lustre_fwrite(struct file *file, const char *str, int len, loff_t *off) -{ - ASSERT_KERNEL_CTXT("kernel doing write outside kernel context\n"); - if (!file || !file->f_op || !off) - RETURN(-ENOSYS); - - if (!file->f_op->write) - RETURN(-EROFS); - - return file->f_op->write(file, str, len, off); -} - -/* - * Sync a file from within kernel context. Prior to calling this - * function we should already have done a push_ctxt(). - */ -int lustre_fsync(struct file *file) -{ - ASSERT_KERNEL_CTXT("kernel doing sync outside kernel context\n"); - if (!file || !file->f_op || !file->f_op->fsync) - RETURN(-ENOSYS); - - return file->f_op->fsync(file, file->f_dentry, 0); -} diff --git a/lustre/lib/target.c b/lustre/lib/target.c deleted file mode 100644 index 141e155..0000000 --- a/lustre/lib/target.c +++ /dev/null @@ -1,175 +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. - * Author: Peter J. Braam - * Author: Phil Schwan - * Author: Mike Shaver - * - * 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. - * - * Target-common OBD method implementations and utility functions. - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_OST /* XXX WRONG */ - -#include -#include -#include -#include - -int target_handle_connect(struct ptlrpc_request *req) -{ - struct obd_device *target; - struct obd_export *export; - struct obd_import *dlmimp; - struct lustre_handle conn; - char *tgtuuid, *cluuid; - int rc, i; - ENTRY; - - tgtuuid = lustre_msg_buf(req->rq_reqmsg, 0); - if (req->rq_reqmsg->buflens[0] > 37) { - CERROR("bad target UUID for connect\n"); - GOTO(out, rc = -EINVAL); - } - - cluuid = lustre_msg_buf(req->rq_reqmsg, 1); - if (req->rq_reqmsg->buflens[1] > 37) { - CERROR("bad client UUID for connect\n"); - GOTO(out, rc = -EINVAL); - } - - i = class_uuid2dev(tgtuuid); - if (i == -1) { - CERROR("UUID '%s' not found for connect\n", tgtuuid); - GOTO(out, rc = -ENODEV); - } - - target = &obd_dev[i]; - if (!target) - GOTO(out, rc = -ENODEV); - - conn.addr = req->rq_reqmsg->addr; - conn.cookie = req->rq_reqmsg->cookie; - - rc = obd_connect(&conn, target, cluuid, ptlrpc_recovd, - target_revoke_connection); - /* EALREADY indicates a reconnection, send the reply normally. */ - if (rc && rc != EALREADY) - GOTO(out, rc); - - rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - GOTO(out, rc); - req->rq_repmsg->addr = conn.addr; - req->rq_repmsg->cookie = conn.cookie; - - export = class_conn2export(&conn); - LASSERT(export); - - req->rq_export = export; - export->exp_connection = ptlrpc_get_connection(&req->rq_peer, cluuid); - if (req->rq_connection != NULL) - ptlrpc_put_connection(req->rq_connection); - req->rq_connection = ptlrpc_connection_addref(export->exp_connection); - - spin_lock(&export->exp_connection->c_lock); - list_add(&export->exp_conn_chain, &export->exp_connection->c_exports); - spin_unlock(&export->exp_connection->c_lock); - recovd_conn_manage(export->exp_connection, ptlrpc_recovd, - target_revoke_connection); - - dlmimp = &export->exp_ldlm_data.led_import; - dlmimp->imp_connection = req->rq_connection; - dlmimp->imp_client = &export->exp_obd->obd_ldlm_client; - dlmimp->imp_handle.addr = req->rq_reqmsg->addr; - dlmimp->imp_handle.cookie = req->rq_reqmsg->cookie; - dlmimp->imp_obd = /* LDLM! */ NULL; - spin_lock_init(&dlmimp->imp_lock); - dlmimp->imp_level = LUSTRE_CONN_FULL; -out: - req->rq_status = rc; - RETURN(rc); -} - -int target_handle_disconnect(struct ptlrpc_request *req) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - int rc; - ENTRY; - - rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - - req->rq_status = obd_disconnect(conn); - - RETURN(0); -} - -static int target_disconnect_client(struct ptlrpc_connection *conn) -{ - struct list_head *expiter, *n; - struct lustre_handle hdl; - struct obd_export *exp; - int rc; - ENTRY; - - list_for_each_safe(expiter, n, &conn->c_exports) { - exp = list_entry(expiter, struct obd_export, exp_conn_chain); - - hdl.addr = (__u64)(unsigned long)exp; - hdl.cookie = exp->exp_cookie; - rc = obd_disconnect(&hdl); - if (rc) - CERROR("disconnecting export %p failed: %d\n", exp, rc); - } - - /* XXX spank the connection (it's frozen in _RECOVD for now!) */ - RETURN(0); -} - -static int target_fence_failed_connection(struct ptlrpc_connection *conn) -{ - ENTRY; - - conn->c_recovd_data.rd_phase = RD_PREPARED; - - RETURN(0); -} - -int target_revoke_connection(struct recovd_data *rd, int phase) -{ - struct ptlrpc_connection *conn = class_rd2conn(rd); - - LASSERT(conn); - ENTRY; - - switch (phase) { - case PTLRPC_RECOVD_PHASE_PREPARE: - RETURN(target_fence_failed_connection(conn)); - case PTLRPC_RECOVD_PHASE_RECOVER: - RETURN(target_disconnect_client(conn)); - case PTLRPC_RECOVD_PHASE_FAILURE: - LBUG(); - RETURN(0); - } - - LBUG(); - RETURN(-ENOSYS); -} diff --git a/lustre/llite/.cvsignore b/lustre/llite/.cvsignore deleted file mode 100644 index e530020..0000000 --- a/lustre/llite/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/llite/Makefile.am b/lustre/llite/Makefile.am deleted file mode 100644 index 071c0fd..0000000 --- a/lustre/llite/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= - -MODULE = llite -modulefs_DATA = llite.o -EXTRA_PROGRAMS = llite - -LINX= ll_pack.c - -llite_SOURCES = dcache.c commit_callback.c super.c rw.c super25.c -llite_SOURCES += file.c dir.c sysctl.c symlink.c $(LINX) -llite_SOURCES += recover.c namei.c lproc_llite.c - -ll_pack.c: - test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c . - -include $(top_srcdir)/Rules diff --git a/lustre/llite/commit_callback.c b/lustre/llite/commit_callback.c deleted file mode 100644 index e5a595a..0000000 --- a/lustre/llite/commit_callback.c +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * The daemon that causes completed but not committed transactions - * on the MDS to be flushed periodically when they are committed. - * A gratuitous getattr RPC is made to the MDS to discover the - * last committed record. - * - * 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include - -static int ll_commitcbd_check_event(struct ll_sb_info *sbi) -{ - int rc = 0; - ENTRY; - - spin_lock(&sbi->ll_commitcbd_lock); - if (sbi->ll_commitcbd_flags & LL_COMMITCBD_STOPPING) { - GOTO(out, rc = 1); - } - - out: - spin_unlock(&sbi->ll_commitcbd_lock); - RETURN(rc); -} - -static int ll_commitcbd_main(void *arg) -{ - struct ll_sb_info *sbi = (struct ll_sb_info *)arg; - - 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, "lustre_commitcbd"); - unlock_kernel(); - - /* Record that the thread is running */ - sbi->ll_commitcbd_waketime = CURRENT_TIME; - sbi->ll_commitcbd_timeout = 10 * HZ; - sbi->ll_commitcbd_thread = current; - sbi->ll_commitcbd_flags = LL_COMMITCBD_RUNNING; - wake_up(&sbi->ll_commitcbd_ctl_waitq); - - /* And now, loop forever on requests */ - while (1) { - wait_event(sbi->ll_commitcbd_waitq, - ll_commitcbd_check_event(sbi)); - - spin_lock(&sbi->ll_commitcbd_lock); - if (sbi->ll_commitcbd_flags & LL_COMMITCBD_STOPPING) { - spin_unlock(&sbi->ll_commitcbd_lock); - CERROR("lustre_commitd quitting\n"); - EXIT; - break; - } - - schedule_timeout(sbi->ll_commitcbd_timeout); - CERROR("commit callback daemon woken up - FIXME\n"); - spin_unlock(&sbi->ll_commitcbd_lock); - } - - sbi->ll_commitcbd_thread = NULL; - sbi->ll_commitcbd_flags = LL_COMMITCBD_STOPPED; - wake_up(&sbi->ll_commitcbd_ctl_waitq); - CDEBUG(D_NET, "commit callback daemon exiting %d\n", current->pid); - RETURN(0); -} - - - -int ll_commitcbd_setup(struct ll_sb_info *sbi) -{ - int rc; - ENTRY; - - rc = kernel_thread(ll_commitcbd_main, (void *) sbi, - CLONE_VM | CLONE_FS | CLONE_FILES); - if (rc < 0) { - CERROR("cannot start thread\n"); - RETURN(rc); - } - wait_event(sbi->ll_commitcbd_ctl_waitq, - sbi->ll_commitcbd_flags & LL_COMMITCBD_RUNNING); - RETURN(0); -} - - -int ll_commitcbd_cleanup(struct ll_sb_info *sbi) -{ - sbi->ll_commitcbd_flags = LL_COMMITCBD_STOPPING; - - wake_up(&sbi->ll_commitcbd_waitq); - wait_event(sbi->ll_commitcbd_ctl_waitq, - sbi->ll_commitcbd_flags & LL_COMMITCBD_STOPPED); - RETURN(0); -} diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c deleted file mode 100644 index 9a12fd5..0000000 --- a/lustre/llite/dcache.c +++ /dev/null @@ -1,185 +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 -#include - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include -#include - -extern struct address_space_operations ll_aops; - -void ll_release(struct dentry *de) -{ - ENTRY; - - OBD_FREE(de->d_fsdata, sizeof(struct ll_dentry_data)); - EXIT; -} - -extern void d_delete_aliases(struct inode *); -void ll_intent_release(struct dentry *de, struct lookup_intent *it) -{ - struct lustre_handle *handle; - ENTRY; - - /* XXX the check for RENAME2 is a workaround for old kernels - which call intent_release twice in rename - */ - if (it == NULL || it->it_op == IT_RENAME2) { - EXIT; - return; - } - - LASSERT(ll_d2d(de) != NULL); - - if (it->it_lock_mode) { - handle = (struct lustre_handle *)it->it_lock_handle; - if (it->it_op == IT_SETATTR) { - int rc; - ldlm_lock_decref(handle, it->it_lock_mode); - rc = ldlm_cli_cancel(handle); - if (rc < 0) - CERROR("ldlm_cli_cancel: %d\n", rc); - } else - ldlm_lock_decref(handle, it->it_lock_mode); - - /* intent_release may be called multiple times, and we don't - * want to double-decref this lock (see bug 494) */ - it->it_lock_mode = 0; - } - - if (!de->d_it || it->it_op == IT_RELEASED_MAGIC) { - EXIT; - return; - } - - if (de->d_it == it) - LL_GET_INTENT(de, it); - - EXIT; -} - -extern struct dentry *ll_find_alias(struct inode *, struct dentry *); - -static int revalidate2_finish(int flag, struct ptlrpc_request *request, - struct dentry **de, - struct lookup_intent *it, - int offset, obd_id ino) -{ - ldlm_lock_set_data((struct lustre_handle *)it->it_lock_handle, - (*de)->d_inode, sizeof(*((*de)->d_inode))); - ptlrpc_req_finished(request); - return 0; -} - -static int ll_have_lock(struct dentry *de) -{ - struct ll_sb_info *sbi = ll_s2sbi(de->d_sb); - struct lustre_handle lockh; - __u64 res_id[RES_NAME_SIZE] = {0}; - struct obd_device *obddev; - ENTRY; - - if (!de->d_inode) - RETURN(0); - - obddev = class_conn2obd(&sbi->ll_mdc_conn); - res_id[0] = de->d_inode->i_ino; - res_id[1] = de->d_inode->i_generation; - - CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id[0]); - - if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_PLAIN, - NULL, 0, LCK_PR, &lockh)) { - ldlm_lock_decref(&lockh, LCK_PR); - RETURN(1); - } - - if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_PLAIN, - NULL, 0, LCK_PW, &lockh)) { - ldlm_lock_decref(&lockh, LCK_PW); - RETURN(1); - } - RETURN(0); -} - -int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it) -{ - int rc; - ENTRY; - - /* We don't want to cache negative dentries, so return 0 immediately. - * We believe that this is safe, that negative dentries cannot be - * pinned by someone else */ - if (de->d_inode == NULL) { - CDEBUG(D_INODE, "negative dentry: ret 0 to force lookup2\n"); - RETURN(0); - } - -// if (it == NULL && ll_have_lock(de)) -// RETURN(1); - - rc = ll_intent_lock(de->d_parent->d_inode, &de, it, revalidate2_finish); - if (rc < 0) { - /* Something bad happened; overwrite it_status? */ - CERROR("ll_intent_lock: %d\n", rc); - } - /* unfortunately ll_intent_lock may cause a callback and revoke our - dentry */ - spin_lock(&dcache_lock); - list_del_init(&de->d_hash); - spin_unlock(&dcache_lock); - d_rehash(de); - - RETURN(1); -} - -int ll_set_dd(struct dentry *de) -{ - ENTRY; - LASSERT(de != NULL); - - lock_kernel(); - - if (de->d_fsdata != NULL) { - CERROR("dentry %p already has d_fsdata set\n", de); - } else { - OBD_ALLOC(de->d_fsdata, sizeof(struct ll_dentry_data)); - sema_init(&ll_d2d(de)->lld_it_sem, 1); - } - - unlock_kernel(); - - RETURN(0); -} - -struct dentry_operations ll_d_ops = { - .d_revalidate2 = ll_revalidate2, - .d_intent_release = ll_intent_release, - .d_release = ll_release, -}; diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c deleted file mode 100644 index 6f67f4b..0000000 --- a/lustre/llite/dir.c +++ /dev/null @@ -1,751 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/minix/dir.c - * linux/fs/ext2/dir.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * ext2 directory handling functions - * - * Big-endian to little-endian byte-swapping/bitmaps by - * David S. Miller (davem@caip.rutgers.edu), 1995 - * - * All code that works with directory layout had been switched to pagecache - * and moved here. AV - * - * Adapted for Lustre Light - * Copyright (C) 2002, Cluster File Systems, Inc. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#include // for wait_on_buffer -#else -#include // for wait_on_buffer -#endif - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include -#include -#include -#include -#include - -typedef struct ext2_dir_entry_2 ext2_dirent; - -#define PageChecked(page) test_bit(PG_checked, &(page)->flags) -#define SetPageChecked(page) set_bit(PG_checked, &(page)->flags) - - -static int ll_dir_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) -{ - return 0; -} - -/* returns the page unlocked, but with a reference */ -static int ll_dir_readpage(struct file *file, struct page *page) -{ - struct inode *inode = page->mapping->host; - struct ll_sb_info *sbi = ll_i2sbi(inode); - char *buf; - __u64 offset; - int rc = 0; - struct ptlrpc_request *request; - struct lustre_handle lockh; - struct mds_body *body; - struct lookup_intent it = { .it_op = IT_READDIR }; - - ENTRY; - - if ((inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT <= page->index){ - memset(kmap(page), 0, PAGE_CACHE_SIZE); - kunmap(page); - GOTO(readpage_out, rc); - } - - rc = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_PLAIN, &it, LCK_PR, inode, - NULL, &lockh, NULL, 0, inode, sizeof(*inode)); - request = (struct ptlrpc_request *)it.it_data; - if (request) - ptlrpc_req_finished(request); - if (rc != ELDLM_OK) { - CERROR("lock enqueue: err: %d\n", rc); - unlock_page(page); - RETURN(rc); - } - ldlm_lock_dump((void *)(unsigned long)lockh.addr); - - if (PageUptodate(page)) { - CERROR("Explain this please?\n"); - GOTO(readpage_out, rc); - } - - offset = page->index << PAGE_SHIFT; - buf = kmap(page); - rc = mdc_readpage(&sbi->ll_mdc_conn, inode->i_ino, - S_IFDIR, offset, buf, &request); - kunmap(page); - if (!rc) { - body = lustre_msg_buf(request->rq_repmsg, 0); - if (!body) - rc = -EINVAL; - else - inode->i_size = body->size; - } - ptlrpc_req_finished(request); - EXIT; - - readpage_out: - if (!rc) - SetPageUptodate(page); - - unlock_page(page); - rc = ll_unlock(LCK_PR, &lockh); - if (rc != ELDLM_OK) - CERROR("ll_unlock: err: %d\n", rc); - return rc; -} /* ll_dir_readpage */ - -struct address_space_operations ll_dir_aops = { - readpage: ll_dir_readpage, - prepare_write: ll_dir_prepare_write -}; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)) -int waitfor_one_page(struct page *page) -{ - int error = 0; - struct buffer_head *bh, *head = page->buffers; - - bh = head; - do { - wait_on_buffer(bh); - if (buffer_req(bh) && !buffer_uptodate(bh)) - error = -EIO; - } while ((bh = bh->b_this_page) != head); - return error; -} -#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -int waitfor_one_page(struct page *page) -{ - wait_on_page_locked(page); - return 0; -} -#endif - -/* - * ext2 uses block-sized chunks. Arguably, sector-sized ones would be - * more robust, but we have what we have - */ -static inline unsigned ext2_chunk_size(struct inode *inode) -{ - return inode->i_sb->s_blocksize; -} - -static inline void ext2_put_page(struct page *page) -{ - kunmap(page); - page_cache_release(page); -} - -static inline unsigned long dir_pages(struct inode *inode) -{ - return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; -} - -extern void set_page_clean(struct page *page); - -static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to) -{ - struct inode *dir = page->mapping->host; - loff_t new_size = (page->index << PAGE_CACHE_SHIFT) + to; - int err = 0; - - dir->i_version = ++event; - if (new_size > dir->i_size) - dir->i_size = new_size; - SetPageUptodate(page); - set_page_clean(page); - - //page->mapping->a_ops->commit_write(NULL, page, from, to); - //if (IS_SYNC(dir)) - // err = waitfor_one_page(page); - return err; -} - -static void ext2_check_page(struct page *page) -{ - struct inode *dir = page->mapping->host; - unsigned chunk_size = ext2_chunk_size(dir); - char *kaddr = page_address(page); - // u32 max_inumber = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count); - unsigned offs, rec_len; - unsigned limit = PAGE_CACHE_SIZE; - ext2_dirent *p; - char *error; - - if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) { - limit = dir->i_size & ~PAGE_CACHE_MASK; - if (limit & (chunk_size - 1)) { - CERROR("limit %d dir size %lld index %ld\n", - limit, dir->i_size, page->index); - goto Ebadsize; - } - for (offs = limit; offsrec_len = cpu_to_le16(chunk_size); - p->name_len = 0; - p->inode = 0; - } - if (!limit) - goto out; - } - for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) { - p = (ext2_dirent *)(kaddr + offs); - rec_len = le16_to_cpu(p->rec_len); - - if (rec_len < EXT2_DIR_REC_LEN(1)) - goto Eshort; - if (rec_len & 3) - goto Ealign; - if (rec_len < EXT2_DIR_REC_LEN(p->name_len)) - goto Enamelen; - if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1)) - goto Espan; - // if (le32_to_cpu(p->inode) > max_inumber) - //goto Einumber; - } - if (offs != limit) - goto Eend; -out: - SetPageChecked(page); - return; - - /* Too bad, we had an error */ - -Ebadsize: - CERROR("ext2_check_page" - "size of directory #%lu is not a multiple of chunk size\n", - dir->i_ino - ); - goto fail; -Eshort: - error = "rec_len is smaller than minimal"; - goto bad_entry; -Ealign: - error = "unaligned directory entry"; - goto bad_entry; -Enamelen: - error = "rec_len is too small for name_len"; - goto bad_entry; -Espan: - error = "directory entry across blocks"; - goto bad_entry; - //Einumber: - // error = "inode out of bounds"; -bad_entry: - CERROR("ext2_check_page: bad entry in directory #%lu: %s - " - "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", - dir->i_ino, error, (page->index<inode), - rec_len, p->name_len); - goto fail; -Eend: - p = (ext2_dirent *)(kaddr + offs); - CERROR("ext2_check_page" - "entry in directory #%lu spans the page boundary" - "offset=%lu, inode=%lu", - dir->i_ino, (page->index<inode)); -fail: - SetPageChecked(page); - SetPageError(page); - LBUG(); -} - -static struct page * ll_get_page(struct inode *dir, unsigned long n) -{ - struct address_space *mapping = dir->i_mapping; - struct page *page = read_cache_page(mapping, n, - (filler_t*)mapping->a_ops->readpage, NULL); - if (!IS_ERR(page)) { - wait_on_page(page); - kmap(page); - if (!PageUptodate(page)) - goto fail; - if (!PageChecked(page)) - ext2_check_page(page); - if (PageError(page)) - goto fail; - } - return page; - -fail: - ext2_put_page(page); - return ERR_PTR(-EIO); -} - -/* - * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure. - * - * len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller. - */ -static inline int ext2_match (int len, const char * const name, - struct ext2_dir_entry_2 * de) -{ - if (len != de->name_len) - return 0; - if (!de->inode) - return 0; - return !memcmp(name, de->name, len); -} - -/* - * p is at least 6 bytes before the end of page - */ -static inline ext2_dirent *ext2_next_entry(ext2_dirent *p) -{ - return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len)); -} - -static inline unsigned -ext2_validate_entry(char *base, unsigned offset, unsigned mask) -{ - ext2_dirent *de = (ext2_dirent*)(base + offset); - ext2_dirent *p = (ext2_dirent*)(base + (offset&mask)); - while ((char*)p < (char*)de) - p = ext2_next_entry(p); - return (char *)p - base; -} - -static unsigned char ext2_filetype_table[EXT2_FT_MAX] = { - [EXT2_FT_UNKNOWN] DT_UNKNOWN, - [EXT2_FT_REG_FILE] DT_REG, - [EXT2_FT_DIR] DT_DIR, - [EXT2_FT_CHRDEV] DT_CHR, - [EXT2_FT_BLKDEV] DT_BLK, - [EXT2_FT_FIFO] DT_FIFO, - [EXT2_FT_SOCK] DT_SOCK, - [EXT2_FT_SYMLINK] DT_LNK, -}; - -static unsigned int ll_dt2fmt[DT_WHT + 1] = { - [EXT2_FT_UNKNOWN] 0, - [EXT2_FT_REG_FILE] S_IFREG, - [EXT2_FT_DIR] S_IFDIR, - [EXT2_FT_CHRDEV] S_IFCHR, - [EXT2_FT_BLKDEV] S_IFBLK, - [EXT2_FT_FIFO] S_IFIFO, - [EXT2_FT_SOCK] S_IFSOCK, - [EXT2_FT_SYMLINK] S_IFLNK -}; - -#define S_SHIFT 12 -static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = { - [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE, - [S_IFDIR >> S_SHIFT] EXT2_FT_DIR, - [S_IFCHR >> S_SHIFT] EXT2_FT_CHRDEV, - [S_IFBLK >> S_SHIFT] EXT2_FT_BLKDEV, - [S_IFIFO >> S_SHIFT] EXT2_FT_FIFO, - [S_IFSOCK >> S_SHIFT] EXT2_FT_SOCK, - [S_IFLNK >> S_SHIFT] EXT2_FT_SYMLINK, -}; - -static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode) -{ - mode_t mode = inode->i_mode; - de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; -} - -int ll_readdir(struct file * filp, void * dirent, filldir_t filldir) -{ - loff_t pos = filp->f_pos; - struct inode *inode = filp->f_dentry->d_inode; - // XXX struct super_block *sb = inode->i_sb; - unsigned offset = pos & ~PAGE_CACHE_MASK; - unsigned long n = pos >> PAGE_CACHE_SHIFT; - unsigned long npages = dir_pages(inode); - unsigned chunk_mask = ~(ext2_chunk_size(inode)-1); - unsigned char *types = NULL; - int need_revalidate = (filp->f_version != inode->i_version); - ENTRY; - - if (pos > inode->i_size - EXT2_DIR_REC_LEN(1)) - GOTO(done, 0); - - types = ext2_filetype_table; - - for ( ; n < npages; n++, offset = 0) { - char *kaddr, *limit; - ext2_dirent *de; - struct page *page; - - page = ll_get_page(inode, n); - - /* size might have been updated by mdc_readpage */ - npages = dir_pages(inode); - - if (IS_ERR(page)) - continue; - kaddr = page_address(page); - if (need_revalidate) { - offset = ext2_validate_entry(kaddr, offset, chunk_mask); - need_revalidate = 0; - } - de = (ext2_dirent *)(kaddr+offset); - limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1); - for ( ;(char*)de <= limit; de = ext2_next_entry(de)) - if (de->inode) { - int over; - unsigned char d_type = DT_UNKNOWN; - - if (types && de->file_type < EXT2_FT_MAX) - d_type = types[de->file_type]; - - offset = (char *)de - kaddr; - over = filldir(dirent, de->name, de->name_len, - (n<inode), d_type); - if (over) { - ext2_put_page(page); - GOTO(done,0); - } - } - ext2_put_page(page); - } - -done: - filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; - filp->f_version = inode->i_version; - UPDATE_ATIME(inode); - RETURN(0); -} - -/* - * ext2_find_entry() - * - * finds an entry in the specified directory with the wanted name. It - * returns the page in which the entry was found, and the entry itself - * (as a parameter - res_dir). Page is returned mapped and unlocked. - * Entry is guaranteed to be valid. - */ -struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir, - struct dentry *dentry, struct page ** res_page) -{ - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; - unsigned reclen = EXT2_DIR_REC_LEN(namelen); - unsigned long start, n; - unsigned long npages = dir_pages(dir); - struct page *page = NULL; - ext2_dirent * de; - - /* OFFSET_CACHE */ - *res_page = NULL; - - // start = dir->u.ext2_i.i_dir_start_lookup; - start = 0; - if (start >= npages) - start = 0; - n = start; - do { - char *kaddr; - page = ll_get_page(dir, n); - if (!IS_ERR(page)) { - kaddr = page_address(page); - de = (ext2_dirent *) kaddr; - kaddr += PAGE_CACHE_SIZE - reclen; - while ((char *) de <= kaddr) { - if (ext2_match (namelen, name, de)) - goto found; - de = ext2_next_entry(de); - } - ext2_put_page(page); - } - if (++n >= npages) - n = 0; - } while (n != start); - return NULL; - -found: - *res_page = page; - // dir->u.ext2_i.i_dir_start_lookup = n; - return de; -} - -struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p) -{ - struct page *page = ll_get_page(dir, 0); - ext2_dirent *de = NULL; - - if (!IS_ERR(page)) { - de = ext2_next_entry((ext2_dirent *) page_address(page)); - *p = page; - } - return de; -} - -obd_id ll_inode_by_name(struct inode * dir, struct dentry *dentry, int *type) -{ - obd_id res = 0; - struct ext2_dir_entry_2 * de; - struct page *page; - - de = ext2_find_entry (dir, dentry, &page); - if (de) { - res = le32_to_cpu(de->inode); - *type = ll_dt2fmt[de->file_type]; - kunmap(page); - page_cache_release(page); - } - return res; -} - -/* Releases the page */ -void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, - struct page *page, struct inode *inode) -{ - unsigned from = (char *) de - (char *) page_address(page); - unsigned to = from + le16_to_cpu(de->rec_len); - int err; - - lock_page(page); - err = page->mapping->a_ops->prepare_write(NULL, page, from, to); - if (err) - LBUG(); - de->inode = cpu_to_le32(inode->i_ino); - ext2_set_de_type (de, inode); - dir->i_mtime = dir->i_ctime = CURRENT_TIME; - err = ext2_commit_chunk(page, from, to); - unlock_page(page); - ext2_put_page(page); -} - -/* - * Parent is locked. - */ -int ll_add_link (struct dentry *dentry, struct inode *inode) -{ - struct inode *dir = dentry->d_parent->d_inode; - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; - unsigned reclen = EXT2_DIR_REC_LEN(namelen); - unsigned short rec_len, name_len; - struct page *page = NULL; - ext2_dirent * de; - unsigned long npages = dir_pages(dir); - unsigned long n; - char *kaddr; - unsigned from, to; - int err; - - /* We take care of directory expansion in the same loop */ - for (n = 0; n <= npages; n++) { - page = ll_get_page(dir, n); - err = PTR_ERR(page); - if (IS_ERR(page)) - goto out; - kaddr = page_address(page); - de = (ext2_dirent *)kaddr; - kaddr += PAGE_CACHE_SIZE - reclen; - while ((char *)de <= kaddr) { - err = -EEXIST; - if (ext2_match (namelen, name, de)) - goto out_page; - name_len = EXT2_DIR_REC_LEN(de->name_len); - rec_len = le16_to_cpu(de->rec_len); - if ( n==npages && rec_len == 0) { - CERROR("Fatal dir behaviour\n"); - goto out_page; - } - if (!de->inode && rec_len >= reclen) - goto got_it; - if (rec_len >= name_len + reclen) - goto got_it; - de = (ext2_dirent *) ((char *) de + rec_len); - } - ext2_put_page(page); - } - LBUG(); - return -EINVAL; - -got_it: - from = (char*)de - (char*)page_address(page); - to = from + rec_len; - lock_page(page); - err = page->mapping->a_ops->prepare_write(NULL, page, from, to); - if (err) - goto out_unlock; - if (de->inode) { - ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len); - de1->rec_len = cpu_to_le16(rec_len - name_len); - de->rec_len = cpu_to_le16(name_len); - de = de1; - } - de->name_len = namelen; - memcpy (de->name, name, namelen); - de->inode = cpu_to_le32(inode->i_ino); - ext2_set_de_type (de, inode); - CDEBUG(D_INODE, "type set to %o\n", de->file_type); - dir->i_mtime = dir->i_ctime = CURRENT_TIME; - err = ext2_commit_chunk(page, from, to); - - // change_inode happens with the commit_chunk - /* XXX OFFSET_CACHE */ - -out_unlock: - unlock_page(page); -out_page: - ext2_put_page(page); -out: - return err; -} - -/* - * ext2_delete_entry deletes a directory entry by merging it with the - * previous entry. Page is up-to-date. Releases the page. - */ -int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) -{ - struct address_space *mapping = page->mapping; - struct inode *inode = mapping->host; - char *kaddr = page_address(page); - unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); - unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len); - ext2_dirent * pde = NULL; - ext2_dirent * de = (ext2_dirent *) (kaddr + from); - int err; - - while ((char*)de < (char*)dir) { - pde = de; - de = ext2_next_entry(de); - } - if (pde) - from = (char*)pde - (char*)page_address(page); - lock_page(page); - err = mapping->a_ops->prepare_write(NULL, page, from, to); - if (err) - LBUG(); - if (pde) - pde->rec_len = cpu_to_le16(to-from); - dir->inode = 0; - inode->i_ctime = inode->i_mtime = CURRENT_TIME; - err = ext2_commit_chunk(page, from, to); - unlock_page(page); - ext2_put_page(page); - return err; -} - -/* - * Set the first fragment of directory. - */ -int ext2_make_empty(struct inode *inode, struct inode *parent) -{ - struct address_space *mapping = inode->i_mapping; - struct page *page = grab_cache_page(mapping, 0); - unsigned chunk_size = ext2_chunk_size(inode); - struct ext2_dir_entry_2 * de; - char *base; - int err; - ENTRY; - - if (!page) - return -ENOMEM; - base = kmap(page); - if (!base) - return -ENOMEM; - - err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size); - if (err) - goto fail; - - de = (struct ext2_dir_entry_2 *) base; - de->name_len = 1; - de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1)); - memcpy (de->name, ".\0\0", 4); - de->inode = cpu_to_le32(inode->i_ino); - ext2_set_de_type (de, inode); - - de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1)); - de->name_len = 2; - de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1)); - de->inode = cpu_to_le32(parent->i_ino); - memcpy (de->name, "..\0", 4); - ext2_set_de_type (de, inode); - - err = ext2_commit_chunk(page, 0, chunk_size); -fail: - kunmap(page); - unlock_page(page); - page_cache_release(page); - ENTRY; - return err; -} - -/* - * routine to check that the specified directory is empty (for rmdir) - */ -int ext2_empty_dir (struct inode * inode) -{ - struct page *page = NULL; - unsigned long i, npages = dir_pages(inode); - - for (i = 0; i < npages; i++) { - char *kaddr; - ext2_dirent * de; - page = ll_get_page(inode, i); - - if (IS_ERR(page)) - continue; - - kaddr = page_address(page); - de = (ext2_dirent *)kaddr; - kaddr += PAGE_CACHE_SIZE-EXT2_DIR_REC_LEN(1); - - while ((char *)de <= kaddr) { - if (de->inode != 0) { - /* check for . and .. */ - if (de->name[0] != '.') - goto not_empty; - if (de->name_len > 2) - goto not_empty; - if (de->name_len < 2) { - if (de->inode != - cpu_to_le32(inode->i_ino)) - goto not_empty; - } else if (de->name[1] != '.') - goto not_empty; - } - de = ext2_next_entry(de); - } - ext2_put_page(page); - } - return 1; - -not_empty: - ext2_put_page(page); - return 0; -} - -struct file_operations ll_dir_operations = { - read: generic_read_dir, - readdir: ll_readdir -}; diff --git a/lustre/llite/file.c b/lustre/llite/file.c deleted file mode 100644 index a67b023..0000000 --- a/lustre/llite/file.c +++ /dev/null @@ -1,844 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * linux/fs/ext2/file.c - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/minix/file.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * ext2 fs regular file handling primitives - * - * 64-bit file support on 64-bit platforms by Jakub Jelinek - * (jj@sunsite.ms.mff.cuni.cz) - */ - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include /* for lov_mds_md_size() in lov_setstripe() */ -#include - -int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc); -extern int ll_setattr(struct dentry *de, struct iattr *attr); - -int ll_create_objects(struct super_block *sb, obd_id id, uid_t uid, gid_t gid, - struct lov_stripe_md **lsmp) -{ - struct obdo *oa; - int rc; - ENTRY; - - oa = obdo_alloc(); - if (!oa) - RETURN(-ENOMEM); - - oa->o_mode = S_IFREG | 0600; - oa->o_id = id; - oa->o_uid = uid; - oa->o_gid = gid; - oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE | - OBD_MD_FLUID | OBD_MD_FLGID; - rc = obd_create(ll_s2obdconn(sb), oa, lsmp); - obdo_free(oa); - - if (!rc) - LASSERT(*lsmp && (*lsmp)->lsm_object_id); - RETURN(rc); -} - -static int ll_file_open(struct inode *inode, struct file *file) -{ - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ll_inode_info *lli = ll_i2info(inode); - struct lustre_handle *conn = ll_i2obdconn(inode); - struct ptlrpc_request *req = NULL; - struct ll_file_data *fd; - struct obdo *oa; - struct lov_stripe_md *lsm; - struct lov_mds_md *lmm = NULL; - int lmm_size = 0; - int rc = 0; - ENTRY; - - LASSERT(!file->private_data); - - lsm = lli->lli_smd; - - /* delayed create of object (intent created inode) */ - /* XXX object needs to be cleaned up if mdc_open fails */ - /* XXX error handling appropriate here? */ - if (lsm == NULL) { - if (file->f_flags & O_LOV_DELAY_CREATE) { - CDEBUG(D_INODE, "delaying object creation\n"); - RETURN(0); - } - down(&lli->lli_open_sem); - /* Check to see if we lost the race */ - if (!lli->lli_smd) - rc = ll_create_objects(inode->i_sb, inode->i_ino, 0, 0, - &lli->lli_smd); - up(&lli->lli_open_sem); - if (rc) - RETURN(rc); - - lsm = lli->lli_smd; - } - - /* XXX We should only send this to MDS if we just created these - * objects, except we also need to handle the user-stripe case. - */ - rc = obd_packmd(conn, &lmm, lli->lli_smd); - if (rc < 0) - GOTO(out, rc); - - lmm_size = rc; - - fd = kmem_cache_alloc(ll_file_data_slab, SLAB_KERNEL); - if (!fd) { - if (lmm) - obd_free_wiremd(conn, &lmm); - GOTO(out, rc = -ENOMEM); - } - memset(fd, 0, sizeof(*fd)); - - fd->fd_mdshandle.addr = (__u64)(unsigned long)file; - get_random_bytes(&fd->fd_mdshandle.cookie, - sizeof(fd->fd_mdshandle.cookie)); - rc = mdc_open(&sbi->ll_mdc_conn, inode->i_ino, S_IFREG | inode->i_mode, - file->f_flags, lmm, lmm_size, &fd->fd_mdshandle, &req); - if (lmm) - obd_free_wiremd(conn, &lmm); - fd->fd_req = req; - - /* This is the "reply" refcount. */ - ptlrpc_req_finished(req); - if (rc) - GOTO(out_req, -abs(rc)); - if (!fd->fd_mdshandle.addr || - fd->fd_mdshandle.addr == (__u64)(unsigned long)file) { - CERROR("hmm, mdc_open didn't assign fd_mdshandle?\n"); - /* XXX handle this how, abort or is it non-fatal? */ - } - - oa = obdo_alloc(); - if (!oa) - GOTO(out_mdc, rc = -EINVAL); - - oa->o_id = lsm->lsm_object_id; - oa->o_mode = S_IFREG; - oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE | - OBD_MD_FLBLOCKS; - rc = obd_open(ll_i2obdconn(inode), oa, lsm); - obdo_to_inode(inode, oa, oa->o_valid & (OBD_MD_FLSIZE|OBD_MD_FLBLOCKS)); - - obd_oa2handle(&fd->fd_osthandle, oa); - obdo_free(oa); - - if (rc) - GOTO(out_mdc, rc = -abs(rc)); - - atomic_inc(&lli->lli_open_count); - - file->private_data = fd; - - RETURN(0); -out_mdc: - mdc_close(&sbi->ll_mdc_conn, inode->i_ino, - S_IFREG, &fd->fd_mdshandle, &req); -out_req: - ptlrpc_req_finished(req); /* once for reply */ - ptlrpc_req_finished(req); /* once for an early "commit" */ -//out_fd: - fd->fd_mdshandle.cookie = DEAD_HANDLE_MAGIC; - kmem_cache_free(ll_file_data_slab, fd); -out: - return rc; -} - -int ll_size_lock(struct inode *inode, struct lov_stripe_md *lsm, obd_off start, - int mode, struct lustre_handle **lockhs_p) -{ - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ldlm_extent extent; - struct lustre_handle *lockhs = NULL; - int rc, flags = 0, stripe_count; - ENTRY; - - if (sbi->ll_flags & LL_SBI_NOLCK) { - *lockhs_p = NULL; - RETURN(0); - } - - stripe_count = lsm->lsm_stripe_count; - if (!stripe_count) - stripe_count = 1; - - OBD_ALLOC(lockhs, stripe_count * sizeof(*lockhs)); - if (lockhs == NULL) - RETURN(-ENOMEM); - - extent.start = start; - extent.end = OBD_OBJECT_EOF; - - rc = obd_enqueue(&sbi->ll_osc_conn, lsm, NULL, LDLM_EXTENT, &extent, - sizeof(extent), mode, &flags, ll_lock_callback, - inode, sizeof(*inode), lockhs); - if (rc != ELDLM_OK) { - CERROR("lock enqueue: %d\n", rc); - OBD_FREE(lockhs, stripe_count * sizeof(*lockhs)); - } else - *lockhs_p = lockhs; - RETURN(rc); -} - -int ll_size_unlock(struct inode *inode, struct lov_stripe_md *lsm, int mode, - struct lustre_handle *lockhs) -{ - struct ll_sb_info *sbi = ll_i2sbi(inode); - int rc, stripe_count; - ENTRY; - - if (sbi->ll_flags & LL_SBI_NOLCK) - RETURN(0); - - if (lockhs == NULL) { - LBUG(); - RETURN(-EINVAL); - } - - rc = obd_cancel(&sbi->ll_osc_conn, lsm, mode, lockhs); - if (rc != ELDLM_OK) { - CERROR("lock cancel: %d\n", rc); - LBUG(); - } - - stripe_count = lsm->lsm_stripe_count; - if (!stripe_count) - stripe_count = 1; - - OBD_FREE(lockhs, stripe_count * sizeof(*lockhs)); - RETURN(rc); -} - -int ll_file_size(struct inode *inode, struct lov_stripe_md *lsm) -{ - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct lustre_handle *lockhs; - struct obdo oa; - int err, rc; - ENTRY; - - LASSERT(lsm); - LASSERT(sbi); - - rc = ll_size_lock(inode, lsm, 0, LCK_PR, &lockhs); - if (rc != ELDLM_OK) { - CERROR("lock enqueue: %d\n", rc); - RETURN(rc); - } - - oa.o_id = lsm->lsm_object_id; - oa.o_mode = S_IFREG; - oa.o_valid = OBD_MD_FLID|OBD_MD_FLTYPE|OBD_MD_FLSIZE|OBD_MD_FLBLOCKS; - rc = obd_getattr(&sbi->ll_osc_conn, &oa, lsm); - if (!rc) - obdo_to_inode(inode, &oa, - oa.o_valid & ~(OBD_MD_FLTYPE | OBD_MD_FLMODE)); - - err = ll_size_unlock(inode, lsm, LCK_PR, lockhs); - if (err != ELDLM_OK) { - CERROR("lock cancel: %d\n", err); - LBUG(); - } - RETURN(rc); -} - -static int ll_file_release(struct inode *inode, struct file *file) -{ - struct ptlrpc_request *req = NULL; - struct ll_file_data *fd; - struct obdo oa; - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ll_inode_info *lli = ll_i2info(inode); - struct lov_stripe_md *lsm = lli->lli_smd; - int rc, rc2; - - ENTRY; - - fd = (struct ll_file_data *)file->private_data; - if (!fd) { - LASSERT(file->f_flags & O_LOV_DELAY_CREATE); - GOTO(out, rc = 0); - } - - memset(&oa, 0, sizeof(oa)); - oa.o_id = lsm->lsm_object_id; - oa.o_mode = S_IFREG; - oa.o_valid = OBD_MD_FLTYPE | OBD_MD_FLID; - obd_handle2oa(&oa, &fd->fd_osthandle); - rc = obd_close(ll_i2obdconn(inode), &oa, lsm); - if (rc) - GOTO(out_mdc, rc = -abs(rc)); - -#if 0 -#error "This should only be done on the node that already has the EOF lock" -#error "and only in the case where the file size actually changed. For now" -#error "we don't care about the size on the MDS, since we never use it (the" -#error "OST always has the authoritative size and we don't even use the MDS." - /* If this fails and we goto out_fd, the file size on the MDS is out of - * date. Is that a big deal? */ - if (file->f_mode & FMODE_WRITE) { - struct lustre_handle *lockhs; - - rc = ll_size_lock(inode, lsm, 0, LCK_PR, &lockhs); - if (rc) - GOTO(out_mdc, -abs(rc)); - - oa.o_id = lsm->lsm_object_id; - oa.o_mode = S_IFREG; - oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE | - OBD_MD_FLBLOCKS; - rc = obd_getattr(&sbi->ll_osc_conn, &oa, lsm); - if (!rc) { - struct iattr attr; - attr.ia_valid = (ATTR_MTIME | ATTR_CTIME | ATTR_ATIME | - ATTR_SIZE); - attr.ia_mtime = inode->i_mtime; - attr.ia_ctime = inode->i_ctime; - attr.ia_atime = inode->i_atime; - attr.ia_size = oa.o_size; - - inode->i_blocks = oa.o_blocks; - - /* XXX: this introduces a small race that we should - * evaluate */ - rc = ll_inode_setattr(inode, &attr, 0); - } - rc2 = ll_size_unlock(inode, lli->lli_smd, LCK_PR, lockhs); - if (rc2) { - CERROR("lock cancel: %d\n", rc); - LBUG(); - if (!rc) - rc = rc2; - } - } -#endif - -out_mdc: - rc2 = mdc_close(&sbi->ll_mdc_conn, inode->i_ino, - S_IFREG, &fd->fd_mdshandle, &req); - ptlrpc_req_finished(req); - if (rc2) { - if (!rc) - rc = -abs(rc2); - GOTO(out_fd, rc); - } - DEBUG_REQ(D_HA, fd->fd_req, "matched open for this close: "); - ptlrpc_req_finished(fd->fd_req); - - if (atomic_dec_and_test(&lli->lli_open_count)) { - CDEBUG(D_INFO, "last close, cancelling unused locks\n"); - rc = obd_cancel_unused(ll_i2obdconn(inode), lsm, 0); - if (rc) - CERROR("obd_cancel_unused: %d\n", rc); - } else { - CDEBUG(D_INFO, "not last close, not cancelling unused locks\n"); - } - - EXIT; - -out_fd: - fd->fd_mdshandle.cookie = DEAD_HANDLE_MAGIC; - file->private_data = NULL; - kmem_cache_free(ll_file_data_slab, fd); -out: - return rc; -} - -static inline void ll_remove_suid(struct inode *inode) -{ - unsigned int mode; - - /* set S_IGID if S_IXGRP is set, and always set S_ISUID */ - mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID; - - /* was any of the uid bits set? */ - mode &= inode->i_mode; - if (mode && !capable(CAP_FSETID)) { - inode->i_mode &= ~mode; - // XXX careful here - we cannot change the size - } -} - -static void ll_update_atime(struct inode *inode) -{ - struct iattr attr; - - attr.ia_atime = CURRENT_TIME; - attr.ia_valid = ATTR_ATIME; - - if (inode->i_atime == attr.ia_atime) return; - if (IS_RDONLY(inode)) return; - if (IS_NOATIME(inode)) return; - - /* ll_inode_setattr() sets inode->i_atime from attr.ia_atime */ - ll_inode_setattr(inode, &attr, 0); -} - -int ll_lock_callback(struct ldlm_lock *lock, struct ldlm_lock_desc *new, - void *data, __u32 data_len, int flag) -{ - struct inode *inode = data; - struct lustre_handle lockh; - int rc; - ENTRY; - - if (data_len != sizeof(struct inode)) - LBUG(); - - if (inode == NULL) - LBUG(); - - switch (flag) { - case LDLM_CB_BLOCKING: - ldlm_lock2handle(lock, &lockh); - rc = ldlm_cli_cancel(&lockh); - if (rc != ELDLM_OK) - CERROR("ldlm_cli_cancel failed: %d\n", rc); - break; - case LDLM_CB_CANCELING: - CDEBUG(D_INODE, "invalidating obdo/inode %ld\n", inode->i_ino); - /* FIXME: do something better than throwing away everything */ - //down(&inode->i_sem); - ll_invalidate_inode_pages(inode); - //up(&inode->i_sem); - break; - default: - LBUG(); - } - - RETURN(0); -} - -static ssize_t ll_file_read(struct file *filp, char *buf, size_t count, - loff_t *ppos) -{ - struct ll_file_data *fd = (struct ll_file_data *)filp->private_data; - struct inode *inode = filp->f_dentry->d_inode; - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct lustre_handle *lockhs = NULL; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - int flags = 0; - ldlm_error_t err; - ssize_t retval; - ENTRY; - - /* If we don't refresh the file size, generic_file_read may not even - * call us */ - retval = ll_file_size(inode, lsm); - if (retval < 0) { - CERROR("ll_file_size: %d\n", retval); - RETURN(retval); - } - - if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK) && - !(sbi->ll_flags & LL_SBI_NOLCK)) { - struct ldlm_extent extent; - OBD_ALLOC(lockhs, lsm->lsm_stripe_count * sizeof(*lockhs)); - if (!lockhs) - RETURN(-ENOMEM); - - extent.start = *ppos; - extent.end = *ppos + count; - CDEBUG(D_INFO, "Locking inode %ld, start "LPU64" end "LPU64"\n", - inode->i_ino, extent.start, extent.end); - - err = obd_enqueue(&sbi->ll_osc_conn, lsm, NULL, LDLM_EXTENT, - &extent, sizeof(extent), LCK_PR, &flags, - ll_lock_callback, inode, sizeof(*inode), - lockhs); - if (err != ELDLM_OK) { - OBD_FREE(lockhs, lsm->lsm_stripe_count*sizeof(*lockhs)); - CERROR("lock enqueue: err: %d\n", err); - RETURN(err); - } - } - - CDEBUG(D_INFO, "Reading inode %ld, %d bytes, offset %Ld\n", - inode->i_ino, count, *ppos); - retval = generic_file_read(filp, buf, count, ppos); - - if (retval > 0) - ll_update_atime(inode); - - if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK) && - !(sbi->ll_flags & LL_SBI_NOLCK)) { - err = obd_cancel(&sbi->ll_osc_conn, lsm, LCK_PR, lockhs); - if (err != ELDLM_OK) { - CERROR("lock cancel: err: %d\n", err); - retval = err; - } - } - - if (lockhs) - OBD_FREE(lockhs, lsm->lsm_stripe_count * sizeof(*lockhs)); - RETURN(retval); -} - -/* - * Write to a file (through the page cache). - */ -static ssize_t -ll_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) -{ - struct ll_file_data *fd = (struct ll_file_data *)file->private_data; - struct inode *inode = file->f_dentry->d_inode; - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct lustre_handle *lockhs = NULL, *eof_lockhs = NULL; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - int flags = 0; - ldlm_error_t err; - ssize_t retval; - ENTRY; - - if (!S_ISBLK(inode->i_mode) && file->f_flags & O_APPEND) { - struct obdo *oa; - - oa = obdo_alloc(); - if (!oa) - RETURN(-ENOMEM); - - err = ll_size_lock(inode, lsm, 0, LCK_PW, &eof_lockhs); - if (err) { - obdo_free(oa); - RETURN(err); - } - - oa->o_id = lsm->lsm_object_id; - oa->o_mode = inode->i_mode; - oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE | - OBD_MD_FLBLOCKS; - obd_handle2oa(oa, &fd->fd_osthandle); - retval = obd_getattr(&sbi->ll_osc_conn, oa, lsm); - if (retval) { - obdo_free(oa); - GOTO(out_eof, retval); - } - - *ppos = oa->o_size; - obdo_to_inode(inode, oa, oa->o_valid); - obdo_free(oa); - } - - if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK) && - !(sbi->ll_flags & LL_SBI_NOLCK)) { - struct ldlm_extent extent; - OBD_ALLOC(lockhs, lsm->lsm_stripe_count * sizeof(*lockhs)); - if (!lockhs) - GOTO(out_eof, retval = -ENOMEM); - extent.start = *ppos; - extent.end = *ppos + count; - CDEBUG(D_INFO, "Locking inode %ld, start "LPU64" end "LPU64"\n", - inode->i_ino, extent.start, extent.end); - - err = obd_enqueue(&sbi->ll_osc_conn, lsm, NULL, LDLM_EXTENT, - &extent, sizeof(extent), LCK_PW, &flags, - ll_lock_callback, inode, sizeof(*inode), - lockhs); - if (err != ELDLM_OK) { - CERROR("lock enqueue: err: %d\n", err); - GOTO(out_free, retval = err); - } - } - - CDEBUG(D_INFO, "Writing inode %ld, %ld bytes, offset "LPD64"\n", - inode->i_ino, (long)count, *ppos); - - retval = generic_file_write(file, buf, count, ppos); - - if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK) || - sbi->ll_flags & LL_SBI_NOLCK) { - err = obd_cancel(&sbi->ll_osc_conn, lsm, LCK_PW, lockhs); - if (err != ELDLM_OK) { - CERROR("lock cancel: err: %d\n", err); - GOTO(out_free, retval = err); - } - } - - EXIT; - out_free: - if (lockhs) - OBD_FREE(lockhs, lsm->lsm_stripe_count * sizeof(*lockhs)); - - out_eof: - if (!S_ISBLK(inode->i_mode) && file->f_flags & O_APPEND) { - err = ll_size_unlock(inode, lsm, LCK_PW, eof_lockhs); - if (err && !retval) - retval = err; - } - - return retval; -} - -/* Retrieve object striping information. - * - * @arg is a pointer to a user struct with one or more of the fields set to - * indicate the application preference: lmm_stripe_count, lmm_stripe_size, - * lmm_stripe_offset, and lmm_stripe_pattern. lmm_magic must be LOV_MAGIC. - */ -static int ll_lov_setstripe(struct inode *inode, struct file *file, - unsigned long arg) -{ - struct ll_inode_info *lli = ll_i2info(inode); - struct lov_mds_md *lmm = NULL, *lmmu = (void *)arg; - struct lustre_handle *conn = ll_i2obdconn(inode); - int rc; - - rc = obd_alloc_wiremd(conn, &lmm); - if (rc < 0) - RETURN(rc); - - rc = copy_from_user(lmm, lmmu, sizeof(*lmm)); - if (rc) - GOTO(out_free, rc = -EFAULT); - - if (lmm->lmm_magic != LOV_MAGIC) { - CERROR("bad LOV magic %X\n", lmm->lmm_magic); - GOTO(out_free, rc = -EINVAL); - } - - down(&lli->lli_open_sem); - if (lli->lli_smd) { - CERROR("striping data already set for %d\n", inode->i_ino); - GOTO(out_lov_up, rc = -EPERM); - } - rc = obd_unpackmd(conn, &lli->lli_smd, lmm); - if (rc < 0) { - CERROR("error setting LOV striping on %d: rc = %d\n", - inode->i_ino, rc); - GOTO(out_lov_up, rc); - } - - rc = ll_create_objects(inode->i_sb, inode->i_ino, 0, 0, &lli->lli_smd); - if (rc) { - obd_free_memmd(conn, &lli->lli_smd); - } else { - file->f_flags &= ~O_LOV_DELAY_CREATE; - rc = ll_file_open(inode, file); - } -out_lov_up: - up(&lli->lli_open_sem); -out_free: - obd_free_wiremd(conn, &lmm); - return rc; -} - -/* Retrieve object striping information. - * - * @arg is a pointer to a user struct with lmm_ost_count indicating - * the maximum number of OST indices which will fit in the user buffer. - * lmm_magic must be LOV_MAGIC. - */ -static int ll_lov_getstripe(struct inode *inode, unsigned long arg) -{ - struct lov_mds_md lmm, *lmmu = (void *)arg, *lmmk = NULL; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - struct lustre_handle *conn = ll_i2obdconn(inode); - int ost_count, rc, lmm_size; - - if (!lsm) - RETURN(-ENODATA); - - rc = copy_from_user(&lmm, lmmu, sizeof(lmm)); - if (rc) - RETURN(-EFAULT); - - if (lmm.lmm_magic != LOV_MAGIC) - RETURN(-EINVAL); - - if (lsm->lsm_stripe_count == 0) - ost_count = 1; - else { - struct obd_device *obd = class_conn2obd(conn); - struct lov_obd *lov = &obd->u.lov; - ost_count = lov->desc.ld_tgt_count; - } - - /* XXX we _could_ check if indices > user lmm_ost_count are zero */ - if (lmm.lmm_ost_count < ost_count) - RETURN(-EOVERFLOW); - - rc = obd_packmd(conn, &lmmk, lsm); - if (rc < 0) - RETURN(rc); - - lmm_size = rc; - - /* LOV STACKING layering violation to make LOV/OSC return same data */ - if (lsm->lsm_stripe_count == 0) { - struct lov_object_id *loi; - - loi = (void *)lmmu + offsetof(typeof(*lmmu), lmm_objects); - rc = copy_to_user(loi, &lsm->lsm_object_id, sizeof(*loi)); - if (rc) { - lmm_size = 0; - rc = -EFAULT; - } else { - lmmk->lmm_magic = LOV_MAGIC; - lmmk->lmm_ost_count = lmmk->lmm_stripe_count = 1; - } - } - - if (lmm_size && copy_to_user(lmmu, lmmk, lmm_size)) - rc = -EFAULT; - - obd_free_wiremd(conn, &lmmk); - - RETURN(rc); -} - -int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct ll_file_data *fd = (struct ll_file_data *)file->private_data; - struct lustre_handle *conn; - int flags; - - switch(cmd) { - case LL_IOC_GETFLAGS: - /* Get the current value of the file flags */ - return put_user(fd->fd_flags, (int *)arg); - case LL_IOC_SETFLAGS: - case LL_IOC_CLRFLAGS: - /* Set or clear specific file flags */ - /* XXX This probably needs checks to ensure the flags are - * not abused, and to handle any flag side effects. - */ - if (get_user(flags, (int *) arg)) - return -EFAULT; - - if (cmd == LL_IOC_SETFLAGS) - fd->fd_flags |= flags; - else - fd->fd_flags &= ~flags; - return 0; - case LL_IOC_LOV_SETSTRIPE: - return ll_lov_setstripe(inode, file, arg); - case LL_IOC_LOV_GETSTRIPE: - return ll_lov_getstripe(inode, arg); - - /* We need to special case any other ioctls we want to handle, - * to send them to the MDS/OST as appropriate and to properly - * network encode the arg field. - case EXT2_IOC_GETFLAGS: - case EXT2_IOC_SETFLAGS: - case EXT2_IOC_GETVERSION_OLD: - case EXT2_IOC_GETVERSION_NEW: - case EXT2_IOC_SETVERSION_OLD: - case EXT2_IOC_SETVERSION_NEW: - */ - default: - conn = ll_i2obdconn(inode); - return obd_iocontrol(cmd, conn, 0, NULL, (void *)arg); - } -} - -loff_t ll_file_seek(struct file *file, loff_t offset, int origin) -{ - struct inode *inode = file->f_dentry->d_inode; - long long retval; - ENTRY; - - switch (origin) { - case 2: { - struct ll_inode_info *lli = ll_i2info(inode); - - retval = ll_file_size(inode, lli->lli_smd); - if (retval) - RETURN(retval); - - offset += inode->i_size; - break; - } - case 1: - offset += file->f_pos; - } - retval = -EINVAL; - if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) { - if (offset != file->f_pos) { - file->f_pos = offset; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - file->f_reada = 0; -#endif - file->f_version = ++event; - } - retval = offset; - } - RETURN(retval); -} - -/* XXX this does not need to do anything for data, it _does_ need to - call setattr */ -int ll_fsync(struct file *file, struct dentry *dentry, int data) -{ - return 0; -} - - - -static int ll_inode_revalidate(struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - struct lov_stripe_md *lsm; - ENTRY; - - if (!inode) - RETURN(0); - - lsm = ll_i2info(inode)->lli_smd; - if (!lsm) /* object not yet allocated, don't validate size */ - RETURN(0); - - RETURN(ll_file_size(inode, lsm)); -} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int ll_getattr(struct vfsmount *mnt, struct dentry *de, - struct kstat *stat) -{ - return ll_inode_revalidate(de); -} -#endif - -struct file_operations ll_file_operations = { - read: ll_file_read, - write: ll_file_write, - ioctl: ll_file_ioctl, - open: ll_file_open, - release: ll_file_release, - mmap: generic_file_mmap, - llseek: ll_file_seek, - fsync: NULL -}; - -struct inode_operations ll_file_inode_operations = { - setattr: ll_setattr, - truncate: ll_truncate, -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - getattr: ll_getattr, -#else - revalidate: ll_inode_revalidate, -#endif -}; diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c deleted file mode 100644 index 65df985..0000000 --- a/lustre/llite/lproc_llite.c +++ /dev/null @@ -1,249 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define 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, "%lu\n", mystats.f_bsize); - return len; - -} - -int rd_kbytestotal(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; - __u32 blk_size; - __u64 result; - - (sb->s_op->statfs)(sb, &mystats); - blk_size = mystats.f_bsize; - blk_size >>= 10; - result = mystats.f_blocks; - - while(blk_size >>= 1) - result <<= 1; - - len += snprintf(page, count, LPU64"\n", result); - return len; -} - - -int rd_kbytesfree(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; - __u32 blk_size; - __u64 result; - - (sb->s_op->statfs)(sb, &mystats); - blk_size = mystats.f_bsize; - blk_size >>= 10; - result = mystats.f_bfree; - - while(blk_size >>= 1) - result <<= 1; - - len += snprintf(page, count, LPU64"\n", result); - 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; -} - - -struct lprocfs_vars status_var_nm_1[] = { - {"status/uuid", rd_uuid, 0, 0}, - {"status/mntpt_path", rd_path, 0, 0}, - {"status/fstype", rd_fstype, 0, 0}, - {"status/blocksize",rd_blksize, 0, 0}, - {"status/kbytestotal",rd_kbytestotal, 0, 0}, - {"status/kbytesfree", rd_kbytesfree, 0, 0}, - {"status/filestotal", rd_filestotal, 0, 0}, - {"status/filesfree", rd_filesfree, 0, 0}, - {"status/filegroups", rd_filegroups, 0, 0}, - {0} -}; - -/* - * Proc registration function for Lustre - * file system - */ - - -#define MAX_STRING_SIZE 100 -void ll_proc_namespace(struct super_block* sb, char* osc, char* mdc) -{ - char mnt_name[MAX_STRING_SIZE+1]; - char uuid_name[MAX_STRING_SIZE+1]; - struct lprocfs_vars d_vars[3]; - struct ll_sb_info *sbi = ll_s2sbi(sb); - struct obd_device* obd; - int err; - - /* Register this mount instance with LProcFS */ - snprintf(mnt_name, MAX_STRING_SIZE, "mount_%s", sbi->ll_sb_uuid); - mnt_name[MAX_STRING_SIZE] = '\0'; - sbi->ll_proc_root = lprocfs_reg_mnt(mnt_name); - if (sbi->ll_proc_root == NULL) { - CDEBUG(D_OTHER, "Could not register FS"); - return; - } - /* Add the static configuration info */ - err = lprocfs_add_vars(sbi->ll_proc_root,status_var_nm_1, sb); - if (err) { - CDEBUG(D_OTHER, "Unable to add procfs variables\n"); - return; - } - /* MDC */ - obd = class_uuid2obd(mdc); - snprintf(mnt_name, MAX_STRING_SIZE, "status/%s/common_name", - obd->obd_type->typ_name); - mnt_name[MAX_STRING_SIZE] = '\0'; - memset(d_vars, 0, sizeof(d_vars)); - d_vars[0].read_fptr = rd_dev_name; - d_vars[0].write_fptr = NULL; - d_vars[0].name = mnt_name; - snprintf(uuid_name, MAX_STRING_SIZE, "status/%s/uuid", - obd->obd_type->typ_name); - uuid_name[MAX_STRING_SIZE] = '\0'; - d_vars[1].read_fptr = rd_dev_uuid; - d_vars[1].write_fptr = NULL; - d_vars[1].name = uuid_name; - - err = lprocfs_add_vars(sbi->ll_proc_root, d_vars, obd); - if (err) { - CDEBUG(D_OTHER, "Unable to add fs proc dynamic variables\n"); - return; - } - /* OSC or LOV*/ - obd = class_uuid2obd(osc); - - /* Reuse mnt_name */ - snprintf(mnt_name, MAX_STRING_SIZE, - "status/%s/common_name", obd->obd_type->typ_name); - mnt_name[MAX_STRING_SIZE] = '\0'; - memset(d_vars, 0, sizeof(d_vars)); - d_vars[0].read_fptr = rd_dev_name; - d_vars[0].write_fptr = NULL; - d_vars[0].name = mnt_name; - - snprintf(uuid_name, MAX_STRING_SIZE, "status/%s/uuid", - obd->obd_type->typ_name); - uuid_name[MAX_STRING_SIZE] = '\0'; - d_vars[1].read_fptr = rd_dev_uuid; - d_vars[1].write_fptr = NULL; - d_vars[1].name = uuid_name; - - err = lprocfs_add_vars(sbi->ll_proc_root, d_vars, obd); - if (err) { - CDEBUG(D_OTHER, "Unable to add fs proc dynamic variables\n"); - return; - } -} -#undef MAX_STRING_SIZE diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c deleted file mode 100644 index 9670af0..0000000 --- a/lustre/llite/namei.c +++ /dev/null @@ -1,988 +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) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/ext2/namei.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * Big-endian to little-endian byte-swapping/bitmaps by - * 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 - * - * Changes for use in OBDFS - * Copyright (c) 1999, Seagate Technology Inc. - * Copyright (C) 2001, Cluster File Systems, Inc. - * Rewritten based on recent ext2 page cache use. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include - -extern struct address_space_operations ll_aops; - -/* from super.c */ -extern void ll_change_inode(struct inode *inode); -extern int ll_setattr(struct dentry *de, struct iattr *attr); - -/* from dir.c */ -extern int ll_add_link (struct dentry *dentry, struct inode *inode); -obd_id ll_inode_by_name(struct inode * dir, struct dentry *dentry, int *typ); -int ext2_make_empty(struct inode *inode, struct inode *parent); -struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir, - struct dentry *dentry, struct page ** res_page); -int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ); -int ext2_empty_dir (struct inode * inode); -struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p); -void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, - struct page *page, struct inode *inode); - -/* - * Couple of helper functions - make the code slightly cleaner. - */ -static inline void ext2_inc_count(struct inode *inode) -{ - inode->i_nlink++; -} - -/* postpone the disk update until the inode really goes away */ -static inline void ext2_dec_count(struct inode *inode) -{ - inode->i_nlink--; -} -static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) -{ - int err; - err = ll_add_link(dentry, inode); - if (!err) { - d_instantiate(dentry, inode); - return 0; - } - ext2_dec_count(inode); - iput(inode); - return err; -} - -/* methods */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -static int ll_find_inode(struct inode *inode, unsigned long ino, void *opaque) -#else -static int ll_test_inode(struct inode *inode, void *opaque) -#endif -{ - struct ll_read_inode2_cookie *lic = opaque; - struct mds_body *body = lic->lic_body; - - if (inode->i_generation != lic->lic_body->generation) - return 0; - - /* Apply the attributes in 'opaque' to this inode */ - ll_update_inode(inode, body); - - return 1; -} - -extern struct dentry_operations ll_d_ops; - -int ll_unlock(__u32 mode, struct lustre_handle *lockh) -{ - ENTRY; - - ldlm_lock_decref(lockh, mode); - - RETURN(0); -} - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -extern int ll_read_inode2(struct inode *inode, void *opaque); -struct inode *ll_iget(struct super_block *sb, ino_t hash, - struct ll_read_inode2_cookie *lic) -{ - struct inode *inode; - - LASSERT(hash != 0); - inode = iget5_locked(sb, hash, ll_test_inode, ll_read_inode2, lic); - - if (!inode) - return ERR_PTR(-ENOMEM); - - if (inode->i_state & I_NEW) - unlock_new_inode(inode); - - // XXX Coda always fills inodes, should Lustre? - return inode; -} -#else -struct inode *ll_iget(struct super_block *sb, ino_t hash, - struct ll_read_inode2_cookie *lic) -{ - struct inode *inode; - LASSERT(hash != 0); - inode = iget4(sb, hash, ll_find_inode, lic); - return inode; -} -#endif - -static int ll_intent_to_lock_mode(struct lookup_intent *it) -{ - /* CREAT needs to be tested before open (both could be set) */ - if ((it->it_op & (IT_CREAT | IT_MKDIR | IT_SETATTR | IT_MKNOD))) { - return LCK_PW; - } else if (it->it_op & (IT_READDIR | IT_GETATTR | IT_OPEN | IT_UNLINK | - IT_RMDIR | IT_RENAME | IT_RENAME2 | IT_READLINK| - IT_LINK | IT_LINK2 | IT_LOOKUP | IT_SYMLINK)) { - return LCK_PR; - } - - LBUG(); - RETURN(-EINVAL); -} - -#define LL_LOOKUP_POSITIVE 1 -#define LL_LOOKUP_NEGATIVE 2 - -int ll_intent_lock(struct inode *parent, struct dentry **de, - struct lookup_intent *it, - intent_finish_cb intent_finish) -{ - struct dentry *dentry = *de; - struct ll_sb_info *sbi = ll_i2sbi(parent); - struct lustre_handle lockh; - struct lookup_intent lookup_it = { .it_op = IT_LOOKUP }; - struct ptlrpc_request *request = NULL; - char *data = NULL; - int rc, lock_mode, datalen = 0, offset, flag = LL_LOOKUP_POSITIVE; - obd_id ino = 0; - - ENTRY; - - if (it == NULL) - it = &lookup_it; - - CDEBUG(D_INFO, "name: %*s, intent: %s\n", dentry->d_name.len, - dentry->d_name.name, ldlm_it2str(it->it_op)); - - if (dentry->d_name.len > EXT2_NAME_LEN) - RETURN(-ENAMETOOLONG); - - lock_mode = ll_intent_to_lock_mode(it); - if (it->it_op & IT_SYMLINK) { - data = it->it_data; - datalen = strlen(data) + 1; - it->it_data = NULL; - } - - rc = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_PLAIN, it, lock_mode, parent, - dentry, &lockh, data, datalen, parent,sizeof(*parent)); - if (rc < 0) - RETURN(rc); - memcpy(it->it_lock_handle, &lockh, sizeof(lockh)); - - request = (struct ptlrpc_request *)it->it_data; - /* it_disposition == 1 indicates that the server performed the - * intent on our behalf. */ - if (it->it_disposition) { - struct mds_body *mds_body; - int mode; - obd_flag valid; - - /* This long block is all about fixing up the local - * state so that it is correct as of the moment - * _before_ the operation was applied; that way, the - * VFS will think that everything is normal and call - * Lustre's regular FS function. - * - * If we're performing a creation, that means that unless the - * creation failed with EEXIST, we should fake up a negative - * dentry. Likewise for the target of a hard link. - * - * For everything else, we want to lookup to succeed. */ - - /* One additional note: if CREATE/MKDIR/etc succeeded, - * we add an extra reference to the request because we - * need to keep it around until ll_create gets called. - * For anything else which results in - * LL_LOOKUP_POSITIVE, we can do the iget() - * immediately with the contents of the reply (in the - * intent_finish callback). In the create case, - * however, we need to wait until ll_create_node to do - * the iget() or the VFS will abort with -EEXISTS. - */ - - offset = 1; - mds_body = lustre_msg_buf(request->rq_repmsg, offset); - ino = mds_body->fid1.id; - mode = mds_body->mode; - - if (it->it_op & (IT_CREAT | IT_MKDIR | IT_SYMLINK | IT_MKNOD)) { - mdc_store_inode_generation(request, 2, 1); - /* For create ops, we want the lookup to be negative, - * unless the create failed in a way that indicates - * that the file is already there */ - if (it->it_status == 0) - atomic_inc(&request->rq_refcount); - if (it->it_status != -EEXIST) - GOTO(out, flag = LL_LOOKUP_NEGATIVE); - /* - * Fall through to update attibutes: it may already - * have appeared in the namespace of another client - */ - } else if (it->it_op & (IT_GETATTR | IT_SETATTR | IT_LOOKUP | - IT_READLINK)) { - /* For check ops, we want the lookup to succeed */ - it->it_data = NULL; - if (it->it_status) - GOTO(out, flag = LL_LOOKUP_NEGATIVE); - /* Fall through to update attibutes. */ - } else if (it->it_op & (IT_RENAME | IT_LINK)) { - /* For rename, we want the source lookup to succeed */ - if (it->it_status) { - it->it_data = NULL; - GOTO(drop_req, rc = it->it_status); - } - /* Fall through to update attibutes. */ - } else if (it->it_op & (IT_UNLINK | IT_RMDIR)) { - /* For remove ops, we want the lookup to succeed unless - * the file truly doesn't exist */ - it->it_data = NULL; - if (it->it_status == -ENOENT) - GOTO(out, flag = LL_LOOKUP_NEGATIVE); - /* No point in updating attributes that we're about to - * unlink. -phil */ - GOTO(out, flag = LL_LOOKUP_POSITIVE); - } else if (it->it_op == IT_OPEN) { - it->it_data = NULL; - if (it->it_status && it->it_status != -EEXIST) - GOTO(out, flag = LL_LOOKUP_NEGATIVE); - /* Fall through to update attibutes. */ - } else if (it->it_op & (IT_RENAME2 | IT_LINK2)) { - it->it_data = NULL; - /* This means the target lookup is negative */ - if (mds_body->valid == 0) - GOTO(out, flag = LL_LOOKUP_NEGATIVE); - /* XXX bug 289: should we maybe fall through here? -p */ - GOTO(out, flag = LL_LOOKUP_POSITIVE); - } - - /* Do a getattr now that we have the lock */ - valid = OBD_MD_FLNOTOBD; - if (it->it_op == IT_READLINK) { - datalen = mds_body->size; - valid |= OBD_MD_LINKNAME; - } else if (S_ISREG(mode)) { - datalen = obd_size_wiremd(&sbi->ll_osc_conn, NULL); - valid |= OBD_MD_FLEASIZE; - } - ptlrpc_req_finished(request); - request = NULL; - rc = mdc_getattr(&sbi->ll_mdc_conn, ino, mode, - valid, datalen, &request); - if (rc) { - CERROR("failure %d inode "LPX64"\n", rc, ino); - GOTO(drop_req, rc = -abs(rc)); - } - offset = 0; - } else { - obd_flag valid; - int mode; - - LBUG(); /* For the moment, no non-intent locks */ - - /* it_disposition == 0 indicates that it just did a simple lock - * request, for which we are very thankful. move along with - * the local lookup then. */ - - //memcpy(&lli->lli_intent_lock_handle, &lockh, sizeof(lockh)); - offset = 0; - - ino = ll_inode_by_name(parent, dentry, &mode); - if (!ino) { - CERROR("inode %*s not found by name\n", - dentry->d_name.len, dentry->d_name.name); - GOTO(drop_lock, rc = -ENOENT); - } - - valid = OBD_MD_FLNOTOBD; - - if (S_ISREG(mode)) { - datalen = obd_size_wiremd(&sbi->ll_osc_conn, NULL), - valid |= OBD_MD_FLEASIZE; - } - - rc = mdc_getattr(&sbi->ll_mdc_conn, ino, mode, valid, - datalen, &request); - if (rc) { - CERROR("failure %d inode "LPX64"\n", rc, ino); - GOTO(drop_req, rc = -abs(rc)); - } - } - - EXIT; - out: - if (intent_finish != NULL) { - rc = intent_finish(flag, request, de, it, offset, ino); - dentry = *de; /* intent_finish may change *de */ - } else { - ptlrpc_req_finished(request); - } - - if (it->it_disposition && it->it_op & (IT_RENAME | IT_LINK)) - it->it_data = dentry; - - /* this places the intent in the dentry so that the vfs_xxx - * operation can lay its hands on it; but that is not - * always needed... - */ - if ( // it->it_status == 0 && - it->it_op != IT_RENAME2 && - it->it_op != IT_SETATTR && - it->it_op != IT_GETATTR && - it->it_op != IT_READDIR && - it->it_op != IT_LOOKUP) { - LL_SAVE_INTENT(dentry, it); - } else { - CDEBUG(D_DENTRY, - "D_IT dentry %p fsdata %p intent: %s status %d\n", - dentry, ll_d2d(dentry), ldlm_it2str(it->it_op), - it->it_status); - } - - if (rc < 0 || it->it_op == IT_LOOKUP) - ll_intent_release(dentry, it); - - RETURN(rc); - - drop_req: - ptlrpc_free_req(request); - drop_lock: -#warning FIXME: must release lock here - RETURN(rc); -} - -/* Search "inode"'s alias list for a dentry that has the same name and parent as - * de. If found, return it. If not found, return de. */ -struct dentry *ll_find_alias(struct inode *inode, struct dentry *de) -{ - struct list_head *tmp; - - spin_lock(&dcache_lock); - list_for_each(tmp, &inode->i_dentry) { - struct dentry *dentry = list_entry(tmp, struct dentry, d_alias); - - /* We are called here with 'de' already on the aliases list. */ - if (dentry == de) { - CERROR("whoops\n"); - continue; - } - - if (dentry->d_parent != de->d_parent) - continue; - - if (dentry->d_name.len != de->d_name.len) - continue; - - if (memcmp(dentry->d_name.name, de->d_name.name, - de->d_name.len) != 0) - continue; - - if (!list_empty(&dentry->d_lru)) - list_del_init(&dentry->d_lru); - - list_del_init(&dentry->d_hash); - spin_unlock(&dcache_lock); - d_rehash(dentry); - atomic_inc(&dentry->d_count); - iput(inode); - return dentry; - } - - spin_unlock(&dcache_lock); - - return de; -} - -static int -lookup2_finish(int flag, struct ptlrpc_request *request, struct dentry **de, - struct lookup_intent *it, int offset, obd_id ino) -{ - struct dentry *dentry = *de, *saved = *de; - struct inode *inode = NULL; - struct ll_read_inode2_cookie lic = {.lic_body = NULL, .lic_lmm = NULL}; - - if (flag == LL_LOOKUP_POSITIVE) { - ENTRY; - lic.lic_body = lustre_msg_buf(request->rq_repmsg, offset); - - if (S_ISREG(lic.lic_body->mode) && - lic.lic_body->valid & OBD_MD_FLEASIZE) { - LASSERT(request->rq_repmsg->bufcount > offset); - lic.lic_lmm = lustre_msg_buf(request->rq_repmsg, - offset + 1); - } else { - lic.lic_lmm = NULL; - } - - /* No rpc's happen during iget4, -ENOMEM's are possible */ - inode = ll_iget(dentry->d_sb, ino, &lic); - if (!inode) { - /* XXX make sure that request is freed in this case; - * I think it is, but double-check refcounts. -phil */ - RETURN(-ENOMEM); - } - - dentry = *de = ll_find_alias(inode, dentry); - - /* We asked for a lock on the directory, and may have been - * granted a lock on the inode. Just in case, fixup the data - * pointer. */ - ldlm_lock_set_data((struct lustre_handle *)it->it_lock_handle, - inode, sizeof(*inode)); - - EXIT; - } else { - ENTRY; - } - - ptlrpc_req_finished(request); - - dentry->d_op = &ll_d_ops; - if (ll_d2d(dentry) == NULL) { - ll_set_dd(dentry); - } - - if (dentry == saved) - d_add(dentry, inode); - - RETURN(0); -} - -static struct dentry *ll_lookup2(struct inode *parent, struct dentry *dentry, - struct lookup_intent *it) -{ - struct dentry *save = dentry; - int rc; - - rc = ll_intent_lock(parent, &dentry, it, lookup2_finish); - if (rc < 0) { - CERROR("ll_intent_lock: %d\n", rc); - return ERR_PTR(rc); - } - - if (dentry == save) - return NULL; - else - return dentry; -} - -static struct inode *ll_create_node(struct inode *dir, const char *name, - int namelen, const void *data, int datalen, - int mode, __u64 extra, - struct lookup_intent *it) -{ - struct inode *inode; - struct ptlrpc_request *request = NULL; - struct mds_body *body; - time_t time = CURRENT_TIME; - struct ll_sb_info *sbi = ll_i2sbi(dir); - struct ll_read_inode2_cookie lic = { .lic_lmm = NULL, }; - ENTRY; - - if (it && it->it_disposition) { - int rc = it->it_status; - if (rc) { - CERROR("error creating MDS inode for %*s: rc = %d\n", - namelen, name, rc); - RETURN(ERR_PTR(rc)); - } - ll_invalidate_inode_pages(dir); - request = it->it_data; - body = lustre_msg_buf(request->rq_repmsg, 1); - } else { - int gid = current->fsgid; - int rc; - - if (dir->i_mode & S_ISGID) { - gid = dir->i_gid; - if (S_ISDIR(mode)) - mode |= S_ISGID; - } - - rc = mdc_create(&sbi->ll_mdc_conn, dir, name, namelen, - data, datalen, mode, current->fsuid, gid, - time, extra, &request); - if (rc) { - inode = ERR_PTR(rc); - GOTO(out, rc); - } - body = lustre_msg_buf(request->rq_repmsg, 0); - } - - lic.lic_body = body; - - inode = ll_iget(dir->i_sb, body->ino, &lic); - if (IS_ERR(inode)) { - int rc = PTR_ERR(inode); - CERROR("new_inode -fatal: rc %d\n", rc); - LBUG(); - GOTO(out, rc); - } - - if (!list_empty(&inode->i_dentry)) { - CERROR("new_inode -fatal: inode %d, ct %d lnk %d\n", - body->ino, atomic_read(&inode->i_count), - inode->i_nlink); - iput(inode); - LBUG(); - inode = ERR_PTR(-EIO); - GOTO(out, -EIO); - } - - if (it && it->it_disposition) { - /* We asked for a lock on the directory, but were - * granted a lock on the inode. Since we finally have - * an inode pointer, stuff it in the lock. */ - ldlm_lock_set_data((struct lustre_handle *)it->it_lock_handle, - inode, sizeof(*inode)); - } - - EXIT; - out: - ptlrpc_req_finished(request); - return inode; -} - -static int ll_mdc_unlink(struct inode *dir, struct inode *child, __u32 mode, - const char *name, int len) -{ - struct ptlrpc_request *request = NULL; - struct ll_sb_info *sbi = ll_i2sbi(dir); - int err; - - ENTRY; - - err = mdc_unlink(&sbi->ll_mdc_conn, dir, child, mode, name, len, - &request); - ptlrpc_req_finished(request); - - RETURN(err); -} - -int ll_mdc_link(struct dentry *src, struct inode *dir, - const char *name, int len) -{ - struct ptlrpc_request *request = NULL; - int err; - struct ll_sb_info *sbi = ll_i2sbi(dir); - - ENTRY; - - err = mdc_link(&sbi->ll_mdc_conn, src, dir, name, len, &request); - ptlrpc_req_finished(request); - - RETURN(err); -} - -int ll_mdc_rename(struct inode *src, struct inode *tgt, - struct dentry *old, struct dentry *new) -{ - struct ptlrpc_request *request = NULL; - struct ll_sb_info *sbi = ll_i2sbi(src); - int err; - - ENTRY; - - err = mdc_rename(&sbi->ll_mdc_conn, src, tgt, - old->d_name.name, old->d_name.len, - new->d_name.name, new->d_name.len, &request); - ptlrpc_req_finished(request); - - RETURN(err); -} - -/* - * By the time this is called, we already have created the directory cache - * entry for the new file, but it is so far negative - it has no inode. - * - * We defer creating the OBD object(s) until open, to keep the intent and - * non-intent code paths similar, and also because we do not have the MDS - * inode number before calling ll_create_node() (which is needed for LOV), - * so we would need to do yet another RPC to the MDS to store the LOV EA - * data on the MDS. If needed, we would pass the PACKED lmm as data and - * lmm_size in datalen (the MDS still has code which will handle that). - * - * If the create succeeds, we fill in the inode information - * with d_instantiate(). - */ -static int ll_create(struct inode *dir, struct dentry *dentry, int mode) -{ - struct lookup_intent *it; - struct inode *inode; - int rc = 0; - ENTRY; - - LL_GET_INTENT(dentry, it); - - inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len, - NULL, 0, mode, 0, it); - - if (IS_ERR(inode)) - RETURN(PTR_ERR(inode)); - - if (it && it->it_disposition) { - d_instantiate(dentry, inode); - } else { - /* no directory data updates when intents rule */ - rc = ext2_add_nondir(dentry, inode); - } - - RETURN(rc); -} - -static int ll_mknod(struct inode *dir, struct dentry *dentry, int mode, - int rdev) -{ - struct lookup_intent *it; - struct inode *inode; - int rc = 0; - - LL_GET_INTENT(dentry, it); - - inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len, - NULL, 0, mode, rdev, it); - - if (IS_ERR(inode)) - RETURN(PTR_ERR(inode)); - - /* no directory data updates when intents rule */ - if (it && it->it_disposition) - d_instantiate(dentry, inode); - else - rc = ext2_add_nondir(dentry, inode); - - return rc; -} - -static int ll_symlink(struct inode *dir, struct dentry *dentry, - const char *symname) -{ - struct lookup_intent *it; - unsigned l = strlen(symname) + 1; - struct inode *inode; - struct ll_inode_info *lli; - int err = 0; - ENTRY; - - LL_GET_INTENT(dentry, it); - - inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len, - symname, l, S_IFLNK | S_IRWXUGO, 0, it); - if (IS_ERR(inode)) - RETURN(PTR_ERR(inode)); - - lli = ll_i2info(inode); - - OBD_ALLOC(lli->lli_symlink_name, l); - /* this _could_ be a non-fatal error, since the symlink is already - * stored on the MDS by this point, and we can re-get it in readlink. - */ - if (!lli->lli_symlink_name) - RETURN(-ENOMEM); - - memcpy(lli->lli_symlink_name, symname, l); - inode->i_size = l - 1; - - /* no directory data updates when intents rule */ - if (it && it->it_disposition) - d_instantiate(dentry, inode); - else - err = ext2_add_nondir(dentry, inode); - - RETURN(err); -} - -static int ll_link(struct dentry *old_dentry, struct inode * dir, - struct dentry *dentry) -{ - struct lookup_intent *it; - struct inode *inode = old_dentry->d_inode; - int rc; - - LL_GET_INTENT(dentry, it); - - if (it && it->it_disposition) { - if (it->it_status) - RETURN(it->it_status); - inode->i_ctime = CURRENT_TIME; - ext2_inc_count(inode); - atomic_inc(&inode->i_count); - d_instantiate(dentry, inode); - ll_invalidate_inode_pages(dir); - RETURN(0); - } - - if (S_ISDIR(inode->i_mode)) - return -EPERM; - - if (inode->i_nlink >= EXT2_LINK_MAX) - return -EMLINK; - - rc = ll_mdc_link(old_dentry, dir, - dentry->d_name.name, dentry->d_name.len); - if (rc) - RETURN(rc); - - inode->i_ctime = CURRENT_TIME; - ext2_inc_count(inode); - atomic_inc(&inode->i_count); - - return ext2_add_nondir(dentry, inode); -} - -static int ll_mkdir(struct inode *dir, struct dentry *dentry, int mode) -{ - struct lookup_intent *it; - struct inode * inode; - int err = -EMLINK; - ENTRY; - - LL_GET_INTENT(dentry, it); - - if (dir->i_nlink >= EXT2_LINK_MAX) - goto out; - - ext2_inc_count(dir); - inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len, - NULL, 0, S_IFDIR | mode, 0, it); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_dir; - - err = ext2_make_empty(inode, dir); - if (err) - goto out_fail; - - /* no directory data updates when intents rule */ - if (!it || !it->it_disposition) { - /* XXX FIXME This code needs re-checked for non-intents */ - ext2_inc_count(inode); - err = ll_add_link(dentry, inode); - if (err) - goto out_fail; - } - - d_instantiate(dentry, inode); -out: - EXIT; - return err; - -out_fail: - ext2_dec_count(inode); - ext2_dec_count(inode); - iput(inode); - EXIT; -out_dir: - ext2_dec_count(dir); - EXIT; - goto out; -} - -static int ll_common_unlink(struct inode *dir, struct dentry *dentry, - struct lookup_intent *it, __u32 mode) -{ - struct inode *inode = dentry->d_inode; - struct ext2_dir_entry_2 * de; - struct page * page; - int rc = 0; - - if (it && it->it_disposition) { - rc = it->it_status; - ll_invalidate_inode_pages(dir); - if (rc) - GOTO(out, rc); - GOTO(out_dec, 0); - } - - de = ext2_find_entry(dir, dentry, &page); - if (!de) - GOTO(out, rc = -ENOENT); - rc = ll_mdc_unlink(dir, dentry->d_inode, mode, - dentry->d_name.name, dentry->d_name.len); - if (rc) - GOTO(out, rc); - - rc = ext2_delete_entry(de, page); - if (rc) - GOTO(out, rc); - - /* AED: not sure if needed - directory lock revocation should do it - * in the case where the client has cached it for non-intent ops. - */ - ll_invalidate_inode_pages(dir); - - inode->i_ctime = dir->i_ctime; -out_dec: - ext2_dec_count(inode); -out: - return rc; -} - -static int ll_unlink(struct inode *dir, struct dentry *dentry) -{ - struct lookup_intent * it; - - LL_GET_INTENT(dentry, it); - - return ll_common_unlink(dir, dentry, it, S_IFREG); -} - -static int ll_rmdir(struct inode *dir, struct dentry *dentry) -{ - struct inode * inode = dentry->d_inode; - struct lookup_intent *it; - int rc; - ENTRY; - - LL_GET_INTENT(dentry, it); - - if ((!it || !it->it_disposition) && !ext2_empty_dir(inode)) - RETURN(-ENOTEMPTY); - - rc = ll_common_unlink(dir, dentry, it, S_IFDIR); - if (!rc) { - inode->i_size = 0; - ext2_dec_count(inode); - ext2_dec_count(dir); - } - - RETURN(rc); -} - -static int ll_rename(struct inode * old_dir, struct dentry * old_dentry, - struct inode * new_dir, struct dentry * new_dentry) -{ - struct lookup_intent *it; - struct inode * old_inode = old_dentry->d_inode; - struct inode * tgt_inode = new_dentry->d_inode; - struct page * dir_page = NULL; - struct ext2_dir_entry_2 * dir_de = NULL; - struct ext2_dir_entry_2 * old_de; - struct page * old_page; - int err; - - LL_GET_INTENT(old_dentry, it); - - if (it && it->it_disposition) { - if (tgt_inode) { - tgt_inode->i_ctime = CURRENT_TIME; - tgt_inode->i_nlink--; - } - ll_invalidate_inode_pages(old_dir); - ll_invalidate_inode_pages(new_dir); - GOTO(out, err = it->it_status); - } - - err = ll_mdc_rename(old_dir, new_dir, old_dentry, new_dentry); - if (err) - goto out; - - old_de = ext2_find_entry (old_dir, old_dentry, &old_page); - if (!old_de) - goto out; - - if (S_ISDIR(old_inode->i_mode)) { - err = -EIO; - dir_de = ext2_dotdot(old_inode, &dir_page); - if (!dir_de) - goto out_old; - } - - if (tgt_inode) { - struct page *new_page; - struct ext2_dir_entry_2 *new_de; - - err = -ENOTEMPTY; - if (dir_de && !ext2_empty_dir (tgt_inode)) - goto out_dir; - - err = -ENOENT; - new_de = ext2_find_entry (new_dir, new_dentry, &new_page); - if (!new_de) - goto out_dir; - ext2_inc_count(old_inode); - ext2_set_link(new_dir, new_de, new_page, old_inode); - tgt_inode->i_ctime = CURRENT_TIME; - if (dir_de) - tgt_inode->i_nlink--; - ext2_dec_count(tgt_inode); - } else { - if (dir_de) { - err = -EMLINK; - if (new_dir->i_nlink >= EXT2_LINK_MAX) - goto out_dir; - } - ext2_inc_count(old_inode); - err = ll_add_link(new_dentry, old_inode); - if (err) { - ext2_dec_count(old_inode); - goto out_dir; - } - if (dir_de) - ext2_inc_count(new_dir); - } - - ext2_delete_entry (old_de, old_page); - ext2_dec_count(old_inode); - - if (dir_de) { - ext2_set_link(old_inode, dir_de, dir_page, new_dir); - ext2_dec_count(old_dir); - } - return 0; - -out_dir: - if (dir_de) { - kunmap(dir_page); - page_cache_release(dir_page); - } -out_old: - kunmap(old_page); - page_cache_release(old_page); -out: - return err; -} - -struct inode_operations ll_dir_inode_operations = { - create: ll_create, - lookup2: ll_lookup2, - link: ll_link, - unlink: ll_unlink, - symlink: ll_symlink, - mkdir: ll_mkdir, - rmdir: ll_rmdir, - mknod: ll_mknod, - rename: ll_rename, - setattr: ll_setattr -}; diff --git a/lustre/llite/recover.c b/lustre/llite/recover.c deleted file mode 100644 index 3310c34..0000000 --- a/lustre/llite/recover.c +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Lustre Lite recovery infrastructure. - * - * Copyright (C) 2002 Cluster File Systems Inc. - */ - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include -#include - -static int ll_retry_recovery(struct ptlrpc_connection *conn) -{ - ENTRY; - RETURN(0); -} - -int ll_recover(struct recovd_data *rd, int phase) -{ - struct ptlrpc_connection *conn = class_rd2conn(rd); - struct list_head *tmp; - - LASSERT(conn); - ENTRY; - - switch (phase) { - case PTLRPC_RECOVD_PHASE_PREPARE: - case PTLRPC_RECOVD_PHASE_RECOVER: - list_for_each(tmp, &conn->c_imports) { - struct obd_import *imp = - list_entry(tmp, struct obd_import, imp_chain); - - if (phase == PTLRPC_RECOVD_PHASE_PREPARE) { - spin_lock(&imp->imp_lock); - imp->imp_level = LUSTRE_CONN_RECOVD; - spin_unlock(&imp->imp_lock); - } - imp->imp_recover(imp, phase); - } - - if (phase == PTLRPC_RECOVD_PHASE_PREPARE) - RETURN(ptlrpc_run_recovery_upcall(conn)); - RETURN(0); - - case PTLRPC_RECOVD_PHASE_FAILURE: - RETURN(ll_retry_recovery(conn)); - } - - LBUG(); - RETURN(-ENOSYS); -} diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c deleted file mode 100644 index 095c145..0000000 --- a/lustre/llite/rw.c +++ /dev/null @@ -1,429 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Lustre Lite I/O Page Cache - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include - -/* - * Remove page from dirty list - */ -static void __set_page_clean(struct page *page) -{ - struct address_space *mapping = page->mapping; - struct inode *inode; - - if (!mapping) - return; - -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)) - spin_lock(&pagecache_lock); -#endif - - list_del(&page->list); - list_add(&page->list, &mapping->clean_pages); - - inode = mapping->host; - if (list_empty(&mapping->dirty_pages)) { - CDEBUG(D_INODE, "inode clean\n"); - inode->i_state &= ~I_DIRTY_PAGES; - } -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)) - spin_unlock(&pagecache_lock); -#endif - EXIT; -} - -inline void set_page_clean(struct page *page) -{ - if (PageDirty(page)) { - ClearPageDirty(page); - __set_page_clean(page); - } -} - -/* SYNCHRONOUS I/O to object storage for an inode */ -static int ll_brw(int cmd, struct inode *inode, struct page *page, int create) -{ - struct ll_inode_info *lli = ll_i2info(inode); - struct lov_stripe_md *lsm = lli->lli_smd; - struct obd_brw_set *set; - struct brw_page pg; - int rc; - ENTRY; - - set = obd_brw_set_new(); - if (set == NULL) - RETURN(-ENOMEM); - - pg.pg = page; - pg.off = ((obd_off)page->index) << PAGE_SHIFT; - - if (cmd == OBD_BRW_WRITE && (pg.off + PAGE_SIZE > inode->i_size)) - pg.count = inode->i_size % PAGE_SIZE; - else - pg.count = PAGE_SIZE; - - pg.flag = create ? OBD_BRW_CREATE : 0; - - set->brw_callback = ll_brw_sync_wait; - rc = obd_brw(cmd, ll_i2obdconn(inode), lsm, 1, &pg, set); - if (rc) { - if (rc != -EIO) - CERROR("error from obd_brw: rc = %d\n", rc); - } else { - rc = ll_brw_sync_wait(set, CB_PHASE_START); - if (rc) - CERROR("error from callback: rc = %d\n", rc); - } - obd_brw_set_free(set); - - RETURN(rc); -} - -/* returns the page unlocked, but with a reference */ -static int ll_readpage(struct file *file, struct page *page) -{ - struct inode *inode = page->mapping->host; - obd_off offset = ((obd_off)page->index) << PAGE_SHIFT; - int rc = 0; - ENTRY; - - if (!PageLocked(page)) - LBUG(); - - if (inode->i_size <= offset) { - memset(kmap(page), 0, PAGE_SIZE); - kunmap(page); - GOTO(readpage_out, rc); - } - - if (PageUptodate(page)) { - CERROR("Explain this please?\n"); - GOTO(readpage_out, rc); - } - - rc = ll_brw(OBD_BRW_READ, inode, page, 0); - EXIT; - - readpage_out: - if (!rc) - SetPageUptodate(page); - unlock_page(page); - return 0; -} /* ll_readpage */ - -void ll_truncate(struct inode *inode) -{ - struct obdo oa = {0}; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - struct lustre_handle *lockhs = NULL; - int err; - ENTRY; - - if (!lsm) { - /* object not yet allocated */ - inode->i_mtime = inode->i_ctime = CURRENT_TIME; - return; - } - - oa.o_id = lsm->lsm_object_id; - oa.o_mode = inode->i_mode; - oa.o_valid = OBD_MD_FLID | OBD_MD_FLMODE | OBD_MD_FLTYPE; - - CDEBUG(D_INFO, "calling punch for "LPX64" (all bytes after "LPD64")\n", - oa.o_id, inode->i_size); - - err = ll_size_lock(inode, lsm, inode->i_size, LCK_PW, &lockhs); - if (err) { - CERROR("ll_size_lock failed: %d\n", err); - /* FIXME: What to do here? It's too late to back out... */ - LBUG(); - } - - /* truncate == punch from new size to absolute end of file */ - err = obd_punch(ll_i2obdconn(inode), &oa, lsm, inode->i_size, - OBD_OBJECT_EOF); - if (err) { - LBUG(); - CERROR("obd_truncate fails (%d) ino %ld\n", err, - inode->i_ino); - } else - obdo_to_inode(inode, &oa, oa.o_valid); - - err = ll_size_unlock(inode, lsm, LCK_PW, lockhs); - if (err) - CERROR("ll_size_unlock failed: %d\n", err); - - EXIT; - return; -} /* ll_truncate */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - -static int ll_prepare_write(struct file *file, struct page *page, unsigned from, - unsigned to) -{ - struct inode *inode = page->mapping->host; - obd_off offset = ((obd_off)page->index) << PAGE_SHIFT; - int rc = 0; - char *addr; - ENTRY; - - addr = kmap(page); - if (!PageLocked(page)) - LBUG(); - - if (Page_Uptodate(page)) - GOTO(prepare_done, rc); - - /* We're completely overwriting an existing page, so _don't_ set it up - * to date until commit_write */ - if (from == 0 && to == PAGE_SIZE) - RETURN(0); - - /* We are writing to a new page, no need to read old data */ - if (inode->i_size <= offset) { - memset(addr, 0, PAGE_SIZE); - GOTO(prepare_done, rc=0); - } - - rc = ll_brw(OBD_BRW_READ, inode, page, 0); - - EXIT; - prepare_done: - if (!rc) - SetPageUptodate(page); - - return rc; -} - -/* returns the page unlocked, but with a reference */ -static int ll_writepage(struct page *page) -{ - struct inode *inode = page->mapping->host; - int err; - ENTRY; - - if (!PageLocked(page)) - LBUG(); - - err = ll_brw(OBD_BRW_WRITE, inode, page, 1); - if ( !err ) { - //SetPageUptodate(page); - set_page_clean(page); - } else { - CERROR("ll_brw failure %d\n", err); - } - unlock_page(page); - RETURN(err); -} - - -/* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated - * too */ -static int ll_commit_write(struct file *file, struct page *page, - unsigned from, unsigned to) -{ - struct inode *inode = page->mapping->host; - struct ll_inode_info *lli = ll_i2info(inode); - struct lov_stripe_md *md = lli->lli_smd; - struct brw_page pg; - struct obd_brw_set *set; - int rc, create = 1; - loff_t size; - ENTRY; - - pg.pg = page; - pg.count = to; - pg.off = (((obd_off)page->index) << PAGE_SHIFT); - pg.flag = create ? OBD_BRW_CREATE : 0; - - set = obd_brw_set_new(); - if (set == NULL) - RETURN(-ENOMEM); - - SetPageUptodate(page); - - if (!PageLocked(page)) - LBUG(); - - CDEBUG(D_INODE, "commit_page writing (off "LPD64"), count "LPD64"\n", - pg.off, pg.count); - - set->brw_callback = ll_brw_sync_wait; - rc = obd_brw(OBD_BRW_WRITE, ll_i2obdconn(inode), md, 1, &pg, 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); - } - obd_brw_set_free(set); - kunmap(page); - - size = pg.off + pg.count; - /* do NOT truncate when writing in the middle of a file */ - if (size > inode->i_size) - inode->i_size = size; - - RETURN(rc); -} /* ll_commit_write */ - - -static int ll_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf, - unsigned long blocknr, int blocksize) -{ - obd_count bufs_per_obdo = iobuf->nr_pages; - struct ll_inode_info *lli = ll_i2info(inode); - struct lov_stripe_md *lsm = lli->lli_smd; - struct brw_page *pga; - struct obd_brw_set *set; - int i, rc = 0; - ENTRY; - - if (!lsm || !lsm->lsm_object_id) - RETURN(-ENOMEM); - - if (blocksize != PAGE_SIZE) { - CERROR("direct_IO blocksize != PAGE_SIZE\n"); - RETURN(-EINVAL); - } - - set = obd_brw_set_new(); - if (set == NULL) - RETURN(-ENOMEM); - - OBD_ALLOC(pga, sizeof(*pga) * bufs_per_obdo); - if (!pga) { - obd_brw_set_free(set); - RETURN(-ENOMEM); - } - - /* NB: we can't use iobuf->maplist[i]->index for the offset - * instead of "blocknr" because ->index contains garbage. - */ - for (i = 0; i < bufs_per_obdo; i++, blocknr++) { - pga[i].pg = iobuf->maplist[i]; - pga[i].count = PAGE_SIZE; - pga[i].off = (obd_off)blocknr << PAGE_SHIFT; - pga[i].flag = OBD_BRW_CREATE; - } - - set->brw_callback = ll_brw_sync_wait; - rc = obd_brw(rw == WRITE ? OBD_BRW_WRITE : OBD_BRW_READ, - ll_i2obdconn(inode), lsm, bufs_per_obdo, pga, 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); - } - obd_brw_set_free(set); - if (rc == 0) - rc = bufs_per_obdo * PAGE_SIZE; - - OBD_FREE(pga, sizeof(*pga) * bufs_per_obdo); - RETURN(rc); -} - -int ll_flush_inode_pages(struct inode * inode) -{ - obd_count bufs_per_obdo = 0; - obd_size *count = NULL; - obd_off *offset = NULL; - obd_flag *flags = NULL; - int err = 0; - - ENTRY; - - spin_lock(&pagecache_lock); - - spin_unlock(&pagecache_lock); - - - OBD_ALLOC(count, sizeof(*count) * bufs_per_obdo); - OBD_ALLOC(offset, sizeof(*offset) * bufs_per_obdo); - OBD_ALLOC(flags, sizeof(*flags) * bufs_per_obdo); - if (!count || !offset || !flags) - GOTO(out, err=-ENOMEM); - -#if 0 - for (i = 0 ; i < bufs_per_obdo ; i++) { - count[i] = PAGE_SIZE; - offset[i] = ((obd_off)(iobuf->maplist[i])->index) << PAGE_SHIFT; - flags[i] = OBD_BRW_CREATE; - } - - err = obd_brw(OBD_BRW_WRITE, ll_i2obdconn(inode), - ll_i2info(inode)->lli_smd, bufs_per_obdo, - iobuf->maplist, count, offset, flags, NULL, NULL); - if (err == 0) - err = bufs_per_obdo * 4096; -#endif - out: - OBD_FREE(flags, sizeof(*flags) * bufs_per_obdo); - OBD_FREE(count, sizeof(*count) * bufs_per_obdo); - OBD_FREE(offset, sizeof(*offset) * bufs_per_obdo); - RETURN(err); -} - -#endif - - -struct address_space_operations ll_aops = { - readpage: ll_readpage, -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)) - direct_IO: ll_direct_IO, - writepage: ll_writepage, - sync_page: block_sync_page, - prepare_write: ll_prepare_write, - commit_write: ll_commit_write, - bmap: NULL -#endif -}; diff --git a/lustre/llite/super.c b/lustre/llite/super.c deleted file mode 100644 index cb3ae90..0000000 --- a/lustre/llite/super.c +++ /dev/null @@ -1,621 +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) 2002 Cluster File Systems, Inc. - */ - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -kmem_cache_t *ll_file_data_slab; -extern struct address_space_operations ll_aops; -extern struct address_space_operations ll_dir_aops; -struct super_operations ll_super_operations; - -extern int ll_recover(struct recovd_data *, int); -extern int ll_commitcbd_setup(struct ll_sb_info *); -extern int ll_commitcbd_cleanup(struct ll_sb_info *); - -extern void ll_proc_namespace(struct super_block* sb, char* osc, char* mdc); - -static char *ll_read_opt(const char *opt, char *data) -{ - char *value; - char *retval; - ENTRY; - - CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data); - if ( strncmp(opt, data, strlen(opt)) ) - RETURN(NULL); - if ( (value = strchr(data, '=')) == NULL ) - RETURN(NULL); - - value++; - OBD_ALLOC(retval, strlen(value) + 1); - if ( !retval ) { - CERROR("out of memory!\n"); - RETURN(NULL); - } - - memcpy(retval, value, strlen(value)+1); - CDEBUG(D_SUPER, "Assigned option: %s, value %s\n", opt, retval); - RETURN(retval); -} - -static int ll_set_opt(const char *opt, char *data, int fl) -{ - ENTRY; - - CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data); - if ( strncmp(opt, data, strlen(opt)) ) - RETURN(0); - else - RETURN(fl); -} - -static void ll_options(char *options, char **ost, char **mds, int *flags) -{ - char *this_char; - ENTRY; - - if (!options) { - EXIT; - return; - } - - for (this_char = strtok (options, ","); - this_char != NULL; - this_char = strtok (NULL, ",")) { - CDEBUG(D_SUPER, "this_char %s\n", this_char); - if ( (!*ost && (*ost = ll_read_opt("osc", this_char)))|| - (!*mds && (*mds = ll_read_opt("mdc", this_char)))|| - (!(*flags & LL_SBI_NOLCK) && ((*flags) = (*flags) | - ll_set_opt("nolock", this_char, LL_SBI_NOLCK))) ) - continue; - } - EXIT; -} - -#ifndef log2 -#define log2(n) ffz(~(n)) -#endif - -static struct super_block * ll_read_super(struct super_block *sb, - void *data, int silent) -{ - struct inode *root = 0; - struct obd_device *obd; - struct ll_sb_info *sbi; - char *osc = NULL; - char *mdc = NULL; - int err; - struct ll_fid rootfid; - struct obd_statfs osfs; - struct ptlrpc_request *request = NULL; - struct ptlrpc_connection *mdc_conn; - struct ll_read_inode2_cookie lic; - class_uuid_t uuid; - - ENTRY; - MOD_INC_USE_COUNT; - - OBD_ALLOC(sbi, sizeof(*sbi)); - if (!sbi) { - MOD_DEC_USE_COUNT; - RETURN(NULL); - } - - INIT_LIST_HEAD(&sbi->ll_conn_chain); - INIT_LIST_HEAD(&sbi->ll_orphan_dentry_list); - generate_random_uuid(uuid); - class_uuid_unparse(uuid, sbi->ll_sb_uuid); - - sb->u.generic_sbp = sbi; - - ll_options(data, &osc, &mdc, &sbi->ll_flags); - - if (!osc) { - CERROR("no osc\n"); - GOTO(out_free, sb = NULL); - } - - if (!mdc) { - CERROR("no mdc\n"); - GOTO(out_free, sb = NULL); - } - - obd = class_uuid2obd(mdc); - if (!obd) { - CERROR("MDC %s: not setup or attached\n", mdc); - GOTO(out_free, sb = NULL); - } - - err = obd_connect(&sbi->ll_mdc_conn, obd, sbi->ll_sb_uuid, - ptlrpc_recovd, ll_recover); - if (err) { - CERROR("cannot connect to %s: rc = %d\n", mdc, err); - GOTO(out_free, sb = NULL); - } - - mdc_conn = sbi2mdc(sbi)->cl_import.imp_connection; - list_add(&mdc_conn->c_sb_chain, &sbi->ll_conn_chain); - - obd = class_uuid2obd(osc); - if (!obd) { - CERROR("OSC %s: not setup or attached\n", osc); - GOTO(out_mdc, sb = NULL); - } - - err = obd_connect(&sbi->ll_osc_conn, obd, sbi->ll_sb_uuid, - ptlrpc_recovd, ll_recover); - if (err) { - CERROR("cannot connect to %s: rc = %d\n", osc, err); - GOTO(out_mdc, sb = NULL); - } - - err = mdc_getstatus(&sbi->ll_mdc_conn, &rootfid); - if (err) { - CERROR("cannot mds_connect: rc = %d\n", err); - GOTO(out_mdc, sb = NULL); - } - CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id); - sbi->ll_rootino = rootfid.id; - - memset(&osfs, 0, sizeof(osfs)); - err = obd_statfs(&sbi->ll_mdc_conn, &osfs); - sb->s_blocksize = osfs.os_bsize; - sb->s_blocksize_bits = log2(osfs.os_bsize); - sb->s_magic = LL_SUPER_MAGIC; - sb->s_maxbytes = (1ULL << (32 + 9)) - osfs.os_bsize; - - sb->s_op = &ll_super_operations; - - /* make root inode */ - err = mdc_getattr(&sbi->ll_mdc_conn, sbi->ll_rootino, S_IFDIR, - OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request); - if (err) { - CERROR("mdc_getattr failed for root: rc = %d\n", err); - GOTO(out_request, sb = NULL); - } - - /* initialize committed transaction callback daemon */ - spin_lock_init(&sbi->ll_commitcbd_lock); - init_waitqueue_head(&sbi->ll_commitcbd_waitq); - init_waitqueue_head(&sbi->ll_commitcbd_ctl_waitq); - sbi->ll_commitcbd_flags = 0; - err = ll_commitcbd_setup(sbi); - if (err) { - CERROR("failed to start commit callback daemon: rc = %d\n",err); - GOTO(out_request, sb = NULL); - } - - lic.lic_body = lustre_msg_buf(request->rq_repmsg, 0); - lic.lic_lmm = NULL; - LASSERT(sbi->ll_rootino != 0); - root = iget4(sb, sbi->ll_rootino, NULL, &lic); - - if (root) { - sb->s_root = d_alloc_root(root); - } else { - CERROR("lustre_lite: bad iget4 for root\n"); - GOTO(out_cdb, sb = NULL); - } - - ptlrpc_req_finished(request); - request = NULL; - ll_proc_namespace(sb, osc, mdc); - -out_dev: - if (mdc) - OBD_FREE(mdc, strlen(mdc) + 1); - if (osc) - OBD_FREE(osc, strlen(osc) + 1); - - RETURN(sb); - -out_cdb: - ll_commitcbd_cleanup(sbi); -out_request: - ptlrpc_req_finished(request); - obd_disconnect(&sbi->ll_osc_conn); -out_mdc: - obd_disconnect(&sbi->ll_mdc_conn); -out_free: - OBD_FREE(sbi, sizeof(*sbi)); - - MOD_DEC_USE_COUNT; - goto out_dev; -} /* ll_read_super */ - -static void ll_put_super(struct super_block *sb) -{ - struct ll_sb_info *sbi = ll_s2sbi(sb); - struct list_head *tmp, *next; - struct ll_fid rootfid; - ENTRY; - - list_del(&sbi->ll_conn_chain); - ll_commitcbd_cleanup(sbi); - obd_disconnect(&sbi->ll_osc_conn); - - /* NULL request to force sync on the MDS, and get the last_committed - * value to flush remaining RPCs from the sending queue on client. - * - * XXX This should be an mdc_sync() call to sync the whole MDS fs, - * which we can call for other reasons as well. - */ - mdc_getstatus(&sbi->ll_mdc_conn, &rootfid); - - lprocfs_dereg_mnt(sbi->ll_proc_root); - sbi->ll_proc_root = NULL; - - obd_disconnect(&sbi->ll_mdc_conn); - - spin_lock(&dcache_lock); - list_for_each_safe(tmp, next, &sbi->ll_orphan_dentry_list) { - struct dentry *dentry = list_entry(tmp, struct dentry, d_hash); - shrink_dcache_parent(dentry); - } - spin_unlock(&dcache_lock); - - OBD_FREE(sbi, sizeof(*sbi)); - - MOD_DEC_USE_COUNT; - EXIT; -} /* ll_put_super */ - -static void ll_clear_inode(struct inode *inode) -{ - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ll_inode_info *lli = ll_i2info(inode); - int rc; - ENTRY; - - rc = mdc_cancel_unused(&sbi->ll_mdc_conn, inode, LDLM_FL_NO_CALLBACK); - if (rc < 0) { - CERROR("mdc_cancel_unused: %d\n", rc); - /* XXX FIXME do something dramatic */ - } - - if (lli->lli_smd) { - rc = obd_cancel_unused(&sbi->ll_osc_conn, lli->lli_smd, 0); - if (rc < 0) { - CERROR("obd_cancel_unused: %d\n", rc); - /* XXX FIXME do something dramatic */ - } - } - - if (atomic_read(&inode->i_count) == 0) { - char *symlink_name = lli->lli_symlink_name; - - if (lli->lli_smd) - obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd); - - if (symlink_name) { - OBD_FREE(symlink_name, strlen(symlink_name) + 1); - lli->lli_symlink_name = NULL; - } - } - - EXIT; -} - -static void ll_delete_inode(struct inode *inode) -{ - ENTRY; - if (S_ISREG(inode->i_mode)) { - int err; - struct obdo *oa; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - - if (!lsm) - GOTO(out, -EINVAL); - - if (lsm->lsm_object_id == 0) { - CERROR("This really happens\n"); - /* No obdo was ever created */ - GOTO(out, 0); - } - - oa = obdo_alloc(); - if (oa == NULL) - GOTO(out, -ENOMEM); - - oa->o_id = lsm->lsm_object_id; - oa->o_mode = inode->i_mode; - oa->o_valid = OBD_MD_FLID | OBD_MD_FLEASIZE | OBD_MD_FLTYPE; - - err = obd_destroy(ll_i2obdconn(inode), oa, lsm); - obdo_free(oa); - CDEBUG(D_SUPER, "obd destroy of objid "LPX64" error %d\n", - lsm->lsm_object_id, err); - } -out: - clear_inode(inode); - EXIT; -} - -/* like inode_setattr, but doesn't mark the inode dirty */ -static int ll_attr2inode(struct inode * inode, struct iattr * attr, int trunc) -{ - unsigned int ia_valid = attr->ia_valid; - int error = 0; - - if ((ia_valid & ATTR_SIZE) && trunc) { - error = vmtruncate(inode, attr->ia_size); - if (error) - goto out; - } else if (ia_valid & ATTR_SIZE) - inode->i_size = attr->ia_size; - - if (ia_valid & ATTR_UID) - inode->i_uid = attr->ia_uid; - if (ia_valid & ATTR_GID) - inode->i_gid = attr->ia_gid; - if (ia_valid & ATTR_ATIME) - inode->i_atime = attr->ia_atime; - if (ia_valid & ATTR_MTIME) - inode->i_mtime = attr->ia_mtime; - if (ia_valid & ATTR_CTIME) - inode->i_ctime = attr->ia_ctime; - if (ia_valid & ATTR_MODE) { - inode->i_mode = attr->ia_mode; - if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) - inode->i_mode &= ~S_ISGID; - } -out: - return error; -} - -int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc) -{ - struct ptlrpc_request *request = NULL; - struct ll_sb_info *sbi = ll_i2sbi(inode); - int err; - - ENTRY; - - /* change incore inode */ - ll_attr2inode(inode, attr, do_trunc); - - err = mdc_setattr(&sbi->ll_mdc_conn, inode, attr, &request); - if (err) - CERROR("mdc_setattr fails (%d)\n", err); - - ptlrpc_req_finished(request); - - RETURN(err); -} - -int ll_setattr(struct dentry *de, struct iattr *attr) -{ - int rc = inode_change_ok(de->d_inode, attr); - - if (rc) - return rc; - - return ll_inode_setattr(de->d_inode, attr, 1); -} - -static int ll_statfs(struct super_block *sb, struct statfs *sfs) -{ - struct ll_sb_info *sbi = ll_s2sbi(sb); - struct obd_statfs osfs; - int rc; - ENTRY; - - memset(sfs, 0, sizeof(*sfs)); - rc = obd_statfs(&sbi->ll_mdc_conn, &osfs); - statfs_unpack(sfs, &osfs); - if (rc) - CERROR("mdc_statfs fails: rc = %d\n", rc); - else - CDEBUG(D_SUPER, "mdc_statfs shows blocks "LPU64"/"LPU64 - " objects "LPU64"/"LPU64"\n", - osfs.os_bavail, osfs.os_blocks, - osfs.os_ffree, osfs.os_files); - - /* temporary until mds_statfs returns statfs info for all OSTs */ - if (!rc) { - rc = obd_statfs(&sbi->ll_osc_conn, &osfs); - if (rc) { - CERROR("obd_statfs fails: rc = %d\n", rc); - GOTO(out, rc); - } - CDEBUG(D_SUPER, "obd_statfs shows blocks "LPU64"/"LPU64 - " objects "LPU64"/"LPU64"\n", - osfs.os_bavail, osfs.os_blocks, - osfs.os_ffree, osfs.os_files); - - while (osfs.os_blocks > ~0UL) { - sfs->f_bsize <<= 1; - - osfs.os_blocks >>= 1; - osfs.os_bfree >>= 1; - osfs.os_bavail >>= 1; - } - sfs->f_blocks = osfs.os_blocks; - sfs->f_bfree = osfs.os_bfree; - sfs->f_bavail = osfs.os_bavail; - if (osfs.os_ffree < (__u64)sfs->f_ffree) - sfs->f_ffree = osfs.os_ffree; - } - -out: - RETURN(rc); -} - -void ll_update_inode(struct inode *inode, struct mds_body *body) -{ - if (body->valid & OBD_MD_FLID) - inode->i_ino = body->ino; - if (body->valid & OBD_MD_FLATIME) - inode->i_atime = body->atime; - if (body->valid & OBD_MD_FLMTIME) - inode->i_mtime = body->mtime; - if (body->valid & OBD_MD_FLCTIME) - inode->i_ctime = body->ctime; - if (body->valid & OBD_MD_FLMODE) - inode->i_mode = (inode->i_mode & S_IFMT)|(body->mode & ~S_IFMT); - if (body->valid & OBD_MD_FLTYPE) - inode->i_mode = (inode->i_mode & ~S_IFMT)|(body->mode & S_IFMT); - if (body->valid & OBD_MD_FLUID) - inode->i_uid = body->uid; - if (body->valid & OBD_MD_FLGID) - inode->i_gid = body->gid; - if (body->valid & OBD_MD_FLFLAGS) - inode->i_flags = body->flags; - if (body->valid & OBD_MD_FLNLINK) - inode->i_nlink = body->nlink; - if (body->valid & OBD_MD_FLGENER) - inode->i_generation = body->generation; - if (body->valid & OBD_MD_FLRDEV) - inode->i_rdev = body->rdev; - if (body->valid & OBD_MD_FLSIZE) - inode->i_size = body->size; -} - -static void ll_read_inode2(struct inode *inode, void *opaque) -{ - struct ll_read_inode2_cookie *lic = opaque; - struct mds_body *body = lic->lic_body; - struct ll_inode_info *lli = ll_i2info(inode); - ENTRY; - - sema_init(&lli->lli_open_sem, 1); - atomic_set(&lli->lli_open_count, 0); - - /* core attributes first */ - ll_update_inode(inode, body); - - //if (body->valid & OBD_MD_FLEASIZE) - LASSERT(!lli->lli_smd); - if (lic && lic->lic_lmm) - obd_unpackmd(ll_i2obdconn(inode), &lli->lli_smd, lic->lic_lmm); - - /* Get the authoritative file size */ - if (lli->lli_smd && (inode->i_mode & S_IFREG)) { - int rc; - LASSERT(lli->lli_smd->lsm_object_id != 0); - rc = ll_file_size(inode, lli->lli_smd); - if (rc) { - CERROR("ll_file_size: %d\n", rc); - /* FIXME: need to somehow prevent inode creation */ - LBUG(); - make_bad_inode(inode); - } - } - - /* OIDEBUG(inode); */ - - if (S_ISREG(inode->i_mode)) { - inode->i_op = &ll_file_inode_operations; - inode->i_fop = &ll_file_operations; - inode->i_mapping->a_ops = &ll_aops; - EXIT; - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &ll_dir_inode_operations; - inode->i_fop = &ll_dir_operations; - inode->i_mapping->a_ops = &ll_dir_aops; - EXIT; - } else if (S_ISLNK(inode->i_mode)) { - inode->i_op = &ll_fast_symlink_inode_operations; - EXIT; - } else { - init_special_inode(inode, inode->i_mode, inode->i_rdev); - EXIT; - } -} - -static inline void invalidate_request_list(struct list_head *req_list) -{ - struct list_head *tmp, *n; - list_for_each_safe(tmp, n, req_list) { - struct ptlrpc_request *req = - list_entry(tmp, struct ptlrpc_request, rq_list); - CERROR("invalidating req xid "LPD64" op %d to %s:%d\n", - (unsigned long long)req->rq_xid, req->rq_reqmsg->opc, - req->rq_connection->c_remote_uuid, - req->rq_import->imp_client->cli_request_portal); - req->rq_flags |= PTL_RPC_FL_ERR; - wake_up(&req->rq_wait_for_rep); - } -} - -void ll_umount_begin(struct super_block *sb) -{ - struct ll_sb_info *sbi = ll_s2sbi(sb); - struct list_head *ctmp; - - ENTRY; - - list_for_each(ctmp, &sbi->ll_conn_chain) { - struct ptlrpc_connection *conn; - conn = list_entry(ctmp, struct ptlrpc_connection, c_sb_chain); - - spin_lock(&conn->c_lock); - /* XXX should just be dealing with imports, probably through - * XXX iocontrol, need next-gen recovery! */ - conn->c_flags |= CONN_INVALID; - /* invalidate_request_list(&conn->c_sending_head); */ - invalidate_request_list(&conn->c_delayed_head); - spin_unlock(&conn->c_lock); - } - - EXIT; -} - -/* exported operations */ -struct super_operations ll_super_operations = -{ - read_inode2: ll_read_inode2, - clear_inode: ll_clear_inode, - delete_inode: ll_delete_inode, - put_super: ll_put_super, - statfs: ll_statfs, - umount_begin: ll_umount_begin -}; - -struct file_system_type lustre_lite_fs_type = { - "lustre_lite", 0, ll_read_super, NULL -}; - -static int __init init_lustre_lite(void) -{ - printk(KERN_INFO "Lustre Lite 0.5.14, info@clusterfs.com\n"); - ll_file_data_slab = kmem_cache_create("ll_file_data", - sizeof(struct ll_file_data), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); - if (ll_file_data_slab == NULL) - return -ENOMEM; - return register_filesystem(&lustre_lite_fs_type); -} - -static void __exit exit_lustre_lite(void) -{ - unregister_filesystem(&lustre_lite_fs_type); - kmem_cache_destroy(ll_file_data_slab); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Lite Client File System v1.0"); -MODULE_LICENSE("GPL"); - -module_init(init_lustre_lite); -module_exit(exit_lustre_lite); -#endif diff --git a/lustre/llite/super25.c b/lustre/llite/super25.c deleted file mode 100644 index cd6544a..0000000 --- a/lustre/llite/super25.c +++ /dev/null @@ -1,659 +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) 2002 Cluster File Systems, Inc. - */ - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -kmem_cache_t *ll_file_data_slab; -extern struct address_space_operations ll_aops; -extern struct address_space_operations ll_dir_aops; -struct super_operations ll_super_operations; - -extern int ll_init_inodecache(void); -extern void ll_destroy_inodecache(void); -extern int ll_recover(struct recovd_data *, int); -extern int ll_commitcbd_setup(struct ll_sb_info *); -extern int ll_commitcbd_cleanup(struct ll_sb_info *); -int ll_read_inode2(struct inode *inode, void *opaque); - -extern void ll_proc_namespace(struct super_block* sb, char* osc, char* mdc) - -static char *ll_read_opt(const char *opt, char *data) -{ - char *value; - char *retval; - ENTRY; - - CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data); - if ( strncmp(opt, data, strlen(opt)) ) - RETURN(NULL); - if ( (value = strchr(data, '=')) == NULL ) - RETURN(NULL); - - value++; - OBD_ALLOC(retval, strlen(value) + 1); - if ( !retval ) { - CERROR("out of memory!\n"); - RETURN(NULL); - } - - memcpy(retval, value, strlen(value)+1); - CDEBUG(D_SUPER, "Assigned option: %s, value %s\n", opt, retval); - RETURN(retval); -} - -static int ll_set_opt(const char *opt, char *data, int fl) -{ - ENTRY; - - CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data); - if ( strncmp(opt, data, strlen(opt)) ) - RETURN(0); - else - RETURN(fl); -} - -static void ll_options(char *options, char **ost, char **mds, int *flags) -{ - char *opt_ptr = options; - char *this_char; - ENTRY; - - if (!options) { - EXIT; - return; - } - - while ((this_char = strsep (&opt_ptr, ",")) != NULL) { - CDEBUG(D_SUPER, "this_char %s\n", this_char); - if ( (!*ost && (*ost = ll_read_opt("osc", this_char)))|| - (!*mds && (*mds = ll_read_opt("mdc", this_char)))|| - (!(*flags & LL_SBI_NOLCK) && ((*flags) = (*flags) | - ll_set_opt("nolock", this_char, LL_SBI_NOLCK))) ) - continue; - } - EXIT; -} - -#ifndef log2 -#define log2(n) ffz(~(n)) -#endif - - -static int ll_fill_super(struct super_block *sb, void *data, int silent) -{ - struct inode *root = 0; - struct obd_device *obd; - struct ll_sb_info *sbi; - char *osc = NULL; - char *mdc = NULL; - int err; - struct ll_fid rootfid; - struct obd_statfs osfs; - struct ptlrpc_request *request = NULL; - struct ptlrpc_connection *mdc_conn; - struct ll_read_inode2_cookie lic; - class_uuid_t uuid; - - ENTRY; - MOD_INC_USE_COUNT; - - OBD_ALLOC(sbi, sizeof(*sbi)); - if (!sbi) { - MOD_DEC_USE_COUNT; - RETURN(-ENOMEM); - } - - INIT_LIST_HEAD(&sbi->ll_conn_chain); - generate_random_uuid(uuid); - class_uuid_unparse(uuid, sbi->ll_sb_uuid); - - sb->s_fs_info = sbi; - - ll_options(data, &osc, &mdc, &sbi->ll_flags); - - if (!osc) { - CERROR("no osc\n"); - GOTO(out_free, sb = NULL); - } - - if (!mdc) { - CERROR("no mdc\n"); - GOTO(out_free, sb = NULL); - } - - obd = class_uuid2obd(mdc); - if (!obd) { - CERROR("MDC %s: not setup or attached\n", mdc); - GOTO(out_free, sb = NULL); - } - - err = obd_connect(&sbi->ll_mdc_conn, obd, sbi->ll_sb_uuid, - ptlrpc_recovd, ll_recover); - if (err) { - CERROR("cannot connect to %s: rc = %d\n", mdc, err); - GOTO(out_free, sb = NULL); - } - - mdc_conn = sbi2mdc(sbi)->cl_import.imp_connection; - list_add(&mdc_conn->c_sb_chain, &sbi->ll_conn_chain); - - obd = class_uuid2obd(osc); - if (!obd) { - CERROR("OSC %s: not setup or attached\n", osc); - GOTO(out_mdc, sb = NULL); - } - - err = obd_connect(&sbi->ll_osc_conn, obd, sbi->ll_sb_uuid, - ptlrpc_recovd, ll_recover); - if (err) { - CERROR("cannot connect to %s: rc = %d\n", osc, err); - GOTO(out_mdc, sb = NULL); - } - - err = mdc_getstatus(&sbi->ll_mdc_conn, &rootfid); - if (err) { - CERROR("cannot mds_connect: rc = %d\n", err); - GOTO(out_mdc, sb = NULL); - } - CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id); - sbi->ll_rootino = rootfid.id; - - memset(&osfs, 0, sizeof(osfs)); - err = mdc_statfs(&sbi->ll_mdc_conn, &osfs); - sb->s_blocksize = osfs.os_bsize; - sb->s_blocksize_bits = log2(osfs.os_bsize); - sb->s_magic = LL_SUPER_MAGIC; - sb->s_maxbytes = (1ULL << (32 + 9)) - osfs.os_bsize; - - sb->s_op = &ll_super_operations; - - /* make root inode */ - err = mdc_getattr(&sbi->ll_mdc_conn, sbi->ll_rootino, S_IFDIR, - OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request); - if (err) { - CERROR("mdc_getattr failed for root: rc = %d\n", err); - GOTO(out_request, sb = NULL); - } - - /* initialize committed transaction callback daemon */ - spin_lock_init(&sbi->ll_commitcbd_lock); - init_waitqueue_head(&sbi->ll_commitcbd_waitq); - init_waitqueue_head(&sbi->ll_commitcbd_ctl_waitq); - sbi->ll_commitcbd_flags = 0; - err = ll_commitcbd_setup(sbi); - if (err) { - CERROR("failed to start commit callback daemon: rc = %d\n",err); - GOTO(out_request, sb = NULL); - } - - lic.lic_body = lustre_msg_buf(request->rq_repmsg, 0); - lic.lic_lmm = NULL; - root = iget5_locked(sb, sbi->ll_rootino, NULL, - ll_read_inode2, &lic); - - if (root) { - sb->s_root = d_alloc_root(root); - } else { - CERROR("lustre_lite: bad iget4 for root\n"); - GOTO(out_cdb, sb = NULL); - } - - ptlrpc_req_finished(request); - request = NULL; - ll_proc_namespace(sb, osc, mdc) -out_dev: - if (mdc) - OBD_FREE(mdc, strlen(mdc) + 1); - if (osc) - OBD_FREE(osc, strlen(osc) + 1); - - RETURN(0); - -out_cdb: - ll_commitcbd_cleanup(sbi); -out_request: - ptlrpc_req_finished(request); - obd_disconnect(&sbi->ll_osc_conn); -out_mdc: - obd_disconnect(&sbi->ll_mdc_conn); -out_free: - OBD_FREE(sbi, sizeof(*sbi)); - - MOD_DEC_USE_COUNT; - goto out_dev; -} /* ll_fill_super */ - -struct super_block * ll_get_sb(struct file_system_type *fs_type, - int flags, char *devname, void * data) -{ - return get_sb_nodev(fs_type, flags, data, ll_fill_super); -} - -static void ll_put_super(struct super_block *sb) -{ - struct ll_sb_info *sbi = ll_s2sbi(sb); - struct ll_fid rootfid; - ENTRY; - - list_del(&sbi->ll_conn_chain); - ll_commitcbd_cleanup(sbi); - obd_disconnect(&sbi->ll_osc_conn); - - /* NULL request to force sync on the MDS, and get the last_committed - * value to flush remaining RPCs from the pending queue on client. - * - * XXX This should be an mdc_sync() call to sync the whole MDS fs, - * which we can call for other reasons as well. - */ - mdc_getstatus(&sbi->ll_mdc_conn, &rootfid); - - lprocfs_dereg_mnt(sbi->ll_proc_root); - sbi->ll_proc_root = NULL; - - obd_disconnect(&sbi->ll_mdc_conn); - OBD_FREE(sbi, sizeof(*sbi)); - - MOD_DEC_USE_COUNT; - EXIT; -} /* ll_put_super */ - -static void ll_clear_inode(struct inode *inode) -{ - ENTRY; - - if (atomic_read(&inode->i_count) == 0) { - struct ll_inode_info *lli = ll_i2info(inode); - char *symlink_name = lli->lli_symlink_name; - - if (lli->lli_smd) - obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd); - if (symlink_name) { - OBD_FREE(symlink_name, strlen(symlink_name) + 1); - lli->lli_symlink_name = NULL; - } - } - EXIT; -} - -static void ll_delete_inode(struct inode *inode) -{ - ENTRY; - if (S_ISREG(inode->i_mode)) { - int err; - struct obdo *oa; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - - if (!lsm) - GOTO(out, -EINVAL); - - if (lsm->lsm_object_id == 0) { - CERROR("This really happens\n"); - /* No obdo was ever created */ - GOTO(out, 0); - } - - oa = obdo_alloc(); - if (oa == NULL) - GOTO(out, -ENOMEM); - - oa->o_id = lsm->lsm_object_id; - oa->o_mode = inode->i_mode; - oa->o_valid = OBD_MD_FLID | OBD_MD_FLEASIZE | OBD_MD_FLTYPE; - - err = obd_destroy(ll_i2obdconn(inode), oa, lsm); - obdo_free(oa); - CDEBUG(D_SUPER, "obd destroy of objid "LPX64" error %d\n", - lsm->lsm_object_id, err); - } -out: - clear_inode(inode); - EXIT; -} - -/* like inode_setattr, but doesn't mark the inode dirty */ -static int ll_attr2inode(struct inode * inode, struct iattr * attr, int trunc) -{ - unsigned int ia_valid = attr->ia_valid; - int error = 0; - - if ((ia_valid & ATTR_SIZE) && trunc) { - error = vmtruncate(inode, attr->ia_size); - if (error) - goto out; - } else if (ia_valid & ATTR_SIZE) - inode->i_size = attr->ia_size; - - if (ia_valid & ATTR_UID) - inode->i_uid = attr->ia_uid; - if (ia_valid & ATTR_GID) - inode->i_gid = attr->ia_gid; - if (ia_valid & ATTR_ATIME) - inode->i_atime = attr->ia_atime; - if (ia_valid & ATTR_MTIME) - inode->i_mtime = attr->ia_mtime; - if (ia_valid & ATTR_CTIME) - inode->i_ctime = attr->ia_ctime; - if (ia_valid & ATTR_MODE) { - inode->i_mode = attr->ia_mode; - if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) - inode->i_mode &= ~S_ISGID; - } -out: - return error; -} - -int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc) -{ - struct ptlrpc_request *request = NULL; - struct ll_sb_info *sbi = ll_i2sbi(inode); - int err; - - ENTRY; - - /* change incore inode */ - ll_attr2inode(inode, attr, do_trunc); - - err = mdc_setattr(&sbi->ll_mdc_conn, inode, attr, &request); - if (err) - CERROR("mdc_setattr fails (%d)\n", err); - - ptlrpc_req_finished(request); - - RETURN(err); -} - -int ll_setattr(struct dentry *de, struct iattr *attr) -{ - int rc = inode_change_ok(de->d_inode, attr); - - if (rc) - return rc; - - return ll_inode_setattr(de->d_inode, attr, 1); -} - -static int ll_statfs(struct super_block *sb, struct statfs *sfs) -{ - struct ll_sb_info *sbi = ll_s2sbi(sb); - struct obd_statfs osfs; - int rc; - ENTRY; - - memset(sfs, 0, sizeof(*sfs)); - rc = obd_statfs(&sbi->ll_mdc_conn, &osfs); - statfs_unpack(sfs, &osfs); - if (rc) - CERROR("mdc_statfs fails: rc = %d\n", rc); - else - CDEBUG(D_SUPER, "mdc_statfs shows blocks "LPU64"/"LPU64 - " objects "LPU64"/"LPU64"\n", - osfs.os_bavail, osfs.os_blocks, - osfs.os_ffree, osfs.os_files); - - /* temporary until mds_statfs returns statfs info for all OSTs */ - if (!rc) { - rc = obd_statfs(&sbi->ll_osc_conn, &osfs); - if (rc) { - CERROR("obd_statfs fails: rc = %d\n", rc); - GOTO(out, rc); - } - CDEBUG(D_SUPER, "obd_statfs shows blocks "LPU64"/"LPU64 - " objects "LPU64"/"LPU64"\n", - osfs.os_bavail, osfs.os_blocks, - osfs.os_ffree, osfs.os_files); - - while (osfs.os_blocks > ~0UL) { - sfs->f_bsize <<= 1; - - osfs.os_blocks >>= 1; - osfs.os_bfree >>= 1; - osfs.os_bavail >>= 1; - } - sfs->f_blocks = osfs.os_blocks; - sfs->f_bfree = osfs.os_bfree; - sfs->f_bavail = osfs.os_bavail; - if (osfs.os_ffree < (__u64)sfs->f_ffree) - sfs->f_ffree = osfs.os_ffree; - } - -out: - RETURN(rc); -} - -void ll_update_inode(struct inode *inode, struct mds_body *body) -{ - if (body->valid & OBD_MD_FLID) - inode->i_ino = body->ino; - if (body->valid & OBD_MD_FLATIME) - inode->i_atime = body->atime; - if (body->valid & OBD_MD_FLMTIME) - inode->i_mtime = body->mtime; - if (body->valid & OBD_MD_FLCTIME) - inode->i_ctime = body->ctime; - if (body->valid & OBD_MD_FLMODE) - inode->i_mode = (inode->i_mode & S_IFMT)|(body->mode & ~S_IFMT); - if (body->valid & OBD_MD_FLTYPE) - inode->i_mode = (inode->i_mode & ~S_IFMT)|(body->mode & S_IFMT); - if (body->valid & OBD_MD_FLUID) - inode->i_uid = body->uid; - if (body->valid & OBD_MD_FLGID) - inode->i_gid = body->gid; - if (body->valid & OBD_MD_FLFLAGS) - inode->i_flags = body->flags; - if (body->valid & OBD_MD_FLNLINK) - inode->i_nlink = body->nlink; - if (body->valid & OBD_MD_FLGENER) - inode->i_generation = body->generation; - if (body->valid & OBD_MD_FLRDEV) - inode->i_rdev = to_kdev_t(body->rdev); - if (body->valid & OBD_MD_FLSIZE) - inode->i_size = body->size; -} - -int ll_read_inode2(struct inode *inode, void *opaque) -{ - struct ll_read_inode2_cookie *lic = opaque; - struct mds_body *body = lic->lic_body; - struct ll_inode_info *lli = ll_i2info(inode); - int rc = 0; - ENTRY; - - sema_init(&lli->lli_open_sem, 1); - - /* core attributes first */ - ll_update_inode(inode, body); - - //if (body->valid & OBD_MD_FLEASIZE) - LASSERT(!lli->lli_smd); - if (lic && lic->lic_lmm) - obd_unpackmd(ll_i2obdconn(inode), &lli->lli_smd, lic->lic_lmm); - - /* Get the authoritative file size */ - if (lli->lli_smd && S_ISREG(inode->i_mode)) { - rc = ll_file_size(inode, lli->lli_smd); - if (rc) { - CERROR("ll_file_size: %d\n", rc); - /* FIXME: need to somehow prevent inode creation */ - LBUG(); - make_bad_inode(inode); - } - } - - /* OIDEBUG(inode); */ - - if (S_ISREG(inode->i_mode)) { - inode->i_op = &ll_file_inode_operations; - inode->i_fop = &ll_file_operations; - inode->i_mapping->a_ops = &ll_aops; - EXIT; - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &ll_dir_inode_operations; - inode->i_fop = &ll_dir_operations; - inode->i_mapping->a_ops = &ll_dir_aops; - EXIT; - } else if (S_ISLNK(inode->i_mode)) { - inode->i_op = &ll_fast_symlink_inode_operations; - EXIT; - } else { - init_special_inode(inode, inode->i_mode, - kdev_t_to_nr(inode->i_rdev)); - EXIT; - } - - return rc; -} - -static inline void invalidate_request_list(struct list_head *req_list) -{ - struct list_head *tmp, *n; - list_for_each_safe(tmp, n, req_list) { - struct ptlrpc_request *req = - list_entry(tmp, struct ptlrpc_request, rq_list); - CERROR("invalidating req xid %d op %d to %s:%d\n", - (unsigned long long)req->rq_xid, req->rq_reqmsg->opc, - req->rq_connection->c_remote_uuid, - req->rq_import->imp_client->cli_request_portal); - req->rq_flags |= PTL_RPC_FL_ERR; - wake_up(&req->rq_wait_for_rep); - } -} - -void ll_umount_begin(struct super_block *sb) -{ - struct ll_sb_info *sbi = ll_s2sbi(sb); - struct list_head *ctmp; - - ENTRY; - - list_for_each(ctmp, &sbi->ll_conn_chain) { - struct ptlrpc_connection *conn; - conn = list_entry(ctmp, struct ptlrpc_connection, c_sb_chain); - - spin_lock(&conn->c_lock); - conn->c_flags |= CONN_INVALID; - invalidate_request_list(&conn->c_sending_head); - invalidate_request_list(&conn->c_delayed_head); - spin_unlock(&conn->c_lock); - } - - EXIT; -} - - -static kmem_cache_t *ll_inode_cachep; - -static struct inode *ll_alloc_inode(struct super_block *sb) -{ - struct ll_inode_info *lli; - lli = kmem_cache_alloc(ll_inode_cachep, SLAB_KERNEL); - if (!lli) - return NULL; - - memset(lli, 0, (char *)&lli->lli_vfs_inode - (char *)lli); - sema_init(&lli->lli_open_sem, 1); - - return &lli->lli_vfs_inode; -} - -static void ll_destroy_inode(struct inode *inode) -{ - kmem_cache_free(ll_inode_cachep, ll_i2info(inode)); -} - -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) -{ - struct ll_inode_info *lli = foo; - - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&lli->lli_vfs_inode); -} - -int ll_init_inodecache(void) -{ - ll_inode_cachep = kmem_cache_create("lustre_inode_cache", - sizeof(struct ll_inode_info), - 0, SLAB_HWCACHE_ALIGN, - init_once, NULL); - if (ll_inode_cachep == NULL) - return -ENOMEM; - return 0; -} - -void ll_destroy_inodecache(void) -{ - if (kmem_cache_destroy(ll_inode_cachep)) - CERROR("ll_inode_cache: not all structures were freed\n"); -} - - - -/* exported operations */ -struct super_operations ll_super_operations = -{ - alloc_inode: ll_alloc_inode, - destroy_inode: ll_destroy_inode, - clear_inode: ll_clear_inode, - delete_inode: ll_delete_inode, - put_super: ll_put_super, - statfs: ll_statfs, - umount_begin: ll_umount_begin -}; - -struct file_system_type lustre_lite_fs_type = { - .owner = THIS_MODULE, - .name = "lustre_lite", - .get_sb = ll_get_sb, - .kill_sb = kill_litter_super, -}; - -static int __init init_lustre_lite(void) -{ - int rc; - printk(KERN_INFO "Lustre Lite 0.5.14, info@clusterfs.com\n"); - rc = ll_init_inodecache(); - if (rc) - return -ENOMEM; - ll_file_data_slab = kmem_cache_create("ll_file_data", - sizeof(struct ll_file_data), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); - if (ll_file_data_slab == NULL) { - ll_destroy_inodecache(); - return -ENOMEM; - } - return register_filesystem(&lustre_lite_fs_type); -} - -static void __exit exit_lustre_lite(void) -{ - unregister_filesystem(&lustre_lite_fs_type); - ll_destroy_inodecache(); - kmem_cache_destroy(ll_file_data_slab); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Lite Client File System v1.0"); -MODULE_LICENSE("GPL"); - -module_init(init_lustre_lite); -module_exit(exit_lustre_lite); -#endif diff --git a/lustre/llite/symlink.c b/lustre/llite/symlink.c deleted file mode 100644 index 93a4bdb..0000000 --- a/lustre/llite/symlink.c +++ /dev/null @@ -1,123 +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. - */ - -#include -#include -#include -#include -#define DEBUG_SUBSYSTEM S_LLITE - -#include - -static int ll_readlink_internal(struct inode *inode, - struct ptlrpc_request **request, char **symname) -{ - struct ll_inode_info *lli = ll_i2info(inode); - struct ll_sb_info *sbi = ll_i2sbi(inode); - int rc, symlen = inode->i_size + 1; - ENTRY; - - *request = NULL; - - if (lli->lli_symlink_name) { - *symname = lli->lli_symlink_name; - CDEBUG(D_INODE, "using cached symlink %s\n", *symname); - RETURN(0); - } - - rc = mdc_getattr(&sbi->ll_mdc_conn, inode->i_ino, S_IFLNK, - OBD_MD_LINKNAME, symlen, request); - if (rc) { - CERROR("inode "LPD64": rc = %d\n", inode->i_ino, rc); - RETURN(rc); - } - - *symname = lustre_msg_buf((*request)->rq_repmsg, 1); - - OBD_ALLOC(lli->lli_symlink_name, symlen); - /* do not return an error if we cannot cache the symlink locally */ - if (lli->lli_symlink_name) - memcpy(lli->lli_symlink_name, *symname, symlen); - - RETURN(0); -} - -static int ll_readlink(struct dentry *dentry, char *buffer, int buflen) -{ - struct inode *inode = dentry->d_inode; - struct ll_inode_info *lli = ll_i2info(inode); - struct ptlrpc_request *request; - char *symname; - int rc; - ENTRY; - - /* on symlinks lli_open_sem protects lli_symlink_name allocation/data */ - down(&lli->lli_open_sem); - rc = ll_readlink_internal(inode, &request, &symname); - if (rc) - GOTO(out, rc); - - rc = vfs_readlink(dentry, buffer, buflen, symname); - out: - up(&lli->lli_open_sem); - ptlrpc_req_finished(request); - - RETURN(rc); -} - -static int ll_follow_link(struct dentry *dentry, struct nameidata *nd, - struct lookup_intent *it) -{ - struct inode *inode = dentry->d_inode; - struct ll_inode_info *lli = ll_i2info(inode); - struct ptlrpc_request *request; - int op, mode; - char *symname; - int rc; - ENTRY; - - op = it->it_op; - mode = it->it_mode; - - ll_intent_release(dentry, it); - down(&lli->lli_open_sem); - - it->it_op = op; - it->it_mode = mode; - - rc = ll_readlink_internal(inode, &request, &symname); - if (rc) - GOTO(out, rc); - - rc = vfs_follow_link_it(nd, symname, it); - out: - up(&lli->lli_open_sem); - ptlrpc_req_finished(request); - - RETURN(rc); -} - -extern int ll_setattr(struct dentry *de, struct iattr *attr); -struct inode_operations ll_fast_symlink_inode_operations = { - readlink: ll_readlink, - setattr: ll_setattr, - follow_link2: ll_follow_link -}; diff --git a/lustre/llite/sysctl.c b/lustre/llite/sysctl.c deleted file mode 100644 index ee4ac75..0000000 --- a/lustre/llite/sysctl.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) 2001 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct ctl_table_header *ll_table_header = NULL; - -int ll_debug_level = 0; -int ll_print_entry = 1; - - -#define LL_SYSCTL 1 - -#define LL_DEBUG 1 /* control debugging */ -#define LL_ENTRY 2 /* control enter/leave pattern */ -#define LL_TIMEOUT 3 /* timeout on upcalls to become intrble */ -#define LL_HARD 4 /* mount type "hard" or "soft" */ -#define LL_VARS 5 -#define LL_INDEX 6 -#define LL_RESET 7 - -#define LL_VARS_SLOT 2 - -static ctl_table ll_table[] = { - {LL_DEBUG, "debug", &ll_debug_level, sizeof(int), 0644, NULL, &proc_dointvec}, - {LL_ENTRY, "trace", &ll_print_entry, sizeof(int), 0644, NULL, &proc_dointvec}, - { 0 } -}; - -static ctl_table top_table[] = { - {LL_SYSCTL, "lustre_light", NULL, 0, 0555, ll_table}, - {0} -}; - -void ll_sysctl_init (void) -{ - -#ifdef CONFIG_SYSCTL - if ( !ll_table_header ) - ll_table_header = register_sysctl_table(top_table, 0); -#endif -} - -void ll_sysctl_clean (void) -{ -#ifdef CONFIG_SYSCTL - if ( ll_table_header ) - unregister_sysctl_table(ll_table_header); - ll_table_header = NULL; -#endif -} diff --git a/lustre/lov/.cvsignore b/lustre/lov/.cvsignore deleted file mode 100644 index e995588..0000000 --- a/lustre/lov/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.deps -Makefile -Makefile.in diff --git a/lustre/lov/Makefile.am b/lustre/lov/Makefile.am deleted file mode 100644 index 2320dcc..0000000 --- a/lustre/lov/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 = lov -modulefs_DATA = lov.o -EXTRA_PROGRAMS = lov -LINX= - -lov_SOURCES = lov_obd.c lov_pack.c lproc_lov.c $(LINX) - -include $(top_srcdir)/Rules diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c deleted file mode 100644 index e7cf3cb..0000000 --- a/lustre/lov/lov_obd.c +++ /dev/null @@ -1,1503 +0,0 @@ - /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lov/lov.c - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Phil Schwan - * Peter Braam - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_LOV - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern struct lprocfs_vars status_var_nm_1[]; -extern struct lprocfs_vars status_class_var[]; - -static kmem_cache_t *lov_file_cache; - -struct lov_file_handles { - struct list_head lfh_list; - __u64 lfh_cookie; - int lfh_count; - struct lustre_handle *lfh_handles; -}; - -extern int lov_packmd(struct lustre_handle *conn, struct lov_mds_md **lmm, - struct lov_stripe_md *lsm); -extern int lov_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsm, - struct lov_mds_md *lmm); - -/* obd methods */ -int lov_attach(struct obd_device *dev, obd_count len, void *data) -{ - return lprocfs_reg_obd(dev, status_var_nm_1, dev); -} - -int lov_detach(struct obd_device *dev) -{ - return lprocfs_dereg_obd(dev); -} - -static int lov_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct ptlrpc_request *req = NULL; - struct lov_obd *lov = &obd->u.lov; - struct client_obd *mdc = &lov->mdcobd->u.cli; - struct lov_desc *desc = &lov->desc; - struct obd_export *exp; - struct lustre_handle mdc_conn; - obd_uuid_t *uuidarray; - int rc, rc2, i; - ENTRY; - - MOD_INC_USE_COUNT; - rc = class_connect(conn, obd, cluuid); - if (rc) - GOTO(out_dec, rc); - - /* We don't want to actually do the underlying connections more than - * once, so keep track. */ - lov->refcount++; - if (lov->refcount > 1) - RETURN(0); - - exp = class_conn2export(conn); - INIT_LIST_HEAD(&exp->exp_lov_data.led_open_head); - - /* retrieve LOV metadata from MDS */ - rc = obd_connect(&mdc_conn, lov->mdcobd, NULL, recovd, recover); - if (rc) { - CERROR("cannot connect to mdc: rc = %d\n", rc); - GOTO(out_conn, rc); - } - - rc = mdc_getlovinfo(obd, &mdc_conn, &req); - rc2 = obd_disconnect(&mdc_conn); - if (rc) { - CERROR("cannot get lov info %d\n", rc); - GOTO(out_conn, rc); - } - - if (rc2) { - CERROR("error disconnecting from MDS %d\n", rc2); - GOTO(out_conn, rc = rc2); - } - - /* sanity... */ - if (req->rq_repmsg->bufcount < 2 || - req->rq_repmsg->buflens[0] < sizeof(*desc)) { - CERROR("LOV desc: invalid descriptor returned\n"); - GOTO(out_conn, rc = -EINVAL); - } - - memcpy(desc, lustre_msg_buf(req->rq_repmsg, 0), sizeof(*desc)); - lov_unpackdesc(desc); - - if (req->rq_repmsg->buflens[1] < sizeof(*uuidarray)*desc->ld_tgt_count){ - CERROR("LOV desc: invalid uuid array returned\n"); - GOTO(out_conn, rc = -EINVAL); - } - - if (memcmp(obd->obd_uuid, desc->ld_uuid, sizeof(desc->ld_uuid))) { - CERROR("LOV desc: uuid %s not on mds device (%s)\n", - obd->obd_uuid, desc->ld_uuid); - GOTO(out_conn, rc = -EINVAL); - } - - if (desc->ld_tgt_count > 1000) { - CERROR("LOV desc: target count > 1000 (%d)\n", - desc->ld_tgt_count); - GOTO(out_conn, rc = -EINVAL); - } - - /* Because of 64-bit divide/mod operations only work with a 32-bit - * divisor in a 32-bit kernel, we cannot support a stripe width - * of 4GB or larger on 32-bit CPUs. - */ - if ((desc->ld_default_stripe_count ? - desc->ld_default_stripe_count : desc->ld_tgt_count) * - desc->ld_default_stripe_size > ~0UL) { - CERROR("LOV: stripe width "LPU64"x%u > %lu on 32-bit system\n", - desc->ld_default_stripe_size, - desc->ld_default_stripe_count ? - desc->ld_default_stripe_count : desc->ld_tgt_count,~0UL); - GOTO(out_conn, rc = -EINVAL); - } - - lov->bufsize = sizeof(struct lov_tgt_desc) * desc->ld_tgt_count; - OBD_ALLOC(lov->tgts, lov->bufsize); - if (!lov->tgts) { - CERROR("Out of memory\n"); - GOTO(out_conn, rc = -ENOMEM); - } - - uuidarray = lustre_msg_buf(req->rq_repmsg, 1); - for (i = 0; i < desc->ld_tgt_count; i++) - memcpy(lov->tgts[i].uuid, uuidarray[i], sizeof(*uuidarray)); - - for (i = 0; i < desc->ld_tgt_count; i++) { - struct obd_device *tgt = class_uuid2obd(uuidarray[i]); - int rc2; - - if (!tgt) { - CERROR("Target %s not attached\n", uuidarray[i]); - GOTO(out_disc, rc = -EINVAL); - } - - if (!(tgt->obd_flags & OBD_SET_UP)) { - CERROR("Target %s not set up\n", uuidarray[i]); - GOTO(out_disc, rc = -EINVAL); - } - - rc = obd_connect(&lov->tgts[i].conn, tgt, NULL, recovd, - recover); - - /* Register even if connect failed, so that we get reactivation - * notices. - */ - rc2 = obd_iocontrol(IOC_OSC_REGISTER_LOV, &lov->tgts[i].conn, - sizeof(struct obd_device *), obd, NULL); - if (rc2) { - CERROR("Target %s REGISTER_LOV error %d\n", - uuidarray[i], rc2); - GOTO(out_disc, rc2); - } - - /* But mark failed-connect OSCs as inactive! */ - if (rc) { - CDEBUG(D_INFO, "Target %s connect error %d\n", - uuidarray[i], rc); - LASSERT(lov->tgts[i].active == 0); - rc = 0; - continue; - } - - desc->ld_active_tgt_count++; - lov->tgts[i].active = 1; - } - - mdc->cl_max_mds_easize = obd_size_wiremd(conn, NULL); - - out: - ptlrpc_req_finished(req); - RETURN(rc); - - out_disc: - while (i-- > 0) { - desc->ld_active_tgt_count--; - lov->tgts[i].active = 0; - rc2 = obd_disconnect(&lov->tgts[i].conn); - if (rc2) - CERROR("LOV Target %s disconnect error: rc = %d\n", - uuidarray[i], rc2); - } - OBD_FREE(lov->tgts, lov->bufsize); - out_conn: - class_disconnect(conn); - out_dec: - MOD_DEC_USE_COUNT; - goto out; -} - -static int lov_disconnect(struct lustre_handle *conn) -{ - struct obd_device *obd = class_conn2obd(conn); - struct lov_obd *lov = &obd->u.lov; - struct obd_export *exp; - struct list_head *p, *n; - int rc, i; - - if (!lov->tgts) - goto out_local; - - /* Only disconnect the underlying layers on the final disconnect. */ - lov->refcount--; - if (lov->refcount != 0) - goto out_local; - - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - rc = obd_disconnect(&lov->tgts[i].conn); - if (rc) { - if (lov->tgts[i].active) { - CERROR("Target %s disconnect error %d\n", - lov->tgts[i].uuid, rc); - } - rc = 0; - } - if (lov->tgts[i].active) { - lov->desc.ld_active_tgt_count--; - lov->tgts[i].active = 0; - } - } - OBD_FREE(lov->tgts, lov->bufsize); - lov->bufsize = 0; - lov->tgts = NULL; - - exp = class_conn2export(conn); - list_for_each_safe(p, n, &exp->exp_lov_data.led_open_head) { - /* XXX close these, instead of just discarding them? */ - struct lov_file_handles *lfh; - lfh = list_entry(p, typeof(*lfh), lfh_list); - CERROR("discarding open LOV handle %p:"LPX64"\n", - lfh, lfh->lfh_cookie); - list_del(&lfh->lfh_list); - OBD_FREE(lfh->lfh_handles, - lfh->lfh_count * sizeof(*lfh->lfh_handles)); - kmem_cache_free(lov_file_cache, lfh); - } - - out_local: - rc = class_disconnect(conn); - if (!rc) - MOD_DEC_USE_COUNT; - return rc; -} - -/* Error codes: - * - * -EINVAL : UUID can't be found in the LOV's target list - * -ENOTCONN: The UUID is found, but the target connection is bad (!) - * -EBADF : The UUID is found, but the OBD is the wrong type (!) - * -EALREADY: The OSC is already marked (in)active - */ -static int lov_set_osc_active(struct lov_obd *lov, obd_uuid_t uuid, - int activate) -{ - struct obd_device *obd; - int i, rc = 0; - ENTRY; - - CDEBUG(D_INFO, "Searching in lov %p for uuid %s (activate=%d)\n", - lov, uuid, activate); - - spin_lock(&lov->lov_lock); - for (i = 0; i < lov->desc.ld_tgt_count; i++) - if (strncmp(uuid, lov->tgts[i].uuid, - sizeof(lov->tgts[i].uuid)) == 0) - break; - - if (i == lov->desc.ld_tgt_count) - GOTO(out, rc = -EINVAL); - - obd = class_conn2obd(&lov->tgts[i].conn); - if (obd == NULL) { - LBUG(); - GOTO(out, rc = -ENOTCONN); - } - - CDEBUG(D_INFO, "Found OBD %p type %s\n", obd, obd->obd_type->typ_name); - if (strcmp(obd->obd_type->typ_name, "osc") != 0) { - LBUG(); - GOTO(out, rc = -EBADF); - } - - if (lov->tgts[i].active == activate) { - CDEBUG(D_INFO, "OBD %p already %sactive!\n", obd, - activate ? "" : "in"); - GOTO(out, rc = -EALREADY); - } - - CDEBUG(D_INFO, "Marking OBD %p %sactive\n", obd, activate ? "" : "in"); - - lov->tgts[i].active = activate; - if (activate) { - /* - * foreach(export) - * foreach(open_file) - * if (file_handle uses this_osc) - * if (has_no_filehandle) - * open(file_handle, this_osc); - */ - /* XXX reconnect? */ - lov->desc.ld_active_tgt_count++; - } else { - /* - * Should I invalidate filehandles that refer to this OSC, so - * that I reopen them during reactivation? - */ - /* XXX disconnect from OSC? */ - lov->desc.ld_active_tgt_count--; - } - - EXIT; - out: - spin_unlock(&lov->lov_lock); - return rc; -} - -static int lov_setup(struct obd_device *obd, obd_count len, void *buf) -{ - struct obd_ioctl_data *data = buf; - struct lov_obd *lov = &obd->u.lov; - int rc = 0; - ENTRY; - - if (data->ioc_inllen1 < 1) { - CERROR("LOV setup requires an MDC UUID\n"); - RETURN(-EINVAL); - } - - if (data->ioc_inllen1 > 37) { - CERROR("mdc UUID must be 36 characters or less\n"); - RETURN(-EINVAL); - } - - spin_lock_init(&lov->lov_lock); - lov->mdcobd = class_uuid2obd(data->ioc_inlbuf1); - if (!lov->mdcobd) { - CERROR("LOV %s cannot locate MDC %s\n", obd->obd_uuid, - data->ioc_inlbuf1); - rc = -EINVAL; - } - RETURN(rc); -} - -static struct lov_file_handles *lov_handle2lfh(struct lustre_handle *handle) -{ - struct lov_file_handles *lfh = NULL; - - if (!handle || !handle->addr) - RETURN(NULL); - - lfh = (struct lov_file_handles *)(unsigned long)(handle->addr); - if (!kmem_cache_validate(lov_file_cache, lfh)) - RETURN(NULL); - - if (lfh->lfh_cookie != handle->cookie) - RETURN(NULL); - - return lfh; -} - -/* the LOV expects oa->o_id to be set to the LOV object id */ -static int lov_create(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md **ea) -{ - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct lov_stripe_md *lsm; - struct lov_oinfo *loi; - struct obdo *tmp; - int ost_count, ost_idx = 1; - int rc = 0, i; - ENTRY; - - LASSERT(ea); - - if (!export) - RETURN(-EINVAL); - - tmp = obdo_alloc(); - if (!tmp) - RETURN(-ENOMEM); - - lov = &export->exp_obd->u.lov; - - if (!lov->desc.ld_active_tgt_count) - RETURN(-EIO); - - spin_lock(&lov->lov_lock); - ost_count = lov->desc.ld_tgt_count; - - lsm = *ea; - - /* Can't create more stripes than we have targets (incl inactive). */ - if (lsm && lsm->lsm_stripe_count > lov->desc.ld_tgt_count) - GOTO(out_tmp, rc = -EINVAL); - - /* Free the user lsm if it needs to be changed, to avoid memory leaks */ - if (!lsm || (lsm && - lsm->lsm_stripe_count > lov->desc.ld_active_tgt_count)) { - struct lov_stripe_md *lsm_new = NULL; - rc = obd_alloc_memmd(conn, &lsm_new); - if (rc < 0) { - spin_unlock(&lov->lov_lock); - if (lsm) - obd_free_memmd(conn, &lsm); - GOTO(out_tmp, rc); - } - if (lsm) { - LASSERT(lsm->lsm_magic == LOV_MAGIC); - CERROR("replace user LOV MD: stripes %u > %u active\n", - lsm->lsm_stripe_count, - lov->desc.ld_active_tgt_count); - lsm_new->lsm_stripe_offset = lsm->lsm_stripe_offset; - lsm_new->lsm_stripe_size = lsm->lsm_stripe_size; - lsm_new->lsm_stripe_pattern = lsm->lsm_stripe_pattern; - obd_free_memmd(conn, &lsm); - } - lsm = lsm_new; - ost_idx = 0; /* if lsm->lsm_stripe_offset is set yet */ - lsm->lsm_magic = LOV_MAGIC; - } - - LASSERT(oa->o_valid & OBD_MD_FLID); - lsm->lsm_object_id = oa->o_id; - if (!lsm->lsm_stripe_size) - lsm->lsm_stripe_size = lov->desc.ld_default_stripe_size; - - /* Because of 64-bit divide/mod operations only work with a 32-bit - * divisor in a 32-bit kernel, we cannot support a stripe width - * of 4GB or larger on 32-bit CPUs. - */ - if (lsm->lsm_stripe_size * lsm->lsm_stripe_count > ~0UL) { - CERROR("LOV: stripe width "LPU64"x%u > %lu on 32-bit system\n", - lsm->lsm_stripe_size, lsm->lsm_stripe_count, ~0UL); - spin_unlock(&lov->lov_lock); - GOTO(out_free, rc = -EINVAL); - } - - if (!ost_idx || lsm->lsm_stripe_offset >= ost_count) { - int mult = lsm->lsm_object_id * lsm->lsm_stripe_count; - int stripe_offset = mult % ost_count; - int sub_offset = (mult / ost_count) % lsm->lsm_stripe_count; - - lsm->lsm_stripe_offset = stripe_offset + sub_offset; - } - - /* Start with lsm_stripe_offset on an active OSC to avoid confusion */ - while (!lov->tgts[lsm->lsm_stripe_offset].active) - lsm->lsm_stripe_offset = (lsm->lsm_stripe_offset+1) % ost_count; - - /* Pick the OSTs before we release the lock */ - ost_idx = lsm->lsm_stripe_offset; - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - CDEBUG(D_INODE, "objid "LPX64"[%d] is ost_idx %d (uuid %s)\n", - lsm->lsm_object_id, i, ost_idx, lov->tgts[ost_idx].uuid); - loi->loi_ost_idx = ost_idx; - do { - ost_idx = (ost_idx + 1) % ost_count; - } while (!lov->tgts[ost_idx].active); - } - - spin_unlock(&lov->lov_lock); - - CDEBUG(D_INODE, "allocating %d subobjs for objid "LPX64" at idx %d\n", - lsm->lsm_stripe_count,lsm->lsm_object_id,lsm->lsm_stripe_offset); - - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - struct lov_stripe_md obj_md; - struct lov_stripe_md *obj_mdp = &obj_md; - - ost_idx = loi->loi_ost_idx; - - /* create data objects with "parent" OA */ - memcpy(tmp, oa, sizeof(*tmp)); - /* XXX: LOV STACKING: use real "obj_mdp" sub-data */ - rc = obd_create(&lov->tgts[ost_idx].conn, tmp, &obj_mdp); - if (rc) { - CERROR("error creating objid "LPX64" sub-object on " - "OST idx %d: rc = %d\n", oa->o_id, ost_idx, rc); - GOTO(out_cleanup, rc); - } - loi->loi_id = tmp->o_id; - CDEBUG(D_INODE, "objid "LPX64" has subobj "LPX64" at idx %d\n", - lsm->lsm_object_id, loi->loi_id, ost_idx); - } - - *ea = lsm; - - out_tmp: - obdo_free(tmp); - RETURN(rc); - - out_cleanup: - while (i-- > 0) { - int err; - - --loi; - /* destroy already created objects here */ - memcpy(tmp, oa, sizeof(*tmp)); - tmp->o_id = loi->loi_id; - err = obd_destroy(&lov->tgts[loi->loi_ost_idx].conn, tmp, NULL); - if (err) - CERROR("Failed to uncreate objid "LPX64" subobj " - LPX64" on OST idx %d: rc = %d\n", - oa->o_id, loi->loi_id, loi->loi_ost_idx, - err); - } - out_free: - if (!*ea) - obd_free_memmd(conn, &lsm); - goto out_tmp; -} - -static int lov_destroy(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm) -{ - struct obdo tmp; - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct lov_oinfo *loi; - struct lov_file_handles *lfh = NULL; - int rc = 0, i; - ENTRY; - - if (!lsm) { - CERROR("LOV requires striping ea for destruction\n"); - RETURN(-EINVAL); - } - - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("LOV striping magic bad %#lx != %#lx\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - if (oa->o_valid & OBD_MD_FLHANDLE) - lfh = lov_handle2lfh(obdo_handle(oa)); - - lov = &export->exp_obd->u.lov; - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - int err; - if (lov->tgts[loi->loi_ost_idx].active == 0) { - /* Orphan clean up will (someday) fix this up. */ - continue; - } - - memcpy(&tmp, oa, sizeof(tmp)); - tmp.o_id = loi->loi_id; - if (lfh) - memcpy(obdo_handle(&tmp), &lfh->lfh_handles[i], - sizeof(lfh->lfh_handles[i])); - else - tmp.o_valid &= ~OBD_MD_FLHANDLE; - err = obd_destroy(&lov->tgts[loi->loi_ost_idx].conn, &tmp, - NULL); - if (err && lov->tgts[loi->loi_ost_idx].active) { - CERROR("Error destroying objid "LPX64" subobj " - LPX64" on OST idx %d\n: rc = %d", - oa->o_id, loi->loi_id, loi->loi_ost_idx, err); - if (!rc) - rc = err; - } - } - RETURN(rc); -} - -/* compute object size given "stripeno" and the ost size */ -static obd_size lov_stripe_size(struct lov_stripe_md *lsm, obd_size ost_size, - int stripeno) -{ - unsigned long ssize = lsm->lsm_stripe_size; - unsigned long swidth = ssize * lsm->lsm_stripe_count; - unsigned long stripe_size; - obd_size lov_size; - - if (ost_size == 0) - return 0; - - /* do_div(a, b) returns a % b, and a = a / b */ - stripe_size = do_div(ost_size, ssize); - - if (stripe_size) - lov_size = ost_size * swidth + stripeno * ssize + stripe_size; - else - lov_size = (ost_size - 1) * swidth + (stripeno + 1) * ssize; - - return lov_size; -} - -static void lov_merge_attrs(struct obdo *tgt, struct obdo *src, obd_flag valid, - struct lov_stripe_md *lsm, int stripeno, int *new) -{ - if (*new) { - obdo_cpy_md(tgt, src, valid); - if (valid & OBD_MD_FLSIZE) - tgt->o_size = lov_stripe_size(lsm,src->o_size,stripeno); - *new = 0; - } else { - if (valid & OBD_MD_FLSIZE) { - /* this handles sparse files properly */ - obd_size lov_size; - - lov_size = lov_stripe_size(lsm, src->o_size, stripeno); - if (lov_size > tgt->o_size) - tgt->o_size = lov_size; - } - if (valid & OBD_MD_FLBLOCKS) - tgt->o_blocks += src->o_blocks; - if (valid & OBD_MD_FLCTIME && tgt->o_ctime < src->o_ctime) - tgt->o_ctime = src->o_ctime; - if (valid & OBD_MD_FLMTIME && tgt->o_mtime < src->o_mtime) - tgt->o_mtime = src->o_mtime; - } -} - -static int lov_getattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm) -{ - struct obdo tmp; - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct lov_oinfo *loi; - struct lov_file_handles *lfh = NULL; - int i; - int new = 1; - ENTRY; - - if (!lsm) { - CERROR("LOV requires striping ea\n"); - RETURN(-EINVAL); - } - - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("LOV striping magic bad %#lx != %#lx\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - lov = &export->exp_obd->u.lov; - - if (oa->o_valid & OBD_MD_FLHANDLE) - lfh = lov_handle2lfh(obdo_handle(oa)); - - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - int err; - - if (loi->loi_id == 0) - continue; - - if (lov->tgts[loi->loi_ost_idx].active == 0) - continue; - - CDEBUG(D_INFO, "objid "LPX64"[%d] has subobj "LPX64" at idx " - "%u\n", oa->o_id, i, loi->loi_id, loi->loi_ost_idx); - /* create data objects with "parent" OA */ - memcpy(&tmp, oa, sizeof(tmp)); - tmp.o_id = loi->loi_id; - if (lfh) - memcpy(obdo_handle(&tmp), &lfh->lfh_handles[i], - sizeof(lfh->lfh_handles[i])); - else - tmp.o_valid &= ~OBD_MD_FLHANDLE; - - err = obd_getattr(&lov->tgts[loi->loi_ost_idx].conn, &tmp,NULL); - if (err && lov->tgts[loi->loi_ost_idx].active) { - CERROR("Error getattr objid "LPX64" subobj "LPX64 - " on OST idx %d: rc = %d\n", - oa->o_id, loi->loi_id, loi->loi_ost_idx, err); - RETURN(err); - } - lov_merge_attrs(oa, &tmp, tmp.o_valid, lsm, i, &new); - } - - RETURN(0); -} - -static int lov_setattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm) -{ - struct obdo *tmp; - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct lov_oinfo *loi; - struct lov_file_handles *lfh = NULL; - int rc = 0, i; - ENTRY; - - /* Note that this code is currently unused, hence LBUG(), just - * to know when/if it is ever revived that it needs cleanups. - */ - LBUG(); - - if (!lsm) { - CERROR("LOV requires striping ea\n"); - RETURN(-EINVAL); - } - - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("LOV striping magic bad %#lx != %#lx\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - /* size changes should go through punch and not setattr */ - LASSERT(!(oa->o_valid & OBD_MD_FLSIZE)); - - tmp = obdo_alloc(); - if (!tmp) - RETURN(-ENOMEM); - - if (oa->o_valid & OBD_MD_FLHANDLE) - lfh = lov_handle2lfh(obdo_handle(oa)); - - lov = &export->exp_obd->u.lov; - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - int err; - - obdo_cpy_md(tmp, oa, oa->o_valid); - - if (lfh) - memcpy(obdo_handle(tmp), &lfh->lfh_handles[i], - sizeof(lfh->lfh_handles[i])); - else - tmp->o_valid &= ~OBD_MD_FLHANDLE; - - tmp->o_id = loi->loi_id; - - err = obd_setattr(&lov->tgts[loi->loi_ost_idx].conn, tmp, NULL); - if (err) { - CERROR("Error setattr objid "LPX64" subobj "LPX64 - " on OST idx %d: rc = %d\n", - oa->o_id, loi->loi_id, loi->loi_ost_idx, err); - if (!rc) - rc = err; - } - } - obdo_free(tmp); - RETURN(rc); -} - -static int lov_open(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm) -{ - struct obdo *tmp; /* on the heap here, on the stack in lov_close? */ - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct lov_oinfo *loi; - struct lov_file_handles *lfh = NULL; - struct lustre_handle *handle; - int new = 1; - int rc = 0, i; - ENTRY; - - if (!lsm) { - CERROR("LOV requires striping ea for opening\n"); - RETURN(-EINVAL); - } - - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("LOV striping magic bad %#lx != %#lx\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - tmp = obdo_alloc(); - if (!tmp) - RETURN(-ENOMEM); - - lfh = kmem_cache_alloc(lov_file_cache, GFP_KERNEL); - if (!lfh) - GOTO(out_tmp, rc = -ENOMEM); - OBD_ALLOC(lfh->lfh_handles, - lsm->lsm_stripe_count * sizeof(*lfh->lfh_handles)); - if (!lfh->lfh_handles) - GOTO(out_lfh, rc = -ENOMEM); - - lov = &export->exp_obd->u.lov; - oa->o_size = 0; - oa->o_blocks = 0; - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - - if (lov->tgts[loi->loi_ost_idx].active == 0) { - continue; - } - - /* create data objects with "parent" OA */ - memcpy(tmp, oa, sizeof(*tmp)); - tmp->o_id = loi->loi_id; - - rc = obd_open(&lov->tgts[loi->loi_ost_idx].conn, tmp, NULL); - if (rc && lov->tgts[loi->loi_ost_idx].active) { - CERROR("Error open objid "LPX64" subobj "LPX64 - " on OST idx %d: rc = %d\n", - oa->o_id, lsm->lsm_oinfo[i].loi_id, - loi->loi_ost_idx, rc); - goto out_handles; - } - - lov_merge_attrs(oa, tmp, tmp->o_valid, lsm, i, &new); - - if (tmp->o_valid & OBD_MD_FLHANDLE) - memcpy(&lfh->lfh_handles[i], obdo_handle(tmp), - sizeof(lfh->lfh_handles[i])); - } - - handle = obdo_handle(oa); - - lfh->lfh_count = lsm->lsm_stripe_count; - get_random_bytes(&lfh->lfh_cookie, sizeof(lfh->lfh_cookie)); - - handle->addr = (__u64)(unsigned long)lfh; - handle->cookie = lfh->lfh_cookie; - oa->o_valid |= OBD_MD_FLHANDLE; - list_add(&lfh->lfh_list, &export->exp_lov_data.led_open_head); - -out_tmp: - obdo_free(tmp); - RETURN(rc); - -out_handles: - for (i--, loi = &lsm->lsm_oinfo[i]; i >= 0; i--, loi--) { - int err; - - if (lov->tgts[loi->loi_ost_idx].active == 0) - continue; - - memcpy(tmp, oa, sizeof(*tmp)); - tmp->o_id = loi->loi_id; - memcpy(obdo_handle(tmp), &lfh->lfh_handles[i], - sizeof(lfh->lfh_handles[i])); - - err = obd_close(&lov->tgts[loi->loi_ost_idx].conn, tmp, NULL); - if (err) { - CERROR("Error closing objid "LPX64" subobj "LPX64 - " on OST idx %d after open error: rc = %d\n", - oa->o_id, loi->loi_id, loi->loi_ost_idx, err); - } - } - - OBD_FREE(lfh->lfh_handles, - lsm->lsm_stripe_count * sizeof(*lfh->lfh_handles)); -out_lfh: - lfh->lfh_cookie = DEAD_HANDLE_MAGIC; - kmem_cache_free(lov_file_cache, lfh); - goto out_tmp; -} - -static int lov_close(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm) -{ - struct obdo tmp; - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct lov_oinfo *loi; - struct lov_file_handles *lfh = NULL; - int rc = 0, i; - ENTRY; - - if (!lsm) { - CERROR("LOV requires striping ea\n"); - RETURN(-EINVAL); - } - - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("LOV striping magic bad %#lx != %#lx\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - if (oa->o_valid & OBD_MD_FLHANDLE) - lfh = lov_handle2lfh(obdo_handle(oa)); - - lov = &export->exp_obd->u.lov; - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - int err; - - if (lov->tgts[loi->loi_ost_idx].active == 0) - continue; - - /* create data objects with "parent" OA */ - memcpy(&tmp, oa, sizeof(tmp)); - tmp.o_id = loi->loi_id; - if (lfh) - memcpy(obdo_handle(&tmp), &lfh->lfh_handles[i], - sizeof(lfh->lfh_handles[i])); - else - tmp.o_valid &= ~OBD_MD_FLHANDLE; - - err = obd_close(&lov->tgts[loi->loi_ost_idx].conn, &tmp, NULL); - if (err) { - CERROR("Error close objid "LPX64" subobj "LPX64 - " on OST idx %d: rc = %d\n", - oa->o_id, loi->loi_id, loi->loi_ost_idx, err); - if (!rc) - rc = err; - } - } - if (lfh) { - list_del(&lfh->lfh_list); - OBD_FREE(lfh->lfh_handles, - lsm->lsm_stripe_count * sizeof(*lfh->lfh_handles)); - lfh->lfh_cookie = DEAD_HANDLE_MAGIC; - kmem_cache_free(lov_file_cache, lfh); - } - - RETURN(rc); -} - -#ifndef log2 -#define log2(n) ffz(~(n)) -#endif - -#warning FIXME: merge these two functions now that they are nearly the same - -/* compute ost offset in stripe "stripeno" corresponding to offset "lov_off" */ -static obd_off lov_stripe_offset(struct lov_stripe_md *lsm, obd_off lov_off, - int stripeno) -{ - unsigned long ssize = lsm->lsm_stripe_size; - unsigned long swidth = ssize * lsm->lsm_stripe_count; - unsigned long stripe_off, this_stripe; - - if (lov_off == OBD_OBJECT_EOF || lov_off == 0) - return lov_off; - - /* do_div(a, b) returns a % b, and a = a / b */ - stripe_off = do_div(lov_off, swidth); - - this_stripe = stripeno * ssize; - if (stripe_off <= this_stripe) - stripe_off = 0; - else { - stripe_off -= this_stripe; - - if (stripe_off > ssize) - stripe_off = ssize; - } - - - return lov_off * ssize + stripe_off; -} - -/* compute which stripe number "lov_off" will be written into */ -static int lov_stripe_number(struct lov_stripe_md *lsm, obd_off lov_off) -{ - unsigned long ssize = lsm->lsm_stripe_size; - unsigned long swidth = ssize * lsm->lsm_stripe_count; - unsigned long stripe_off; - - stripe_off = do_div(lov_off, swidth); - - return stripe_off / ssize; -} - - -/* FIXME: maybe we'll just make one node the authoritative attribute node, then - * we can send this 'punch' to just the authoritative node and the nodes - * that the punch will affect. */ -static int lov_punch(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm, - obd_off start, obd_off end) -{ - struct obdo tmp; - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct lov_oinfo *loi; - struct lov_file_handles *lfh = NULL; - int rc = 0, i; - ENTRY; - - if (!lsm) { - CERROR("LOV requires striping ea\n"); - RETURN(-EINVAL); - } - - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("LOV striping magic bad %#lx != %#lx\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - if (oa->o_valid & OBD_MD_FLHANDLE) - lfh = lov_handle2lfh(obdo_handle(oa)); - - lov = &export->exp_obd->u.lov; - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - obd_off starti = lov_stripe_offset(lsm, start, i); - obd_off endi = lov_stripe_offset(lsm, end, i); - int err; - - if (starti == endi) - continue; - /* create data objects with "parent" OA */ - memcpy(&tmp, oa, sizeof(tmp)); - tmp.o_id = loi->loi_id; - if (lfh) - memcpy(obdo_handle(&tmp), &lfh->lfh_handles[i], - sizeof(lfh->lfh_handles[i])); - else - tmp.o_valid &= ~OBD_MD_FLHANDLE; - - err = obd_punch(&lov->tgts[loi->loi_ost_idx].conn, &tmp, NULL, - starti, endi); - if (err) { - CERROR("Error punch objid "LPX64" subobj "LPX64 - " on OST idx %d: rc = %d\n", - oa->o_id, loi->loi_id, loi->loi_ost_idx, err); - if (!rc) - rc = err; - } - } - RETURN(rc); -} - -static inline int lov_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 { - int bufct; - int index; - int subcount; - struct lov_stripe_md lsm; - int ost_idx; - } *stripeinfo, *si, *si_last; - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct brw_page *ioarr; - struct lov_oinfo *loi; - int rc = 0, i, *where, stripe_count = lsm->lsm_stripe_count; - ENTRY; - - if (!lsm) { - CERROR("LOV requires striping ea\n"); - RETURN(-EINVAL); - } - - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("LOV striping magic bad %#lx != %#lx\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - - lov = &export->exp_obd->u.lov; - - OBD_ALLOC(stripeinfo, stripe_count * sizeof(*stripeinfo)); - if (!stripeinfo) - GOTO(out_cbdata, rc = -ENOMEM); - - OBD_ALLOC(where, sizeof(*where) * oa_bufs); - if (!where) - GOTO(out_sinfo, rc = -ENOMEM); - - OBD_ALLOC(ioarr, sizeof(*ioarr) * oa_bufs); - if (!ioarr) - GOTO(out_where, rc = -ENOMEM); - - for (i = 0; i < oa_bufs; i++) { - where[i] = lov_stripe_number(lsm, pga[i].off); - stripeinfo[where[i]].bufct++; - } - - for (i = 0, loi = lsm->lsm_oinfo, si_last = si = stripeinfo; - i < stripe_count; i++, loi++, si_last = si, si++) { - if (lov->tgts[loi->loi_ost_idx].active == 0) - GOTO(out_ioarr, rc = -EIO); - if (i > 0) - si->index = si_last->index + si_last->bufct; - si->lsm.lsm_object_id = loi->loi_id; - si->ost_idx = loi->loi_ost_idx; - } - - for (i = 0; i < oa_bufs; i++) { - int which = where[i]; - int shift; - - shift = stripeinfo[which].index + stripeinfo[which].subcount; - LASSERT(shift < oa_bufs); - ioarr[shift] = pga[i]; - ioarr[shift].off = lov_stripe_offset(lsm, pga[i].off, which); - stripeinfo[which].subcount++; - } - - for (i = 0, si = stripeinfo; i < stripe_count; i++, si++) { - int shift = si->index; - - if (si->bufct) { - LASSERT(shift < oa_bufs); - rc = obd_brw(cmd, &lov->tgts[si->ost_idx].conn, - &si->lsm, si->bufct, &ioarr[shift], set); - if (rc) - GOTO(out_ioarr, rc); - } - } - - out_ioarr: - OBD_FREE(ioarr, sizeof(*ioarr) * oa_bufs); - out_where: - OBD_FREE(where, sizeof(*where) * oa_bufs); - out_sinfo: - OBD_FREE(stripeinfo, stripe_count * sizeof(*stripeinfo)); - out_cbdata: - RETURN(rc); -} - -static int lov_enqueue(struct lustre_handle *conn, struct lov_stripe_md *lsm, - struct lustre_handle *parent_lock, - __u32 type, void *cookie, int cookielen, __u32 mode, - int *flags, void *cb, void *data, int datalen, - struct lustre_handle *lockhs) -{ - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct lov_oinfo *loi; - struct lov_stripe_md submd; - int rc = 0, i; - ENTRY; - - if (!lsm) { - CERROR("LOV requires striping ea\n"); - RETURN(-EINVAL); - } - - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("LOV striping magic bad %#lx != %#lx\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - - /* we should never be asked to replay a lock. */ - - LASSERT((*flags & LDLM_FL_REPLAY) == 0); - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - memset(lockhs, 0, sizeof(*lockhs) * lsm->lsm_stripe_count); - - lov = &export->exp_obd->u.lov; - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - struct ldlm_extent *extent = (struct ldlm_extent *)cookie; - struct ldlm_extent sub_ext; - - if (lov->tgts[loi->loi_ost_idx].active == 0) - continue; - - *flags = 0; - sub_ext.start = lov_stripe_offset(lsm, extent->start, i); - sub_ext.end = lov_stripe_offset(lsm, extent->end, i); - if (sub_ext.start == sub_ext.end) - continue; - - submd.lsm_object_id = loi->loi_id; - /* XXX submd should be that from the subobj, it should come - * opaquely from the LOV. - */ - submd.lsm_stripe_count = 0; - /* XXX submd is not fully initialized here */ - *flags = 0; - rc = obd_enqueue(&(lov->tgts[loi->loi_ost_idx].conn), &submd, - parent_lock, type, &sub_ext, sizeof(sub_ext), - mode, flags, cb, data, datalen, &(lockhs[i])); - // XXX add a lock debug statement here - if (rc && lov->tgts[loi->loi_ost_idx].active) { - CERROR("Error enqueue objid "LPX64" subobj "LPX64 - " on OST idx %d: rc = %d\n", lsm->lsm_object_id, - loi->loi_id, loi->loi_ost_idx, rc); - goto out_locks; - } - } - - RETURN(0); - - out_locks: - for (i--, loi = &lsm->lsm_oinfo[i]; i >= 0; i--, loi--) { - int err; - - if (lov->tgts[loi->loi_ost_idx].active == 0) - continue; - - submd.lsm_object_id = loi->loi_id; - submd.lsm_stripe_count = 0; - err = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd, - mode, &lockhs[i]); - if (err) { - CERROR("Error cancelling objid "LPX64" subobj "LPX64 - " on OST idx %d after enqueue error: rc = %d\n", - loi->loi_id, loi->loi_ost_idx, err); - } - } - RETURN(rc); -} - -static int lov_cancel(struct lustre_handle *conn, struct lov_stripe_md *lsm, - __u32 mode, struct lustre_handle *lockhs) -{ - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct lov_oinfo *loi; - int rc = 0, i; - ENTRY; - - if (!lsm) { - CERROR("LOV requires striping ea\n"); - RETURN(-EINVAL); - } - - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("LOV striping magic bad %#lx != %#lx\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - lov = &export->exp_obd->u.lov; - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - struct lov_stripe_md submd; - int err; - - if (lov->tgts[loi->loi_ost_idx].active == 0) - continue; - - if (lockhs[i].addr == 0) - continue; - - submd.lsm_object_id = loi->loi_id; - submd.lsm_stripe_count = 0; - err = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd, - mode, &lockhs[i]); - if (err && lov->tgts[loi->loi_ost_idx].active) { - CERROR("Error cancel objid "LPX64" subobj "LPX64 - " on OST idx %d: rc = %d\n", lsm->lsm_object_id, - loi->loi_id, loi->loi_ost_idx, err); - if (!rc) - rc = err; - } - } - RETURN(rc); -} - -static int lov_cancel_unused(struct lustre_handle *conn, - struct lov_stripe_md *lsm, int flags) -{ - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct lov_oinfo *loi; - int rc = 0, i, err; - ENTRY; - - if (!lsm) { - CERROR("LOV requires striping ea for lock cancellation\n"); - RETURN(-EINVAL); - } - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - lov = &export->exp_obd->u.lov; - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - struct lov_stripe_md submd; - - submd.lsm_object_id = loi->loi_id; - submd.lsm_stripe_count = 0; - err = obd_cancel_unused(&lov->tgts[loi->loi_ost_idx].conn, - &submd, flags); - if (err && lov->tgts[loi->loi_ost_idx].active) { - CERROR("Error cancel unused objid "LPX64" subobj "LPX64 - " on OST idx %d: rc = %d\n", lsm->lsm_object_id, - loi->loi_id, loi->loi_ost_idx, err); - if (!rc) - rc = err; - } - } - - RETURN(rc); -} - -static int lov_statfs(struct lustre_handle *conn, struct obd_statfs *osfs) -{ - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; - struct obd_statfs lov_sfs; - int set = 0; - int rc = 0; - int i; - ENTRY; - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - lov = &export->exp_obd->u.lov; - - /* We only get block data from the OBD */ - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - int err; - - if (!lov->tgts[i].active) - continue; - - err = obd_statfs(&lov->tgts[i].conn, &lov_sfs); - if (err) { - CERROR("Error statfs OSC %s idx %d: err = %d\n", - lov->tgts[i].uuid, i, err); - if (!rc) - rc = err; - continue; /* XXX or break? - probably OK to continue */ - } - if (!set) { - memcpy(osfs, &lov_sfs, sizeof(lov_sfs)); - set = 1; - } else { - osfs->os_bfree += lov_sfs.os_bfree; - osfs->os_bavail += lov_sfs.os_bavail; - osfs->os_blocks += lov_sfs.os_blocks; - /* XXX not sure about this one - depends on policy. - * - could be minimum if we always stripe on all OBDs - * (but that would be wrong for any other policy, - * if one of the OBDs has no more objects left) - * - could be sum if we stripe whole objects - * - could be average, just to give a nice number - * - we just pick first OST and hope it is enough - sfs->f_ffree += lov_sfs.f_ffree; - */ - } - } - RETURN(rc); -} - -static int lov_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len, - void *karg, void *uarg) -{ - struct obd_device *obddev = class_conn2obd(conn); - struct lov_obd *lov = &obddev->u.lov; - struct obd_ioctl_data *data = karg; - int i, count = lov->desc.ld_tgt_count; - int rc; - - ENTRY; - - switch (cmd) { - case IOC_LOV_SET_OSC_ACTIVE: { - rc = lov_set_osc_active(lov,data->ioc_inlbuf1,data->ioc_offset); - break; - } - case OBD_IOC_LOV_GET_CONFIG: { - struct lov_tgt_desc *tgtdesc; - struct lov_desc *desc; - obd_uuid_t *uuidp; - char *buf = NULL; - - buf = NULL; - len = 0; - if (obd_ioctl_getdata(&buf, &len, (void *)uarg)) - RETURN(-EINVAL); - - data = (struct obd_ioctl_data *)buf; - - if (sizeof(*desc) > data->ioc_inllen1) { - OBD_FREE(buf, len); - RETURN(-EINVAL); - } - - if (sizeof(*uuidp) * count > data->ioc_inllen2) { - OBD_FREE(buf, len); - RETURN(-EINVAL); - } - - desc = (struct lov_desc *)data->ioc_inlbuf1; - uuidp = (obd_uuid_t *)data->ioc_inlbuf2; - memcpy(desc, &(lov->desc), sizeof(*desc)); - - tgtdesc = lov->tgts; - for (i = 0; i < count; i++, uuidp++, tgtdesc++) - memcpy(uuidp, tgtdesc->uuid, sizeof(*uuidp)); - - rc = copy_to_user((void *)uarg, buf, len); - if (rc) - rc = -EFAULT; - OBD_FREE(buf, len); - break; - } - default: - if (count == 0) - RETURN(-ENOTTY); - rc = 0; - for (i = 0; i < count; i++) { - int err = obd_iocontrol(cmd, &lov->tgts[i].conn, - len, karg, uarg); - if (err && !rc) - rc = err; - } - } - - RETURN(rc); -} - -struct obd_ops lov_obd_ops = { - o_attach: lov_attach, - o_detach: lov_detach, - o_setup: lov_setup, - o_connect: lov_connect, - o_disconnect: lov_disconnect, - o_statfs: lov_statfs, - o_packmd: lov_packmd, - o_unpackmd: lov_unpackmd, - o_create: lov_create, - o_destroy: lov_destroy, - o_getattr: lov_getattr, - o_setattr: lov_setattr, - o_open: lov_open, - o_close: lov_close, - o_brw: lov_brw, - o_punch: lov_punch, - o_enqueue: lov_enqueue, - o_cancel: lov_cancel, - o_cancel_unused: lov_cancel_unused, - o_iocontrol: lov_iocontrol -}; - - -#define LOV_VERSION "v0.1" - -static int __init lov_init(void) -{ - int rc; - printk(KERN_INFO "Lustre Logical Object Volume driver " LOV_VERSION - ", info@clusterfs.com\n"); - lov_file_cache = kmem_cache_create("ll_lov_file_data", - sizeof(struct lov_file_handles), - 0, 0, NULL, NULL); - if (!lov_file_cache) - RETURN(-ENOMEM); - - rc = class_register_type(&lov_obd_ops, status_class_var, - OBD_LOV_DEVICENAME); - RETURN(rc); -} - -static void __exit lov_exit(void) -{ - if (kmem_cache_destroy(lov_file_cache)) - CERROR("couldn't free LOV open cache\n"); - class_unregister_type(OBD_LOV_DEVICENAME); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Logical Object Volume OBD driver " LOV_VERSION); -MODULE_LICENSE("GPL"); - -module_init(lov_init); -module_exit(lov_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 a68b57e..0000000 --- a/lustre/lov/lproc_lov.c +++ /dev/null @@ -1,204 +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_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_filestotal(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_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(i < lov->desc.ld_tgt_count){ - len += snprintf(&page[len], 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; -} - -struct lprocfs_vars status_var_nm_1[] = { - {"status/uuid", rd_uuid, 0, 0}, - {"status/stripesize",rd_stripesize, 0, 0}, - {"status/stripeoffset",rd_stripeoffset, 0, 0}, - {"status/stripecount",rd_stripecount, 0, 0}, - {"status/stripetype", rd_stripetype, 0, 0}, - {"status/numobd",rd_numobd, 0, 0}, - {"status/activeobd", rd_activeobd, 0, 0}, - {"status/filestotal", rd_filestotal, 0, 0}, - {"status/filesfree", rd_filesfree, 0, 0}, - {"status/filegroups", rd_filegroups, 0, 0}, - {"status/blocksize", rd_blksize, 0, 0}, - {"status/kbytestotal", rd_kbtotal, 0, 0}, - {"status/kbytesfree", rd_kbfree, 0, 0}, - {"status/target_obd", rd_target, 0, 0}, - {"status/target_mdc", rd_mdc, 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; - int len = 0; - len += snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -struct lprocfs_vars status_class_var[]={ - {"status/num_refs", rd_numrefs, 0, 0}, - {0} -}; diff --git a/lustre/mdc/.cvsignore b/lustre/mdc/.cvsignore deleted file mode 100644 index e530020..0000000 --- a/lustre/mdc/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/mdc/Makefile.am b/lustre/mdc/Makefile.am deleted file mode 100644 index 8dd9175..0000000 --- a/lustre/mdc/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= - -MODULE = mdc -modulefs_DATA = mdc.o -EXTRA_PROGRAMS = mdc - -LINX= mds_updates.c ll_pack.c client.c -mdc_SOURCES = mdc_request.c mdc_reint.c lproc_mdc.c $(LINX) - -ll_pack.c: - test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c . -mds_updates.c: - test -e mds_updates.c || ln -sf $(top_srcdir)/lib/mds_updates.c . -client.c: - test -e client.c || ln -sf $(top_srcdir)/lib/client.c . - -include $(top_srcdir)/Rules diff --git a/lustre/mdc/lproc_mdc.c b/lustre/mdc/lproc_mdc.c deleted file mode 100644 index b0fcad6..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_filestotal(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; - -} - -struct lprocfs_vars status_var_nm_1[] = { - {"status/uuid", rd_uuid, 0, 0}, - {"status/blocksize",rd_blksize, 0, 0}, - {"status/kbytestotal",rd_kbtotal, 0, 0}, - {"status/kbytesfree", rd_kbfree, 0, 0}, - {"status/filestotal", rd_filestotal, 0, 0}, - {"status/filesfree", rd_filesfree, 0, 0}, - {"status/filegroups", rd_filegroups, 0, 0}, - {"status/mds_server_uuid", rd_server_uuid, 0, 0}, - {"status/mds_conn_uuid", rd_conn_uuid, 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; - int len = 0; - len += snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -struct lprocfs_vars status_class_var[] = { - {"status/num_refs", rd_numrefs, 0, 0}, - {0} -}; diff --git a/lustre/mdc/mdc_reint.c b/lustre/mdc/mdc_reint.c deleted file mode 100644 index 63c1ef0..0000000 --- a/lustre/mdc/mdc_reint.c +++ /dev/null @@ -1,197 +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.sf.net/projects/lustre/ - * - * 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 - -#define DEBUG_SUBSYSTEM S_MDC - -#include -#include - -static int mdc_reint(struct ptlrpc_request *request, int level) -{ - int rc; - request->rq_level = level; - - rc = ptlrpc_queue_wait(request); - - if (rc) { - CERROR("error in handling %d\n", rc); - } else { - /* For future resend/replays. */ - u32 *opcodeptr = lustre_msg_buf(request->rq_reqmsg, 0); - *opcodeptr |= REINT_REPLAYING; - } - return rc; -} - -int mdc_setattr(struct lustre_handle *conn, - struct inode *inode, struct iattr *iattr, - struct ptlrpc_request **request) -{ - struct ptlrpc_request *req; - struct mds_rec_setattr *rec; - int rc, size = sizeof(*rec); - ENTRY; - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 1, &size, - NULL); - if (!req) - RETURN(-ENOMEM); - - mds_setattr_pack(req, 0, inode, iattr, NULL, 0); - - size = sizeof(struct mds_body); - req->rq_replen = lustre_msg_size(1, &size); - - rc = mdc_reint(req, LUSTRE_CONN_FULL); - *request = req; - if (rc == -ERESTARTSYS ) - rc = 0; - - RETURN(rc); -} - -int mdc_create(struct lustre_handle *conn, struct inode *dir, - const char *name, int namelen, const void *data, int datalen, - int mode, __u32 uid, __u32 gid, __u64 time, __u64 rdev, - struct ptlrpc_request **request) -{ - struct ptlrpc_request *req; - int rc, size[3] = {sizeof(struct mds_rec_create), namelen + 1, 0}; - int level, bufcount = 2; - ENTRY; - - if (data && datalen) { - size[bufcount] = datalen; - bufcount++; - } - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, bufcount, - size, NULL); - if (!req) - RETURN(-ENOMEM); - - /* mds_create_pack fills msg->bufs[1] with name - * and msg->bufs[2] with tgt, for symlinks or lov MD data */ - mds_create_pack(req, 0, dir, mode, rdev, uid, gid, time, - name, namelen, data, datalen); - - size[0] = sizeof(struct mds_body); - req->rq_replen = lustre_msg_size(1, size); - - level = LUSTRE_CONN_FULL; - resend: - rc = mdc_reint(req, level); - /* Resend if we were told to. */ - if (rc == -ERESTARTSYS) { - level = LUSTRE_CONN_RECOVD; - req->rq_flags = 0; - goto resend; - } - - mdc_store_inode_generation(req, 0, 0); - - *request = req; - RETURN(rc); -} - -int mdc_unlink(struct lustre_handle *conn, struct inode *dir, - struct inode *child, __u32 mode, const char *name, int namelen, - struct ptlrpc_request **request) -{ - struct ptlrpc_request *req; - int rc, size[2] = {sizeof(struct mds_rec_unlink), namelen + 1}; - ENTRY; - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 2, size, NULL); - if (!req) - RETURN(-ENOMEM); - - mds_unlink_pack(req, 0, dir, child, mode, name, namelen); - - size[0] = sizeof(struct mds_body); - req->rq_replen = lustre_msg_size(1, size); - - rc = mdc_reint(req, LUSTRE_CONN_FULL); - *request = req; - if (rc == -ERESTARTSYS) - rc = 0; - - RETURN(rc); -} - -int mdc_link(struct lustre_handle *conn, - struct dentry *src, struct inode *dir, const char *name, - int namelen, struct ptlrpc_request **request) -{ - struct ptlrpc_request *req; - int rc, size[2] = {sizeof(struct mds_rec_link), namelen + 1}; - ENTRY; - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 2, size, NULL); - if (!req) - RETURN(-ENOMEM); - - mds_link_pack(req, 0, src->d_inode, dir, name, namelen); - - size[0] = sizeof(struct mds_body); - req->rq_replen = lustre_msg_size(1, size); - - rc = mdc_reint(req, LUSTRE_CONN_FULL); - *request = req; - if (rc == -ERESTARTSYS ) - rc = 0; - - RETURN(rc); -} - -int mdc_rename(struct lustre_handle *conn, - struct inode *src, struct inode *tgt, const char *old, - int oldlen, const char *new, int newlen, - struct ptlrpc_request **request) -{ - struct ptlrpc_request *req; - int rc, size[3] = {sizeof(struct mds_rec_rename), oldlen + 1, - newlen + 1}; - ENTRY; - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 3, size, NULL); - if (!req) - RETURN(-ENOMEM); - - mds_rename_pack(req, 0, src, tgt, old, oldlen, new, newlen); - - size[0] = sizeof(struct mds_body); - req->rq_replen = lustre_msg_size(1, size); - - rc = mdc_reint(req, LUSTRE_CONN_FULL); - *request = req; - if (rc == -ERESTARTSYS) - rc = 0; - - RETURN(rc); -} diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c deleted file mode 100644 index 79b07ba..0000000 --- a/lustre/mdc/mdc_request.c +++ /dev/null @@ -1,730 +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.sf.net/projects/lustre/ - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_MDC - -#include -#include -#include -#include -#include -#include -#include - -#define REQUEST_MINOR 244 - -extern int mds_queue_req(struct ptlrpc_request *); -extern struct lprocfs_vars status_var_nm_1[]; -extern struct lprocfs_vars status_class_var[]; - -/* should become mdc_getinfo() */ -int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid) -{ - struct ptlrpc_request *req; - struct mds_body *body; - int rc, size = sizeof(*body); - ENTRY; - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_GETSTATUS, 1, &size, - NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - req->rq_level = LUSTRE_CONN_CON; - req->rq_replen = lustre_msg_size(1, &size); - - mds_pack_req_body(req); - rc = ptlrpc_queue_wait(req); - - if (!rc) { - body = lustre_msg_buf(req->rq_repmsg, 0); - mds_unpack_body(body); - memcpy(rootfid, &body->fid1, sizeof(*rootfid)); - - CDEBUG(D_NET, "root ino="LPU64", last_committed="LPU64 - ", last_xid="LPU64"\n", - rootfid->id, req->rq_repmsg->last_committed, - req->rq_repmsg->last_xid); - } - - EXIT; - out: - ptlrpc_req_finished(req); - return rc; -} - -int mdc_getlovinfo(struct obd_device *obd, struct lustre_handle *mdc_connh, - struct ptlrpc_request **request) -{ - struct ptlrpc_request *req; - struct mds_status_req *streq; - int rc, size[2] = {sizeof(*streq)}; - ENTRY; - - req = ptlrpc_prep_req(class_conn2cliimp(mdc_connh), MDS_GETLOVINFO, 1, - size, NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - - *request = req; - streq = lustre_msg_buf(req->rq_reqmsg, 0); - streq->flags = HTON__u32(MDS_STATUS_LOV); - streq->repbuf = HTON__u32(8192); - - /* prepare for reply */ - req->rq_level = LUSTRE_CONN_CON; - size[0] = 512; - size[1] = 8192; - req->rq_replen = lustre_msg_size(2, size); - - rc = ptlrpc_queue_wait(req); - - out: - RETURN(rc); -} - - -int mdc_getattr(struct lustre_handle *conn, - obd_id ino, int type, unsigned long valid, size_t ea_size, - struct ptlrpc_request **request) -{ - struct ptlrpc_request *req; - struct mds_body *body; - int rc, size[2] = {sizeof(*body), 0}, bufcount = 1; - ENTRY; - - /* XXX do we need to make another request here? We just did a getattr - * to do the lookup in the first place. - */ - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_GETATTR, 1, size, - NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - ll_ino2fid(&body->fid1, ino, 0, type); - body->valid = valid; - - if (ea_size) { - size[bufcount] = ea_size; - bufcount++; - body->size = ea_size; - CDEBUG(D_INODE, "reserving %d bytes for MD/symlink in packet\n", - ea_size); - } - req->rq_replen = lustre_msg_size(bufcount, size); - mds_pack_req_body(req); - - rc = ptlrpc_queue_wait(req); - - if (!rc) { - body = lustre_msg_buf(req->rq_repmsg, 0); - mds_unpack_body(body); - CDEBUG(D_NET, "mode: %o\n", body->mode); - } - - EXIT; - out: - *request = req; - return rc; -} - -void d_delete_aliases(struct inode *inode) -{ - struct dentry *dentry = NULL; - struct list_head *tmp; - struct ll_sb_info *sbi = ll_i2sbi(inode); - ENTRY; - - spin_lock(&dcache_lock); - list_for_each(tmp, &inode->i_dentry) { - dentry = list_entry(tmp, struct dentry, d_alias); - - list_del_init(&dentry->d_hash); - list_add(&dentry->d_hash, &sbi->ll_orphan_dentry_list); - } - - spin_unlock(&dcache_lock); - EXIT; -} - -static int mdc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, - void *data, __u32 data_len, int flag) -{ - int rc; - struct lustre_handle lockh; - ENTRY; - - switch (flag) { - case LDLM_CB_BLOCKING: - ldlm_lock2handle(lock, &lockh); - rc = ldlm_cli_cancel(&lockh); - if (rc < 0) { - CDEBUG(D_INODE, "ldlm_cli_cancel: %d\n", rc); - RETURN(rc); - } - break; - case LDLM_CB_CANCELING: { - /* Invalidate all dentries associated with this inode */ - struct inode *inode = data; - -#warning "FIXME: what tells us that 'inode' is valid at all?" - if (inode->i_state & I_FREEING) - break; - - LASSERT(inode != NULL); - LASSERT(data_len == sizeof(*inode)); - - if (S_ISDIR(inode->i_mode)) { - CDEBUG(D_INODE, "invalidating inode %ld\n", - inode->i_ino); - - ll_invalidate_inode_pages(inode); - } - - if ( inode != inode->i_sb->s_root->d_inode ) { - /* XXX should this igrab move up 12 lines? */ - LASSERT(igrab(inode) == inode); - d_delete_aliases(inode); - iput(inode); - } - break; - } - default: - LBUG(); - } - - RETURN(0); -} - -/* This should be called with both the request and the reply still packed. */ -void mdc_store_inode_generation(struct ptlrpc_request *req, int reqoff, - int repoff) -{ - struct mds_rec_create *rec = lustre_msg_buf(req->rq_reqmsg, reqoff); - struct mds_body *body = lustre_msg_buf(req->rq_repmsg, repoff); - - DEBUG_REQ(D_HA, req, "storing generation %x for ino "LPD64, - body->fid1.generation, body->fid1.id); - memcpy(&rec->cr_replayfid, &body->fid1, sizeof rec->cr_replayfid); -} - -int mdc_enqueue(struct lustre_handle *conn, int lock_type, - struct lookup_intent *it, int lock_mode, struct inode *dir, - struct dentry *de, struct lustre_handle *lockh, - char *tgt, int tgtlen, void *data, int datalen) -{ - struct ptlrpc_request *req; - struct obd_device *obddev = class_conn2obd(conn); - __u64 res_id[RES_NAME_SIZE] = {dir->i_ino, (__u64)dir->i_generation}; - int size[6] = {sizeof(struct ldlm_request), sizeof(struct ldlm_intent)}; - int rc, flags = LDLM_FL_HAS_INTENT; - int repsize[3] = {sizeof(struct ldlm_reply), - sizeof(struct mds_body), - obddev->u.cli.cl_max_mds_easize}; - struct ldlm_reply *dlm_rep; - struct ldlm_intent *lit; - struct ldlm_request *lockreq; - ENTRY; - - LDLM_DEBUG_NOLOCK("mdsintent %s parent dir %ld", - ldlm_it2str(it->it_op), dir->i_ino); - - if (it->it_op & (IT_MKDIR | IT_CREAT | IT_SYMLINK | IT_MKNOD)) { - switch (it->it_op) { - case IT_MKDIR: - it->it_mode |= S_IFDIR; - break; - case (IT_CREAT|IT_OPEN): - case IT_CREAT: - it->it_mode |= S_IFREG; - break; - case IT_SYMLINK: - it->it_mode |= S_IFLNK; - break; - } - it->it_mode &= ~current->fs->umask; - - size[2] = sizeof(struct mds_rec_create); - size[3] = de->d_name.len + 1; - size[4] = tgtlen + 1; - req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 5, - size, NULL); - if (!req) - RETURN(-ENOMEM); - - /* pack the intent */ - lit = lustre_msg_buf(req->rq_reqmsg, 1); - lit->opc = NTOH__u64((__u64)it->it_op); - - /* pack the intended request */ - mds_create_pack(req, 2, dir, it->it_mode, 0, current->fsuid, - current->fsgid, CURRENT_TIME, de->d_name.name, - de->d_name.len, tgt, tgtlen); - req->rq_replen = lustre_msg_size(3, repsize); - } else if (it->it_op == IT_RENAME2) { - struct dentry *old_de = it->it_data; - - size[2] = sizeof(struct mds_rec_rename); - size[3] = old_de->d_name.len + 1; - size[4] = de->d_name.len + 1; - req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 5, - size, NULL); - if (!req) - RETURN(-ENOMEM); - - /* pack the intent */ - lit = lustre_msg_buf(req->rq_reqmsg, 1); - lit->opc = NTOH__u64((__u64)it->it_op); - - /* pack the intended request */ - mds_rename_pack(req, 2, old_de->d_parent->d_inode, dir, - old_de->d_name.name, old_de->d_name.len, - de->d_name.name, de->d_name.len); - req->rq_replen = lustre_msg_size(3, repsize); - } else if (it->it_op == IT_LINK2) { - struct dentry *old_de = it->it_data; - - size[2] = sizeof(struct mds_rec_link); - size[3] = de->d_name.len + 1; - req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 4, - size, NULL); - if (!req) - RETURN(-ENOMEM); - - /* pack the intent */ - lit = lustre_msg_buf(req->rq_reqmsg, 1); - lit->opc = NTOH__u64((__u64)it->it_op); - - /* pack the intended request */ - mds_link_pack(req, 2, old_de->d_inode, dir, - de->d_name.name, de->d_name.len); - req->rq_replen = lustre_msg_size(3, repsize); - } else if (it->it_op == IT_UNLINK || it->it_op == IT_RMDIR) { - size[2] = sizeof(struct mds_rec_unlink); - size[3] = de->d_name.len + 1; - req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 4, - size, NULL); - if (!req) - RETURN(-ENOMEM); - - /* pack the intent */ - lit = lustre_msg_buf(req->rq_reqmsg, 1); - lit->opc = NTOH__u64((__u64)it->it_op); - - /* pack the intended request */ - mds_unlink_pack(req, 2, dir, NULL, - it->it_op == IT_UNLINK ? S_IFREG : S_IFDIR, - de->d_name.name, de->d_name.len); - - req->rq_replen = lustre_msg_size(3, repsize); - } else if (it->it_op & (IT_GETATTR | IT_RENAME | IT_LINK | - IT_OPEN | IT_SETATTR | IT_LOOKUP | IT_READLINK)) { - size[2] = sizeof(struct mds_body); - size[3] = de->d_name.len + 1; - - req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 4, - size, NULL); - if (!req) - RETURN(-ENOMEM); - - /* pack the intent */ - lit = lustre_msg_buf(req->rq_reqmsg, 1); - lit->opc = NTOH__u64((__u64)it->it_op); - - /* pack the intended request */ - mds_getattr_pack(req, 2, dir, de->d_name.name, de->d_name.len); - - /* get ready for the reply */ - req->rq_replen = lustre_msg_size(3, repsize); - } else if (it->it_op == IT_READDIR) { - req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 1, - size, NULL); - if (!req) - RETURN(-ENOMEM); - - /* get ready for the reply */ - req->rq_replen = lustre_msg_size(1, repsize); - } else { - LBUG(); - RETURN(-EINVAL); - } - - rc = ldlm_cli_enqueue(conn, req, obddev->obd_namespace, NULL, res_id, - lock_type, NULL, 0, lock_mode, &flags, - ldlm_completion_ast, mdc_blocking_ast, data, - datalen, lockh); - - if (it->it_op != IT_READDIR) { - /* XXX This should become a lustre_msg flag, but for now... */ - __u32 *opp = lustre_msg_buf(req->rq_reqmsg, 2); - *opp |= REINT_REPLAYING; - } - - if (rc == -ENOENT) { - /* This can go when we're sure that this can never happen */ - LBUG(); - } - if (rc == ELDLM_LOCK_ABORTED) { - lock_mode = 0; - memset(lockh, 0, sizeof(*lockh)); - /* rc = 0 */ - } else if (rc != 0) { - CERROR("ldlm_cli_enqueue: %d\n", rc); - RETURN(rc); - } else { - /* The server almost certainly gave us a lock other than the one - * that we asked for. If we already have a matching lock, then - * cancel this one--we don't need two. */ - struct ldlm_lock *lock = ldlm_handle2lock(lockh); - struct lustre_handle lockh2; - LASSERT(lock); - - LDLM_DEBUG(lock, "matching against this"); - - memcpy(&lockh2, lockh, sizeof(lockh2)); - if (ldlm_lock_match(NULL, NULL, LDLM_PLAIN, NULL, 0, LCK_NL, - &lockh2)) { - /* We already have a lock; cancel the old one */ - ldlm_lock_decref(lockh, lock_mode); - ldlm_cli_cancel(lockh); - memcpy(lockh, &lockh2, sizeof(lockh2)); - } - LDLM_LOCK_PUT(lock); - } - - /* On replay, we don't want the lock granted. */ - lockreq = lustre_msg_buf(req->rq_reqmsg, 0); - lockreq->lock_flags |= LDLM_FL_INTENT_ONLY; - - dlm_rep = lustre_msg_buf(req->rq_repmsg, 0); - it->it_disposition = (int) dlm_rep->lock_policy_res1; - it->it_status = (int) dlm_rep->lock_policy_res2; - it->it_lock_mode = lock_mode; - it->it_data = req; - - RETURN(0); -} - -int mdc_cancel_unused(struct lustre_handle *conn, struct inode *inode, - int flags) -{ - __u64 res_id[RES_NAME_SIZE] = {inode->i_ino, inode->i_generation}; - struct obd_device *obddev = class_conn2obd(conn); - ENTRY; - RETURN(ldlm_cli_cancel_unused(obddev->obd_namespace, res_id, flags)); -} - -struct replay_open_data { - struct lustre_handle *fh; -}; - -static void mdc_replay_open(struct ptlrpc_request *req) -{ - int offset; - struct replay_open_data *saved; - struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 0); - - if (lustre_msg_get_op_flags(req->rq_reqmsg) & MDS_OPEN_HAS_EA) - offset = 2; - else - offset = 1; - - saved = lustre_msg_buf(req->rq_reqmsg, offset); - mds_unpack_body(body); - CDEBUG(D_HA, "updating from "LPD64"/"LPD64" to "LPD64"/"LPD64"\n", - saved->fh->addr, saved->fh->cookie, - body->handle.addr, body->handle.cookie); - memcpy(saved->fh, &body->handle, sizeof(body->handle)); -} - -int mdc_open(struct lustre_handle *conn, obd_id ino, int type, int flags, - struct lov_mds_md *lmm, int lmm_size, struct lustre_handle *fh, - struct ptlrpc_request **request) -{ - struct mds_body *body; - struct replay_open_data *replay_data; - int rc, size[3] = {sizeof(*body), sizeof(*replay_data)}, bufcount = 2; - struct ptlrpc_request *req; - ENTRY; - - if (lmm && lmm_size) { - bufcount = 3; - size[2] = size[1]; /* shuffle the spare data along */ - size[1] = lmm_size; - } - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_OPEN, bufcount, size, - NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - - req->rq_flags |= PTL_RPC_FL_REPLAY; - body = lustre_msg_buf(req->rq_reqmsg, 0); - - ll_ino2fid(&body->fid1, ino, 0, type); - body->flags = HTON__u32(flags); - memcpy(&body->handle, fh, sizeof(body->handle)); - - if (lmm && lmm_size) { - CDEBUG(D_INODE, "sending %u bytes MD for ino "LPU64"\n", - lmm_size, ino); - lustre_msg_set_op_flags(req->rq_reqmsg, MDS_OPEN_HAS_EA); - memcpy(lustre_msg_buf(req->rq_reqmsg, 1), lmm, lmm_size); - body->flags |= HTON__u32(OBD_MD_FLEASIZE); - } - - req->rq_replen = lustre_msg_size(1, size); - - rc = ptlrpc_queue_wait(req); - if (!rc) { - body = lustre_msg_buf(req->rq_repmsg, 0); - mds_unpack_body(body); - memcpy(fh, &body->handle, sizeof(*fh)); - } - - /* If open is replayed, we need to fix up the fh. */ - req->rq_replay_cb = mdc_replay_open; - replay_data = lustre_msg_buf(req->rq_reqmsg, lmm ? 2 : 1); - replay_data->fh = fh; - - EXIT; - out: - *request = req; - return rc; -} - -int mdc_close(struct lustre_handle *conn, obd_id ino, int type, - struct lustre_handle *fh, struct ptlrpc_request **request) -{ - struct mds_body *body; - int rc, size = sizeof(*body); - struct ptlrpc_request *req; - ENTRY; - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_CLOSE, 1, &size, - NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - ll_ino2fid(&body->fid1, ino, 0, type); - memcpy(&body->handle, fh, sizeof(body->handle)); - - req->rq_replen = lustre_msg_size(0, NULL); - - rc = ptlrpc_queue_wait(req); - - EXIT; - out: - *request = req; - return rc; -} - -int mdc_readpage(struct lustre_handle *conn, obd_id ino, int type, __u64 offset, - char *addr, struct ptlrpc_request **request) -{ - struct ptlrpc_connection *connection = - client_conn2cli(conn)->cl_import.imp_connection; - struct ptlrpc_request *req = NULL; - struct ptlrpc_bulk_desc *desc = NULL; - struct ptlrpc_bulk_page *bulk = NULL; - struct mds_body *body; - int rc, size = sizeof(*body); - ENTRY; - - CDEBUG(D_INODE, "inode: %ld\n", (long)ino); - - desc = ptlrpc_prep_bulk(connection); - if (desc == NULL) - GOTO(out, rc = -ENOMEM); - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_READPAGE, 1, &size, - NULL); - if (!req) - GOTO(out2, rc = -ENOMEM); - - bulk = ptlrpc_prep_bulk_page(desc); - bulk->bp_buflen = PAGE_SIZE; - bulk->bp_buf = addr; - bulk->bp_xid = req->rq_xid; - desc->bd_portal = MDS_BULK_PORTAL; - - rc = ptlrpc_register_bulk(desc); - if (rc) { - CERROR("couldn't setup bulk sink: error %d.\n", rc); - GOTO(out2, rc); - } - - mds_readdir_pack(req, offset, ino, type); - - req->rq_replen = lustre_msg_size(1, &size); - rc = ptlrpc_queue_wait(req); - if (rc) { - ptlrpc_abort_bulk(desc); - GOTO(out2, rc); - } else { - body = lustre_msg_buf(req->rq_repmsg, 0); - mds_unpack_body(body); - } - - EXIT; - out2: - ptlrpc_free_bulk(desc); - out: - *request = req; - return rc; -} - -static int mdc_statfs(struct lustre_handle *conn, struct obd_statfs *osfs) -{ - struct ptlrpc_request *req; - int rc, size = sizeof(*osfs); - ENTRY; - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_STATFS, 0, NULL, - NULL); - if (!req) - RETURN(-ENOMEM); - - req->rq_replen = lustre_msg_size(1, &size); - - rc = ptlrpc_queue_wait(req); - - if (rc) - GOTO(out, rc); - - obd_statfs_unpack(osfs, lustre_msg_buf(req->rq_repmsg, 0)); - - EXIT; -out: - ptlrpc_req_finished(req); - - return rc; -} - -static int mdc_attach(struct obd_device *dev, obd_count len, void *data) -{ - return lprocfs_reg_obd(dev, status_var_nm_1, dev); -} - -static int mdc_detach(struct obd_device *dev) -{ - return lprocfs_dereg_obd(dev); -} - -static int mdc_recover(struct obd_import *imp, int phase) -{ - int rc; - ENTRY; - - switch(phase) { - case PTLRPC_RECOVD_PHASE_PREPARE: - ldlm_cli_cancel_unused(imp->imp_obd->obd_namespace, - NULL, LDLM_FL_LOCAL_ONLY); - RETURN(0); - case PTLRPC_RECOVD_PHASE_RECOVER: - rc = ptlrpc_reconnect_import(imp, MDS_CONNECT); - if (rc == EALREADY) - RETURN(ptlrpc_replay(imp, 0)); - if (rc) - RETURN(rc); - - rc = ptlrpc_replay(imp, 0 /* no last flag*/); - if (rc) - RETURN(rc); - - rc = ldlm_replay_locks(imp); - if (rc) - RETURN(rc); - - spin_lock(&imp->imp_lock); - imp->imp_level = LUSTRE_CONN_FULL; - spin_unlock(&imp->imp_lock); - - ptlrpc_wake_delayed(imp); - - rc = ptlrpc_resend(imp); - if (rc) - RETURN(rc); - - RETURN(0); - default: - RETURN(-EINVAL); - } -} - -static int mdc_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct obd_import *imp = &obd->u.cli.cl_import; - imp->imp_recover = mdc_recover; - return client_obd_connect(conn, obd, cluuid, recovd, recover); -} - -struct obd_ops mdc_obd_ops = { - o_attach: mdc_attach, - o_detach: mdc_detach, - o_setup: client_obd_setup, - o_cleanup: client_obd_cleanup, - o_connect: mdc_connect, - o_disconnect: client_obd_disconnect, - o_statfs: mdc_statfs, -}; - -static int __init ptlrpc_request_init(void) -{ - return class_register_type(&mdc_obd_ops, status_class_var, - LUSTRE_MDC_NAME); -} - -static void __exit ptlrpc_request_exit(void) -{ - class_unregister_type(LUSTRE_MDC_NAME); -} - -MODULE_AUTHOR("Cluster File Systems "); -MODULE_DESCRIPTION("Lustre Metadata Client v1.0"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(d_delete_aliases); -EXPORT_SYMBOL(mdc_getstatus); -EXPORT_SYMBOL(mdc_getlovinfo); -EXPORT_SYMBOL(mdc_enqueue); -EXPORT_SYMBOL(mdc_cancel_unused); -EXPORT_SYMBOL(mdc_getattr); -EXPORT_SYMBOL(mdc_create); -EXPORT_SYMBOL(mdc_unlink); -EXPORT_SYMBOL(mdc_rename); -EXPORT_SYMBOL(mdc_link); -EXPORT_SYMBOL(mdc_readpage); -EXPORT_SYMBOL(mdc_setattr); -EXPORT_SYMBOL(mdc_close); -EXPORT_SYMBOL(mdc_open); - -EXPORT_SYMBOL(mdc_store_inode_generation); - -module_init(ptlrpc_request_init); -module_exit(ptlrpc_request_exit); diff --git a/lustre/mds/.cvsignore b/lustre/mds/.cvsignore deleted file mode 100644 index e530020..0000000 --- a/lustre/mds/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/mds/Makefile.am b/lustre/mds/Makefile.am deleted file mode 100644 index 3332d0b..0000000 --- a/lustre/mds/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= - -if LINUX25 -FSMOD = mds_ext3 -else -FSMOD = mds_extN -endif - -MODULE = mds -modulefs_DATA = mds.o $(FSMOD).o -EXTRA_PROGRAMS = mds $(FSMOD) - -LINX= mds_updates.c simple.c ll_pack.c target.c - -ll_pack.c: - test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c -mds_updates.c: - test -e mds_updates.c || ln -sf $(top_srcdir)/lib/mds_updates.c -simple.c: - test -e simple.c || ln -sf $(top_srcdir)/lib/simple.c -target.c: - test -e target.c || ln -sf $(top_srcdir)/lib/target.c - -mds_SOURCES = mds_lov.c handler.c mds_reint.c mds_fs.c lproc_mds.c $(LINX) - -include $(top_srcdir)/Rules diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c deleted file mode 100644 index ee12652..0000000 --- a/lustre/mds/handler.c +++ /dev/null @@ -1,1839 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/mds/handler.c - * Lustre Metadata Server (mds) request handler - * - * Copyright (c) 2001, 2002 Cluster File Systems, Inc. - * Author: Peter Braam - * Author: Andreas Dilger - * Author: Phil Schwan - * Author: Mike Shaver - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_MDS - -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#include - -static kmem_cache_t *mds_file_cache; - -extern int mds_get_lovtgts(struct mds_obd *obd, int tgt_count, - obd_uuid_t *uuidarray); -extern int mds_get_lovdesc(struct mds_obd *obd, struct lov_desc *desc); -extern void mds_start_transno(struct mds_obd *mds); -extern int mds_finish_transno(struct mds_obd *mds, void *handle, - struct ptlrpc_request *req, int rc); -static int mds_cleanup(struct obd_device * obddev); - -extern struct lprocfs_vars status_var_nm_1[]; -extern struct lprocfs_vars status_class_var[]; - -inline struct mds_obd *mds_req2mds(struct ptlrpc_request *req) -{ - return &req->rq_export->exp_obd->u.mds; -} - -static int mds_bulk_timeout(void *data) -{ - struct ptlrpc_bulk_desc *desc = data; - - ENTRY; - recovd_conn_fail(desc->bd_connection); - RETURN(1); -} - -/* Assumes caller has already pushed into the kernel filesystem context */ -static int mds_sendpage(struct ptlrpc_request *req, struct file *file, - __u64 offset) -{ - int rc = 0; - struct mds_obd *mds = mds_req2mds(req); - struct ptlrpc_bulk_desc *desc; - struct ptlrpc_bulk_page *bulk; - struct l_wait_info lwi; - char *buf; - ENTRY; - - desc = ptlrpc_prep_bulk(req->rq_connection); - if (desc == NULL) - GOTO(out, rc = -ENOMEM); - - bulk = ptlrpc_prep_bulk_page(desc); - if (bulk == NULL) - GOTO(cleanup_bulk, rc = -ENOMEM); - - OBD_ALLOC(buf, PAGE_SIZE); - if (buf == NULL) - GOTO(cleanup_bulk, rc = -ENOMEM); - - rc = mds_fs_readpage(mds, file, buf, PAGE_SIZE, (loff_t *)&offset); - - if (rc != PAGE_SIZE) - GOTO(cleanup_buf, rc = -EIO); - - bulk->bp_xid = req->rq_xid; - bulk->bp_buf = buf; - bulk->bp_buflen = PAGE_SIZE; - desc->bd_portal = MDS_BULK_PORTAL; - - rc = ptlrpc_send_bulk(desc); - if (rc) - GOTO(cleanup_buf, rc); - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_SENDPAGE)) { - CERROR("obd_fail_loc=%x, fail operation rc=%d\n", - OBD_FAIL_MDS_SENDPAGE, rc); - ptlrpc_abort_bulk(desc); - GOTO(cleanup_buf, rc); - } - - lwi = LWI_TIMEOUT(obd_timeout * HZ, mds_bulk_timeout, desc); - rc = l_wait_event(desc->bd_waitq, desc->bd_flags & PTL_BULK_FL_SENT, - &lwi); - if (rc) { - if (rc != -ETIMEDOUT) - LBUG(); - GOTO(cleanup_buf, rc); - } - - EXIT; - cleanup_buf: - OBD_FREE(buf, PAGE_SIZE); - cleanup_bulk: - ptlrpc_free_bulk(desc); - out: - return rc; -} - -/* - * Look up a named entry in a directory, and get an LDLM lock on it. - * 'dir' is a inode for which an LDLM lock has already been taken. - * - * If we do not need an exclusive or write lock on this entry (e.g. - * a read lock for attribute lookup only) then we do not hold the - * directory semaphore on return. It is up to the caller to know what - * type of lock it is getting, and clean up appropriately. - */ -struct dentry *mds_name2locked_dentry(struct obd_device *obd, - struct dentry *dir, struct vfsmount **mnt, - char *name, int namelen, int lock_mode, - struct lustre_handle *lockh, - int dir_lock_mode) -{ - struct dentry *dchild; - int flags = 0, rc; - __u64 res_id[3] = {0}; - ENTRY; - - down(&dir->d_inode->i_sem); - dchild = lookup_one_len(name, dir, namelen); - if (IS_ERR(dchild)) { - CERROR("child lookup error %ld\n", PTR_ERR(dchild)); - up(&dir->d_inode->i_sem); - LBUG(); - RETURN(dchild); - } - if (dir_lock_mode != LCK_EX && dir_lock_mode != LCK_PW) { - up(&dir->d_inode->i_sem); - ldlm_lock_decref(lockh, dir_lock_mode); - } - - if (lock_mode == 0 || !dchild->d_inode) - RETURN(dchild); - - res_id[0] = dchild->d_inode->i_ino; - res_id[1] = dchild->d_inode->i_generation; - rc = ldlm_match_or_enqueue(NULL, NULL, obd->obd_namespace, NULL, - res_id, LDLM_PLAIN, NULL, 0, lock_mode, - &flags, ldlm_completion_ast, - mds_blocking_ast, NULL, 0, lockh); - if (rc != ELDLM_OK) { - l_dput(dchild); - up(&dir->d_inode->i_sem); - RETURN(ERR_PTR(-ENOLCK)); /* XXX translate ldlm code */ - } - - RETURN(dchild); -} - -struct dentry *mds_fid2locked_dentry(struct obd_device *obd, struct ll_fid *fid, - struct vfsmount **mnt, int lock_mode, - struct lustre_handle *lockh) -{ - struct mds_obd *mds = &obd->u.mds; - struct dentry *de = mds_fid2dentry(mds, fid, mnt), *retval = de; - int flags = 0, rc; - __u64 res_id[3] = {0}; - ENTRY; - - if (IS_ERR(de)) - RETURN(de); - - res_id[0] = de->d_inode->i_ino; - res_id[1] = de->d_inode->i_generation; - rc = ldlm_match_or_enqueue(NULL, NULL, obd->obd_namespace, NULL, - res_id, LDLM_PLAIN, NULL, 0, lock_mode, - &flags, ldlm_completion_ast, - mds_blocking_ast, NULL, 0, lockh); - if (rc != ELDLM_OK) { - l_dput(de); - retval = ERR_PTR(-ENOLCK); /* XXX translate ldlm code */ - } - - RETURN(retval); -} - -#ifndef DCACHE_DISCONNECTED -#define DCACHE_DISCONNECTED DCACHE_NFSD_DISCONNECTED -#endif - -/* Look up an entry by inode number. */ -struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, - struct vfsmount **mnt) -{ - /* stolen from NFS */ - struct super_block *sb = mds->mds_sb; - unsigned long ino = fid->id; - __u32 generation = fid->generation; - struct inode *inode; - struct list_head *lp; - struct dentry *result; - - if (ino == 0) - RETURN(ERR_PTR(-ESTALE)); - - inode = iget(sb, ino); - if (inode == NULL) - RETURN(ERR_PTR(-ENOMEM)); - - CDEBUG(D_DENTRY, "--> mds_fid2dentry: sb %p\n", inode->i_sb); - - if (is_bad_inode(inode) || - (generation && inode->i_generation != generation)) { - /* we didn't find the right inode.. */ - CERROR("bad inode %lu, link: %d ct: %d or version %u/%u\n", - inode->i_ino, inode->i_nlink, - atomic_read(&inode->i_count), inode->i_generation, - generation); - iput(inode); - RETURN(ERR_PTR(-ENOENT)); - } - - /* now to find a dentry. If possible, get a well-connected one */ - if (mnt) - *mnt = mds->mds_vfsmnt; - spin_lock(&dcache_lock); - list_for_each(lp, &inode->i_dentry) { - result = list_entry(lp, struct dentry, d_alias); - if (!(result->d_flags & DCACHE_DISCONNECTED)) { - dget_locked(result); - result->d_vfs_flags |= DCACHE_REFERENCED; - spin_unlock(&dcache_lock); - iput(inode); - if (mnt) - mntget(*mnt); - return result; - } - } - spin_unlock(&dcache_lock); - result = d_alloc_root(inode); - if (result == NULL) { - iput(inode); - return ERR_PTR(-ENOMEM); - } - if (mnt) - mntget(*mnt); - result->d_flags |= DCACHE_DISCONNECTED; - return result; -} - -/* Establish a connection to the MDS. - * - * This will set up an export structure for the client to hold state data - * about that client, like open files, the last operation number it did - * on the server, etc. - */ -static int mds_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct obd_export *exp; - struct mds_export_data *med; - struct mds_client_data *mcd; - struct list_head *p; - int rc; - ENTRY; - - if (!conn || !obd || !cluuid) - RETURN(-EINVAL); - - MOD_INC_USE_COUNT; - - spin_lock(&obd->obd_dev_lock); - list_for_each(p, &obd->obd_exports) { - exp = list_entry(p, struct obd_export, exp_obd_chain); - mcd = exp->exp_mds_data.med_mcd; - if (!mcd) { - CERROR("FYI: NULL mcd - simultaneous connects\n"); - continue; - } - if (!memcmp(cluuid, mcd->mcd_uuid, sizeof mcd->mcd_uuid)) { - /* XXX make handle-found-export a subroutine */ - LASSERT(exp->exp_obd == obd); - - spin_unlock(&obd->obd_dev_lock); - if (exp->exp_connection) { - struct lustre_handle *hdl; - hdl = &exp->exp_ldlm_data.led_import.imp_handle; - /* Might be a re-connect after a partition. */ - if (!memcmp(conn, hdl, sizeof *conn)) { - CERROR("%s reconnecting\n", cluuid); - conn->addr = (__u64) (unsigned long)exp; - conn->cookie = exp->exp_cookie; - rc = EALREADY; - } else { - CERROR("%s reconnecting from %s, " - "handle mismatch (ours %Lx/%Lx, " - "theirs %Lx/%Lx)\n", cluuid, - exp->exp_connection-> - c_remote_uuid, hdl->addr, - hdl->cookie, conn->addr, - conn->cookie); - /* XXX disconnect them here? */ - memset(conn, 0, sizeof *conn); - rc = -EALREADY; - } - MOD_DEC_USE_COUNT; - RETURN(rc); - } - conn->addr = (__u64) (unsigned long)exp; - conn->cookie = exp->exp_cookie; - CDEBUG(D_INFO, "existing export for UUID '%s' at %p\n", - cluuid, exp); - CDEBUG(D_IOCTL,"connect: addr %Lx cookie %Lx\n", - (long long)conn->addr, (long long)conn->cookie); - RETURN(0); - } - } - spin_unlock(&obd->obd_dev_lock); - - if (obd->u.mds.mds_recoverable_clients != 0) { - CERROR("denying connection for new client %s: in recovery\n", - cluuid); - MOD_DEC_USE_COUNT; - RETURN(-EBUSY); - } - - /* XXX There is a small race between checking the list and adding a - * new connection for the same UUID, but the real threat (list - * corruption when multiple different clients connect) is solved. - * - * There is a second race between adding the export to the list, - * and filling in the client data below. Hence skipping the case - * of NULL mcd above. We should already be controlling multiple - * connects at the client, and we can't hold the spinlock over - * memory allocations without risk of deadlocking. - */ - rc = class_connect(conn, obd, cluuid); - if (rc) - GOTO(out_dec, rc); - exp = class_conn2export(conn); - LASSERT(exp); - med = &exp->exp_mds_data; - - OBD_ALLOC(mcd, sizeof(*mcd)); - if (!mcd) { - CERROR("mds: out of memory for client data\n"); - GOTO(out_export, rc = -ENOMEM); - } - - memcpy(mcd->mcd_uuid, cluuid, sizeof(mcd->mcd_uuid)); - med->med_mcd = mcd; - - INIT_LIST_HEAD(&med->med_open_head); - spin_lock_init(&med->med_open_lock); - - rc = mds_client_add(&obd->u.mds, med, -1); - if (rc) - GOTO(out_mcd, rc); - - RETURN(0); - -out_mcd: - OBD_FREE(mcd, sizeof(*mcd)); -out_export: - class_disconnect(conn); -out_dec: - MOD_DEC_USE_COUNT; - - return rc; -} - -/* Call with med->med_open_lock held, please. */ -inline int mds_close_mfd(struct mds_file_data *mfd, struct mds_export_data *med) -{ - struct file *file = mfd->mfd_file; - LASSERT(file->private_data == mfd); - - list_del(&mfd->mfd_list); - mfd->mfd_servercookie = DEAD_HANDLE_MAGIC; - kmem_cache_free(mds_file_cache, mfd); - - return filp_close(file, 0); -} - -static int mds_disconnect(struct lustre_handle *conn) -{ - struct obd_export *export = class_conn2export(conn); - struct list_head *tmp, *n; - struct mds_export_data *med = &export->exp_mds_data; - int rc; - ENTRY; - - /* - * Close any open files. - */ - spin_lock(&med->med_open_lock); - list_for_each_safe(tmp, n, &med->med_open_head) { - struct mds_file_data *mfd = - list_entry(tmp, struct mds_file_data, mfd_list); - rc = mds_close_mfd(mfd, med); - if (rc) { - /* XXX better diagnostics, with file path and stuff */ - CDEBUG(D_INODE, "Error %d closing mfd %p\n", rc, mfd); - } - } - spin_unlock(&med->med_open_lock); - - ldlm_cancel_locks_for_export(export); - mds_client_free(export); - - rc = class_disconnect(conn); - if (!rc) - MOD_DEC_USE_COUNT; - - RETURN(rc); -} - -/* - * XXX This is NOT guaranteed to flush all transactions to disk (even though - * it is equivalent to calling sync()) because it only _starts_ the flush - * and does not wait for completion. It's better than nothing though. - * What we really want is a mild form of fsync_dev_lockfs(), but it is - * non-standard, or enabling do_sync_supers in ext3, just for this call. - */ -static void mds_fsync_super(struct super_block *sb) -{ - lock_kernel(); - lock_super(sb); - if (sb->s_dirt && sb->s_op && sb->s_op->write_super) - sb->s_op->write_super(sb); - unlock_super(sb); - unlock_kernel(); -} - -static int mds_getstatus(struct ptlrpc_request *req) -{ - struct mds_obd *mds = mds_req2mds(req); - struct mds_body *body; - int rc, size = sizeof(*body); - ENTRY; - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_GETSTATUS_PACK)) { - CERROR("mds: out of memory for message: size=%d\n", size); - req->rq_status = -ENOMEM; - RETURN(0); - } - - /* Flush any outstanding transactions to disk so the client will - * get the latest last_committed value and can drop their local - * requests if they have any. This would be fsync_super() if it - * was exported. - */ - mds_fsync_super(mds->mds_sb); - - body = lustre_msg_buf(req->rq_repmsg, 0); - memcpy(&body->fid1, &mds->mds_rootfid, sizeof(body->fid1)); - - /* the last_committed and last_xid fields are filled in for all - * replies already - no need to do so here also. - */ - RETURN(0); -} - -static int mds_getlovinfo(struct ptlrpc_request *req) -{ - struct mds_obd *mds = mds_req2mds(req); - struct mds_status_req *streq; - struct lov_desc *desc; - int tgt_count; - int rc, size[2] = {sizeof(*desc)}; - ENTRY; - - streq = lustre_msg_buf(req->rq_reqmsg, 0); - streq->flags = NTOH__u32(streq->flags); - streq->repbuf = NTOH__u32(streq->repbuf); - size[1] = streq->repbuf; - - rc = lustre_pack_msg(2, size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) { - CERROR("mds: out of memory for message: size=%d\n", size[1]); - req->rq_status = -ENOMEM; - RETURN(0); - } - - desc = lustre_msg_buf(req->rq_repmsg, 0); - rc = mds_get_lovdesc(mds, desc); - if (rc) { - req->rq_status = rc; - RETURN(0); - } - - tgt_count = le32_to_cpu(desc->ld_tgt_count); - if (tgt_count * sizeof(obd_uuid_t) > streq->repbuf) { - CERROR("too many targets, enlarge client buffers\n"); - req->rq_status = -ENOSPC; - RETURN(0); - } - - /* XXX the MDS should not really know about this */ - mds->mds_max_mdsize = lov_mds_md_size(tgt_count); - rc = mds_get_lovtgts(mds, tgt_count, - lustre_msg_buf(req->rq_repmsg, 1)); - if (rc) { - CERROR("get_lovtgts error %d\n", rc); - req->rq_status = rc; - RETURN(0); - } - RETURN(0); -} - -int mds_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, - void *data, __u32 data_len, int flag) -{ - int do_ast; - ENTRY; - - if (flag == LDLM_CB_CANCELING) { - /* Don't need to do anything here. */ - RETURN(0); - } - - /* XXX layering violation! -phil */ - l_lock(&lock->l_resource->lr_namespace->ns_lock); - lock->l_flags |= LDLM_FL_CBPENDING; - do_ast = (!lock->l_readers && !lock->l_writers); - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - - if (do_ast) { - struct lustre_handle lockh; - int rc; - - LDLM_DEBUG(lock, "already unused, calling ldlm_cli_cancel"); - ldlm_lock2handle(lock, &lockh); - rc = ldlm_cli_cancel(&lockh); - if (rc < 0) - CERROR("ldlm_cli_cancel: %d\n", rc); - } else - LDLM_DEBUG(lock, "Lock still has references, will be" - "cancelled later"); - RETURN(0); -} - -int mds_pack_md(struct mds_obd *mds, struct ptlrpc_request *req, - int offset, struct mds_body *body, struct inode *inode) -{ - struct lov_mds_md *lmm; - int lmm_size = req->rq_repmsg->buflens[offset]; - int rc; - - if (lmm_size == 0) { - CDEBUG(D_INFO, "no space reserved for inode %u MD\n", inode->i_ino); - RETURN(0); - } - - lmm = lustre_msg_buf(req->rq_repmsg, offset); - - /* I don't really like this, but it is a sanity check on the client - * MD request. However, if the client doesn't know how much space - * to reserve for the MD, this shouldn't be fatal either... - */ - if (lmm_size > mds->mds_max_mdsize) { - CERROR("Reading MD for inode %u of %d bytes > max %d\n", - inode->i_ino, lmm_size, mds->mds_max_mdsize); - // RETURN(-EINVAL); - } - - /* We don't need to store the reply size, because this buffer is - * discarded right after unpacking, and the LOV can figure out the - * size itself from the ost count. - */ - if ((rc = mds_fs_get_md(mds, inode, lmm, lmm_size)) < 0) { - CDEBUG(D_INFO, "No md for ino %u: rc = %d\n", inode->i_ino, rc); - } else if (rc > 0) { - body->valid |= OBD_MD_FLEASIZE; - rc = 0; - } - - return rc; -} - -static int mds_getattr_internal(struct mds_obd *mds, struct dentry *dentry, - struct ptlrpc_request *req, - struct mds_body *reqbody, int reply_off) -{ - struct mds_body *body; - struct inode *inode = dentry->d_inode; - int rc = 0; - ENTRY; - - if (inode == NULL) - RETURN(-ENOENT); - - body = lustre_msg_buf(req->rq_repmsg, reply_off); - - mds_pack_inode2fid(&body->fid1, inode); - mds_pack_inode2body(body, inode); - - if (S_ISREG(inode->i_mode)) { - rc = mds_pack_md(mds, req, reply_off + 1, body, inode); - } else if (S_ISLNK(inode->i_mode) && reqbody->valid & OBD_MD_LINKNAME) { - char *symname = lustre_msg_buf(req->rq_repmsg, reply_off + 1); - int len = req->rq_repmsg->buflens[reply_off + 1]; - - rc = inode->i_op->readlink(dentry, symname, len); - if (rc < 0) { - CERROR("readlink failed: %d\n", rc); - } else { - CDEBUG(D_INODE, "read symlink dest %s\n", symname); - body->valid |= OBD_MD_LINKNAME; - } - } - RETURN(rc); -} - -static int mds_getattr_name(int offset, struct ptlrpc_request *req) -{ - struct mds_obd *mds = mds_req2mds(req); - struct obd_device *obd = req->rq_export->exp_obd; - struct obd_run_ctxt saved; - struct mds_body *body; - struct dentry *de = NULL, *dchild = NULL; - struct inode *dir; - struct lustre_handle lockh; - char *name; - int namelen, flags = 0, lock_mode, rc = 0; - struct obd_ucred uc; - __u64 res_id[3] = {0, 0, 0}; - ENTRY; - - LASSERT(!strcmp(req->rq_export->exp_obd->obd_type->typ_name, "mds")); - - if (req->rq_reqmsg->bufcount <= offset + 1) { - LBUG(); - GOTO(out_pre_de, rc = -EINVAL); - } - - body = lustre_msg_buf(req->rq_reqmsg, offset); - name = lustre_msg_buf(req->rq_reqmsg, offset + 1); - namelen = req->rq_reqmsg->buflens[offset + 1]; - /* requests were at offset 2, replies go back at 1 */ - if (offset) - offset = 1; - - uc.ouc_fsuid = body->fsuid; - uc.ouc_fsgid = body->fsgid; - uc.ouc_cap = body->capability; - push_ctxt(&saved, &mds->mds_ctxt, &uc); - de = mds_fid2dentry(mds, &body->fid1, NULL); - if (IS_ERR(de)) { - GOTO(out_pre_de, rc = -ENOENT); - } - - dir = de->d_inode; - CDEBUG(D_INODE, "parent ino %ld, name %*s\n", dir->i_ino,namelen,name); - - lock_mode = LCK_PR; - res_id[0] = dir->i_ino; - res_id[1] = dir->i_generation; - - rc = ldlm_lock_match(obd->obd_namespace, res_id, LDLM_PLAIN, - NULL, 0, lock_mode, &lockh); - if (rc == 0) { - LDLM_DEBUG_NOLOCK("enqueue res "LPU64, res_id[0]); - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, - res_id, LDLM_PLAIN, NULL, 0, lock_mode, - &flags, ldlm_completion_ast, - mds_blocking_ast, NULL, 0, &lockh); - if (rc != ELDLM_OK) { - CERROR("lock enqueue: err: %d\n", rc); - GOTO(out_create_de, rc = -EIO); - } - } - ldlm_lock_dump((void *)(unsigned long)lockh.addr); - - down(&dir->i_sem); - dchild = lookup_one_len(name, de, namelen - 1); - if (IS_ERR(dchild)) { - CDEBUG(D_INODE, "child lookup error %ld\n", PTR_ERR(dchild)); - up(&dir->i_sem); - GOTO(out_create_dchild, rc = PTR_ERR(dchild)); - } - - rc = mds_getattr_internal(mds, dchild, req, body, offset); - - EXIT; -out_create_dchild: - l_dput(dchild); - up(&dir->i_sem); - ldlm_lock_decref(&lockh, lock_mode); -out_create_de: - l_dput(de); -out_pre_de: - req->rq_status = rc; - pop_ctxt(&saved, &mds->mds_ctxt, &uc); - return 0; -} - -static int mds_getattr(int offset, struct ptlrpc_request *req) -{ - struct mds_obd *mds = mds_req2mds(req); - struct obd_run_ctxt saved; - struct dentry *de; - struct inode *inode; - struct mds_body *body; - struct obd_ucred uc; - int rc = 0, size[2] = {sizeof(*body)}, bufcount = 1; - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, offset); - uc.ouc_fsuid = body->fsuid; - uc.ouc_fsgid = body->fsgid; - uc.ouc_cap = body->capability; - push_ctxt(&saved, &mds->mds_ctxt, &uc); - de = mds_fid2dentry(mds, &body->fid1, NULL); - if (IS_ERR(de)) { - rc = req->rq_status = -ENOENT; - GOTO(out_pop, PTR_ERR(de)); - } - - inode = de->d_inode; - if (S_ISREG(body->fid1.f_type)) { - int rc = mds_fs_get_md(mds, inode, NULL, 0); - CDEBUG(D_INODE, "got %d bytes MD data for inode %u\n", - rc, inode->i_ino); - if (rc < 0) { - if (rc != -ENODATA) - CERROR("error getting inode %u MD: rc = %d\n", - inode->i_ino, rc); - size[bufcount] = 0; - } else if (rc > mds->mds_max_mdsize) { - size[bufcount] = 0; - CERROR("MD size %d larger than maximum possible %u\n", - rc, mds->mds_max_mdsize); - } else - size[bufcount] = rc; - bufcount++; - } else if (body->valid & OBD_MD_LINKNAME) { - size[bufcount] = MIN(inode->i_size + 1, body->size); - bufcount++; - CDEBUG(D_INODE, "symlink size: %d, reply space: %d\n", - inode->i_size + 1, body->size); - } - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETATTR_PACK)) { - CERROR("failed MDS_GETATTR_PACK test\n"); - req->rq_status = -ENOMEM; - GOTO(out, rc = -ENOMEM); - } - - rc = lustre_pack_msg(bufcount, size, NULL, &req->rq_replen, - &req->rq_repmsg); - if (rc) { - CERROR("out of memoryK\n"); - req->rq_status = rc; - GOTO(out, rc); - } - - req->rq_status = mds_getattr_internal(mds, de, req, body, 0); - -out: - l_dput(de); -out_pop: - pop_ctxt(&saved, &mds->mds_ctxt, &uc); - RETURN(rc); -} - -static int mds_statfs(struct ptlrpc_request *req) -{ - struct mds_obd *mds = mds_req2mds(req); - struct obd_statfs *osfs; - struct statfs sfs; - int rc, size = sizeof(*osfs); - ENTRY; - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_STATFS_PACK)) { - CERROR("mds: statfs lustre_pack_msg failed: rc = %d\n", rc); - GOTO(out, rc); - } - - rc = mds_fs_statfs(mds, &sfs); - if (rc) { - CERROR("mds: statfs failed: rc %d\n", rc); - GOTO(out, rc); - } - osfs = lustre_msg_buf(req->rq_repmsg, 0); - memset(osfs, 0, size); - statfs_pack(osfs, &sfs); - obd_statfs_pack(osfs, osfs); - -out: - req->rq_status = rc; - RETURN(0); -} - -static struct mds_file_data *mds_handle2mfd(struct lustre_handle *handle) -{ - struct mds_file_data *mfd = NULL; - - if (!handle || !handle->addr) - RETURN(NULL); - - mfd = (struct mds_file_data *)(unsigned long)(handle->addr); - if (!kmem_cache_validate(mds_file_cache, mfd)) - RETURN(NULL); - - if (mfd->mfd_servercookie != handle->cookie) - RETURN(NULL); - - return mfd; -} - -static int mds_store_md(struct mds_obd *mds, struct ptlrpc_request *req, - int offset, struct mds_body *body, struct inode *inode) -{ - struct lov_mds_md *lmm = lustre_msg_buf(req->rq_reqmsg, offset); - int lmm_size = req->rq_reqmsg->buflens[offset]; - struct obd_run_ctxt saved; - struct obd_ucred uc; - void *handle; - int rc, rc2; - ENTRY; - - /* I don't really like this, but it is a sanity check on the client - * MD request. - */ - if (lmm_size > mds->mds_max_mdsize) { - CERROR("Saving MD for inode %u of %d bytes > max %d\n", - inode->i_ino, lmm_size, mds->mds_max_mdsize); - //RETURN(-EINVAL); - } - - CDEBUG(D_INODE, "storing %d bytes MD for inode %u\n", - lmm_size, inode->i_ino); - uc.ouc_fsuid = body->fsuid; - uc.ouc_fsgid = body->fsgid; - uc.ouc_cap = body->capability; - push_ctxt(&saved, &mds->mds_ctxt, &uc); - mds_start_transno(mds); - handle = mds_fs_start(mds, inode, MDS_FSOP_SETATTR); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - mds_finish_transno(mds, handle, req, rc); - GOTO(out_ea, rc); - } - - rc = mds_fs_set_md(mds, inode, handle, lmm, lmm_size); - rc = mds_finish_transno(mds, handle, req, rc); - - rc2 = mds_fs_commit(mds, inode, handle); - if (rc2 && !rc) - rc = rc2; -out_ea: - pop_ctxt(&saved, &mds->mds_ctxt, &uc); - - RETURN(rc); -} - -static int mds_open(struct ptlrpc_request *req) -{ - struct mds_obd *mds = mds_req2mds(req); - struct mds_body *body; - struct mds_export_data *med; - struct mds_file_data *mfd; - struct dentry *de; - struct file *file; - struct vfsmount *mnt; - __u32 flags; - struct list_head *tmp; - int rc, size = sizeof(*body); - ENTRY; - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OPEN_PACK)) { - CERROR("test case OBD_FAIL_MDS_OPEN_PACK\n"); - req->rq_status = -ENOMEM; - RETURN(-ENOMEM); - } - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) { - CERROR("mds: pack error: rc = %d\n", rc); - req->rq_status = rc; - RETURN(rc); - } - - body = lustre_msg_buf(req->rq_reqmsg, 0); - - /* was this animal open already and the client lost the reply? */ - /* XXX need some way to detect a reopen, to avoid locked list walks */ - med = &req->rq_export->exp_mds_data; - spin_lock(&med->med_open_lock); - list_for_each(tmp, &med->med_open_head) { - mfd = list_entry(tmp, typeof(*mfd), mfd_list); - if (!memcmp(&mfd->mfd_clienthandle, &body->handle, - sizeof(mfd->mfd_clienthandle)) && - body->fid1.id == mfd->mfd_file->f_dentry->d_inode->i_ino) { - de = mfd->mfd_file->f_dentry; - spin_unlock(&med->med_open_lock); - CERROR("Re opening "LPD64"\n", body->fid1.id); - GOTO(out_pack, rc = 0); - } - } - spin_unlock(&med->med_open_lock); - - mfd = kmem_cache_alloc(mds_file_cache, GFP_KERNEL); - if (!mfd) { - CERROR("mds: out of memory\n"); - req->rq_status = -ENOMEM; - RETURN(0); - } - - de = mds_fid2dentry(mds, &body->fid1, &mnt); - if (IS_ERR(de)) - GOTO(out_free, rc = PTR_ERR(de)); - - /* check if this inode has seen a delayed object creation */ - if (lustre_msg_get_op_flags(req->rq_reqmsg) & MDS_OPEN_HAS_EA) { - rc = mds_store_md(mds, req, 1, body, de->d_inode); - if (rc) { - l_dput(de); - mntput(mnt); - GOTO(out_free, rc); - } - } - - flags = body->flags; - /* dentry_open does a dput(de) and mntput(mnt) on error */ - file = dentry_open(de, mnt, flags & ~O_DIRECT); - if (IS_ERR(file)) { - rc = PTR_ERR(file); - GOTO(out_free, 0); - } - - file->private_data = mfd; - mfd->mfd_file = file; - memcpy(&mfd->mfd_clienthandle, &body->handle, sizeof(body->handle)); - get_random_bytes(&mfd->mfd_servercookie, sizeof(mfd->mfd_servercookie)); - spin_lock(&med->med_open_lock); - list_add(&mfd->mfd_list, &med->med_open_head); - spin_unlock(&med->med_open_lock); - -out_pack: - body = lustre_msg_buf(req->rq_repmsg, 0); - mds_pack_inode2fid(&body->fid1, de->d_inode); - mds_pack_inode2body(body, de->d_inode); - body->handle.addr = (__u64)(unsigned long)mfd; - body->handle.cookie = mfd->mfd_servercookie; - CDEBUG(D_INODE, "llite file "LPX64": addr %p, cookie "LPX64"\n", - mfd->mfd_clienthandle.addr, mfd, mfd->mfd_servercookie); - RETURN(0); - -out_free: - mfd->mfd_servercookie = DEAD_HANDLE_MAGIC; - kmem_cache_free(mds_file_cache, mfd); - req->rq_status = rc; - RETURN(0); -} - -static int mds_close(struct ptlrpc_request *req) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_body *body; - struct mds_file_data *mfd; - int rc; - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, 0); - - mfd = mds_handle2mfd(&body->handle); - if (!mfd) { - CERROR("no handle for file close "LPD64 - ": addr "LPX64", cookie "LPX64"\n", - body->fid1.id, body->handle.addr, body->handle.cookie); - RETURN(-ESTALE); - } - - spin_lock(&med->med_open_lock); - req->rq_status = mds_close_mfd(mfd, med); - spin_unlock(&med->med_open_lock); - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_CLOSE_PACK)) { - CERROR("test case OBD_FAIL_MDS_CLOSE_PACK\n"); - req->rq_status = -ENOMEM; - RETURN(-ENOMEM); - } - - rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) { - CERROR("mds: lustre_pack_msg: rc = %d\n", rc); - req->rq_status = rc; - } - - RETURN(0); -} - -static int mds_readpage(struct ptlrpc_request *req) -{ - struct mds_obd *mds = mds_req2mds(req); - struct vfsmount *mnt; - struct dentry *de; - struct file *file; - struct mds_body *body, *repbody; - struct obd_run_ctxt saved; - int rc, size = sizeof(*body); - struct obd_ucred uc; - ENTRY; - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_READPAGE_PACK)) { - CERROR("mds: out of memory\n"); - GOTO(out, rc = -ENOMEM); - } - - body = lustre_msg_buf(req->rq_reqmsg, 0); - uc.ouc_fsuid = body->fsuid; - uc.ouc_fsgid = body->fsgid; - uc.ouc_cap = body->capability; - push_ctxt(&saved, &mds->mds_ctxt, &uc); - de = mds_fid2dentry(mds, &body->fid1, &mnt); - if (IS_ERR(de)) - GOTO(out_pop, rc = PTR_ERR(de)); - - CDEBUG(D_INODE, "ino %ld\n", de->d_inode->i_ino); - - file = dentry_open(de, mnt, O_RDONLY | O_LARGEFILE); - /* note: in case of an error, dentry_open puts dentry */ - if (IS_ERR(file)) - GOTO(out_pop, rc = PTR_ERR(file)); - - repbody = lustre_msg_buf(req->rq_repmsg, 0); - repbody->size = file->f_dentry->d_inode->i_size; - repbody->valid = OBD_MD_FLSIZE; - - /* to make this asynchronous make sure that the handling function - doesn't send a reply when this function completes. Instead a - callback function would send the reply */ - /* note: in case of an error, dentry_open puts dentry */ - rc = mds_sendpage(req, file, body->size); - - filp_close(file, 0); -out_pop: - pop_ctxt(&saved, &mds->mds_ctxt, &uc); -out: - req->rq_status = rc; - RETURN(0); -} - -int mds_reint(struct ptlrpc_request *req, int offset) -{ - int rc; - struct mds_update_record rec; - - rc = mds_update_unpack(req, offset, &rec); - if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNPACK)) { - CERROR("invalid record\n"); - req->rq_status = -EINVAL; - RETURN(0); - } - /* rc will be used to interrupt a for loop over multiple records */ - rc = mds_reint_rec(&rec, offset, req); - return rc; -} - -/* forward declaration */ -int mds_handle(struct ptlrpc_request *req); - -static int check_for_next_transno(struct mds_obd *mds) -{ - struct ptlrpc_request *req; - req = list_entry(mds->mds_recovery_queue.next, - struct ptlrpc_request, rq_list); - return req->rq_reqmsg->transno == mds->mds_next_recovery_transno; -} - -static void process_recovery_queue(struct mds_obd *mds) -{ - struct ptlrpc_request *req; - - for (;;) { - spin_lock(&mds->mds_processing_task_lock); - req = list_entry(mds->mds_recovery_queue.next, - struct ptlrpc_request, rq_list); - - if (req->rq_reqmsg->transno != mds->mds_next_recovery_transno) { - spin_unlock(&mds->mds_processing_task_lock); - wait_event(mds->mds_next_transno_waitq, - check_for_next_transno(mds)); - continue; - } - list_del(&req->rq_list); - spin_unlock(&mds->mds_processing_task_lock); - - DEBUG_REQ(D_HA, req, ""); - mds_handle(req); - - if (list_empty(&mds->mds_recovery_queue)) - break; - } -} - -static int queue_recovery_request(struct ptlrpc_request *req, - struct mds_obd *mds) -{ - struct list_head *tmp; - int inserted = 0, transno = req->rq_reqmsg->transno; - - if (!transno) { - DEBUG_REQ(D_HA, req, "not queueing"); - return 1; - } - - spin_lock(&mds->mds_processing_task_lock); - - if (mds->mds_processing_task == current->pid) { - /* Processing the queue right now, don't re-add. */ - spin_unlock(&mds->mds_processing_task_lock); - return 1; - } - - /* XXX O(n^2) */ - list_for_each(tmp, &mds->mds_recovery_queue) { - struct ptlrpc_request *reqiter = - list_entry(tmp, struct ptlrpc_request, rq_list); - if (reqiter->rq_reqmsg->transno > transno) { - list_add_tail(&req->rq_list, &reqiter->rq_list); - inserted = 1; - break; - } - } - - if (!inserted) - list_add_tail(&req->rq_list, &mds->mds_recovery_queue); - - if (mds->mds_processing_task != 0) { - /* Someone else is processing this queue, we'll leave it to - * them. - */ - spin_unlock(&mds->mds_processing_task_lock); - if (transno == mds->mds_next_recovery_transno) - wake_up(&mds->mds_next_transno_waitq); - return 0; - } - - /* Nobody is processing, and we know there's (at least) one to process - * now, so we'll do the honours. - */ - mds->mds_processing_task = current->pid; - spin_unlock(&mds->mds_processing_task_lock); - - process_recovery_queue(mds); - return 0; -} - -static int filter_recovery_request(struct ptlrpc_request *req, - struct mds_obd *mds, int *process) -{ - switch (req->rq_reqmsg->opc) { - case MDS_CONNECT: - case MDS_DISCONNECT: - case MDS_OPEN: - *process = 1; - RETURN(0); - - case MDS_GETSTATUS: /* used in unmounting */ - case MDS_REINT: - case LDLM_ENQUEUE: - *process = queue_recovery_request(req, mds); - RETURN(0); - - default: - DEBUG_REQ(D_ERROR, req, "not permitted during recovery"); - *process = 0; - RETURN(ptlrpc_error(req->rq_svc, req)); - } -} - -static int mds_queue_final_reply(struct ptlrpc_request *req, int rc) -{ - struct mds_obd *mds = mds_req2mds(req); - - if (rc) { - /* Just like ptlrpc_error, but without the sending. */ - lustre_pack_msg(0, NULL, NULL, &req->rq_replen, - &req->rq_repmsg); - req->rq_type = PTL_RPC_MSG_ERR; - } - - list_add(&req->rq_list, &mds->mds_delayed_reply_queue); - if (--mds->mds_recoverable_clients == 0) { - struct list_head *tmp, *n; - - CDEBUG(D_HA, - "all clients recovered, sending delayed replies\n"); - list_for_each_safe(tmp, n, &mds->mds_delayed_reply_queue) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - DEBUG_REQ(D_HA, req, "delayed:"); - ptlrpc_reply(req->rq_svc, req); - } - } else { - CDEBUG(D_HA, "%d recoverable clients remain\n", - mds->mds_recoverable_clients); - } - - return 1; -} - -static char *reint_names[] = { - [REINT_SETATTR] "setattr", - [REINT_CREATE] "create", - [REINT_LINK] "link", - [REINT_UNLINK] "unlink", - [REINT_RENAME] "rename" -}; - -int mds_handle(struct ptlrpc_request *req) -{ - int rc; - int should_process; - struct mds_obd *mds = NULL; /* quell gcc overwarning */ - ENTRY; - - rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); - if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_HANDLE_UNPACK)) { - CERROR("lustre_mds: Invalid request\n"); - GOTO(out, rc); - } - - LASSERT(!strcmp(req->rq_obd->obd_type->typ_name, LUSTRE_MDT_NAME)); - - if (req->rq_reqmsg->opc != MDS_CONNECT) { - if (req->rq_export == NULL) - GOTO(out, rc = -ENOTCONN); - - mds = mds_req2mds(req); - if (mds->mds_recoverable_clients != 0) { - rc = filter_recovery_request(req, mds, &should_process); - if (rc || !should_process) - RETURN(rc); - } - } - - switch (req->rq_reqmsg->opc) { - case MDS_CONNECT: - DEBUG_REQ(D_INODE, req, "connect"); - OBD_FAIL_RETURN(OBD_FAIL_MDS_CONNECT_NET, 0); - rc = target_handle_connect(req); - /* Make sure that last_rcvd is correct. */ - if (!rc) { - /* Now that we have an export, set mds. */ - mds = mds_req2mds(req); - mds_fsync_super(mds->mds_sb); - } - break; - - case MDS_DISCONNECT: - DEBUG_REQ(D_INODE, req, "disconnect"); - OBD_FAIL_RETURN(OBD_FAIL_MDS_DISCONNECT_NET, 0); - rc = target_handle_disconnect(req); - /* Make sure that last_rcvd is correct. */ - if (!rc) - mds_fsync_super(mds->mds_sb); - goto out; - - case MDS_GETSTATUS: - DEBUG_REQ(D_INODE, req, "getstatus"); - OBD_FAIL_RETURN(OBD_FAIL_MDS_GETSTATUS_NET, 0); - rc = mds_getstatus(req); - break; - - case MDS_GETLOVINFO: - DEBUG_REQ(D_INODE, req, "getlovinfo"); - rc = mds_getlovinfo(req); - break; - - case MDS_GETATTR: - DEBUG_REQ(D_INODE, req, "getattr"); - OBD_FAIL_RETURN(OBD_FAIL_MDS_GETATTR_NET, 0); - rc = mds_getattr(0, req); - break; - - case MDS_STATFS: - DEBUG_REQ(D_INODE, req, "statfs"); - OBD_FAIL_RETURN(OBD_FAIL_MDS_STATFS_NET, 0); - rc = mds_statfs(req); - break; - - case MDS_READPAGE: - DEBUG_REQ(D_INODE, req, "readpage\n"); - OBD_FAIL_RETURN(OBD_FAIL_MDS_READPAGE_NET, 0); - rc = mds_readpage(req); - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_SENDPAGE)) - return 0; - break; - - case MDS_REINT: { - int size = sizeof(struct mds_body); - int opc = *(u32 *)lustre_msg_buf(req->rq_reqmsg, 0), - realopc = opc & REINT_OPCODE_MASK; - - DEBUG_REQ(D_INODE, req, "reint (%s%s)", - reint_names[realopc], - opc & REINT_REPLAYING ? "|REPLAYING" : ""); - - OBD_FAIL_RETURN(OBD_FAIL_MDS_REINT_NET, 0); - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, - &req->rq_repmsg); - if (rc) { - req->rq_status = rc; - break; - } - rc = mds_reint(req, 0); - OBD_FAIL_RETURN(OBD_FAIL_MDS_REINT_NET_REP, 0); - break; - } - - case MDS_OPEN: - DEBUG_REQ(D_INODE, req, "open"); - OBD_FAIL_RETURN(OBD_FAIL_MDS_OPEN_NET, 0); - rc = mds_open(req); - break; - - case MDS_CLOSE: - DEBUG_REQ(D_INODE, req, "close"); - OBD_FAIL_RETURN(OBD_FAIL_MDS_CLOSE_NET, 0); - rc = mds_close(req); - break; - - case LDLM_ENQUEUE: - DEBUG_REQ(D_INODE, req, "enqueue"); - OBD_FAIL_RETURN(OBD_FAIL_LDLM_ENQUEUE, 0); - rc = ldlm_handle_enqueue(req); - break; - case LDLM_CONVERT: - DEBUG_REQ(D_INODE, req, "convert"); - OBD_FAIL_RETURN(OBD_FAIL_LDLM_CONVERT, 0); - rc = ldlm_handle_convert(req); - break; - case LDLM_BL_CALLBACK: - case LDLM_CP_CALLBACK: - DEBUG_REQ(D_INODE, req, "callback"); - CERROR("callbacks should not happen on MDS\n"); - LBUG(); - OBD_FAIL_RETURN(OBD_FAIL_LDLM_BL_CALLBACK, 0); - break; - default: - rc = ptlrpc_error(req->rq_svc, req); - RETURN(rc); - } - - EXIT; - - if (!rc) { - struct mds_export_data *med = &req->rq_export->exp_mds_data; - - req->rq_repmsg->last_xid = - HTON__u64(le64_to_cpu(med->med_mcd->mcd_last_xid)); - req->rq_repmsg->last_committed = - HTON__u64(mds->mds_last_committed); - CDEBUG(D_INFO, "last_rcvd ~%Lu, last_committed %Lu, xid %d\n", - (unsigned long long)mds->mds_last_rcvd, - (unsigned long long)mds->mds_last_committed, - cpu_to_le32(req->rq_xid)); - } - out: - - if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_LAST_REPLAY) { - struct mds_obd *mds = mds_req2mds(req); - LASSERT(mds->mds_recoverable_clients); - DEBUG_REQ(D_HA, req, "LAST_REPLAY, queuing reply"); - return mds_queue_final_reply(req, rc); - } - - /* MDS_CONNECT / EALREADY (note: not -EALREADY!) isn't an error */ - if (rc && (req->rq_reqmsg->opc != MDS_CONNECT || - rc != EALREADY)) { - CERROR("mds: processing error (opcode %d): %d\n", - req->rq_reqmsg->opc, rc); - ptlrpc_error(req->rq_svc, req); - } else { - CDEBUG(D_NET, "sending reply\n"); - ptlrpc_reply(req->rq_svc, req); - } - return 0; -} - -/* Update the server data on disk. This stores the new mount_count and - * also the last_rcvd value to disk. If we don't have a clean shutdown, - * then the server last_rcvd value may be less than that of the clients. - * This will alert us that we may need to do client recovery. - * - * Assumes we are already in the server filesystem context. - * - * Also assumes for mds_last_rcvd that we are not modifying it (no locking). - */ -int mds_update_server_data(struct mds_obd *mds) -{ - struct mds_server_data *msd = mds->mds_server_data; - struct file *filp = mds->mds_rcvd_filp; - loff_t off = 0; - int rc; - - msd->msd_last_rcvd = cpu_to_le64(mds->mds_last_rcvd); - msd->msd_mount_count = cpu_to_le64(mds->mds_mount_count); - - CDEBUG(D_SUPER, "MDS mount_count is %Lu, last_rcvd is %Lu\n", - (unsigned long long)mds->mds_mount_count, - (unsigned long long)mds->mds_last_rcvd); - rc = lustre_fwrite(filp, (char *)msd, sizeof(*msd), &off); - if (rc != sizeof(*msd)) { - CERROR("error writing MDS server data: rc = %d\n", rc); - if (rc > 0) - RETURN(-EIO); - RETURN(rc); - } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - rc = fsync_dev(filp->f_dentry->d_inode->i_rdev); -#else - rc = file_fsync(filp, filp->f_dentry, 1); -#endif - if (rc) - CERROR("error flushing MDS server data: rc = %d\n", rc); - - return 0; -} - -/* Do recovery actions for the MDS */ -static int mds_recovery_complete(struct obd_device *obddev) -{ - struct mds_obd *mds = &obddev->u.mds; - struct obd_run_ctxt saved; - int rc; - - LASSERT(mds->mds_recoverable_clients == 0); - - /* This happens at the end when recovery is complete */ - ++mds->mds_mount_count; - push_ctxt(&saved, &mds->mds_ctxt, NULL); - rc = mds_update_server_data(mds); - pop_ctxt(&saved, &mds->mds_ctxt, NULL); - - return rc; -} - -/* mount the file system (secretly) */ -static int mds_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct obd_ioctl_data* data = buf; - struct mds_obd *mds = &obddev->u.mds; - struct vfsmount *mnt; - int rc = 0; - ENTRY; - - MOD_INC_USE_COUNT; -#ifdef CONFIG_DEV_RDONLY - dev_clear_rdonly(2); -#endif - if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2) - GOTO(err_dec, rc = -EINVAL); - - mds->mds_fstype = strdup(data->ioc_inlbuf2); - - mnt = do_kern_mount(mds->mds_fstype, 0, data->ioc_inlbuf1, NULL); - if (IS_ERR(mnt)) { - rc = PTR_ERR(mnt); - CERROR("do_kern_mount failed: rc = %d\n", rc); - GOTO(err_kfree, rc); - } - - CERROR("%s: mnt is %p\n", data->ioc_inlbuf1, mnt); - mds->mds_sb = mnt->mnt_root->d_inode->i_sb; - if (!mds->mds_sb) - GOTO(err_put, rc = -ENODEV); - - init_MUTEX(&mds->mds_transno_sem); - mds->mds_max_mdsize = sizeof(struct lov_mds_md); - rc = mds_fs_setup(obddev, mnt); - if (rc) { - CERROR("MDS filesystem method init failed: rc = %d\n", rc); - GOTO(err_put, rc); - } - - obddev->obd_namespace = - ldlm_namespace_new("mds_server", LDLM_NAMESPACE_SERVER); - if (obddev->obd_namespace == NULL) { - mds_cleanup(obddev); - GOTO(err_fs, rc = -ENOMEM); - } - - ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL, - "mds_ldlm_client", &obddev->obd_ldlm_client); - - spin_lock_init(&mds->mds_processing_task_lock); - mds->mds_processing_task = 0; - INIT_LIST_HEAD(&mds->mds_recovery_queue); - INIT_LIST_HEAD(&mds->mds_delayed_reply_queue); - - RETURN(0); - -err_fs: - mds_fs_cleanup(obddev); -err_put: - unlock_kernel(); - mntput(mds->mds_vfsmnt); - mds->mds_sb = 0; - lock_kernel(); -err_kfree: - kfree(mds->mds_fstype); -err_dec: - MOD_DEC_USE_COUNT; - RETURN(rc); -} - -static int mds_cleanup(struct obd_device *obddev) -{ - struct super_block *sb; - struct mds_obd *mds = &obddev->u.mds; - struct obd_run_ctxt saved; - ENTRY; - - sb = mds->mds_sb; - if (!mds->mds_sb) - RETURN(0); - - push_ctxt(&saved, &mds->mds_ctxt, NULL); - mds_update_server_data(mds); - - if (mds->mds_rcvd_filp) { - int rc = filp_close(mds->mds_rcvd_filp, 0); - mds->mds_rcvd_filp = NULL; - - if (rc) - CERROR("last_rcvd file won't close, rc=%d\n", rc); - } - pop_ctxt(&saved, &mds->mds_ctxt, NULL); - - unlock_kernel(); - mntput(mds->mds_vfsmnt); - mds->mds_sb = 0; - kfree(mds->mds_fstype); - - ldlm_namespace_free(obddev->obd_namespace); - - lock_kernel(); -#ifdef CONFIG_DEV_RDONLY - dev_clear_rdonly(2); -#endif - mds_fs_cleanup(obddev); - - MOD_DEC_USE_COUNT; - RETURN(0); -} - -static int ldlm_intent_policy(struct ldlm_lock *lock, void *req_cookie, - ldlm_mode_t mode, int flags, void *data) -{ - struct ptlrpc_request *req = req_cookie; - int rc = 0; - ENTRY; - - if (!req_cookie) - RETURN(0); - - if (req->rq_reqmsg->bufcount > 1) { - /* an intent needs to be considered */ - struct ldlm_intent *it = lustre_msg_buf(req->rq_reqmsg, 1); - struct mds_obd *mds= &req->rq_export->exp_obd->u.mds; - struct mds_body *mds_rep; - struct ldlm_reply *rep; - __u64 new_resid[3] = {0, 0, 0}, old_res; - int rc, size[3] = {sizeof(struct ldlm_reply), - sizeof(struct mds_body), - mds->mds_max_mdsize}; - - it->opc = NTOH__u64(it->opc); - - LDLM_DEBUG(lock, "intent policy, opc: %s", - ldlm_it2str(it->opc)); - - rc = lustre_pack_msg(3, size, NULL, &req->rq_replen, - &req->rq_repmsg); - if (rc) { - rc = req->rq_status = -ENOMEM; - RETURN(rc); - } - - rep = lustre_msg_buf(req->rq_repmsg, 0); - rep->lock_policy_res1 = 1; - - /* execute policy */ - switch ((long)it->opc) { - case IT_CREAT|IT_OPEN: - rc = mds_reint(req, 2); - if (rc || (req->rq_status != 0 && - req->rq_status != -EEXIST)) { - rep->lock_policy_res2 = req->rq_status; - RETURN(ELDLM_LOCK_ABORTED); - } - break; - case IT_CREAT: - case IT_MKDIR: - case IT_MKNOD: - case IT_RENAME2: - case IT_LINK2: - case IT_RMDIR: - case IT_SYMLINK: - case IT_UNLINK: - rc = mds_reint(req, 2); - if (rc || (req->rq_status != 0 && - req->rq_status != -EISDIR && - req->rq_status != -ENOTDIR)) { - rep->lock_policy_res2 = req->rq_status; - RETURN(ELDLM_LOCK_ABORTED); - } - break; - case IT_GETATTR: - case IT_LOOKUP: - case IT_OPEN: - case IT_READDIR: - case IT_READLINK: - case IT_RENAME: - case IT_LINK: - case IT_SETATTR: - rc = mds_getattr_name(2, req); - /* FIXME: we need to sit down and decide on who should - * set req->rq_status, who should return negative and - * positive return values, and what they all mean. */ - if (rc || req->rq_status != 0) { - rep->lock_policy_res2 = req->rq_status; - RETURN(ELDLM_LOCK_ABORTED); - } - break; - case IT_READDIR|IT_OPEN: - LBUG(); - break; - default: - CERROR("Unhandled intent "LPD64"\n", it->opc); - LBUG(); - } - - /* We don't bother returning a lock to the client for a file - * or directory we are removing. - * - * As for link and rename, there is no reason for the client - * to get a lock on the target at this point. If they are - * going to modify the file/directory later they will get a - * lock at that time. - */ - if (it->opc & (IT_UNLINK | IT_RMDIR | IT_LINK | IT_LINK2 | - IT_RENAME | IT_RENAME2)) - RETURN(ELDLM_LOCK_ABORTED); - - rep->lock_policy_res2 = req->rq_status; - mds_rep = lustre_msg_buf(req->rq_repmsg, 1); - - /* If the client is about to open a file that doesn't have an MD - * stripe record, it's going to need a write lock. */ - if (it->opc & IT_OPEN && !(mds_rep->valid & OBD_MD_FLEASIZE)) { - LDLM_DEBUG(lock, "open with no EA; returning PW lock"); - lock->l_req_mode = LCK_PW; - } - - if (flags & LDLM_FL_INTENT_ONLY) { - LDLM_DEBUG(lock, "INTENT_ONLY, aborting lock"); - RETURN(ELDLM_LOCK_ABORTED); - } - /* Give the client a lock on the child object, instead of the - * parent that it requested. */ - new_resid[0] = NTOH__u32(mds_rep->ino); - new_resid[1] = NTOH__u32(mds_rep->generation); - if (new_resid[0] == 0) - LBUG(); - old_res = lock->l_resource->lr_name[0]; - - ldlm_lock_change_resource(lock, new_resid); - if (lock->l_resource == NULL) { - LBUG(); - RETURN(-ENOMEM); - } - LDLM_DEBUG(lock, "intent policy, old res %ld", - (long)old_res); - RETURN(ELDLM_LOCK_CHANGED); - } else { - int size = sizeof(struct ldlm_reply); - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, - &req->rq_repmsg); - if (rc) { - LBUG(); - RETURN(-ENOMEM); - } - } - RETURN(rc); -} - -int mds_attach(struct obd_device *dev, obd_count len, void *data) -{ - return lprocfs_reg_obd(dev, status_var_nm_1, dev); -} - -int mds_detach(struct obd_device *dev) -{ - return lprocfs_dereg_obd(dev); -} - -static int mdt_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - int i; - // struct obd_ioctl_data* data = buf; - struct mds_obd *mds = &obddev->u.mds; - int rc = 0; - ENTRY; - - MOD_INC_USE_COUNT; - - mds->mds_service = ptlrpc_init_svc(MDS_NEVENTS, MDS_NBUFS, - MDS_BUFSIZE, MDS_MAXREQSIZE, - MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL, - "self", mds_handle, "mds"); - if (!mds->mds_service) { - CERROR("failed to start service\n"); - GOTO(err_dec, rc = -ENOMEM); - } - - for (i = 0; i < MDT_NUM_THREADS; i++) { - char name[32]; - sprintf(name, "ll_mdt_%02d", i); - rc = ptlrpc_start_thread(obddev, mds->mds_service, name); - if (rc) { - CERROR("cannot start MDT thread #%d: rc %d\n", i, rc); - GOTO(err_thread, rc); - } - } - - RETURN(0); - -err_thread: - ptlrpc_stop_all_threads(mds->mds_service); - ptlrpc_unregister_service(mds->mds_service); -err_dec: - MOD_DEC_USE_COUNT; - RETURN(rc); -} - - -static int mdt_cleanup(struct obd_device *obddev) -{ - struct mds_obd *mds = &obddev->u.mds; - ENTRY; - - ptlrpc_stop_all_threads(mds->mds_service); - ptlrpc_unregister_service(mds->mds_service); - - MOD_DEC_USE_COUNT; - RETURN(0); -} - -extern int mds_iocontrol(unsigned int cmd, struct lustre_handle *conn, - int len, void *karg, void *uarg); - -/* use obd ops to offer management infrastructure */ -static struct obd_ops mds_obd_ops = { - o_attach: mds_attach, - o_detach: mds_detach, - o_connect: mds_connect, - o_disconnect: mds_disconnect, - o_setup: mds_setup, - o_cleanup: mds_cleanup, - o_iocontrol: mds_iocontrol -}; - -static struct obd_ops mdt_obd_ops = { - o_setup: mdt_setup, - o_cleanup: mdt_cleanup, -}; - - -static int __init mds_init(void) -{ - - mds_file_cache = kmem_cache_create("ll_mds_file_data", - sizeof(struct mds_file_data), - 0, 0, NULL, NULL); - if (mds_file_cache == NULL) - return -ENOMEM; - - class_register_type(&mds_obd_ops, status_class_var, LUSTRE_MDS_NAME); - class_register_type(&mdt_obd_ops, 0, LUSTRE_MDT_NAME); - ldlm_register_intent(ldlm_intent_policy); - return 0; - -} - -static void __exit mds_exit(void) -{ - - - ldlm_unregister_intent(); - class_unregister_type(LUSTRE_MDS_NAME); - class_unregister_type(LUSTRE_MDT_NAME); - if (kmem_cache_destroy(mds_file_cache)) - CERROR("couldn't free MDS file cache\n"); - -} - -MODULE_AUTHOR("Cluster File Systems "); -MODULE_DESCRIPTION("Lustre Metadata Server (MDS) v0.01"); -MODULE_LICENSE("GPL"); - -module_init(mds_init); -module_exit(mds_exit); diff --git a/lustre/mds/lproc_mds.c b/lustre/mds/lproc_mds.c deleted file mode 100644 index 0fc96bd..0000000 --- a/lustre/mds/lproc_mds.c +++ /dev/null @@ -1,183 +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_kbtotal(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; - __u32 blk_size; - __u64 result; - - rc = vfs_statfs(mds->mds_sb, &mystats); - if (rc) { - CERROR("mds: statfs failed: rc %d\n", rc); - return 0; - } - - blk_size = mystats.f_bsize; - blk_size >>= 10; - result = mystats.f_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 mds_obd *mds = &temp->u.mds; - struct statfs mystats; - int rc, len = 0; - __u32 blk_size; - __u64 result; - - - rc = vfs_statfs(mds->mds_sb, &mystats); - if (rc) { - CERROR("mds: statfs failed: rc %d\n", rc); - return 0; - } - blk_size = mystats.f_bsize; - blk_size >>= 10; - result = mystats.f_blocks; - while(blk_size >>= 1){ - result <<= 1; - } - 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; - struct mds_obd *mds = &temp->u.mds; - int len = 0; - len += snprintf(page, count, "%s\n", mds->mds_fstype); - return len; - -} - -int rd_filestotal(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_filesfree(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_filegroups(char* page, char **start, off_t off, int count, int *eof, - void *data) -{ - return 0; -} -struct lprocfs_vars status_var_nm_1[]={ - {"status/uuid", rd_uuid, 0, 0}, - {"status/blocksize",rd_blksize, 0, 0}, - {"status/kbytestotal",rd_kbtotal, 0, 0}, - {"status/kbytesfree", rd_kbfree, 0, 0}, - {"status/fstype", rd_fstype, 0, 0}, - {"status/filestotal", rd_filestotal, 0, 0}, - {"status/filesfree", rd_filesfree, 0, 0}, - {"status/filegroups", rd_filegroups, 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; - int len = 0; - len += snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -struct lprocfs_vars status_class_var[]={ - {"status/num_refs", rd_numrefs, 0, 0}, - {0} -}; diff --git a/lustre/mds/mds_ext2.c b/lustre/mds/mds_ext2.c deleted file mode 100644 index ef1d8e5..0000000 --- a/lustre/mds/mds_ext2.c +++ /dev/null @@ -1,145 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * linux/mds/mds_null.c - * - * Lustre Metadata Server (mds) journal abstraction routines - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * author: Andreas Dilger - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - */ - -#define DEBUG_SUBSYSTEM S_MDS - -#include -#include -#include -#include - -static void *mds_ext2_start(struct inode *inode, int nblocks) -{ - return (void *)1; -} - -static int mds_ext2_stop(struct inode *inode, void *handle) -{ - return 0; -} - -static int mds_ext2_setattr(struct dentry *dentry, void *handle, - struct iattr *iattr) -{ - struct inode *inode = dentry->d_inode; - - lock_kernel(); - - /* a _really_ horrible hack to avoid removing the data stored - in the block pointers; this data is the object id - this will go into an extended attribute at some point. - */ - if (iattr->ia_valid & ATTR_SIZE) { - /* ATTR_SIZE would invoke truncate: clear it */ - iattr->ia_valid &= ~ATTR_SIZE; - inode->i_size = iattr->ia_size; - - /* make sure _something_ gets set - so new inode - goes to disk (probably won't work over XFS */ - if (!iattr->ia_valid & ATTR_MODE) { - iattr->ia_valid |= ATTR_MODE; - iattr->ia_mode = inode->i_mode; - } - } - - if (inode->i_op->setattr) - rc = inode->i_op->setattr(dentry, iattr); - else - rc = inode_setattr(inode, iattr); - - unlock_kernel(); - - return rc; -} - -/* - * FIXME: nasty hack - store the object id in the first two - * direct block spots. This should be done with EAs... - */ -static int mds_ext2_set_objid(struct inode *inode, void *handle, obd_id id) -{ - (__u64)(inode->u.ext2_i.i_data[0]) = cpu_to_le64(id); - return 0; -} - -static int mds_ext2_get_objid(struct inode *inode, obd_id *id) -{ - *id = le64_to_cpu(inode->u.ext2_i.i_data[0]); - - return 0; -} - -static ssize_t mds_ext2_readpage(struct file *file, char *buf, size_t count, - loff_t *offset) -{ - if (S_ISREG(file->f_dentry->d_inode->i_mode)) - return file->f_op->read(file, buf, count, offset); - else - return generic_file_read(file, buf, count, offset); -} - -static struct mds_fs_operations mds_ext2_fs_ops; - -static void mds_ext2_delete_inode(struct inode *inode) -{ - if (S_ISREG(inode->i_mode)) - mds_ext2_set_objid(inode, NULL, 0); - - mds_ext2_fs_ops.cl_delete_inode(inode); -} - -static int mds_ext2_set_last_rcvd(struct mds_obd *mds, void *handle) -{ - /* Bail for ext2 - can't tell when it is on disk anyways, sync? */ - mds->mds_last_committed = mds->mds_last_rcvd; - - return 0; -} - -static int mds_ext2_journal_data(struct file *filp) -{ - return 0; -} - -static struct mds_fs_operations mds_ext2_fs_ops = { - fs_owner: THIS_MODULE, - fs_start: mds_ext2_start, - fs_commit: mds_ext2_stop, - fs_setattr: mds_ext2_setattr, - fs_set_objid: mds_ext2_set_objid, - fs_get_objid: mds_ext2_get_objid, - fs_readpage: mds_ext2_readpage, - fs_delete_inode: mds_ext2_delete_inode, - cl_delete_inode: clear_inode, - fs_journal_data: mds_ext2_journal_data, - fs_set_last_rcvd: mds_ext2_set_last_rcvd, -}; - -static int __init mds_ext2_init(void) -{ - return mds_register_fs_type(&mds_ext2_fs_ops, "ext2"); -} - -static void __exit mds_ext2_exit(void) -{ - mds_unregister_fs_type("ext2"); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre MDS ext2 Filesystem Helper v0.1"); -MODULE_LICENSE("GPL"); - -module_init(mds_ext2_init); -module_exit(mds_ext2_exit); diff --git a/lustre/mds/mds_ext3.c b/lustre/mds/mds_ext3.c deleted file mode 100644 index 4fb5756..0000000 --- a/lustre/mds/mds_ext3.c +++ /dev/null @@ -1,357 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/mds/mds_ext3.c - * Lustre Metadata Server (mds) journal 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_MDS - -#include -#include -#include -#include -#include -#include -#include <../fs/ext3/xattr.h> -#include -#include -#include -#include - -static struct mds_fs_operations mds_ext3_fs_ops; -static kmem_cache_t *mcb_cache; -static int mcb_cache_count; - -struct mds_cb_data { - struct journal_callback cb_jcb; - struct mds_obd *cb_mds; - __u64 cb_last_rcvd; -}; - -#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 *mds_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 MDS_FSOP_RMDIR: - case MDS_FSOP_UNLINK: - nblocks += EXT3_DELETE_TRANS_BLOCKS; - break; - case MDS_FSOP_RENAME: - /* We may be modifying two directories */ - nblocks += EXT3_DATA_TRANS_BLOCKS; - case MDS_FSOP_SYMLINK: - /* Possible new block + block bitmap + GDT for long symlink */ - nblocks += 3; - case MDS_FSOP_CREATE: - case MDS_FSOP_MKDIR: - case MDS_FSOP_MKNOD: - /* New inode + block bitmap + GDT for new file */ - nblocks += 3; - case MDS_FSOP_LINK: - /* Change parent directory */ - nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS+EXT3_DATA_TRANS_BLOCKS; - break; - case MDS_FSOP_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 mds_ext3_commit(struct inode *inode, void *handle) -{ - int rc; - - lock_kernel(); - rc = journal_stop((handle_t *)handle); - unlock_kernel(); - - return rc; -} - -static int mds_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 mds_ext3_set_md(struct inode *inode, void *handle, - struct lov_mds_md *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 objectid "LPX64" to inode %ld: %d\n", - lmm->lmm_object_id, inode->i_ino, rc); - if (rc != -ENOSPC) LBUG(); - } - return rc; -} - -static int mds_ext3_get_md(struct inode *inode, struct lov_mds_md *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 MDS inode %ld: " - "rc = %d\n", XATTR_LUSTRE_MDS_OBJID, inode->i_ino, rc); - memset(lmm, 0, size); - return (rc == -ENODATA) ? 0 : rc; - } - - /* This field is byteswapped because it appears in the - * catalogue. All others are opaque to the MDS */ - lmm->lmm_object_id = le64_to_cpu(lmm->lmm_object_id); - - return rc; -} - -static ssize_t mds_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 mds_ext3_delete_inode(struct inode *inode) -{ - if (S_ISREG(inode->i_mode)) { - void *handle = mds_ext3_start(inode, MDS_FSOP_UNLINK); - - if (IS_ERR(handle)) { - CERROR("unable to start transaction"); - EXIT; - return; - } - if (mds_ext3_set_md(inode, handle, NULL, 0)) - CERROR("error clearing objid on %ld\n", inode->i_ino); - - if (mds_ext3_fs_ops.cl_delete_inode) - mds_ext3_fs_ops.cl_delete_inode(inode); - - if (mds_ext3_commit(inode, handle)) - CERROR("error closing handle on %ld\n", inode->i_ino); - } else - mds_ext3_fs_ops.cl_delete_inode(inode); -} - -static void mds_ext3_callback_status(struct journal_callback *jcb, int error) -{ - struct mds_cb_data *mcb = (struct mds_cb_data *)jcb; - - CDEBUG(D_EXT2, "got callback for last_rcvd "LPD64": rc = %d\n", - mcb->cb_last_rcvd, error); - if (!error && mcb->cb_last_rcvd > mcb->cb_mds->mds_last_committed) - mcb->cb_mds->mds_last_committed = mcb->cb_last_rcvd; - - kmem_cache_free(mcb_cache, mcb); - --mcb_cache_count; -} - -static int mds_ext3_set_last_rcvd(struct mds_obd *mds, void *handle) -{ - struct mds_cb_data *mcb; - - mcb = kmem_cache_alloc(mcb_cache, GFP_NOFS); - if (!mcb) - RETURN(-ENOMEM); - - ++mcb_cache_count; - mcb->cb_mds = mds; - mcb->cb_last_rcvd = mds->mds_last_rcvd; - -#ifdef HAVE_JOURNAL_CALLBACK_STATUS - CDEBUG(D_EXT2, "set callback for last_rcvd: "LPD64"\n", - mcb->cb_last_rcvd); - lock_kernel(); - /* Note that an "incompatible pointer" warning here is OK for now */ - journal_callback_set(handle, mds_ext3_callback_status, - (struct journal_callback *)mcb); - 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; - } - - mds_ext3_callback_status((struct journal_callback *)mcb, 0); -#endif - - return 0; -} - -static int mds_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 mds_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 mds_fs_operations mds_ext3_fs_ops = { - fs_owner: THIS_MODULE, - fs_start: mds_ext3_start, - fs_commit: mds_ext3_commit, - fs_setattr: mds_ext3_setattr, - fs_set_md: mds_ext3_set_md, - fs_get_md: mds_ext3_get_md, - fs_readpage: mds_ext3_readpage, - fs_delete_inode: mds_ext3_delete_inode, - cl_delete_inode: clear_inode, - fs_journal_data: mds_ext3_journal_data, - fs_set_last_rcvd: mds_ext3_set_last_rcvd, - fs_statfs: mds_ext3_statfs, -}; - -static int __init mds_ext3_init(void) -{ - int rc; - - //rc = ext3_xattr_register(); - mcb_cache = kmem_cache_create("mds_ext3_mcb", - sizeof(struct mds_cb_data), 0, - 0, NULL, NULL); - if (!mcb_cache) { - CERROR("error allocating MDS journal callback cache\n"); - GOTO(out, rc = -ENOMEM); - } - - rc = mds_register_fs_type(&mds_ext3_fs_ops, "ext3"); - - if (rc) - kmem_cache_destroy(mcb_cache); -out: - return rc; -} - -static void __exit mds_ext3_exit(void) -{ - int rc; - - mds_unregister_fs_type("ext3"); - rc = kmem_cache_destroy(mcb_cache); - - if (rc || mcb_cache_count) { - CERROR("can't free MDS callback cache: count %d, rc = %d\n", - mcb_cache_count, rc); - } - - //rc = ext3_xattr_unregister(); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre MDS ext3 Filesystem Helper v0.1"); -MODULE_LICENSE("GPL"); - -module_init(mds_ext3_init); -module_exit(mds_ext3_exit); diff --git a/lustre/mds/mds_extN.c b/lustre/mds/mds_extN.c deleted file mode 100644 index 8368573..0000000 --- a/lustre/mds/mds_extN.c +++ /dev/null @@ -1,356 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/mds/mds_extN.c - * Lustre Metadata Server (mds) journal 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_MDS - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct mds_fs_operations mds_extN_fs_ops; -static kmem_cache_t *mcb_cache; -static int mcb_cache_count; - -struct mds_cb_data { - struct journal_callback cb_jcb; - struct mds_obd *cb_mds; - __u64 cb_last_rcvd; -}; - -#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 *mds_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 MDS_FSOP_RMDIR: - case MDS_FSOP_UNLINK: - nblocks += EXTN_DELETE_TRANS_BLOCKS; - break; - case MDS_FSOP_RENAME: - /* We may be modifying two directories */ - nblocks += EXTN_DATA_TRANS_BLOCKS; - case MDS_FSOP_SYMLINK: - /* Possible new block + block bitmap + GDT for long symlink */ - nblocks += 3; - case MDS_FSOP_CREATE: - case MDS_FSOP_MKDIR: - case MDS_FSOP_MKNOD: - /* New inode + block bitmap + GDT for new file */ - nblocks += 3; - case MDS_FSOP_LINK: - /* Change parent directory */ - nblocks += EXTN_INDEX_EXTRA_TRANS_BLOCKS+EXTN_DATA_TRANS_BLOCKS; - break; - case MDS_FSOP_SETATTR: - /* Setattr on inode */ - nblocks += 1; - break; - default: CERROR("unknown transaction start op %d\n", op); - LBUG(); - } - - lock_kernel(); - handle = journal_start(EXTN_JOURNAL(inode), nblocks); - unlock_kernel(); - - return handle; -} - -static int mds_extN_commit(struct inode *inode, void *handle) -{ - int rc; - - lock_kernel(); - rc = journal_stop((handle_t *)handle); - unlock_kernel(); - - return rc; -} - -static int mds_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 mds_extN_set_md(struct inode *inode, void *handle, - struct lov_mds_md *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 objectid "LPX64" to inode %ld: %d\n", - lmm->lmm_object_id, inode->i_ino, rc); - if (rc != -ENOSPC) LBUG(); - } - return rc; -} - -static int mds_extN_get_md(struct inode *inode, struct lov_mds_md *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 MDS inode %ld: " - "rc = %d\n", XATTR_LUSTRE_MDS_OBJID, inode->i_ino, rc); - memset(lmm, 0, size); - return (rc == -ENODATA) ? 0 : rc; - } - - /* This field is byteswapped because it appears in the - * catalogue. All others are opaque to the MDS */ - lmm->lmm_object_id = le64_to_cpu(lmm->lmm_object_id); - - return rc; -} - -static ssize_t mds_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 mds_extN_delete_inode(struct inode *inode) -{ - if (S_ISREG(inode->i_mode)) { - void *handle = mds_extN_start(inode, MDS_FSOP_UNLINK); - - if (IS_ERR(handle)) { - CERROR("unable to start transaction"); - EXIT; - return; - } - if (mds_extN_set_md(inode, handle, NULL, 0)) - CERROR("error clearing objid on %ld\n", inode->i_ino); - - if (mds_extN_fs_ops.cl_delete_inode) - mds_extN_fs_ops.cl_delete_inode(inode); - - if (mds_extN_commit(inode, handle)) - CERROR("error closing handle on %ld\n", inode->i_ino); - } else - mds_extN_fs_ops.cl_delete_inode(inode); -} - -static void mds_extN_callback_status(struct journal_callback *jcb, int error) -{ - struct mds_cb_data *mcb = (struct mds_cb_data *)jcb; - - CDEBUG(D_EXT2, "got callback for last_rcvd "LPD64": rc = %d\n", - mcb->cb_last_rcvd, error); - if (!error && mcb->cb_last_rcvd > mcb->cb_mds->mds_last_committed) - mcb->cb_mds->mds_last_committed = mcb->cb_last_rcvd; - - kmem_cache_free(mcb_cache, mcb); - --mcb_cache_count; -} - -static int mds_extN_set_last_rcvd(struct mds_obd *mds, void *handle) -{ - struct mds_cb_data *mcb; - - mcb = kmem_cache_alloc(mcb_cache, GFP_NOFS); - if (!mcb) - RETURN(-ENOMEM); - - ++mcb_cache_count; - mcb->cb_mds = mds; - mcb->cb_last_rcvd = mds->mds_last_rcvd; - -#ifdef HAVE_JOURNAL_CALLBACK_STATUS - CDEBUG(D_EXT2, "set callback for last_rcvd: "LPD64"\n", - mcb->cb_last_rcvd); - lock_kernel(); - /* Note that an "incompatible pointer" warning here is OK for now */ - journal_callback_set(handle, mds_extN_callback_status, - (struct journal_callback *)mcb); - 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; - } - - mds_extN_callback_status((struct journal_callback *)mcb, 0); -#endif - - return 0; -} - -static int mds_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 mds_extN_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 mds_fs_operations mds_extN_fs_ops = { - fs_owner: THIS_MODULE, - fs_start: mds_extN_start, - fs_commit: mds_extN_commit, - fs_setattr: mds_extN_setattr, - fs_set_md: mds_extN_set_md, - fs_get_md: mds_extN_get_md, - fs_readpage: mds_extN_readpage, - fs_delete_inode: mds_extN_delete_inode, - cl_delete_inode: clear_inode, - fs_journal_data: mds_extN_journal_data, - fs_set_last_rcvd: mds_extN_set_last_rcvd, - fs_statfs: mds_extN_statfs, -}; - -static int __init mds_extN_init(void) -{ - int rc; - - //rc = extN_xattr_register(); - mcb_cache = kmem_cache_create("mds_extN_mcb", - sizeof(struct mds_cb_data), 0, - 0, NULL, NULL); - if (!mcb_cache) { - CERROR("error allocating MDS journal callback cache\n"); - GOTO(out, rc = -ENOMEM); - } - - rc = mds_register_fs_type(&mds_extN_fs_ops, "extN"); - - if (rc) - kmem_cache_destroy(mcb_cache); -out: - return rc; -} - -static void __exit mds_extN_exit(void) -{ - int rc; - - mds_unregister_fs_type("extN"); - rc = kmem_cache_destroy(mcb_cache); - - if (rc || mcb_cache_count) { - CERROR("can't free MDS callback cache: count %d, rc = %d\n", - mcb_cache_count, rc); - } - - //rc = extN_xattr_unregister(); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre MDS extN Filesystem Helper v0.1"); -MODULE_LICENSE("GPL"); - -module_init(mds_extN_init); -module_exit(mds_extN_exit); diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c deleted file mode 100644 index 163a45f..0000000 --- a/lustre/mds/mds_fs.c +++ /dev/null @@ -1,513 +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 -#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 limit is arbitrary, but for now we fit it in 1 page (32k clients) */ -#define MDS_MAX_CLIENTS (PAGE_SIZE * 8) -#define MDS_MAX_CLIENT_WORDS (MDS_MAX_CLIENTS / sizeof(unsigned long)) - -static unsigned long last_rcvd_slots[MDS_MAX_CLIENT_WORDS]; - -#define LAST_RCVD "last_rcvd" - -/* Add client data to the MDS. 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_export_data *med, int cl_off) -{ - int new_client = (cl_off == -1); - - /* the bitmap operations can handle cl_off > sizeof(long) * 8, so - * there's no need for extra complication here - */ - if (new_client) { - cl_off = find_first_zero_bit(last_rcvd_slots, MDS_MAX_CLIENTS); - repeat: - if (cl_off >= MDS_MAX_CLIENTS) { - CERROR("no room for clients - fix MDS_MAX_CLIENTS\n"); - return -ENOMEM; - } - if (test_and_set_bit(cl_off, last_rcvd_slots)) { - CERROR("MDS client %d: found bit is set in bitmap\n", - cl_off); - cl_off = find_next_zero_bit(last_rcvd_slots, - MDS_MAX_CLIENTS, cl_off); - goto repeat; - } - } else { - if (test_and_set_bit(cl_off, last_rcvd_slots)) { - CERROR("MDS client %d: bit already set in bitmap!!\n", - cl_off); - LBUG(); - } - } - - CDEBUG(D_INFO, "client at offset %d with UUID '%s' added\n", - cl_off, med->med_mcd->mcd_uuid); - - med->med_off = cl_off; - - if (new_client) { - struct obd_run_ctxt saved; - loff_t off = MDS_LR_CLIENT + (cl_off * MDS_LR_SIZE); - ssize_t written; - - push_ctxt(&saved, &mds->mds_ctxt, NULL); - written = lustre_fwrite(mds->mds_rcvd_filp, - (char *)med->med_mcd, - sizeof(*med->med_mcd), &off); - pop_ctxt(&saved, &mds->mds_ctxt, NULL); - - if (written != sizeof(*med->med_mcd)) { - if (written < 0) - RETURN(written); - RETURN(-EIO); - } - } - return 0; -} - -int mds_client_free(struct obd_export *exp) -{ - struct mds_export_data *med = &exp->exp_mds_data; - struct mds_obd *mds = &exp->exp_obd->u.mds; - struct mds_client_data zero_mcd; - struct obd_run_ctxt saved; - int written; - loff_t off; - - if (!med->med_mcd) - RETURN(0); - - CDEBUG(D_INFO, "freeing client at offset %d with UUID '%s'\n", - med->med_off, med->med_mcd->mcd_uuid); - - if (!test_and_clear_bit(med->med_off, last_rcvd_slots)) { - CERROR("MDS client %d: bit already clear in bitmap!!\n", - med->med_off); - LBUG(); - } - - off = med->med_off; - - memset(&zero_mcd, 0, sizeof zero_mcd); - push_ctxt(&saved, &mds->mds_ctxt, NULL); - written = lustre_fwrite(mds->mds_rcvd_filp, (const char *)&zero_mcd, - sizeof zero_mcd, &off); - pop_ctxt(&saved, &mds->mds_ctxt, NULL); - - if (written != sizeof zero_mcd) { - CERROR("error zeroing out client %s off %d in %s: %d\n", - med->med_mcd->mcd_uuid, med->med_off, LAST_RCVD, - written); - LBUG(); - } else { - CDEBUG(D_INFO, "zeroed out disconnecting client %s at off %d\n", - med->med_mcd->mcd_uuid, med->med_off); - } - - OBD_FREE(med->med_mcd, sizeof(*med->med_mcd)); - - 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; -} - -static int mds_read_last_rcvd(struct obd_device *obddev, struct file *f) -{ - struct mds_obd *mds = &obddev->u.mds; - struct mds_server_data *msd; - struct mds_client_data *mcd = NULL; - loff_t off = 0; - int cl_off; - int max_off = f->f_dentry->d_inode->i_size / sizeof(*mcd); - __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); - } - - 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; - off < max_off; - off += MDS_LR_SIZE, cl_off++) { - int mount_age; - - 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; - } - - if (mcd->mcd_uuid[0] == '\0') { - CDEBUG(D_INFO, "skipping zeroed client at offset %d\n", - cl_off); - continue; - } - - last_rcvd = le64_to_cpu(mcd->mcd_last_rcvd); - - /* The exports are cleaned up by mds_disconnect, so they - * need to be set up like real exports also. - */ - mount_age = last_mount - le64_to_cpu(mcd->mcd_mount_count); - if (last_rcvd && mount_age < MDS_MOUNT_RECOV) { - struct obd_export *exp = class_new_export(obddev); - struct mds_export_data *med; - - if (!exp) { - rc = -ENOMEM; - break; - } - - med = &exp->exp_mds_data; - med->med_mcd = mcd; - mds_client_add(mds, med, cl_off); - /* XXX put this in a helper if it gets more complex */ - INIT_LIST_HEAD(&med->med_open_head); - spin_lock_init(&med->med_open_lock); - - mcd = NULL; - mds->mds_recoverable_clients++; - MOD_INC_USE_COUNT; - } else { - CDEBUG(D_INFO, - "discarded client %d, UUID '%s', count %Ld\n", - cl_off, mcd->mcd_uuid, - (long long)le64_to_cpu(mcd->mcd_mount_count)); - } - - 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; - } - } - - mds->mds_last_committed = mds->mds_last_rcvd; - if (mds->mds_recoverable_clients) { - CERROR("need recovery: %d recoverable clients, last_rcvd %Lu\n", - mds->mds_recoverable_clients, mds->mds_last_rcvd); - } - - if (mcd) - OBD_FREE(mcd, sizeof(*mcd)); - - return 0; - -err_msd: - mds_server_free_data(mds); - return rc; -} - -static int mds_fs_prep(struct obd_device *obddev) -{ - struct mds_obd *mds = &obddev->u.mds; - struct obd_run_ctxt saved; - struct dentry *dentry; - struct file *f; - int rc; - - push_ctxt(&saved, &mds->mds_ctxt, NULL); - 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); - } - - mds->mds_rootfid.id = dentry->d_inode->i_ino; - mds->mds_rootfid.generation = dentry->d_inode->i_generation; - mds->mds_rootfid.f_type = S_IFDIR; - - dput(dentry); - - 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); - - 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(obddev, f); - if (rc) { - CERROR("cannot read %s: rc = %d\n", LAST_RCVD, rc); - GOTO(err_client, rc); - } - mds->mds_rcvd_filp = f; -err_pop: - pop_ctxt(&saved, &mds->mds_ctxt, NULL); - - return rc; - -err_client: - class_disconnect_all(obddev); -err_filp: - if (filp_close(f, 0)) - CERROR("can't close %s after error\n", LAST_RCVD); - goto err_pop; -} - -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 */ -} - -struct mds_fs_operations *mds_fs_get_ops(char *fstype) -{ - struct mds_fs_operations *fs_ops; - - if (!(fs_ops = mds_search_fs_type(fstype))) { - char name[32]; - int rc; - - snprintf(name, sizeof(name) - 1, "mds_%s", fstype); - name[sizeof(name) - 1] = '\0'; - - if ((rc = request_module(name))) { - fs_ops = mds_search_fs_type(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(ERR_PTR(rc)); - } - } - __MOD_INC_USE_COUNT(fs_ops->fs_owner); - - return fs_ops; -} - -void mds_fs_put_ops(struct mds_fs_operations *fs_ops) -{ - __MOD_DEC_USE_COUNT(fs_ops->fs_owner); -} - -int mds_fs_setup(struct obd_device *obddev, struct vfsmount *mnt) -{ - struct mds_obd *mds = &obddev->u.mds; - int rc; - - mds->mds_fsops = mds_fs_get_ops(mds->mds_fstype); - if (IS_ERR(mds->mds_fsops)) - RETURN(PTR_ERR(mds->mds_fsops)); - - mds->mds_vfsmnt = mnt; - - OBD_SET_CTXT_MAGIC(&mds->mds_ctxt); - mds->mds_ctxt.pwdmnt = mnt; - mds->mds_ctxt.pwd = mnt->mnt_root; - mds->mds_ctxt.fs = get_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) - GOTO(out_dec, rc = -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(obddev); - - if (rc) - GOTO(out_free, rc); - - return 0; - -out_free: - OBD_FREE(mds->mds_sop, sizeof(*mds->mds_sop)); -out_dec: - mds_fs_put_ops(mds->mds_fsops); - return rc; -} - -void mds_fs_cleanup(struct obd_device *obddev) -{ - struct mds_obd *mds = &obddev->u.mds; - - class_disconnect_all(obddev); /* this cleans up client info too */ - mds_server_free_data(mds); - - OBD_FREE(mds->mds_sop, sizeof(*mds->mds_sop)); - mds_fs_put_ops(mds->mds_fsops); -} - -EXPORT_SYMBOL(mds_register_fs_type); -EXPORT_SYMBOL(mds_unregister_fs_type); diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c deleted file mode 100644 index ba9a750..0000000 --- a/lustre/mds/mds_lov.c +++ /dev/null @@ -1,211 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * linux/mds/mds_lov.c - * - * Lustre Metadata Server (mds) handling of striped file data - * - * 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_MDS - -#include -#include -#include -#include -#include -#include - -/* lov_unpackdesc() is in lov/lov_pack.c */ - -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); -} - -int mds_set_lovdesc(struct obd_device *obd, struct lov_desc *desc, - obd_uuid_t *uuidarray) -{ - struct mds_obd *mds = &obd->u.mds; - struct obd_run_ctxt saved; - struct file *f; - int tgt_count; - int rc; - int i; - ENTRY; - - tgt_count = desc->ld_tgt_count; - lov_packdesc(desc); - - push_ctxt(&saved, &mds->mds_ctxt, NULL); - f = filp_open("LOVDESC", O_CREAT|O_RDWR, 0644); - if (IS_ERR(f)) { - CERROR("Cannot open/create LOVDESC file\n"); - GOTO(out, rc = PTR_ERR(f)); - } - - rc = lustre_fwrite(f, (char *)desc, sizeof(*desc), &f->f_pos); - if (filp_close(f, 0)) - CERROR("Error closing LOVDESC file\n"); - if (rc != sizeof(*desc)) { - CERROR("Cannot open/create LOVDESC file\n"); - GOTO(out, rc = PTR_ERR(f)); - } - - f = filp_open("LOVTGTS", O_CREAT|O_RDWR, 0644); - if (IS_ERR(f)) { - CERROR("Cannot open/create LOVTGTS file\n"); - GOTO(out, rc = PTR_ERR(f)); - } - - rc = 0; - for (i = 0; i < tgt_count ; i++) { - rc = lustre_fwrite(f, uuidarray[i], - sizeof(uuidarray[i]), &f->f_pos); - if (rc != sizeof(uuidarray[i])) { - CERROR("cannot write LOV UUID %s (%d)\n", - uuidarray[i], i); - if (rc >= 0) - rc = -EIO; - break; - } else - rc = 0; - } - if (filp_close(f, 0)) - CERROR("Error closing LOVTGTS file\n"); - -out: - pop_ctxt(&saved, &mds->mds_ctxt, NULL); - RETURN(rc); -} - -int mds_get_lovdesc(struct mds_obd *mds, struct lov_desc *desc) -{ - struct obd_run_ctxt saved; - struct file *f; - int rc; - ENTRY; - - push_ctxt(&saved, &mds->mds_ctxt, NULL); - f = filp_open("LOVDESC", O_RDONLY, 0644); - if (IS_ERR(f)) { - CERROR("Cannot open LOVDESC file\n"); - GOTO(out, rc = PTR_ERR(f)); - } - - rc = lustre_fread(f, (char *)desc, sizeof(*desc), &f->f_pos); - if (filp_close(f, 0)) - CERROR("Error closing LOVDESC file\n"); - - if (rc != sizeof(*desc)) { - CERROR("Cannot read LOVDESC file: rc = %d\n", rc); - GOTO(out, rc = -EIO); - } else - rc = 0; - EXIT; -out: - pop_ctxt(&saved, &mds->mds_ctxt, NULL); - - return rc; -} - -int mds_get_lovtgts(struct mds_obd *mds, int tgt_count,obd_uuid_t *uuidarray) -{ - struct obd_run_ctxt saved; - struct file *f; - int rc; - int rc2; - - push_ctxt(&saved, &mds->mds_ctxt, NULL); - f = filp_open("LOVTGTS", O_RDONLY, 0644); - if (IS_ERR(f)) { - CERROR("Cannot open LOVTGTS file\n"); - GOTO(out, rc = PTR_ERR(f)); - } - - rc = lustre_fread(f, (char *)uuidarray, tgt_count * sizeof(*uuidarray), - &f->f_pos); - rc2 = filp_close(f, 0); - if (rc2) - CERROR("Error closing LOVTGTS file: rc = %d\n", rc2); - - if (rc != tgt_count * sizeof(*uuidarray)) { - CERROR("Error reading LOVTGTS file: rc = %d\n", rc); - if (rc >= 0) - rc = -EIO; - GOTO(out, rc); - } else - rc = 0; - EXIT; -out: - pop_ctxt(&saved, &mds->mds_ctxt, NULL); - - RETURN(rc); -} - -int mds_iocontrol(unsigned int cmd, struct lustre_handle *conn, - int len, void *karg, void *uarg) -{ - struct obd_device *obd = class_conn2obd(conn); - struct obd_ioctl_data *data = karg; - struct lov_desc *desc; - obd_uuid_t *uuidarray; - int count; - int rc; - - - switch (cmd) { - case OBD_IOC_LOV_SET_CONFIG: - desc = (struct lov_desc *)data->ioc_inlbuf1; - if (sizeof(*desc) > data->ioc_inllen1) { - CERROR("descriptor size wrong\n"); - RETURN(-EINVAL); - } - - count = desc->ld_tgt_count; - uuidarray = (obd_uuid_t *)data->ioc_inlbuf2; - if (sizeof(*uuidarray) * count != data->ioc_inllen2) { - CERROR("UUID array size wrong\n"); - RETURN(-EINVAL); - } - rc = mds_set_lovdesc(obd, desc, uuidarray); - - RETURN(rc); - case OBD_IOC_LOV_GET_CONFIG: - desc = (struct lov_desc *)data->ioc_inlbuf1; - if (sizeof(*desc) > data->ioc_inllen1) { - CERROR("descriptor size wrong\n"); - RETURN(-EINVAL); - } - - count = desc->ld_tgt_count; - uuidarray = (obd_uuid_t *)data->ioc_inlbuf2; - if (sizeof(*uuidarray) * count != data->ioc_inllen2) { - CERROR("UUID array size wrong\n"); - RETURN(-EINVAL); - } - rc = mds_get_lovdesc(&obd->u.mds, desc); - if (desc->ld_tgt_count > count) { - CERROR("UUID array size too small\n"); - RETURN(-ENOSPC); - } - rc = mds_get_lovtgts(&obd->u.mds, desc->ld_tgt_count, uuidarray); - - RETURN(rc); - default: - RETURN(-EINVAL); - } - - RETURN(0); -} diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c deleted file mode 100644 index 5ac6e6e..0000000 --- a/lustre/mds/mds_reint.c +++ /dev/null @@ -1,867 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * linux/mds/mds_reint.c - * Lustre Metadata Server (mds) reintegration routines - * - * 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. - * - * Author: Peter Braam - * Author: Andreas Dilger - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_MDS - -#include -#include -#include -#include -#include -#include -#include -#include - -extern inline struct mds_obd *mds_req2mds(struct ptlrpc_request *req); - -void mds_start_transno(struct mds_obd *mds) -{ - ENTRY; - down(&mds->mds_transno_sem); -} - -/* Assumes caller has already pushed us into the kernel context. */ -int mds_finish_transno(struct mds_obd *mds, void *handle, - struct ptlrpc_request *req, int rc) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_client_data *mcd = med->med_mcd; - __u64 last_rcvd; - loff_t off; - ssize_t written; - - /* Propagate error code. */ - if (rc) - goto out; - - /* we don't allocate new transnos for replayed requests */ - if (req->rq_level == LUSTRE_CONN_RECOVD) { - rc = 0; - goto out; - } - - off = MDS_LR_CLIENT + med->med_off * MDS_LR_SIZE; - - last_rcvd = ++mds->mds_last_rcvd; - req->rq_repmsg->transno = HTON__u64(last_rcvd); - mcd->mcd_last_rcvd = cpu_to_le64(last_rcvd); - mcd->mcd_mount_count = cpu_to_le64(mds->mds_mount_count); - mcd->mcd_last_xid = cpu_to_le64(req->rq_xid); - - mds_fs_set_last_rcvd(mds, handle); - written = lustre_fwrite(mds->mds_rcvd_filp, (char *)mcd, sizeof(*mcd), - &off); - CDEBUG(D_INODE, "wrote trans #"LPD64" for client %s at #%d: written = " - "%d\n", last_rcvd, mcd->mcd_uuid, med->med_off, written); - - if (written == sizeof(*mcd)) - GOTO(out, rc = 0); - CERROR("error writing to last_rcvd file: rc = %d\n", rc); - if (written >= 0) - GOTO(out, rc = -EIO); - - rc = 0; - - out: - EXIT; - up(&mds->mds_transno_sem); - return rc; -} - -/* In the write-back case, the client holds a lock on a subtree. - * In the intent case, the client holds a lock on the child inode. - * In the pathname case, the client (may) hold a lock on the child inode. */ -static int mds_reint_setattr(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req) -{ - struct mds_obd *mds = mds_req2mds(req); - struct obd_device *obd = req->rq_export->exp_obd; - struct mds_body *body; - struct dentry *de; - struct inode *inode; - void *handle; - struct lustre_handle child_lockh; - int rc = 0, err; - - if (req->rq_reqmsg->bufcount > offset + 1) { - struct dentry *dir; - struct lustre_handle dir_lockh; - char *name; - int namelen; - - /* a name was supplied by the client; fid1 is the directory */ - dir = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, LCK_PR, - &dir_lockh); - if (IS_ERR(dir)) { - LBUG(); - GOTO(out_setattr, rc = PTR_ERR(dir)); - } - - name = lustre_msg_buf(req->rq_reqmsg, offset + 1); - namelen = req->rq_reqmsg->buflens[offset + 1] - 1; - de = mds_name2locked_dentry(obd, dir, NULL, name, namelen, - 0, &child_lockh, LCK_PR); - l_dput(dir); - if (IS_ERR(de)) { - LBUG(); - GOTO(out_setattr_de, rc = PTR_ERR(de)); - } - } else { - de = mds_fid2dentry(mds, rec->ur_fid1, NULL); - if (!de || IS_ERR(de)) { - GOTO(out_setattr_de, rc = PTR_ERR(de)); - } - } - inode = de->d_inode; - CDEBUG(D_INODE, "ino %ld\n", inode->i_ino); - - OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_SETATTR_WRITE, - to_kdev_t(inode->i_sb->s_dev)); - - mds_start_transno(mds); - handle = mds_fs_start(mds, inode, MDS_FSOP_SETATTR); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - (void)mds_finish_transno(mds, handle, req, rc); - GOTO(out_setattr_de, rc); - } - - rc = mds_fs_setattr(mds, de, handle, &rec->ur_iattr); - - if (offset) { - body = lustre_msg_buf(req->rq_repmsg, 1); - mds_pack_inode2fid(&body->fid1, inode); - mds_pack_inode2body(body, inode); - } - - rc = mds_finish_transno(mds, handle, req, rc); - - err = mds_fs_commit(mds, de->d_inode, handle); - if (err) { - CERROR("error on commit: err = %d\n", err); - if (!rc) - rc = err; - } - - EXIT; -out_setattr_de: - l_dput(de); -out_setattr: - req->rq_status = rc; - return 0; -} - -static int mds_reint_create(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req) -{ - struct dentry *de = NULL; - struct mds_obd *mds = mds_req2mds(req); - struct obd_device *obd = req->rq_export->exp_obd; - struct dentry *dchild = NULL; - struct inode *dir; - void *handle; - struct lustre_handle lockh; - int rc = 0, err, lock_mode, type = rec->ur_mode & S_IFMT; - ENTRY; - - /* requests were at offset 2, replies go back at 1 */ - if (offset) - offset = 1; - - LASSERT(!strcmp(req->rq_export->exp_obd->obd_type->typ_name, "mds")); - - lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_CW : LCK_PW; - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_CREATE)) - GOTO(out_create, rc = -ESTALE); - - de = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, lock_mode, &lockh); - if (IS_ERR(de)) { - rc = PTR_ERR(de); - CERROR("parent lookup error %d\n", rc); - LBUG(); - GOTO(out_create, rc); - } - dir = de->d_inode; - CDEBUG(D_INODE, "parent ino %ld name %s mode %o\n", - dir->i_ino, rec->ur_name, rec->ur_mode); - - ldlm_lock_dump((void *)(unsigned long)lockh.addr); - - down(&dir->i_sem); - dchild = lookup_one_len(rec->ur_name, de, rec->ur_namelen - 1); - if (IS_ERR(dchild)) { - CERROR("child lookup error %ld\n", PTR_ERR(dchild)); - LBUG(); - GOTO(out_create_de, rc = -ESTALE); - } - - if (dchild->d_inode) { - struct mds_body *body; - struct inode *inode = dchild->d_inode; - - CDEBUG(D_INODE, "child exists (dir %ld, name %s, ino %ld)\n", - dir->i_ino, rec->ur_name, dchild->d_inode->i_ino); - - /* XXX check that mode is correct? */ - - body = lustre_msg_buf(req->rq_repmsg, offset); - mds_pack_inode2fid(&body->fid1, inode); - mds_pack_inode2body(body, inode); - if (S_ISREG(inode->i_mode)) - mds_pack_md(mds, req, offset + 1, body, inode); - - /* This isn't an error for RECREATE. */ - if (rec->ur_opcode & REINT_REPLAYING) { - CDEBUG(D_INODE, "EEXIST suppressed for REPLAYING\n"); - rc = 0; - } else { - rc = -EEXIST; - } - GOTO(out_create_dchild, rc); - } - - OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_CREATE_WRITE, - to_kdev_t(dir->i_sb->s_dev)); - - if (dir->i_mode & S_ISGID) { - rec->ur_gid = dir->i_gid; - if (S_ISDIR(rec->ur_mode)) - rec->ur_mode |= S_ISGID; - } - - /* From here on, we must exit via a path that calls mds_finish_transno, - * so that we release the mds_transno_sem (and, in the case of success, - * update the transno correctly). out_create_commit and - * out_transno_dchild are good candidates. - */ - mds_start_transno(mds); - - switch (type) { - case S_IFREG:{ - handle = mds_fs_start(mds, dir, MDS_FSOP_CREATE); - if (IS_ERR(handle)) - GOTO(out_transno_dchild, rc = PTR_ERR(handle)); - rc = vfs_create(dir, dchild, rec->ur_mode); - EXIT; - break; - } - case S_IFDIR:{ - handle = mds_fs_start(mds, dir, MDS_FSOP_MKDIR); - if (IS_ERR(handle)) - GOTO(out_transno_dchild, rc = PTR_ERR(handle)); - rc = vfs_mkdir(dir, dchild, rec->ur_mode); - EXIT; - break; - } - case S_IFLNK:{ - handle = mds_fs_start(mds, dir, MDS_FSOP_SYMLINK); - if (IS_ERR(handle)) - GOTO(out_transno_dchild, rc = PTR_ERR(handle)); - rc = vfs_symlink(dir, dchild, rec->ur_name); - EXIT; - break; - } - case S_IFCHR: - case S_IFBLK: - case S_IFIFO: - case S_IFSOCK:{ - int rdev = rec->ur_rdev; - handle = mds_fs_start(mds, dir, MDS_FSOP_MKNOD); - if (IS_ERR(handle)) - GOTO(out_transno_dchild, rc = PTR_ERR(handle)); - rc = vfs_mknod(dir, dchild, rec->ur_mode, rdev); - EXIT; - break; - } - default: - CERROR("bad file type %o creating %s\n", type, rec->ur_name); - handle = NULL; /* quell uninitialized warning */ - GOTO(out_transno_dchild, rc = -EINVAL); - } - - if (rc) { - CDEBUG(D_INODE, "error during create: %d\n", rc); - GOTO(out_create_commit, rc); - } else { - struct iattr iattr; - struct inode *inode = dchild->d_inode; - struct mds_body *body; - - iattr.ia_atime = rec->ur_time; - iattr.ia_ctime = rec->ur_time; - iattr.ia_mtime = rec->ur_time; - iattr.ia_uid = rec->ur_uid; - iattr.ia_gid = rec->ur_gid; - iattr.ia_valid = ATTR_UID | ATTR_GID | ATTR_ATIME | - ATTR_MTIME | ATTR_CTIME; - - if (rec->ur_fid2->id) { - LASSERT(rec->ur_opcode & REINT_REPLAYING); - inode->i_generation = rec->ur_fid2->generation; - /* Dirtied and committed by the upcoming setattr. */ - CDEBUG(D_INODE, "recreated ino %ld with gen %ld\n", - inode->i_ino, inode->i_generation); - } else { - CDEBUG(D_INODE, "created ino %ld\n", inode->i_ino); - } - - rc = mds_fs_setattr(mds, dchild, handle, &iattr); - if (rc) { - CERROR("error on setattr: rc = %d\n", rc); - /* XXX should we abort here in case of error? */ - } - - body = lustre_msg_buf(req->rq_repmsg, offset); - mds_pack_inode2fid(&body->fid1, inode); - mds_pack_inode2body(body, inode); - } - EXIT; -out_create_commit: - if (rc) { - rc = mds_finish_transno(mds, handle, req, rc); - } else { - rc = mds_finish_transno(mds, handle, req, rc); - if (rc) - GOTO(out_create_unlink, rc); - } - err = mds_fs_commit(mds, dir, handle); - if (err) { - CERROR("error on commit: err = %d\n", err); - if (!rc) - rc = err; - } -out_create_dchild: - l_dput(dchild); - ldlm_lock_decref(&lockh, lock_mode); -out_create_de: - up(&dir->i_sem); - l_dput(de); -out_create: - req->rq_status = rc; - return 0; - -out_transno_dchild: - /* Need to release the transno lock, and then put the dchild. */ - LASSERT(rc); - mds_finish_transno(mds, handle, req, rc); - goto out_create_dchild; - -out_create_unlink: - /* Destroy the file we just created. This should not need extra - * journal credits, as we have already modified all of the blocks - * needed in order to create the file in the first place. - */ - switch (type) { - case S_IFDIR: - err = vfs_rmdir(dir, dchild); - if (err) - CERROR("failed rmdir in error path: rc = %d\n", err); - break; - default: - err = vfs_unlink(dir, dchild); - if (err) - CERROR("failed unlink in error path: rc = %d\n", err); - break; - } - - goto out_create_commit; -} - -static int mds_reint_unlink(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req) -{ - struct dentry *de = NULL; - struct dentry *dchild = NULL; - struct mds_obd *mds = mds_req2mds(req); - struct obd_device *obd = req->rq_export->exp_obd; - struct mds_body *body = NULL; - char *name; - struct inode *dir, *inode; - struct lustre_handle lockh, child_lockh; - void *handle; - int namelen, lock_mode, err, rc = 0; - ENTRY; - - /* a name was supplied by the client; fid1 is the directory */ - lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_PW : LCK_PW; - de = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, lock_mode, &lockh); - if (IS_ERR(de)) { - LBUG(); - RETURN(PTR_ERR(de)); - } - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNLINK)) - GOTO(out_unlink, rc = -ENOENT); - - name = lustre_msg_buf(req->rq_reqmsg, offset + 1); - namelen = req->rq_reqmsg->buflens[offset + 1] - 1; -#warning "FIXME: if mds_name2locked_dentry decrefs this lock, we must not" - memcpy(&child_lockh, &lockh, sizeof(child_lockh)); - dchild = mds_name2locked_dentry(obd, de, NULL, name, namelen, - LCK_EX, &child_lockh, lock_mode); - - if (IS_ERR(dchild)) { - LBUG(); - GOTO(out_unlink, rc = PTR_ERR(dchild)); - } - - dir = de->d_inode; - inode = dchild->d_inode; - CDEBUG(D_INODE, "parent ino %ld\n", dir->i_ino); - - if (!inode) { - if (rec->ur_opcode & REINT_REPLAYING) { - CDEBUG(D_INODE, - "child missing (%ld/%s); OK for REPLAYING\n", - dir->i_ino, rec->ur_name); - rc = 0; - } else { - CDEBUG(D_INODE, - "child doesn't exist (dir %ld, name %s)\n", - dir->i_ino, rec->ur_name); - rc = -ENOENT; - } - /* going to out_unlink_cancel causes an LBUG, don't know why */ - GOTO(out_unlink_dchild, rc); - } - - if (offset) { - /* XXX offset? */ - offset = 1; - - body = lustre_msg_buf(req->rq_repmsg, offset); - mds_pack_inode2fid(&body->fid1, inode); - mds_pack_inode2body(body, inode); - } - - OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_UNLINK_WRITE, - to_kdev_t(dir->i_sb->s_dev)); - - mds_start_transno(mds); - switch (rec->ur_mode /* & S_IFMT ? */) { - case S_IFDIR: - handle = mds_fs_start(mds, dir, MDS_FSOP_RMDIR); - if (IS_ERR(handle)) - GOTO(out_unlink_cancel_transno, rc = PTR_ERR(handle)); - rc = vfs_rmdir(dir, dchild); - break; - case S_IFREG: - /* get OBD EA data first so client can also destroy object */ - if ((inode->i_mode & S_IFMT) == S_IFREG && offset) - mds_pack_md(mds, req, offset + 1, body, inode); - /* no break */ - case S_IFLNK: - case S_IFCHR: - case S_IFBLK: - case S_IFIFO: - case S_IFSOCK: - handle = mds_fs_start(mds, dir, MDS_FSOP_UNLINK); - if (IS_ERR(handle)) - GOTO(out_unlink_cancel_transno, rc = PTR_ERR(handle)); - rc = vfs_unlink(dir, dchild); - break; - default: - CERROR("bad file type %o unlinking %s\n", rec->ur_mode, name); - handle = NULL; - LBUG(); - GOTO(out_unlink_cancel_transno, rc = -EINVAL); - } - - rc = mds_finish_transno(mds, handle, req, rc); - err = mds_fs_commit(mds, dir, handle); - if (err) { - CERROR("error on commit: err = %d\n", err); - if (!rc) - rc = err; - } - - EXIT; - -out_unlink_cancel: - ldlm_lock_decref(&child_lockh, LCK_EX); - err = ldlm_cli_cancel(&child_lockh); - if (err < 0) { - CERROR("failed to cancel child inode lock: err = %d\n", err); - if (!rc) - rc = -ENOLCK; /*XXX translate LDLM lock error */ - } -out_unlink_dchild: - l_dput(dchild); - up(&dir->i_sem); -out_unlink: - ldlm_lock_decref(&lockh, lock_mode); - l_dput(de); - req->rq_status = rc; - return 0; - -out_unlink_cancel_transno: - rc = mds_finish_transno(mds, handle, req, rc); - goto out_unlink_cancel; -} - -static int mds_reint_link(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req) -{ - struct obd_device *obd = req->rq_export->exp_obd; - struct dentry *de_src = NULL; - struct dentry *de_tgt_dir = NULL; - struct dentry *dchild = NULL; - struct mds_obd *mds = mds_req2mds(req); - struct lustre_handle *handle, tgtlockh, srclockh; - int lock_mode; - __u64 res_id[3] = { 0 }; - int flags = 0; - int rc = 0, err; - - ENTRY; - de_src = mds_fid2dentry(mds, rec->ur_fid1, NULL); - if (IS_ERR(de_src) || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_LINK)) { - GOTO(out_link, rc = -ESTALE); - } - - /* plan to change the link count on this inode: write lock */ - lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_PW : LCK_PW; - res_id[0] = de_src->d_inode->i_ino; - res_id[1] = de_src->d_inode->i_generation; - - rc = ldlm_lock_match(obd->obd_namespace, res_id, LDLM_PLAIN, - NULL, 0, lock_mode, &srclockh); - if (rc == 0) { - LDLM_DEBUG_NOLOCK("enqueue res "LPU64, res_id[0]); - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, - res_id, LDLM_PLAIN, NULL, 0, lock_mode, - &flags, ldlm_completion_ast, - mds_blocking_ast, NULL, 0, &srclockh); - if (rc != ELDLM_OK) { - CERROR("lock enqueue: err: %d\n", rc); - GOTO(out_link_src_put, rc = -EIO); - } - } else - ldlm_lock_dump((void *)(unsigned long)srclockh.addr); - - de_tgt_dir = mds_fid2dentry(mds, rec->ur_fid2, NULL); - if (IS_ERR(de_tgt_dir)) { - GOTO(out_link_src, rc = -ESTALE); - } - - lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_PW : LCK_PW; - res_id[0] = de_tgt_dir->d_inode->i_ino; - res_id[1] = de_tgt_dir->d_inode->i_generation; - - rc = ldlm_lock_match(obd->obd_namespace, res_id, LDLM_PLAIN, - NULL, 0, lock_mode, &tgtlockh); - if (rc == 0) { - LDLM_DEBUG_NOLOCK("enqueue res "LPU64, res_id[0]); - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, - res_id, LDLM_PLAIN, NULL, 0, lock_mode, - &flags, ldlm_completion_ast, - mds_blocking_ast, NULL, 0, &tgtlockh); - if (rc != ELDLM_OK) { - CERROR("lock enqueue: err: %d\n", rc); - GOTO(out_link_tgt_dir_put, rc = -EIO); - } - } else - ldlm_lock_dump((void *)(unsigned long)tgtlockh.addr); - - down(&de_tgt_dir->d_inode->i_sem); - dchild = lookup_one_len(rec->ur_name, de_tgt_dir, rec->ur_namelen - 1); - if (IS_ERR(dchild)) { - CERROR("child lookup error %ld\n", PTR_ERR(dchild)); - GOTO(out_link_tgt_dir, rc = -ESTALE); - } - - if (dchild->d_inode) { - struct inode *inode = dchild->d_inode; - /* in intent case ship back attributes to client */ - if (offset) { - struct mds_body *body = - lustre_msg_buf(req->rq_repmsg, 1); - - mds_pack_inode2fid(&body->fid1, inode); - mds_pack_inode2body(body, inode); - if (S_ISREG(inode->i_mode)) - mds_pack_md(mds, req, 2, body, inode); - } - if (rec->ur_opcode & REINT_REPLAYING) { - /* XXX verify that the link is to the the right file? */ - rc = 0; - CDEBUG(D_INODE, - "child exists (dir %ld, name %s) (REPLAYING)\n", - de_tgt_dir->d_inode->i_ino, rec->ur_name); - } else { - rc = -EEXIST; - CERROR("child exists (dir %ld, name %s)\n", - de_tgt_dir->d_inode->i_ino, rec->ur_name); - } - GOTO(out_link_dchild, rc); - } - - OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_LINK_WRITE, - to_kdev_t(de_src->d_inode->i_sb->s_dev)); - - mds_start_transno(mds); - handle = mds_fs_start(mds, de_tgt_dir->d_inode, MDS_FSOP_LINK); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - mds_finish_transno(mds, handle, req, rc); - GOTO(out_link_dchild, rc); - } - - rc = vfs_link(de_src, de_tgt_dir->d_inode, dchild); - if (rc) - CERROR("link error %d\n", rc); - rc = mds_finish_transno(mds, handle, req, rc); - - err = mds_fs_commit(mds, de_tgt_dir->d_inode, handle); - if (err) { - CERROR("error on commit: err = %d\n", err); - if (!rc) - rc = err; - } - EXIT; - -out_link_dchild: - l_dput(dchild); -out_link_tgt_dir: - ldlm_lock_decref(&tgtlockh, lock_mode); -out_link_tgt_dir_put: - up(&de_tgt_dir->d_inode->i_sem); - l_dput(de_tgt_dir); -out_link_src: - ldlm_lock_decref(&srclockh, lock_mode); -out_link_src_put: - l_dput(de_src); -out_link: - req->rq_status = rc; - return 0; -} - -static int mds_reint_rename(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req) -{ - struct obd_device *obd = req->rq_export->exp_obd; - struct dentry *de_srcdir = NULL; - struct dentry *de_tgtdir = NULL; - struct dentry *de_old = NULL; - struct dentry *de_new = NULL; - struct mds_obd *mds = mds_req2mds(req); - struct lustre_handle tgtlockh, srclockh, oldhandle; - int flags = 0, lock_mode, rc = 0, err; - void *handle; - __u64 res_id[3] = { 0 }; - ENTRY; - - de_srcdir = mds_fid2dentry(mds, rec->ur_fid1, NULL); - if (IS_ERR(de_srcdir)) - GOTO(out_rename, rc = -ESTALE); - - lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_PW : LCK_PW; - res_id[0] = de_srcdir->d_inode->i_ino; - res_id[1] = de_srcdir->d_inode->i_generation; - - rc = ldlm_lock_match(obd->obd_namespace, res_id, LDLM_PLAIN, - NULL, 0, lock_mode, &srclockh); - if (rc == 0) { - LDLM_DEBUG_NOLOCK("enqueue res "LPU64, res_id[0]); - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, - res_id, LDLM_PLAIN, NULL, 0, lock_mode, - &flags, ldlm_completion_ast, - mds_blocking_ast, NULL, 0, &srclockh); - if (rc != ELDLM_OK) { - CERROR("lock enqueue: err: %d\n", rc); - GOTO(out_rename_srcput, rc = -EIO); - } - } else - ldlm_lock_dump((void *)(unsigned long)srclockh.addr); - - de_tgtdir = mds_fid2dentry(mds, rec->ur_fid2, NULL); - if (IS_ERR(de_tgtdir)) - GOTO(out_rename_srcdir, rc = -ESTALE); - - lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_PW : LCK_PW; - res_id[0] = de_tgtdir->d_inode->i_ino; - res_id[1] = de_tgtdir->d_inode->i_generation; - - rc = ldlm_lock_match(obd->obd_namespace, res_id, LDLM_PLAIN, - NULL, 0, lock_mode, &tgtlockh); - if (rc == 0) { - flags = 0; - LDLM_DEBUG_NOLOCK("enqueue res "LPU64, res_id[0]); - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, - res_id, LDLM_PLAIN, NULL, 0, lock_mode, - &flags, ldlm_completion_ast, - mds_blocking_ast, NULL, 0, &tgtlockh); - if (rc != ELDLM_OK) { - CERROR("lock enqueue: err: %d\n", rc); - GOTO(out_rename_tgtput, rc = -EIO); - } - } else - ldlm_lock_dump((void *)(unsigned long)tgtlockh.addr); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - double_lock(de_tgtdir, de_srcdir); -#endif - de_old = lookup_one_len(rec->ur_name, de_srcdir, rec->ur_namelen - 1); - if (IS_ERR(de_old)) { - CERROR("old child lookup error (%*s): %ld\n", - rec->ur_namelen - 1, rec->ur_name, PTR_ERR(de_old)); - GOTO(out_rename_tgtdir, rc = -ENOENT); - } - - de_new = lookup_one_len(rec->ur_tgt, de_tgtdir, rec->ur_tgtlen - 1); - if (IS_ERR(de_new)) { - CERROR("new child lookup error (%*s): %ld\n", - rec->ur_tgtlen - 1, rec->ur_tgt, PTR_ERR(de_new)); - GOTO(out_rename_deold, rc = -ENOENT); - } - - /* in intent case ship back attributes to client */ - if (offset) { - struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 1); - struct inode *inode = de_new->d_inode; - - if (!inode) { - body->valid = 0; - } else { - mds_pack_inode2fid(&body->fid1, inode); - mds_pack_inode2body(body, inode); - if (S_ISREG(inode->i_mode)) - mds_pack_md(mds, req, 2, body, inode); - } - } - - OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_RENAME_WRITE, - to_kdev_t(de_srcdir->d_inode->i_sb->s_dev)); - - mds_start_transno(mds); - handle = mds_fs_start(mds, de_tgtdir->d_inode, MDS_FSOP_RENAME); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - mds_finish_transno(mds, handle, req, rc); - GOTO(out_rename_denew, rc); - } - - lock_kernel(); - rc = vfs_rename(de_srcdir->d_inode, de_old, de_tgtdir->d_inode, de_new, - NULL); - unlock_kernel(); - - rc = mds_finish_transno(mds, handle, req, rc); - - err = mds_fs_commit(mds, de_tgtdir->d_inode, handle); - if (err) { - CERROR("error on commit: err = %d\n", err); - if (!rc) - rc = err; - } - EXIT; - -out_rename_denew: - l_dput(de_new); -out_rename_deold: - if (!rc) { - res_id[0] = de_old->d_inode->i_ino; - res_id[1] = de_old->d_inode->i_generation; - flags = 0; - /* Take an exclusive lock on the resource that we're - * about to free, to force everyone to drop their - * locks. */ - LDLM_DEBUG_NOLOCK("getting EX lock res "LPU64, res_id[0]); - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, - res_id, LDLM_PLAIN, NULL, 0, LCK_EX, - &flags, ldlm_completion_ast, - mds_blocking_ast, NULL, 0, &oldhandle); - if (rc) - CERROR("failed to get child inode lock (child ino " - LPD64" dir ino %ld)\n", - res_id[0], de_old->d_inode->i_ino); - } - - l_dput(de_old); - - if (!rc) { - ldlm_lock_decref(&oldhandle, LCK_EX); - rc = ldlm_cli_cancel(&oldhandle); - if (rc < 0) - CERROR("failed to cancel child inode lock ino " - LPD64": %d\n", res_id[0], rc); - } -out_rename_tgtdir: -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - double_up(&de_srcdir->d_inode->i_sem, &de_tgtdir->d_inode->i_sem); -#endif - ldlm_lock_decref(&tgtlockh, lock_mode); -out_rename_tgtput: - l_dput(de_tgtdir); -out_rename_srcdir: - ldlm_lock_decref(&srclockh, lock_mode); -out_rename_srcput: - l_dput(de_srcdir); -out_rename: - req->rq_status = rc; - return 0; -} - -typedef int (*mds_reinter) (struct mds_update_record *, int offset, - struct ptlrpc_request *); - -static mds_reinter reinters[REINT_MAX + 1] = { - [REINT_SETATTR] mds_reint_setattr, - [REINT_CREATE] mds_reint_create, - [REINT_UNLINK] mds_reint_unlink, - [REINT_LINK] mds_reint_link, - [REINT_RENAME] mds_reint_rename, -}; - -int mds_reint_rec(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req) -{ - struct mds_obd *mds = mds_req2mds(req); - struct obd_run_ctxt saved; - struct obd_ucred uc; - int realop = rec->ur_opcode & REINT_OPCODE_MASK; - int rc; - - if (realop < 1 || realop > REINT_MAX) { - CERROR("opcode %d not valid (%sREPLAYING)\n", realop, - rec->ur_opcode & REINT_REPLAYING ? "" : "not "); - rc = req->rq_status = -EINVAL; - RETURN(rc); - } - - uc.ouc_fsuid = rec->ur_fsuid; - uc.ouc_fsgid = rec->ur_fsgid; - uc.ouc_cap = rec->ur_cap; - - push_ctxt(&saved, &mds->mds_ctxt, &uc); - rc = reinters[realop] (rec, offset, req); - pop_ctxt(&saved, &mds->mds_ctxt, &uc); - - return rc; -} diff --git a/lustre/missing b/lustre/missing deleted file mode 100755 index 6a37006..0000000 --- a/lustre/missing +++ /dev/null @@ -1,336 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. -# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. - -# This program 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, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -run=: - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -case "$1" in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case "$1" in - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch]" - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing 0.4 - GNU automake" - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - - aclocal*) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case "$f" in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is needed, and you do not seem to have it handy on your - system. You might have modified some files without having the - proper tools for further handling them. - You can get \`$1Help2man' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` - test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if [ ! -f y.tab.h ]; then - echo >y.tab.h - fi - if [ ! -f y.tab.c ]; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if [ ! -f lex.yy.c ]; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` - fi - if [ -f "$file" ]; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit 1 - fi - ;; - - makeinfo) - if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then - # We have makeinfo, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` - fi - touch $file - ;; - - tar) - shift - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - fi - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case "$firstarg" in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case "$firstarg" in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and you do not seem to have it handy on your - system. You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequirements for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 diff --git a/lustre/mkinstalldirs b/lustre/mkinstalldirs deleted file mode 100755 index a08f3ca..0000000 --- a/lustre/mkinstalldirs +++ /dev/null @@ -1,40 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# Created: 1993-05-16 -# Public domain - -# $Id: mkinstalldirs,v 1.1 2002/05/27 16:48:11 pschwan Exp $ - -errstatus=0 - -for file -do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d - do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - fi - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus - -# mkinstalldirs ends here diff --git a/lustre/nodist b/lustre/nodist deleted file mode 100644 index 91aecad..0000000 --- a/lustre/nodist +++ /dev/null @@ -1,21 +0,0 @@ -obd-*/obd-* -CVS -*~ -make.rules -config.* -*.o -*.orig -*.backup -.depfiles -ext2obd/dir.c -ext2obd/file.c -ext2obd/ialloc.c -ext2obd/inode.c -ext2obd/super.c -ext2obd/fsync.c -ext2obd/ioctl.c -ext2obd/balloc.c -ext2obd/acl.c -ext2obd/namei.c -ext2obd/symlink.c -ext2obd/bitmap.c diff --git a/lustre/obdclass/.cvsignore b/lustre/obdclass/.cvsignore deleted file mode 100644 index e530020..0000000 --- a/lustre/obdclass/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/obdclass/Makefile.am b/lustre/obdclass/Makefile.am deleted file mode 100644 index d7df0bb..0000000 --- a/lustre/obdclass/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -# FIXME: we need to make it clear that obdclass.o depends on -# lustre_build_version, or 'make -j2' breaks! -DEFS= -MODULE = obdclass -modulefs_DATA = lustre_build_version obdclass.o -EXTRA_PROGRAMS = obdclass -obdclass_SOURCES = debug.c genops.c class_obd.c sysctl.c uuid.c lprocfs_status.c -include $(top_srcdir)/Rules -lustre_build_version: - perl $(top_srcdir)/scripts/version_tag.pl $(top_srcdir) > tmpver - diff -u $(top_builddir)/include/linux/lustre_build_version.h tmpver \ - 2> /dev/null &&\ - $(RM) tmpver || \ - mv tmpver $(top_builddir)/include/linux/lustre_build_version.h diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c deleted file mode 100644 index 32e8c08..0000000 --- a/lustre/obdclass/class_obd.c +++ /dev/null @@ -1,715 +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 - * - * These are the only exported functions, they provide some generic - * infrastructure for managing object devices - * - * Object Devices Class Driver - */ - -#define EXPORT_SYMTAB -#include /* for CONFIG_PROC_FS */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#include -#include -#include -#include -#include /* for PTL_MD_MAX_IOV */ -#include - -struct semaphore obd_conf_sem; /* serialize configuration commands */ -struct obd_device obd_dev[MAX_OBD_DEVICES]; -struct list_head obd_types; -unsigned long obd_memory; - -/* The following are visible and mutable through /proc/sys/lustre/. */ -unsigned long obd_fail_loc; -unsigned long obd_timeout = 100; -char obd_recovery_upcall[128] = "/usr/lib/lustre/ha_assist"; - -extern struct obd_type *class_nm_to_type(char *nm); - -/* opening /dev/obd */ -static int obd_class_open(struct inode * inode, struct file * file) -{ - ENTRY; - - file->private_data = NULL; - CDEBUG(D_IOCTL, "MOD_INC_USE for open: count = %d\n", - atomic_read(&(THIS_MODULE)->uc.usecount)); - MOD_INC_USE_COUNT; - RETURN(0); -} - -/* closing /dev/obd */ -static int obd_class_release(struct inode * inode, struct file * file) -{ - ENTRY; - - // XXX drop lsm, connections here - if (file->private_data) - file->private_data = NULL; - - CDEBUG(D_IOCTL, "MOD_DEC_USE for close: count = %d\n", - atomic_read(&(THIS_MODULE)->uc.usecount) - 1); - MOD_DEC_USE_COUNT; - RETURN(0); -} - -static inline void obd_data2conn(struct lustre_handle *conn, - struct obd_ioctl_data *data) -{ - conn->addr = data->ioc_addr; - conn->cookie = data->ioc_cookie; -} - -static inline void obd_conn2data(struct obd_ioctl_data *data, - struct lustre_handle *conn) -{ - data->ioc_addr = conn->addr; - data->ioc_cookie = conn->cookie; -} - -static void forcibly_detach_exports(struct obd_device *obd) -{ - int rc; - struct list_head *tmp, *n; - struct lustre_handle fake_conn; - - CDEBUG(D_IOCTL, "OBD device %d (%p) has exports, " - "disconnecting them", obd->obd_minor, obd); - list_for_each_safe(tmp, n, &obd->obd_exports) { - struct obd_export *exp = list_entry(tmp, struct obd_export, - exp_obd_chain); - fake_conn.addr = (__u64)(unsigned long)exp; - fake_conn.cookie = exp->exp_cookie; - rc = obd_disconnect(&fake_conn); - if (rc) { - CDEBUG(D_IOCTL, "disconnecting export %p failed: %d\n", - exp, rc); - } else { - CDEBUG(D_IOCTL, "export %p disconnected\n", exp); - } - } -} - -/* to control /dev/obd */ -static int obd_class_ioctl (struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long arg) -{ - char *buf = NULL; - struct obd_ioctl_data *data; - struct obd_device *obd = filp->private_data; - struct lustre_handle conn; - int err = 0, len = 0, serialised = 0; - ENTRY; - - switch (cmd) { - case OBD_IOC_BRW_WRITE: - case OBD_IOC_BRW_READ: - case OBD_IOC_GETATTR: - break; - default: - down(&obd_conf_sem); - serialised = 1; - break; - } - - if (!obd && cmd != OBD_IOC_DEVICE && cmd != TCGETS && - cmd != OBD_IOC_LIST && cmd != OBD_GET_VERSION && - cmd != OBD_IOC_NAME2DEV && cmd != OBD_IOC_NEWDEV) { - CERROR("OBD ioctl: No device\n"); - GOTO(out, err = -EINVAL); - } - if (obd_ioctl_getdata(&buf, &len, (void *)arg)) { - CERROR("OBD ioctl: data error\n"); - GOTO(out, err = -EINVAL); - } - data = (struct obd_ioctl_data *)buf; - - switch (cmd) { - case TCGETS: - GOTO(out, err=-EINVAL); - case OBD_IOC_DEVICE: { - CDEBUG(D_IOCTL, "\n"); - if (data->ioc_dev >= MAX_OBD_DEVICES || data->ioc_dev < 0) { - CERROR("OBD ioctl: DEVICE insufficient devices\n"); - GOTO(out, err=-EINVAL); - } - CDEBUG(D_IOCTL, "device %d\n", data->ioc_dev); - - filp->private_data = &obd_dev[data->ioc_dev]; - GOTO(out, err=0); - } - - case OBD_IOC_LIST: { - int i; - char *buf2 = data->ioc_bulk; - int remains = data->ioc_inllen1; - - if (!data->ioc_inlbuf1) { - CERROR("No buffer passed!\n"); - GOTO(out, err=-EINVAL); - } - - - for (i = 0 ; i < MAX_OBD_DEVICES ; i++) { - int l; - char *status; - struct obd_device *obd = &obd_dev[i]; - if (!obd->obd_type) - continue; - if (obd->obd_flags & OBD_SET_UP) - status = "UP"; - else if (obd->obd_flags & OBD_ATTACHED) - status = "AT"; - else - status = "-"; - l = snprintf(buf2, remains, "%2d %s %s %s %s %d\n", - i, status, obd->obd_type->typ_name, - obd->obd_name, obd->obd_uuid, obd->obd_type->typ_refcnt); - buf2 +=l; - remains -=l; - if (remains <= 0) { - CERROR("not enough space for device listing\n"); - break; - } - } - - err = copy_to_user((void *)arg, data, len); - if (err) - err = -EFAULT; - GOTO(out, err); - } - - case OBD_GET_VERSION: - if (!data->ioc_inlbuf1) { - CERROR("No buffer passed in ioctl\n"); - GOTO(out, err = -EINVAL); - } - - if (strlen(BUILD_VERSION) + 1 > data->ioc_inllen1) { - CERROR("ioctl buffer too small to hold version\n"); - GOTO(out, err = -EINVAL); - } - - memcpy(data->ioc_bulk, BUILD_VERSION, - strlen(BUILD_VERSION) + 1); - - err = copy_to_user((void *)arg, data, len); - if (err) - err = -EFAULT; - GOTO(out, err); - - case OBD_IOC_NAME2DEV: { - /* Resolve a device name. This does not change the - * currently selected device. - */ - int dev; - - if (!data->ioc_inllen1 || !data->ioc_inlbuf1 ) { - CERROR("No name passed,!\n"); - GOTO(out, err=-EINVAL); - } - if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) { - CERROR("Name not nul terminated!\n"); - GOTO(out, err=-EINVAL); - } - - CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1); - dev = class_name2dev(data->ioc_inlbuf1); - data->ioc_dev = dev; - if (dev == -1) { - CDEBUG(D_IOCTL, "No device for name %s!\n", - data->ioc_inlbuf1); - GOTO(out, err=-EINVAL); - } - - CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1, - dev); - err = copy_to_user((void *)arg, data, sizeof(*data)); - if (err) - err = -EFAULT; - GOTO(out, err); - } - - case OBD_IOC_UUID2DEV: { - /* Resolve a device uuid. This does not change the - * currently selected device. - */ - int dev; - - if (!data->ioc_inllen1 || !data->ioc_inlbuf1) { - CERROR("No UUID passed!\n"); - GOTO(out, err=-EINVAL); - } - if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) { - CERROR("Name not nul terminated!\n"); - GOTO(out, err=-EINVAL); - } - - CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1); - dev = class_uuid2dev(data->ioc_inlbuf1); - data->ioc_dev = dev; - if (dev == -1) { - CDEBUG(D_IOCTL, "No device for name %s!\n", - data->ioc_inlbuf1); - GOTO(out, err=-EINVAL); - } - - CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1, - dev); - err = copy_to_user((void *)arg, data, sizeof(*data)); - if (err) - err = -EFAULT; - GOTO(out, err); - } - - case OBD_IOC_NEWDEV: { - int dev = -1; - int i; - - filp->private_data = NULL; - for (i = 0 ; i < MAX_OBD_DEVICES ; i++) { - struct obd_device *obd = &obd_dev[i]; - if (!obd->obd_type) { - filp->private_data = obd; - dev = i; - break; - } - } - - - data->ioc_dev = dev; - if (dev == -1) - GOTO(out, err=-EINVAL); - - err = copy_to_user((void *)arg, data, sizeof(*data)); - if (err) - err = -EFAULT; - GOTO(out, err); - } - - case OBD_IOC_ATTACH: { - struct obd_type *type; - int minor; - - /* have we attached a type to this device */ - if (obd->obd_flags & OBD_ATTACHED || obd->obd_type) { - CERROR("OBD: Device %d already typed as %s.\n", - obd->obd_minor, MKSTR(obd->obd_type->typ_name)); - GOTO(out, err=-EBUSY); - } - - if (!data->ioc_inllen1 || !data->ioc_inlbuf1) { - CERROR("No type passed!\n"); - GOTO(out, err=-EINVAL); - } - if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) { - CERROR("Type not nul terminated!\n"); - GOTO(out, err=-EINVAL); - } - - CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n", - MKSTR(data->ioc_inlbuf1), - MKSTR(data->ioc_inlbuf2), MKSTR(data->ioc_inlbuf3)); - - /* find the type */ - type = class_nm_to_type(data->ioc_inlbuf1); - if (!type) { - CERROR("OBD: unknown type dev %d\n", obd->obd_minor); - GOTO(out, err=-EINVAL); - } - - minor = obd->obd_minor; - memset(obd, 0, sizeof(*obd)); - obd->obd_minor = minor; - obd->obd_type = type; - INIT_LIST_HEAD(&obd->obd_exports); - INIT_LIST_HEAD(&obd->obd_imports); - spin_lock_init(&obd->obd_dev_lock); - - if (data->ioc_inlbuf2) { - int len = strlen(data->ioc_inlbuf2) + 1; - OBD_ALLOC(obd->obd_name, len); - if (!obd->obd_name) { - CERROR("no memory\n"); - LBUG(); - } - memcpy(obd->obd_name, data->ioc_inlbuf2, len); - } else { - CERROR("WARNING: unnamed obd device\n"); - } - if (data->ioc_inlbuf3) { - int len = strlen(data->ioc_inlbuf3); - if (len >= sizeof(obd->obd_uuid)) { - CERROR("uuid must be < %d bytes long\n", - sizeof(obd->obd_uuid)); - if (obd->obd_name) - OBD_FREE(obd->obd_name, - strlen(obd->obd_name) + 1); - GOTO(out, err=-EINVAL); - } - memcpy(obd->obd_uuid, data->ioc_inlbuf3, len); - } - /* do the attach */ - if (OBP(obd, attach)) - err = OBP(obd,attach)(obd, sizeof(*data), data); - if (err) { - if(data->ioc_inlbuf2) - OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1); - obd->obd_type = NULL; - } else { - obd->obd_flags |= OBD_ATTACHED; - - type->typ_refcnt++; - CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n", - obd->obd_minor, data->ioc_inlbuf1); - - CDEBUG(D_IOCTL, "MOD_INC_USE for attach: count = %d\n", - atomic_read(&(THIS_MODULE)->uc.usecount)); - MOD_INC_USE_COUNT; - } - - GOTO(out, err); - } - - case OBD_IOC_DETACH: { - ENTRY; - if (obd->obd_flags & OBD_SET_UP) { - CERROR("OBD device %d still set up\n", obd->obd_minor); - GOTO(out, err=-EBUSY); - } - if (!(obd->obd_flags & OBD_ATTACHED) ) { - CERROR("OBD device %d not attached\n", obd->obd_minor); - GOTO(out, err=-ENODEV); - } - if (!list_empty(&obd->obd_exports)) { - if (!data->ioc_inlbuf1 || data->ioc_inlbuf1[0] != 'F') { - CERROR("OBD device %d (%p) has exports\n", - obd->obd_minor, obd); - GOTO(out, err=-EBUSY); - } - forcibly_detach_exports(obd); - } - if (OBP(obd, detach)) - err=OBP(obd,detach)(obd); - - if (obd->obd_name) { - OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1); - obd->obd_name = NULL; - } - - obd->obd_flags &= ~OBD_ATTACHED; - obd->obd_type->typ_refcnt--; - obd->obd_type = NULL; - CDEBUG(D_IOCTL, "MOD_DEC_USE for detach: count = %d\n", - atomic_read(&(THIS_MODULE)->uc.usecount) - 1); - MOD_DEC_USE_COUNT; - GOTO(out, err = 0); - } - - case OBD_IOC_SETUP: { - /* have we attached a type to this device? */ - if (!(obd->obd_flags & OBD_ATTACHED)) { - CERROR("Device %d not attached\n", obd->obd_minor); - GOTO(out, err=-ENODEV); - } - - /* has this been done already? */ - if ( obd->obd_flags & OBD_SET_UP ) { - CERROR("Device %d already setup (type %s)\n", - obd->obd_minor, obd->obd_type->typ_name); - GOTO(out, err=-EBUSY); - } - - if ( OBT(obd) && OBP(obd, setup) ) - err = obd_setup(obd, sizeof(*data), data); - - if (!err) { - obd->obd_type->typ_refcnt++; - obd->obd_flags |= OBD_SET_UP; - } - - GOTO(out, err); - } - case OBD_IOC_CLEANUP: { - /* have we attached a type to this device? */ - if (!(obd->obd_flags & OBD_ATTACHED)) { - CERROR("Device %d not attached\n", obd->obd_minor); - GOTO(out, err=-ENODEV); - } - - if ( OBT(obd) && OBP(obd, cleanup) ) - err = obd_cleanup(obd); - - if (!err) { - obd->obd_flags &= ~OBD_SET_UP; - obd->obd_type->typ_refcnt--; - } - GOTO(out, err); - } - - case OBD_IOC_CONNECT: { - char * cluuid = "OBD_CLASS_UUID"; - obd_data2conn(&conn, data); - - err = obd_connect(&conn, obd, cluuid, NULL, NULL); - - CDEBUG(D_IOCTL, "assigned export "LPX64"\n", conn.addr); - obd_conn2data(data, &conn); - if (err) - GOTO(out, err); - - err = copy_to_user((void *)arg, data, sizeof(*data)); - if (err) - err = -EFAULT; - // XXX save connection data into file handle - GOTO(out, err); - } - - case OBD_IOC_DISCONNECT: { - obd_data2conn(&conn, data); - err = obd_disconnect(&conn); - GOTO(out, err); - } - - case OBD_IOC_DEC_USE_COUNT: { - CDEBUG(D_IOCTL, "MOD_DEC_USE for force dec: count = %d\n", - atomic_read(&(THIS_MODULE)->uc.usecount) - 1); - MOD_DEC_USE_COUNT; - GOTO(out, err=0); - } - - default: - obd_data2conn(&conn, data); - - err = obd_iocontrol(cmd, &conn, len, data, NULL); - if (err) - GOTO(out, err); - - err = copy_to_user((void *)arg, data, len); - if (err) - err = -EFAULT; - GOTO(out, err); - } - - out: - if (buf) - OBD_FREE(buf, len); - if (serialised) - up(&obd_conf_sem); - RETURN(err); -} /* obd_class_ioctl */ - - - -/* declare character device */ -static struct file_operations obd_psdev_fops = { - ioctl: obd_class_ioctl, /* ioctl */ - open: obd_class_open, /* open */ - release: obd_class_release, /* release */ -}; - -/* modules setup */ -#define OBD_MINOR 241 -static struct miscdevice obd_psdev = { - OBD_MINOR, - "obd_psdev", - &obd_psdev_fops -}; - -void (*class_signal_connection_failure)(struct ptlrpc_connection *); - -#ifdef CONFIG_HIGHMEM -/* Allow at most 3/4 of the kmap mappings to be consumed by vector I/O - * requests. This avoids deadlocks on servers which have a lot of clients - * doing vector I/O. We don't need to do this for non-vector I/O requests - * because singleton requests will just block on the kmap itself and never - * deadlock waiting for additional kmaps to complete. - * - * If we are a "server" task, we can have at most a single reservation - * in excess of the maximum. This avoids a deadlock when multiple client - * threads are on the same machine as the server threads, and the clients - * have consumed all of the available mappings. As long as a single server - * thread is can make progress, we are guaranteed to avoid deadlock. - */ -#define OBD_KMAP_MAX (LAST_PKMAP * 3 / 4) -static atomic_t obd_kmap_count = ATOMIC_INIT(OBD_KMAP_MAX); -static DECLARE_WAIT_QUEUE_HEAD(obd_kmap_waitq); - -void obd_kmap_get(int count, int server) -{ - //CERROR("getting %d kmap counts (%d/%d)\n", count, - // atomic_read(&obd_kmap_count), OBD_KMAP_MAX); - if (count == 1) - atomic_dec(&obd_kmap_count); - else while (atomic_add_negative(-count, &obd_kmap_count)) { - static long next_show = 0; - static int skipped = 0; - - if (server && atomic_read(&obd_kmap_count) >= -PTL_MD_MAX_IOV) - break; - - CDEBUG(D_OTHER, "negative kmap reserved count: %d\n", - atomic_read(&obd_kmap_count)); - atomic_add(count, &obd_kmap_count); - - if (time_after(jiffies, next_show)) { - CERROR("blocking %s (and %d others) for kmaps\n", - current->comm, skipped); - next_show = jiffies + 5*HZ; - skipped = 0; - } else - skipped++; - wait_event(obd_kmap_waitq, - atomic_read(&obd_kmap_count) >= count); - } -} - -void obd_kmap_put(int count) -{ - atomic_add(count, &obd_kmap_count); - /* Wake up sleepers. Sadly, this wakes up all of the tasks at once. - * We could have something smarter here like: - while (atomic_read(&obd_kmap_count) > 0) - wake_up_nr(obd_kmap_waitq, 1); - although we would need to set somewhere (probably obd_class_init): - obd_kmap_waitq.flags |= WQ_FLAG_EXCLUSIVE; - For now the wait_event() condition will handle this OK I believe. - */ - if (atomic_read(&obd_kmap_count) > 0) - wake_up(&obd_kmap_waitq); -} - -EXPORT_SYMBOL(obd_kmap_get); -EXPORT_SYMBOL(obd_kmap_put); -#endif - -EXPORT_SYMBOL(obd_dev); -EXPORT_SYMBOL(obdo_cachep); -EXPORT_SYMBOL(obd_memory); -EXPORT_SYMBOL(obd_fail_loc); -EXPORT_SYMBOL(obd_timeout); -EXPORT_SYMBOL(obd_recovery_upcall); -EXPORT_SYMBOL(ptlrpc_put_connection_superhack); - -EXPORT_SYMBOL(class_register_type); -EXPORT_SYMBOL(class_unregister_type); -EXPORT_SYMBOL(class_name2dev); -EXPORT_SYMBOL(class_uuid2dev); -EXPORT_SYMBOL(class_uuid2obd); -EXPORT_SYMBOL(class_new_export); -EXPORT_SYMBOL(class_destroy_export); -EXPORT_SYMBOL(class_connect); -EXPORT_SYMBOL(class_conn2export); -EXPORT_SYMBOL(class_conn2obd); -EXPORT_SYMBOL(class_conn2cliimp); -EXPORT_SYMBOL(class_conn2ldlmimp); -EXPORT_SYMBOL(class_disconnect); -EXPORT_SYMBOL(class_disconnect_all); -EXPORT_SYMBOL(class_uuid_unparse); - -EXPORT_SYMBOL(class_signal_connection_failure); -EXPORT_SYMBOL(class_nm_to_type); - -static int __init init_obdclass(void) -{ - struct obd_device *obd; - int err; - int i; - - printk(KERN_INFO "OBD class driver Build Version: " BUILD_VERSION - ", info@clusterfs.com\n"); - - sema_init(&obd_conf_sem, 1); - INIT_LIST_HEAD(&obd_types); - - if ((err = misc_register(&obd_psdev))) { - CERROR("cannot register %d err %d\n", OBD_MINOR, err); - return err; - } - - /* This struct is already zerod for us (static global) */ - for (i = 0, obd = obd_dev; i < MAX_OBD_DEVICES; i++, obd++) - obd->obd_minor = i; - - err = obd_init_caches(); - - if (err) - return err; - obd_sysctl_init(); - - err = lprocfs_reg_main(); - - return 0; -} - -static void __exit cleanup_obdclass(void) -{ - int i, err; - ENTRY; - - misc_deregister(&obd_psdev); - for (i = 0; i < MAX_OBD_DEVICES; i++) { - struct obd_device *obd = &obd_dev[i]; - if (obd->obd_type && (obd->obd_flags & OBD_SET_UP) && - OBT(obd) && OBP(obd, detach)) { - /* XXX should this call generic detach otherwise? */ - OBP(obd, detach)(obd); - } - } - - obd_cleanup_caches(); - obd_sysctl_clean(); - - err = lprocfs_dereg_main(); - - CERROR("obd memory leaked: %ld bytes\n", obd_memory); - EXIT; -} - -/* Check that we're building against the appropriate version of the Lustre - * kernel patch */ -#include -#if (LUSTRE_KERNEL_VERSION != 3) -# error Cannot continue: Your Lustre kernel patch is out of date -#endif - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Class Driver Build Version: " BUILD_VERSION); -MODULE_LICENSE("GPL"); - -module_init(init_obdclass); -module_exit(cleanup_obdclass); diff --git a/lustre/obdclass/debug.c b/lustre/obdclass/debug.c deleted file mode 100644 index 8b28706..0000000 --- a/lustre/obdclass/debug.c +++ /dev/null @@ -1,156 +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 - -#define EXPORT_SYMTAB -#include -#include -#include - -int dump_ioo(struct obd_ioobj *ioo) -{ - CERROR("obd_ioobj: ioo_id="LPD64", ioo_gr="LPD64", 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="LPD64", 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="LPD64", len=%d, flags=%x, xid=%d\n", - nb->offset, nb->len, nb->flags, nb->xid); - - return -EINVAL; -} - -int dump_obdo(struct obdo *oa) -{ - __u32 valid = oa->o_valid; - - CERROR("obdo: o_valid = %08x\n", valid); - if (valid & OBD_MD_FLID) - CERROR("obdo: o_id = "LPD64"\n", oa->o_id); - if (valid & OBD_MD_FLATIME) - CERROR("obdo: o_atime = "LPD64"\n", oa->o_atime); - if (valid & OBD_MD_FLMTIME) - CERROR("obdo: o_mtime = "LPD64"\n", oa->o_mtime); - if (valid & OBD_MD_FLCTIME) - CERROR("obdo: o_ctime = "LPD64"\n", oa->o_ctime); - if (valid & OBD_MD_FLSIZE) - CERROR("obdo: o_size = "LPD64"\n", oa->o_size); - if (valid & OBD_MD_FLBLOCKS) /* allocation of space */ - CERROR("obdo: o_blocks = "LPD64"\n", oa->o_blocks); - if (valid & OBD_MD_FLBLKSZ) - CERROR("obdo: o_blksize = %d\n", oa->o_blksize); - if (valid & (OBD_MD_FLTYPE | OBD_MD_FLMODE)) - CERROR("obdo: o_mode = %o\n", - oa->o_mode & ((valid & OBD_MD_FLTYPE ? S_IFMT : 0) | - (valid & OBD_MD_FLMODE ? ~S_IFMT : 0))); - if (valid & OBD_MD_FLUID) - CERROR("obdo: o_uid = %d\n", oa->o_uid); - if (valid & OBD_MD_FLGID) - CERROR("obdo: o_gid = %d\n", oa->o_gid); - if (valid & OBD_MD_FLFLAGS) - CERROR("obdo: o_flags = %x\n", oa->o_flags); - if (valid & OBD_MD_FLNLINK) - CERROR("obdo: o_nlink = %d\n", oa->o_nlink); - if (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); - - dump_obdo(&body->oa); - //dump_niobuf(nb); - dump_ioo(ioo); - - return -EINVAL; -} -*/ - -#define LPDS sizeof(__u64) -int page_debug_setup(void *addr, int len, __u64 off, __u64 id) -{ - LASSERT(addr); - - off = HTON__u64(off); - id = HTON__u64(id); - memcpy(addr, (char *)&off, LPDS); - memcpy(addr + LPDS, (char *)&id, LPDS); - - addr += len - LPDS - LPDS; - memcpy(addr, (char *)&off, LPDS); - memcpy(addr + LPDS, (char *)&id, LPDS); - - return 0; -} - -int page_debug_check(char *who, void *addr, int end, __u64 off, __u64 id) -{ - __u64 ne_off; - int err = 0; - - LASSERT(addr); - - ne_off = HTON__u64(off); - id = HTON__u64(id); - if (memcmp(addr, (char *)&ne_off, LPDS)) { - CERROR("%s: id "LPU64" offset "LPU64" off: "LPX64" != "LPX64"\n", - who, id, off, *(__u64 *)addr, ne_off); - err = -EINVAL; - } - if (memcmp(addr + LPDS, (char *)&id, LPDS)) { - CERROR("%s: id "LPU64" offset "LPU64" id: "LPX64" != "LPX64"\n", - who, id, off, *(__u64 *)(addr + LPDS), id); - err = -EINVAL; - } - - addr += end - LPDS - LPDS; - if (memcmp(addr, (char *)&ne_off, LPDS)) { - CERROR("%s: id "LPU64" offset "LPU64" end off: "LPX64" != "LPX64"\n", - who, id, off, *(__u64 *)addr, ne_off); - err = -EINVAL; - } - if (memcmp(addr + LPDS, (char *)&id, LPDS)) { - CERROR("%s: id "LPU64" offset "LPU64" end id: "LPX64" != "LPX64"\n", - who, id, off, *(__u64 *)(addr + LPDS), id); - err = -EINVAL; - } - - return err; -} -#undef LPDS - -EXPORT_SYMBOL(dump_lniobuf); -EXPORT_SYMBOL(dump_rniobuf); -EXPORT_SYMBOL(dump_ioo); -//EXPORT_SYMBOL(dump_req); -EXPORT_SYMBOL(dump_obdo); -EXPORT_SYMBOL(page_debug_setup); -EXPORT_SYMBOL(page_debug_check); diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c deleted file mode 100644 index 926991a..0000000 --- a/lustre/obdclass/genops.c +++ /dev/null @@ -1,503 +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. - * - * These are the only exported functions, they provide some generic - * infrastructure for managing object devices - */ - -#define DEBUG_SUBSYSTEM S_CLASS -#include /* for request_module() */ -#include -#include -#include -#include -#include - -extern struct list_head obd_types; -kmem_cache_t *obdo_cachep = NULL; -kmem_cache_t *import_cachep = NULL; -kmem_cache_t *export_cachep = NULL; - -int (*ptlrpc_put_connection_superhack)(struct ptlrpc_connection *c); - -/* - * support functions: we could use inter-module communication, but this - * is more portable to other OS's - */ -static struct obd_type *class_search_type(char *nm) -{ - struct list_head *tmp; - struct obd_type *type; - CDEBUG(D_INFO, "SEARCH %s\n", nm); - - tmp = &obd_types; - list_for_each(tmp, &obd_types) { - type = list_entry(tmp, struct obd_type, typ_chain); - CDEBUG(D_INFO, "TYP %s\n", type->typ_name); - if (strlen(type->typ_name) == strlen(nm) && - strcmp(type->typ_name, nm) == 0 ) { - return type; - } - } - return NULL; -} - -struct obd_type *class_nm_to_type(char *nm) -{ - struct obd_type *type = class_search_type(nm); - -#ifdef CONFIG_KMOD - if ( !type ) { - if ( !request_module(nm) ) { - CDEBUG(D_INFO, "Loaded module '%s'\n", nm); - type = class_search_type(nm); - } else { - CDEBUG(D_INFO, "Can't load module '%s'\n", nm); - } - } -#endif - return type; -} - -int class_register_type(struct obd_ops *ops, struct lprocfs_vars *vars, - char *nm) -{ - struct obd_type *type; - int rc; - - ENTRY; - - if (class_search_type(nm)) { - CDEBUG(D_IOCTL, "Type %s already registered\n", nm); - RETURN(-EEXIST); - } - - OBD_ALLOC(type, sizeof(*type)); - OBD_ALLOC(type->typ_ops, sizeof(*type->typ_ops)); - OBD_ALLOC(type->typ_name, strlen(nm) + 1); - if (!type) - RETURN(-ENOMEM); - INIT_LIST_HEAD(&type->typ_chain); - CDEBUG(D_INFO, "MOD_INC_USE for register_type: count = %d\n", - atomic_read(&(THIS_MODULE)->uc.usecount)); - MOD_INC_USE_COUNT; - list_add(&type->typ_chain, &obd_types); - memcpy(type->typ_ops, ops, sizeof(*type->typ_ops)); - strcpy(type->typ_name, nm); - rc = lprocfs_reg_class(type, vars, type); - - RETURN(rc); -} - -int class_unregister_type(char *nm) -{ - struct obd_type *type = class_nm_to_type(nm); - - ENTRY; - - if (!type) { - CERROR("unknown obd type\n"); - RETURN(-EINVAL); - } - - if (type->typ_refcnt) { - CERROR("type %s has refcount (%d)\n", nm, type->typ_refcnt); - /* This is a bad situation, let's make the best of it */ - /* Remove ops, but leave the name for debugging */ - OBD_FREE(type->typ_ops, sizeof(*type->typ_ops)); - RETURN(-EBUSY); - } - if(type->typ_procroot) - lprocfs_dereg_class(type); - - list_del(&type->typ_chain); - OBD_FREE(type->typ_name, strlen(nm) + 1); - if (type->typ_ops != NULL) - OBD_FREE(type->typ_ops, sizeof(*type->typ_ops)); - OBD_FREE(type, sizeof(*type)); - CDEBUG(D_INFO, "MOD_DEC_USE for register_type: count = %d\n", - atomic_read(&(THIS_MODULE)->uc.usecount) - 1); - MOD_DEC_USE_COUNT; - RETURN(0); -} /* class_unregister_type */ - -int class_name2dev(char *name) -{ - int res = -1; - int i; - - if (!name) - return -1; - - for (i=0; i < MAX_OBD_DEVICES; i++) { - struct obd_device *obd = &obd_dev[i]; - if (obd->obd_name && strcmp(name, obd->obd_name) == 0) { - res = i; - return res; - } - } - - return res; -} - -int class_uuid2dev(char *uuid) -{ - int res = -1; - int i; - - for (i=0; i < MAX_OBD_DEVICES; i++) { - struct obd_device *obd = &obd_dev[i]; - if (strncmp(uuid, obd->obd_uuid, sizeof(obd->obd_uuid)) == 0) { - res = i; - return res; - } - } - - return res; -} - - -struct obd_device *class_uuid2obd(char *uuid) -{ - int i; - - for (i=0; i < MAX_OBD_DEVICES; i++) { - struct obd_device *obd = &obd_dev[i]; - if (strncmp(uuid, obd->obd_uuid, sizeof(obd->obd_uuid)) == 0) - return obd; - } - - return NULL; -} - -void obd_cleanup_caches(void) -{ - int rc; - ENTRY; - if (obdo_cachep) { - rc = kmem_cache_destroy(obdo_cachep); - if (rc) - CERROR("Cannot destory ll_obdo_cache\n"); - obdo_cachep = NULL; - } - if (import_cachep) { - rc = kmem_cache_destroy(import_cachep); - if (rc) - CERROR("Cannot destory ll_import_cache\n"); - import_cachep = NULL; - } - if (export_cachep) { - rc = kmem_cache_destroy(export_cachep); - if (rc) - CERROR("Cannot destory ll_export_cache\n"); - export_cachep = NULL; - } - EXIT; -} - -int obd_init_caches(void) -{ - ENTRY; - LASSERT(obdo_cachep == NULL); - obdo_cachep = kmem_cache_create("ll_obdo_cache", sizeof(struct obdo), - 0, 0, NULL, NULL); - if (!obdo_cachep) - GOTO(out, -ENOMEM); - - LASSERT(export_cachep == NULL); - export_cachep = kmem_cache_create("ll_export_cache", - sizeof(struct obd_export), - 0, 0, NULL, NULL); - if (!export_cachep) - GOTO(out, -ENOMEM); - - LASSERT(import_cachep == NULL); - import_cachep = kmem_cache_create("ll_import_cache", - sizeof(struct obd_import), - 0, 0, NULL, NULL); - if (!import_cachep) - GOTO(out, -ENOMEM); - - RETURN(0); - out: - obd_cleanup_caches(); - RETURN(-ENOMEM); - -} - -/* map connection to client */ -struct obd_export *class_conn2export(struct lustre_handle *conn) -{ - struct obd_export *export; - ENTRY; - - if (!conn) { - CDEBUG(D_CACHE, "looking for null handle\n"); - RETURN(NULL); - } - - if (conn->addr == -1) { /* this means assign a new connection */ - CDEBUG(D_CACHE, "want a new connection\n"); - RETURN(NULL); - } - - if (!conn->addr) { - CDEBUG(D_CACHE, "looking for null addr\n"); - fixme(); - RETURN(NULL); - } - - CDEBUG(D_IOCTL, "looking for export addr "LPX64" cookie "LPX64"\n", - conn->addr, conn->cookie); - export = (struct obd_export *) (unsigned long)conn->addr; - if (!kmem_cache_validate(export_cachep, (void *)export)) - RETURN(NULL); - - if (export->exp_cookie != conn->cookie) - RETURN(NULL); - RETURN(export); -} /* class_conn2export */ - -struct obd_device *class_conn2obd(struct lustre_handle *conn) -{ - struct obd_export *export; - export = class_conn2export(conn); - if (export) - return export->exp_obd; - fixme(); - return NULL; -} - -struct obd_import *class_conn2cliimp(struct lustre_handle *conn) -{ - return &class_conn2obd(conn)->u.cli.cl_import; -} - -struct obd_import *class_conn2ldlmimp(struct lustre_handle *conn) -{ - return &class_conn2export(conn)->exp_ldlm_data.led_import; -} - -struct obd_export *class_new_export(struct obd_device *obddev) -{ - struct obd_export * export; - - export = kmem_cache_alloc(export_cachep, GFP_KERNEL); - if (!export) { - CERROR("no memory! (minor %d)\n", obddev->obd_minor); - return NULL; - } - - memset(export, 0, sizeof(*export)); - get_random_bytes(&export->exp_cookie, sizeof(export->exp_cookie)); - export->exp_obd = obddev; - /* XXX this should be in LDLM init */ - INIT_LIST_HEAD(&export->exp_ldlm_data.led_held_locks); - INIT_LIST_HEAD(&export->exp_conn_chain); - spin_lock(&obddev->obd_dev_lock); - list_add(&export->exp_obd_chain, &export->exp_obd->obd_exports); - spin_unlock(&obddev->obd_dev_lock); - return export; -} - -void class_destroy_export(struct obd_export *exp) -{ - ENTRY; - - LASSERT(exp->exp_cookie != DEAD_HANDLE_MAGIC); - - spin_lock(&exp->exp_obd->obd_dev_lock); - list_del(&exp->exp_obd_chain); - spin_unlock(&exp->exp_obd->obd_dev_lock); - - /* XXXshaver no connection here... */ - if (exp->exp_connection) - spin_lock(&exp->exp_connection->c_lock); - list_del(&exp->exp_conn_chain); - if (exp->exp_connection) { - spin_unlock(&exp->exp_connection->c_lock); - ptlrpc_put_connection_superhack(exp->exp_connection); - } - - exp->exp_cookie = DEAD_HANDLE_MAGIC; - kmem_cache_free(export_cachep, exp); - - EXIT; -} - -/* a connection defines an export context in which preallocation can - be managed. */ -int class_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid) -{ - struct obd_export * export; - if (conn == NULL) { - LBUG(); - return -EINVAL; - } - - if (obd == NULL) { - LBUG(); - return -EINVAL; - } - - export = class_new_export(obd); - if (!export) - return -ENOMEM; - - conn->addr = (__u64) (unsigned long)export; - conn->cookie = export->exp_cookie; - - CDEBUG(D_IOCTL, "connect: addr %Lx cookie %Lx\n", - (long long)conn->addr, (long long)conn->cookie); - return 0; -} - -int class_disconnect(struct lustre_handle *conn) -{ - struct obd_export *export; - ENTRY; - - if (!(export = class_conn2export(conn))) { - fixme(); - CDEBUG(D_IOCTL, "disconnect: attempting to free " - "nonexistent client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - CDEBUG(D_IOCTL, "disconnect: addr %Lx cookie %Lx\n", - (long long)conn->addr, (long long)conn->cookie); - - class_destroy_export(export); - - RETURN(0); -} - -void class_disconnect_all(struct obd_device *obddev) -{ - int again = 1; - - while (again) { - spin_lock(&obddev->obd_dev_lock); - if (!list_empty(&obddev->obd_exports)) { - struct obd_export *export; - struct lustre_handle conn; - int rc; - - export = list_entry(obddev->obd_exports.next, - struct obd_export, - exp_obd_chain); - conn.addr = (__u64)(unsigned long)export; - conn.cookie = export->exp_cookie; - spin_unlock(&obddev->obd_dev_lock); - CERROR("force disconnecting %s:%s export %p\n", - export->exp_obd->obd_type->typ_name, - export->exp_connection->c_remote_uuid, export); - rc = obd_disconnect(&conn); - if (rc < 0) { - /* AED: not so sure about this... We can't - * loop here forever, yet we shouldn't leak - * exports on a struct we will soon destroy. - */ - CERROR("destroy export %p with err: rc = %d\n", - export, rc); - class_destroy_export(export); - } - } else { - spin_unlock(&obddev->obd_dev_lock); - again = 0; - } - } -} - -#if 0 - -/* FIXME: Data is a space- or comma-separated list of device IDs. This will - * have to change. */ -int class_multi_setup(struct obd_device *obddev, uint32_t len, void *data) -{ - int count, rc; - char *p; - ENTRY; - - for (p = data, count = 0; p < (char *)data + len; count++) { - char *end; - int tmp = simple_strtoul(p, &end, 0); - - if (p == end) { - CERROR("invalid device ID starting at: %s\n", p); - GOTO(err_disconnect, rc = -EINVAL); - } - - if (tmp < 0 || tmp >= MAX_OBD_DEVICES) { - CERROR("Trying to sub dev %d - dev no too large\n", - tmp); - GOTO(err_disconnect, rc = -EINVAL); - } - - rc = obd_connect(&obddev->obd_multi_conn[count], &obd_dev[tmp]); - if (rc) { - CERROR("cannot connect to device %d: rc = %d\n", tmp, - rc); - GOTO(err_disconnect, rc); - } - - CDEBUG(D_INFO, "target OBD %d is of type %s\n", count, - obd_dev[tmp].obd_type->typ_name); - - p = end + 1; - } - - obddev->obd_multi_count = count; - - RETURN(0); - - err_disconnect: - for (count--; count >= 0; count--) - obd_disconnect(&obddev->obd_multi_conn[count]); - return rc; -} - -/* - * remove all connections to this device - * close all connections to lower devices - * needed for forced unloads of OBD client drivers - */ -int class_multi_cleanup(struct obd_device *obddev) -{ - int i; - - for (i = 0; i < obddev->obd_multi_count; i++) { - int rc; - struct obd_device *obd = - class_conn2obd(&obddev->obd_multi_conn[i]); - - if (!obd) { - CERROR("no such device [i %d]\n", i); - RETURN(-EINVAL); - } - - rc = obd_disconnect(&obddev->obd_multi_conn[i]); - if (rc) - CERROR("disconnect failure %d\n", obd->obd_minor); - } - return 0; -} -#endif diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c deleted file mode 100644 index 62a806e..0000000 --- a/lustre/obdclass/lprocfs_status.c +++ /dev/null @@ -1,331 +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. - * - * Author: Hariharan Thantry thantry@users.sourceforge.net - */ -#define EXPORT_SYMTAB -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_CLASS -#include -#include - -#ifdef LPROC_SNMP - -#define DEFAULT_MODE 0444 -/* - * Tokenizer array. Change this array to include special - * characters for string tokenizing - */ -const char tok[] = {'/', '\0'}; - -/* - * Externs - */ -extern struct proc_dir_entry proc_root; /* Defined in proc/root.c */ - -/* - * Globals - */ -struct proc_dir_entry *proc_lustre_root; -struct proc_dir_entry *proc_lustre_dev_root; -struct proc_dir_entry *proc_lustre_fs_root; - -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 NULL; - temp = head->subdir; - while (temp != NULL) { - if (!strcmp(temp->name, name)) - return temp; - temp = temp->next; - } - return NULL; -} - -void lprocfs_remove_all(struct proc_dir_entry* root) -{ - struct proc_dir_entry *temp = root; - struct proc_dir_entry *rm_entry; - struct proc_dir_entry *parent = root->parent; - - 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 == parent) break; - } -} - -#define MAX_STRING_SIZE 100 -struct proc_dir_entry* lprocfs_new_dir(struct proc_dir_entry* root, - const char* string, const char* tok) -{ - struct proc_dir_entry* new_root; - struct proc_dir_entry* temp_entry; - char temp_string[MAX_STRING_SIZE+1]; - char* my_str; - char* mover_str; - - strncpy(temp_string, string, MAX_STRING_SIZE); - temp_string[MAX_STRING_SIZE] = '\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 == NULL) { - CDEBUG(D_OTHER, "Adding: %s\n", my_str); - temp_entry = lprocfs_mkdir(my_str, new_root); - if (temp_entry == NULL) { - CDEBUG(D_OTHER, - "! Did not create new dir %s !!\n", - my_str); - return temp_entry; - } - } - new_root = temp_entry; - } - return new_root; -} - -int lprocfs_new_vars(struct proc_dir_entry* root, - struct lprocfs_vars* list, - const char* tok, void* data) -{ - struct proc_dir_entry *temp_root; - struct proc_dir_entry *new_leaf; - struct proc_dir_entry *new_parent; - char temp_string[MAX_STRING_SIZE+1]; - - if (list == NULL) - return 0; - - while (list->name) { - temp_root = lprocfs_new_dir(root, list->name, tok); - if (temp_root == NULL) { - CDEBUG(D_OTHER, "!LProcFS: Mods: No root!"); - return -ENOMEM; - } - - /* Convert the last element into a leaf-node */ - strncpy(temp_string, temp_root->name, MAX_STRING_SIZE); - temp_string[MAX_STRING_SIZE] = '\0'; - new_parent = temp_root->parent; - remove_proc_entry(temp_root->name, new_parent); - new_leaf = create_proc_entry(temp_string, DEFAULT_MODE, - new_parent); - if (new_leaf == NULL) { - CERROR("LprocFS: No memory to create /proc entry %s", - temp_string); - return -ENOMEM; - } - new_leaf->read_proc = list->read_fptr; - new_leaf->write_proc = list->write_fptr; - if (data) - new_leaf->data=data; - else - new_leaf->data=list->data; - list++; - } - return 0; - -} -#undef MAX_STRING_SIZE -/* - * API implementations - */ -int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *var, - void *data) -{ - return lprocfs_new_vars(root, var, tok, data); -} - -int lprocfs_reg_obd(struct obd_device *device, struct lprocfs_vars *list, - void *data) -{ - struct proc_dir_entry* this_dev_root; - int retval; - - if(lprocfs_srch(device->obd_type->typ_procroot, device->obd_name)){ - CDEBUG(D_OTHER, "Device with name [%s] exists!", - device->obd_name); - return 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 == NULL) { - CDEBUG(D_OTHER, "! LProcfs: Null pointer !\n"); - return 0; - } - if (device->obd_proc_entry == NULL) { - CDEBUG(D_OTHER, "! Proc entry non-existent !"); - return 0; - } - lprocfs_remove_all(device->obd_proc_entry); - device->obd_proc_entry = NULL; - if (device->counters) - OBD_FREE(device->counters, device->cntr_mem_size); - - return 0; -} - -struct proc_dir_entry* lprocfs_reg_mnt(char* mnt_name) -{ - if(lprocfs_srch(proc_lustre_fs_root, mnt_name)){ - CDEBUG(D_OTHER, "Mount with same name exists!"); - return 0; - } - return lprocfs_mkdir(mnt_name, proc_lustre_fs_root); -} - -int lprocfs_dereg_mnt(struct proc_dir_entry* root) -{ - if(root == NULL){ - CDEBUG(D_OTHER, "Non-existent root!"); - return 0; - } - lprocfs_remove_all(root); - return 0; -} - -int lprocfs_reg_class(struct obd_type* type, struct lprocfs_vars* list, - void* data) -{ - - struct proc_dir_entry* root; - int retval; - root = lprocfs_mkdir(type->typ_name, proc_lustre_dev_root); - lprocfs_add_vars(root, list, data); - type->typ_procroot = root; - retval = lprocfs_add_vars(root, list, data); - return retval; -} - -int lprocfs_dereg_class(struct obd_type* class) -{ - if(class == NULL){ - CDEBUG(D_OTHER, "Non-existent class", - class->typ_name); - return 0; - } - lprocfs_remove_all(class->typ_procroot); - class->typ_procroot = NULL; - 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 == NULL) { - CERROR(" !! Cannot create /proc/lustre !! \n"); - return -EINVAL; - } - - proc_lustre_dev_root = lprocfs_mkdir("devices", proc_lustre_root); - if (proc_lustre_dev_root == NULL) { - 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 == NULL) { - 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 = NULL; - proc_lustre_dev_root = NULL; - proc_lustre_fs_root = NULL; - 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/obdclass/sysctl.c b/lustre/obdclass/sysctl.c deleted file mode 100644 index 8e74aab..0000000 --- a/lustre/obdclass/sysctl.c +++ /dev/null @@ -1,133 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_CLASS - -#include - -struct ctl_table_header *obd_table_header = NULL; - -static int vars[2]; -static int index = 0; - -static int obd_sctl_vars( ctl_table * table, int write, struct file * - filp, void * buffer, size_t * lenp ); -static int obd_sctl_reset( ctl_table * table, int write, struct file - * filp, void * buffer, size_t * lenp ); - -#define OBD_SYSCTL 300 - -#define OBD_FAIL_LOC 1 /* control test failures instrumentation */ -#define OBD_ENTRY 2 /* control enter/leave pattern */ -#define OBD_VARS 3 -#define OBD_INDEX 4 -#define OBD_RESET 5 -#define OBD_TIMEOUT 6 /* RPC timeout before recovery/intr */ -/* XXX move to /proc/sys/lustre/recovery? */ -#define OBD_UPCALL 7 /* path to recovery upcall */ - -#define OBD_VARS_SLOT 2 - -static ctl_table obd_table[] = { - {OBD_FAIL_LOC, "fail_loc", &obd_fail_loc, sizeof(int), 0644, NULL, &proc_dointvec}, - {OBD_VARS, "vars", &vars[0], sizeof(int), 0644, NULL, &proc_dointvec}, - {OBD_INDEX, "index", &index, sizeof(int), 0644, NULL, &obd_sctl_vars}, - {OBD_RESET, "reset", NULL, 0, 0644, NULL, &obd_sctl_reset}, - {OBD_TIMEOUT, "timeout", &obd_timeout, sizeof(int), 0644, NULL, &proc_dointvec}, - /* XXX need to lock so we avoid update races with the recovery upcall! */ - {OBD_UPCALL, "recovery_upcall", obd_recovery_upcall, 128, 0644, NULL, - &proc_dostring, &sysctl_string }, - { 0 } -}; - -static ctl_table parent_table[] = { - {OBD_SYSCTL, "lustre", NULL, 0, 0555, obd_table}, - {0} -}; - -void obd_sysctl_init (void) -{ -#ifdef CONFIG_SYSCTL - if ( !obd_table_header ) - obd_table_header = register_sysctl_table(parent_table, 0); -#endif -} - -void obd_sysctl_clean (void) -{ -#ifdef CONFIG_SYSCTL - if ( obd_table_header ) - unregister_sysctl_table(obd_table_header); - obd_table_header = NULL; -#endif -} - -int obd_sctl_reset (ctl_table * table, int write, - struct file * filp, void * buffer, - size_t * lenp) -{ - if ( write ) { - /* do something here */ - vars[0]=0; - vars[1]=0; - } - - *lenp = 0; - return 0; -} - -int obd_sctl_vars (ctl_table * table, int write, - struct file * filp, void * buffer, - size_t * lenp) -{ - int rc; - - rc = proc_dointvec(table, write, filp, buffer, lenp); - - if ( rc ) - return rc; - - if ( index < 0 || index > 1 ) { - CERROR("Illegal index %d!\n", index); - index = 0; - } else { - obd_table[OBD_VARS_SLOT].data = &vars[index]; - } - - return rc; -} diff --git a/lustre/obdclass/uuid.c b/lustre/obdclass/uuid.c deleted file mode 100644 index 7048baa..0000000 --- a/lustre/obdclass/uuid.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Public include file for the UUID library - * - * Copyright (C) 1996, 1997, 1998 Theodore Ts'o. - * Copyright (C) 2002 Cluster File System - * - changed for use in lustre - * - * %Begin-Header% - * This file may be redistributed under the terms of the GNU - * Library General Public License. - * %End-Header% - */ -#include -#include - -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#include -#include - -struct uuid { - __u32 time_low; - __u16 time_mid; - __u16 time_hi_and_version; - __u16 clock_seq; - __u8 node[6]; -}; - -static void uuid_unpack(class_uuid_t in, struct uuid *uu) -{ - __u8 *ptr = in; - __u32 tmp; - - tmp = *ptr++; - tmp = (tmp << 8) | *ptr++; - tmp = (tmp << 8) | *ptr++; - tmp = (tmp << 8) | *ptr++; - uu->time_low = tmp; - - tmp = *ptr++; - tmp = (tmp << 8) | *ptr++; - uu->time_mid = tmp; - - tmp = *ptr++; - tmp = (tmp << 8) | *ptr++; - uu->time_hi_and_version = tmp; - - tmp = *ptr++; - tmp = (tmp << 8) | *ptr++; - uu->clock_seq = tmp; - - memcpy(uu->node, ptr, 6); -} - -#if 0 -static void uuid_pack(struct uuid *uu, class_uuid_t ptr) -{ - __u32 tmp; - unsigned char *out = ptr; - - tmp = uu->time_low; - out[3] = (unsigned char) tmp; - tmp >>= 8; - out[2] = (unsigned char) tmp; - tmp >>= 8; - out[1] = (unsigned char) tmp; - tmp >>= 8; - out[0] = (unsigned char) tmp; - - tmp = uu->time_mid; - out[5] = (unsigned char) tmp; - tmp >>= 8; - out[4] = (unsigned char) tmp; - - tmp = uu->time_hi_and_version; - out[7] = (unsigned char) tmp; - tmp >>= 8; - out[6] = (unsigned char) tmp; - - tmp = uu->clock_seq; - out[9] = (unsigned char) tmp; - tmp >>= 8; - out[8] = (unsigned char) tmp; - - memcpy(out+10, uu->node, 6); -} - -int class_uuid_parse(obd_uuid_t in, class_uuid_t uu) -{ - struct uuid uuid; - int i; - char *cp, buf[3]; - - if (strlen(in) != 36) - return -1; - for (i=0, cp = in; i <= 36; i++,cp++) { - if ((i == 8) || (i == 13) || (i == 18) || - (i == 23)) - if (*cp == '-') - continue; - if (i== 36) - if (*cp == 0) - continue; - if (!isxdigit(*cp)) - return -1; - } - uuid.time_low = simple_strtoul(in, NULL, 16); - uuid.time_mid = simple_strtoul(in+9, NULL, 16); - uuid.time_hi_and_version = simple_strtoul(in+14, NULL, 16); - uuid.clock_seq = simple_strtoul(in+19, NULL, 16); - cp = in+24; - buf[2] = 0; - for (i=0; i < 6; i++) { - buf[0] = *cp++; - buf[1] = *cp++; - uuid.node[i] = simple_strtoul(buf, NULL, 16); - } - - uuid_pack(&uuid, uu); - return 0; -} -#endif - -void class_uuid_unparse(class_uuid_t uu, obd_uuid_t out) -{ - struct uuid uuid; - - uuid_unpack(uu, &uuid); - sprintf(out, - "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, - uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, - uuid.node[0], uuid.node[1], uuid.node[2], - uuid.node[3], uuid.node[4], uuid.node[5]); -} diff --git a/lustre/obdecho/.cvsignore b/lustre/obdecho/.cvsignore deleted file mode 100644 index e530020..0000000 --- a/lustre/obdecho/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/obdecho/Makefile.am b/lustre/obdecho/Makefile.am deleted file mode 100644 index ad0e0ff..0000000 --- a/lustre/obdecho/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= -MODULE = obdecho -modulefs_DATA = obdecho.o -EXTRA_PROGRAMS = obdecho - -LINX= -obdecho_SOURCES = echo.c echo_client.c lproc_echo.c $(LINX) - -include $(top_srcdir)/Rules - diff --git a/lustre/obdecho/echo.c b/lustre/obdecho/echo.c deleted file mode 100644 index 76fddd8..0000000 --- a/lustre/obdecho/echo.c +++ /dev/null @@ -1,507 +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. - * Author: Peter Braam - * 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 OBDECHO_VERSION "1.0" - -#define EXPORT_SYMTAB - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_ECHO - -#include -#include -#include -#include -#include -#include - -static atomic_t echo_page_rws; -static atomic_t echo_getattrs; - -#define ECHO_PROC_STAT "sys/obdecho" -#define ECHO_INIT_OBJID 0x1000000000000000ULL - -extern struct lprocfs_vars status_var_nm_1[]; -extern struct lprocfs_vars status_class_var[]; - -int echo_proc_read(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - long long attrs = atomic_read(&echo_getattrs); - long long pages = atomic_read(&echo_page_rws); - int len; - - *eof = 1; - if (off != 0) - return (0); - - len = sprintf(page, "%Ld %Ld\n", attrs, pages); - - *start = page; - return (len); -} - -int echo_proc_write(struct file *file, const char *ubuffer, - unsigned long count, void *data) -{ - /* Ignore what we've been asked to write, and just zero the counters */ - atomic_set (&echo_page_rws, 0); - atomic_set (&echo_getattrs, 0); - - return (count); -} - -void echo_proc_init(void) -{ - struct proc_dir_entry *entry; - - entry = create_proc_entry(ECHO_PROC_STAT, S_IFREG|S_IRUGO|S_IWUSR,NULL); - - if (entry == NULL) { - CERROR("couldn't create proc entry %s\n", ECHO_PROC_STAT); - return; - } - - entry->data = NULL; - entry->read_proc = echo_proc_read; - entry->write_proc = echo_proc_write; -} - -void echo_proc_fini(void) -{ - remove_proc_entry(ECHO_PROC_STAT, 0); -} - -static int echo_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - int rc; - - MOD_INC_USE_COUNT; - rc = class_connect(conn, obd, cluuid); - - if (rc) - MOD_DEC_USE_COUNT; - - return rc; -} - -static int echo_disconnect(struct lustre_handle *conn) -{ - int rc; - - rc = class_disconnect(conn); - if (!rc) - MOD_DEC_USE_COUNT; - - return rc; -} - -static __u64 echo_next_id(struct obd_device *obddev) -{ - obd_id id; - - spin_lock(&obddev->u.echo.eo_lock); - id = ++obddev->u.echo.eo_lastino; - spin_unlock(&obddev->u.echo.eo_lock); - - return id; -} - -int echo_create(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md **ea) -{ - struct obd_device *obd = class_conn2obd(conn); - - if (!obd) { - CERROR("invalid client %Lx\n", conn->addr); - return -EINVAL; - } - - if (!(oa->o_mode && S_IFMT)) { - CERROR("filter obd: no type!\n"); - return -ENOENT; - } - - if (!(oa->o_valid & OBD_MD_FLTYPE)) { - CERROR("invalid o_valid %08x\n", oa->o_valid); - return -EINVAL; - } - - oa->o_id = echo_next_id(obd); - oa->o_valid = OBD_MD_FLID; - atomic_inc(&obd->u.echo.eo_create); - - return 0; -} - -int echo_destroy(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea) -{ - struct obd_device *obd = class_conn2obd(conn); - - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - if (!(oa->o_valid & OBD_MD_FLID)) { - CERROR("obdo missing FLID valid flag: %08x\n", oa->o_valid); - RETURN(-EINVAL); - } - - if (oa->o_id > obd->u.echo.eo_lastino || oa->o_id < ECHO_INIT_OBJID) { - CERROR("bad destroy objid: "LPX64"\n", oa->o_id); - RETURN(-EINVAL); - } - - atomic_inc(&obd->u.echo.eo_destroy); - - return 0; -} - -static int echo_open(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md) -{ - return 0; -} - -static int echo_close(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md) -{ - return 0; -} - -static int echo_getattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md) -{ - struct obd_device *obd = class_conn2obd(conn); - obd_id id = oa->o_id; - - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - if (!(oa->o_valid & OBD_MD_FLID)) { - CERROR("obdo missing FLID valid flag: %08x\n", oa->o_valid); - RETURN(-EINVAL); - } - - memcpy(oa, &obd->u.echo.oa, sizeof(*oa)); - oa->o_id = id; - oa->o_valid |= OBD_MD_FLID; - - atomic_inc(&echo_getattrs); - - return 0; -} - -static int echo_setattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md) -{ - struct obd_device *obd = class_conn2obd(conn); - - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - if (!(oa->o_valid & OBD_MD_FLID)) { - CERROR("obdo missing FLID valid flag: %08x\n", oa->o_valid); - RETURN(-EINVAL); - } - - memcpy(&obd->u.echo.oa, oa, sizeof(*oa)); - - atomic_inc(&obd->u.echo.eo_setattr); - - return 0; -} - -/* This allows us to verify that desc_private is passed unmolested */ -#define DESC_PRIV 0x10293847 - -int echo_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; - struct niobuf_local *r = res; - int rc = 0; - int i; - - ENTRY; - - obd = class_conn2obd(conn); - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - memset(res, 0, sizeof(*res) * niocount); - - CDEBUG(D_PAGE, "%s %d obdos with %d IOs\n", - cmd == OBD_BRW_READ ? "reading" : "writing", objcount, niocount); - - *desc_private = (void *)DESC_PRIV; - - obd_kmap_get(niocount, 1); - - for (i = 0; i < objcount; i++, obj++) { - int gfp_mask = (obj->ioo_id & 1) ? GFP_HIGHUSER : GFP_KERNEL; - int verify = obj->ioo_id != 0; - int j; - - for (j = 0 ; j < obj->ioo_bufcnt ; j++, nb++, r++) { - r->page = alloc_pages(gfp_mask, 0); - if (!r->page) { - CERROR("can't get page %d/%d for id "LPU64"\n", - j, obj->ioo_bufcnt, obj->ioo_id); - GOTO(preprw_cleanup, rc = -ENOMEM); - } - atomic_inc(&obd->u.echo.eo_prep); - - r->offset = nb->offset; - r->addr = kmap(r->page); - r->len = nb->len; - - CDEBUG(D_PAGE, "$$$$ get page %p, addr %p@"LPU64"\n", - r->page, r->addr, r->offset); - - if (verify && cmd == OBD_BRW_READ) - page_debug_setup(r->addr, r->len, r->offset, - obj->ioo_id); - else if (verify) - page_debug_setup(r->addr, r->len, - 0xecc0ecc0ecc0ecc0, - 0xecc0ecc0ecc0ecc0); - } - } - CDEBUG(D_PAGE, "%d pages allocated after prep\n", - atomic_read(&obd->u.echo.eo_prep)); - - RETURN(0); - -preprw_cleanup: - /* It is possible that we would rather handle errors by allow - * any already-set-up pages to complete, rather than tearing them - * all down again. I believe that this is what the in-kernel - * prep/commit operations do. - */ - CERROR("cleaning up %ld pages (%d obdos)\n", (long)(r - res), objcount); - while (r-- > res) { - kunmap(r->page); - __free_pages(r->page, 0); - atomic_dec(&obd->u.echo.eo_prep); - } - obd_kmap_put(niocount); - memset(res, 0, sizeof(*res) * niocount); - - return rc; -} - -int echo_commitrw(int cmd, struct lustre_handle *conn, int objcount, - struct obd_ioobj *obj, int niocount, struct niobuf_local *res, - void *desc_private) -{ - struct obd_device *obd; - struct niobuf_local *r = res; - int rc = 0; - int i; - ENTRY; - - obd = class_conn2obd(conn); - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - if ((cmd & OBD_BRW_RWMASK) == OBD_BRW_READ) { - CDEBUG(D_PAGE, "reading %d obdos with %d IOs\n", - objcount, niocount); - } else { - CDEBUG(D_PAGE, "writing %d obdos with %d IOs\n", - objcount, niocount); - } - - if (niocount && !r) { - CERROR("NULL res niobuf with niocount %d\n", niocount); - RETURN(-EINVAL); - } - - LASSERT(desc_private == (void *)DESC_PRIV); - - for (i = 0; i < objcount; i++, obj++) { - int verify = obj->ioo_id != 0; - int j; - - for (j = 0 ; j < obj->ioo_bufcnt ; j++, r++) { - struct page *page = r->page; - void *addr; - - if (!page || !(addr = page_address(page)) || - !kern_addr_valid(addr)) { - - CERROR("bad page objid "LPU64":%p, buf %d/%d\n", - obj->ioo_id, page, j, obj->ioo_bufcnt); - GOTO(commitrw_cleanup, rc = -EFAULT); - } - - atomic_inc(&echo_page_rws); - - CDEBUG(D_PAGE, "$$$$ use page %p, addr %p@"LPU64"\n", - r->page, addr, r->offset); - - if (verify) - page_debug_check("echo", addr, r->len, - r->offset, obj->ioo_id); - - kunmap(page); - obd_kmap_put(1); - __free_pages(page, 0); - atomic_dec(&obd->u.echo.eo_prep); - } - } - CDEBUG(D_PAGE, "%d pages remain after commit\n", - atomic_read(&obd->u.echo.eo_prep)); - RETURN(0); - -commitrw_cleanup: - CERROR("cleaning up %ld pages (%d obdos)\n", - niocount - (long)(r - res) - 1, objcount); - while (++r < res + niocount) { - struct page *page = r->page; - - kunmap(page); - obd_kmap_put(1); - __free_pages(page, 0); - atomic_dec(&obd->u.echo.eo_prep); - } - return rc; -} - -static int echo_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - ENTRY; - - obddev->obd_namespace = - ldlm_namespace_new("echo-tgt", LDLM_NAMESPACE_SERVER); - if (obddev->obd_namespace == NULL) { - LBUG(); - RETURN(-ENOMEM); - } - spin_lock_init(&obddev->u.echo.eo_lock); - obddev->u.echo.eo_lastino = ECHO_INIT_OBJID; - - RETURN(0); -} - -static int echo_cleanup(struct obd_device *obddev) -{ - ENTRY; - - ldlm_namespace_free(obddev->obd_namespace); - CERROR("%d prep/commitrw pages leaked\n", - atomic_read(&obddev->u.echo.eo_prep)); - - RETURN(0); -} - -int echo_attach(struct obd_device *dev, obd_count len, void *data) -{ - return lprocfs_reg_obd(dev, status_var_nm_1, dev); -} - -int echo_detach(struct obd_device *dev) -{ - return lprocfs_dereg_obd(dev); -} - -static struct obd_ops echo_obd_ops = { - o_attach: echo_attach, - o_detach: echo_detach, - o_connect: echo_connect, - o_disconnect: echo_disconnect, - o_create: echo_create, - o_destroy: echo_destroy, - o_open: echo_open, - o_close: echo_close, - o_getattr: echo_getattr, - o_setattr: echo_setattr, - o_preprw: echo_preprw, - o_commitrw: echo_commitrw, - o_setup: echo_setup, - o_cleanup: echo_cleanup -}; - -extern int echo_client_init(void); -extern void echo_client_cleanup(void); - -static int __init obdecho_init(void) -{ - int rc; - - printk(KERN_INFO "Echo OBD driver " OBDECHO_VERSION - " info@clusterfs.com\n"); - - echo_proc_init(); - rc = class_register_type(&echo_obd_ops, status_class_var, - OBD_ECHO_DEVICENAME); - if (rc) - RETURN(rc); - - rc = echo_client_init(); - if (rc) - class_unregister_type(OBD_ECHO_DEVICENAME); - - RETURN(rc); -} - -static void __exit obdecho_exit(void) -{ - echo_proc_fini(); - echo_client_cleanup(); - class_unregister_type(OBD_ECHO_DEVICENAME); -} - -MODULE_AUTHOR("Cluster Filesystems Inc. "); -MODULE_DESCRIPTION("Lustre Testing Echo OBD driver " OBDECHO_VERSION); -MODULE_LICENSE("GPL"); - -module_init(obdecho_init); -module_exit(obdecho_exit); diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c deleted file mode 100644 index 4ccc043..0000000 --- a/lustre/obdecho/echo_client.c +++ /dev/null @@ -1,277 +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(unsigned int 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; - struct lov_stripe_md *lsm = NULL; - ENTRY; - - if (obd == NULL) { - CERROR("ioctl: No device\n"); - GOTO(out, rc = -EINVAL); - } - - if (data->ioc_inllen1 == sizeof(*lsm)) { - lsm = (struct lov_stripe_md *)data->ioc_inlbuf1; - } else if (data->ioc_inllen1 != 0) { - CERROR("nonzero ioc_inllen1 != sizeof(struct lov_stripe_md)\n"); - GOTO(out, rc = -EINVAL); - } - - switch (cmd) { - case OBD_IOC_CREATE: { - struct lov_stripe_md *tmp_lsm = NULL; - rc = obd_create(&ec->conn, &data->ioc_obdo1, &tmp_lsm); - if (lsm) - memcpy(lsm, tmp_lsm, sizeof(*tmp_lsm)); - - GOTO(out, rc); - } - - case OBD_IOC_GETATTR: - rc = obd_getattr(&ec->conn, &data->ioc_obdo1, lsm); - GOTO(out, rc); - - case OBD_IOC_SETATTR: - rc = obd_setattr(&ec->conn, &data->ioc_obdo1, lsm); - GOTO(out, rc); - - case OBD_IOC_DESTROY: - rc = obd_destroy(&ec->conn, &data->ioc_obdo1, lsm); - GOTO(out, rc); - - case OBD_IOC_OPEN: - rc = obd_open(&ec->conn, &data->ioc_obdo1, lsm); - GOTO(out, rc); - - case OBD_IOC_CLOSE: - 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; - struct obd_brw_set *set; - obd_count pages = 0; - struct brw_page *pga, *pgp; - __u64 off, id = data->ioc_obdo1.o_id; - int gfp_mask = (id & 1) ? GFP_HIGHUSER : GFP_KERNEL; - int j, verify = (id != 0); - - if (lsm && lsm->lsm_object_id != id) { - CERROR("LSM object ID ("LPU64") != id ("LPU64")\n", - lsm->lsm_object_id, id); - GOTO(out, rc = -EINVAL); - } - - if (!lsm) { - memset(&tmp_lsm, 0, sizeof(tmp_lsm)); - lsm = &tmp_lsm; - lsm->lsm_object_id = id; - } - - if (data->ioc_count < 0) { - CERROR("invalid buffer size: "LPD64"\n", - data->ioc_count); - GOTO(out, rc = -EINVAL); - } - - 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); - } - - 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: - CERROR ("echo_ioctl(): unrecognised ioctl %#lx\n", cmd); - GOTO (out, rc = -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 449f9c5..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; - -} - - -struct lprocfs_vars status_var_nm_1[] = { - {"status/uuid", rd_uuid, 0, 0}, - {"status/fstype", rd_fstype, 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; - int len = 0; - len += snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -struct lprocfs_vars status_class_var[] = { - {"status/num_refs", rd_numrefs, 0, 0}, - {0} -}; diff --git a/lustre/obdfilter/.cvsignore b/lustre/obdfilter/.cvsignore deleted file mode 100644 index e530020..0000000 --- a/lustre/obdfilter/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/obdfilter/Makefile.am b/lustre/obdfilter/Makefile.am deleted file mode 100644 index a237004..0000000 --- a/lustre/obdfilter/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= -MODULE = obdfilter -modulefs_DATA = obdfilter.o -EXTRA_PROGRAMS = obdfilter - -LINX=simple.c ll_pack.c -ll_pack.c: - test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c - -simple.c: - test -e simple.c || ln -sf $(top_srcdir)/lib/simple.c - -FILTERC = filter.c lproc_obdfilter.c -obdfilter_SOURCES = $(FILTERC) $(LINX) - -dist-hook: - list='$(LINX)'; for f in $$list; do rm -f $(distdir)/$$f; done - -include $(top_srcdir)/Rules - diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c deleted file mode 100644 index 76d21cc..0000000 --- a/lustre/obdfilter/filter.c +++ /dev/null @@ -1,1864 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * linux/fs/obdfilter/filter.c - * - * Copyright (c) 2001, 2002 Cluster File Systems, Inc. - * Author: Peter Braam - * 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 EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_FILTER - -#include -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#include -#include -#include -#include - -extern struct lprocfs_vars status_class_var[]; -extern struct lprocfs_vars status_var_nm_1[]; - -static kmem_cache_t *filter_open_cache; -static kmem_cache_t *filter_dentry_cache; - -#define FILTER_ROOTINO 2 -#define FILTER_ROOTINO_STR __stringify(FILTER_ROOTINO) - -#define S_SHIFT 12 -static char *obd_type_by_mode[S_IFMT >> S_SHIFT] = { - [0] NULL, - [S_IFREG >> S_SHIFT] "R", - [S_IFDIR >> S_SHIFT] "D", - [S_IFCHR >> S_SHIFT] "C", - [S_IFBLK >> S_SHIFT] "B", - [S_IFIFO >> S_SHIFT] "F", - [S_IFSOCK >> S_SHIFT] "S", - [S_IFLNK >> S_SHIFT] "L" -}; - -static inline const char *obd_mode_to_type(int mode) -{ - return obd_type_by_mode[(mode & S_IFMT) >> S_SHIFT]; -} - -/* write the pathname into the string */ -static int filter_id(char *buf, obd_id id, obd_mode mode) -{ - return sprintf(buf, "O/%s/"LPU64, obd_mode_to_type(mode), id); -} - -static inline void f_dput(struct dentry *dentry) -{ - /* Can't go inside filter_ddelete because it can block */ - CDEBUG(D_INODE, "putting %s: %p, count = %d\n", - dentry->d_name.name, dentry, atomic_read(&dentry->d_count) - 1); - LASSERT(atomic_read(&dentry->d_count) > 0); - - dput(dentry); -} - -/* Not racy w.r.t. others, because we are the only user of this dentry */ -static void filter_drelease(struct dentry *dentry) -{ - if (dentry->d_fsdata) - kmem_cache_free(filter_dentry_cache, dentry->d_fsdata); -} - -struct dentry_operations filter_dops = { - .d_release = filter_drelease, -}; - -/* setup the object store with correct subdirectories */ -static int filter_prep(struct obd_device *obd) -{ - struct obd_run_ctxt saved; - struct filter_obd *filter = &obd->u.filter; - struct dentry *dentry; - struct dentry *root; - struct file *file; - struct inode *inode; - int rc = 0; - __u64 lastobjid = 2; - int mode = 0; - - push_ctxt(&saved, &filter->fo_ctxt, NULL); - dentry = simple_mkdir(current->fs->pwd, "O", 0700); - CDEBUG(D_INODE, "got/created O: %p\n", dentry); - if (IS_ERR(dentry)) { - rc = PTR_ERR(dentry); - CERROR("cannot open/create O: rc = %d\n", rc); - GOTO(out, rc); - } - filter->fo_dentry_O = dentry; - dentry = simple_mkdir(current->fs->pwd, "P", 0700); - CDEBUG(D_INODE, "got/created P: %p\n", dentry); - if (IS_ERR(dentry)) { - rc = PTR_ERR(dentry); - CERROR("cannot open/create P: rc = %d\n", rc); - GOTO(out_O, rc); - } - f_dput(dentry); - dentry = simple_mkdir(current->fs->pwd, "D", 0700); - CDEBUG(D_INODE, "got/created D: %p\n", dentry); - if (IS_ERR(dentry)) { - rc = PTR_ERR(dentry); - CERROR("cannot open/create D: rc = %d\n", rc); - GOTO(out_O, rc); - } - - root = simple_mknod(dentry, FILTER_ROOTINO_STR, S_IFREG | 0755); - f_dput(dentry); - if (IS_ERR(root)) { - rc = PTR_ERR(root); - CERROR("OBD filter: cannot open/create root %d: rc = %d\n", - FILTER_ROOTINO, rc); - GOTO(out_O, rc); - } - f_dput(root); - - /* - * Create directories and/or get dentries for each object type. - * This saves us from having to do multiple lookups for each one. - */ - for (mode = 0; mode < (S_IFMT >> S_SHIFT); mode++) { - char *type = obd_type_by_mode[mode]; - - if (!type) { - filter->fo_dentry_O_mode[mode] = NULL; - continue; - } - dentry = simple_mkdir(filter->fo_dentry_O, type, 0700); - CDEBUG(D_INODE, "got/created O/%s: %p\n", type, dentry); - if (IS_ERR(dentry)) { - rc = PTR_ERR(dentry); - CERROR("cannot create O/%s: rc = %d\n", type, rc); - GOTO(out_O_mode, rc); - } - filter->fo_dentry_O_mode[mode] = dentry; - } - - file = filp_open("D/status", O_RDWR | O_CREAT, 0700); - if ( !file || IS_ERR(file) ) { - rc = PTR_ERR(file); - CERROR("OBD filter: cannot open/create status %s: rc = %d\n", - "D/status", rc); - GOTO(out_O_mode, rc); - } - - /* steal operations */ - inode = file->f_dentry->d_inode; - filter->fo_fop = file->f_op; - filter->fo_iop = inode->i_op; - filter->fo_aops = inode->i_mapping->a_ops; - - if (inode->i_size == 0) { - __u64 disk_lastobjid = cpu_to_le64(lastobjid); - ssize_t retval = file->f_op->write(file,(char *)&disk_lastobjid, - sizeof(disk_lastobjid), - &file->f_pos); - if (retval != sizeof(disk_lastobjid)) { - CDEBUG(D_INODE,"OBD filter: error writing lastobjid\n"); - filp_close(file, 0); - GOTO(out_O_mode, rc = -EIO); - } - } else { - __u64 disk_lastobjid; - ssize_t retval = file->f_op->read(file, (char *)&disk_lastobjid, - sizeof(disk_lastobjid), - &file->f_pos); - if (retval != sizeof(disk_lastobjid)) { - CDEBUG(D_INODE,"OBD filter: error reading lastobjid\n"); - filp_close(file, 0); - GOTO(out_O_mode, rc = -EIO); - } - lastobjid = le64_to_cpu(disk_lastobjid); - } - filter->fo_lastobjid = lastobjid; - filp_close(file, 0); - - rc = 0; - out: - pop_ctxt(&saved, &filter->fo_ctxt, NULL); - - return(rc); - -out_O_mode: - while (mode-- > 0) { - struct dentry *dentry = filter->fo_dentry_O_mode[mode]; - if (dentry) { - f_dput(dentry); - filter->fo_dentry_O_mode[mode] = NULL; - } - } -out_O: - f_dput(filter->fo_dentry_O); - filter->fo_dentry_O = NULL; - goto out; -} - -/* cleanup the filter: write last used object id to status file */ -static void filter_post(struct obd_device *obd) -{ - struct obd_run_ctxt saved; - struct filter_obd *filter = &obd->u.filter; - __u64 disk_lastobjid; - long rc; - struct file *file; - int mode; - - push_ctxt(&saved, &filter->fo_ctxt, NULL); - file = filp_open("D/status", O_RDWR | O_CREAT, 0700); - if (IS_ERR(file)) { - CERROR("OBD filter: cannot create status file\n"); - goto out; - } - - file->f_pos = 0; - disk_lastobjid = cpu_to_le64(filter->fo_lastobjid); - rc = file->f_op->write(file, (char *)&disk_lastobjid, - sizeof(disk_lastobjid), &file->f_pos); - if (rc != sizeof(disk_lastobjid)) - CERROR("OBD filter: error writing lastobjid: rc = %ld\n", rc); - - rc = filp_close(file, NULL); - if (rc) - CERROR("OBD filter: cannot close status file: rc = %ld\n", rc); - - for (mode = 0; mode < (S_IFMT >> S_SHIFT); mode++) { - struct dentry *dentry = filter->fo_dentry_O_mode[mode]; - if (dentry) { - f_dput(dentry); - filter->fo_dentry_O_mode[mode] = NULL; - } - } - f_dput(filter->fo_dentry_O); -out: - pop_ctxt(&saved, &filter->fo_ctxt, NULL); -} - - -static __u64 filter_next_id(struct obd_device *obd) -{ - obd_id id; - - spin_lock(&obd->u.filter.fo_objidlock); - id = ++obd->u.filter.fo_lastobjid; - spin_unlock(&obd->u.filter.fo_objidlock); - - /* FIXME: write the lastobjid to disk here */ - return id; -} - -/* how to get files, dentries, inodes from object id's */ -/* parent i_sem is already held if needed for exclusivity */ -static struct dentry *filter_fid2dentry(struct obd_device *obd, - struct dentry *dparent, - __u64 id, __u32 type, int locked) -{ - struct super_block *sb = obd->u.filter.fo_sb; - struct dentry *dchild; - char name[32]; - int len; - ENTRY; - - if (!sb || !sb->s_dev) { - CERROR("fatal: device not initialized.\n"); - RETURN(ERR_PTR(-ENXIO)); - } - - if (id == 0) { - CERROR("fatal: invalid object #0\n"); - LBUG(); - RETURN(ERR_PTR(-ESTALE)); - } - - if (!(type & S_IFMT)) { - CERROR("OBD %s, object "LPU64" has bad type: %o\n", - __FUNCTION__, id, type); - RETURN(ERR_PTR(-EINVAL)); - } - - len = sprintf(name, LPU64, id); - CDEBUG(D_INODE, "opening object O/%s/%s\n", obd_mode_to_type(type), - name); - if (!locked) - down(&dparent->d_inode->i_sem); - dchild = lookup_one_len(name, dparent, len); - if (!locked) - up(&dparent->d_inode->i_sem); - if (IS_ERR(dchild)) { - CERROR("child lookup error %ld\n", PTR_ERR(dchild)); - RETURN(dchild); - } - - CDEBUG(D_INODE, "got child obj O/%s/%s: %p, count = %d\n", - obd_mode_to_type(type), name, dchild, - atomic_read(&dchild->d_count)); - - LASSERT(atomic_read(&dchild->d_count) > 0); - - RETURN(dchild); -} - -static inline struct dentry *filter_parent(struct obd_device *obd, - obd_mode mode) -{ - struct filter_obd *filter = &obd->u.filter; - - return filter->fo_dentry_O_mode[(mode & S_IFMT) >> S_SHIFT]; -} - -static struct file *filter_obj_open(struct obd_export *export, - __u64 id, __u32 type) -{ - struct filter_obd *filter = &export->exp_obd->u.filter; - struct super_block *sb = filter->fo_sb; - struct dentry *dentry; - struct filter_export_data *fed = &export->exp_filter_data; - struct filter_dentry_data *fdd; - struct filter_file_data *ffd; - struct obd_run_ctxt saved; - char name[24]; - struct file *file; - ENTRY; - - if (!sb || !sb->s_dev) { - CERROR("fatal: device not initialized.\n"); - RETURN(ERR_PTR(-ENXIO)); - } - - if (!id) { - CERROR("fatal: invalid obdo "LPU64"\n", id); - RETURN(ERR_PTR(-ESTALE)); - } - - if (!(type & S_IFMT)) { - CERROR("OBD %s, object "LPU64" has bad type: %o\n", - __FUNCTION__, id, type); - RETURN(ERR_PTR(-EINVAL)); - } - - ffd = kmem_cache_alloc(filter_open_cache, SLAB_KERNEL); - if (!ffd) { - CERROR("obdfilter: out of memory\n"); - RETURN(ERR_PTR(-ENOMEM)); - } - - /* We preallocate this to avoid blocking while holding fo_fddlock */ - fdd = kmem_cache_alloc(filter_dentry_cache, SLAB_KERNEL); - if (!fdd) { - CERROR("obdfilter: out of memory\n"); - GOTO(out_ffd, file = ERR_PTR(-ENOMEM)); - } - - filter_id(name, id, type); - push_ctxt(&saved, &filter->fo_ctxt, NULL); - file = filp_open(name, O_RDWR | O_LARGEFILE, 0 /* type? */); - pop_ctxt(&saved, &filter->fo_ctxt, NULL); - - if (IS_ERR(file)) { - CERROR("error opening %s: rc %d\n", name, PTR_ERR(file)); - GOTO(out_fdd, file); - } - - dentry = file->f_dentry; - spin_lock(&filter->fo_fddlock); - if (dentry->d_fsdata) { - spin_unlock(&filter->fo_fddlock); - kmem_cache_free(filter_dentry_cache, fdd); - fdd = dentry->d_fsdata; - LASSERT(kmem_cache_validate(filter_dentry_cache, fdd)); - /* should only happen during client recovery */ - if (fdd->fdd_flags & FILTER_FLAG_DESTROY) - CDEBUG(D_INODE,"opening destroyed object "LPX64"\n",id); - atomic_inc(&fdd->fdd_open_count); - } else { - atomic_set(&fdd->fdd_open_count, 1); - fdd->fdd_flags = 0; - /* If this is racy, then we can use {cmp}xchg and atomic_add */ - dentry->d_fsdata = fdd; - spin_unlock(&filter->fo_fddlock); - } - - get_random_bytes(&ffd->ffd_servercookie, sizeof(ffd->ffd_servercookie)); - ffd->ffd_file = file; - file->private_data = ffd; - - if (!dentry->d_op) - dentry->d_op = &filter_dops; - else - LASSERT(dentry->d_op == &filter_dops); - - spin_lock(&fed->fed_lock); - list_add(&ffd->ffd_export_list, &fed->fed_open_head); - spin_unlock(&fed->fed_lock); - - CDEBUG(D_INODE, "opened objid "LPX64": rc = %p\n", id, file); - -out: - RETURN(file); - -out_fdd: - kmem_cache_free(filter_dentry_cache, fdd); -out_ffd: - ffd->ffd_servercookie = DEAD_HANDLE_MAGIC; - kmem_cache_free(filter_open_cache, ffd); - goto out; -} - -/* Caller must hold i_sem on dir_dentry->d_inode */ -static int filter_destroy_internal(struct obd_device *obd, - struct dentry *dir_dentry, - struct dentry *object_dentry) -{ - struct obd_run_ctxt saved; - struct inode *inode = object_dentry->d_inode; - int rc; - ENTRY; - - if (inode->i_nlink != 1 || atomic_read(&inode->i_count) != 1) { - CERROR("destroying objid %*s nlink = %d, count = %d\n", - object_dentry->d_name.len, - object_dentry->d_name.name, - inode->i_nlink, atomic_read(&inode->i_count)); - } - - push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - rc = vfs_unlink(dir_dentry->d_inode, object_dentry); - /* XXX unlink from PENDING directory now too */ - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - - if (rc) - CERROR("error unlinking objid %*s: rc %d\n", - object_dentry->d_name.len, - object_dentry->d_name.name, rc); - - RETURN(rc); -} - -static int filter_close_internal(struct obd_device *obd, - struct filter_file_data *ffd) -{ - struct file *filp = ffd->ffd_file; - struct dentry *object_dentry = dget(filp->f_dentry); - struct filter_dentry_data *fdd = object_dentry->d_fsdata; - int rc, rc2 = 0; - ENTRY; - - LASSERT(filp->private_data == ffd); - LASSERT(fdd); - - rc = filp_close(filp, 0); - - if (atomic_dec_and_test(&fdd->fdd_open_count) && - fdd->fdd_flags & FILTER_FLAG_DESTROY) { - struct dentry *dir_dentry = filter_parent(obd, S_IFREG); - - down(&dir_dentry->d_inode->i_sem); - rc2 = filter_destroy_internal(obd, dir_dentry, object_dentry); - if (rc2 && !rc) - rc = rc2; - up(&dir_dentry->d_inode->i_sem); - } - - f_dput(object_dentry); - kmem_cache_free(filter_open_cache, ffd); - - RETURN(rc); -} - -/* obd methods */ -static int filter_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct obd_export *exp; - int rc; - - ENTRY; - MOD_INC_USE_COUNT; - rc = class_connect(conn, obd, cluuid); - if (rc) - GOTO(out_dec, rc); - exp = class_conn2export(conn); - LASSERT(exp); - - INIT_LIST_HEAD(&exp->exp_filter_data.fed_open_head); - spin_lock_init(&exp->exp_filter_data.fed_lock); -out: - RETURN(rc); - -out_dec: - MOD_DEC_USE_COUNT; - goto out; -} - -static int filter_disconnect(struct lustre_handle *conn) -{ - struct obd_export *exp = class_conn2export(conn); - struct filter_export_data *fed; - int rc; - ENTRY; - - LASSERT(exp); - fed = &exp->exp_filter_data; - spin_lock(&fed->fed_lock); - while (!list_empty(&fed->fed_open_head)) { - struct filter_file_data *ffd; - - ffd = list_entry(fed->fed_open_head.next, typeof(*ffd), - ffd_export_list); - list_del(&ffd->ffd_export_list); - spin_unlock(&fed->fed_lock); - - CERROR("force closing file %*s on disconnect\n", - ffd->ffd_file->f_dentry->d_name.len, - ffd->ffd_file->f_dentry->d_name.name); - - filter_close_internal(exp->exp_obd, ffd); - spin_lock(&fed->fed_lock); - } - spin_unlock(&fed->fed_lock); - - ldlm_cancel_locks_for_export(exp); - rc = class_disconnect(conn); - if (!rc) - MOD_DEC_USE_COUNT; - - /* XXX cleanup preallocated inodes */ - RETURN(rc); -} - -/* mount the file system (secretly) */ -static int filter_setup(struct obd_device *obd, obd_count len, void *buf) -{ - struct obd_ioctl_data* data = buf; - struct filter_obd *filter; - struct vfsmount *mnt; - int err = 0; - ENTRY; - - if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2) - RETURN(-EINVAL); - - MOD_INC_USE_COUNT; - mnt = do_kern_mount(data->ioc_inlbuf2, 0, data->ioc_inlbuf1, NULL); - err = PTR_ERR(mnt); - if (IS_ERR(mnt)) - GOTO(err_dec, err); - - filter = &obd->u.filter;; - filter->fo_vfsmnt = mnt; - filter->fo_fstype = strdup(data->ioc_inlbuf2); - filter->fo_sb = mnt->mnt_root->d_inode->i_sb; - CERROR("%s: mnt is %p\n", data->ioc_inlbuf1, filter->fo_vfsmnt); - /* XXX is this even possible if do_kern_mount succeeded? */ - if (!filter->fo_sb) - GOTO(err_kfree, err = -ENODEV); - - OBD_SET_CTXT_MAGIC(&filter->fo_ctxt); - filter->fo_ctxt.pwdmnt = mnt; - filter->fo_ctxt.pwd = mnt->mnt_root; - filter->fo_ctxt.fs = get_ds(); - - err = filter_prep(obd); - if (err) - GOTO(err_kfree, err); - spin_lock_init(&filter->fo_fddlock); - spin_lock_init(&filter->fo_objidlock); - INIT_LIST_HEAD(&filter->fo_export_list); - - obd->obd_namespace = - ldlm_namespace_new("filter-tgt", LDLM_NAMESPACE_SERVER); - if (obd->obd_namespace == NULL) - LBUG(); - - ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL, - "filter_ldlm_cb_client", &obd->obd_ldlm_client); - - RETURN(0); - -err_kfree: - kfree(filter->fo_fstype); - unlock_kernel(); - mntput(filter->fo_vfsmnt); - filter->fo_sb = 0; - lock_kernel(); - -err_dec: - MOD_DEC_USE_COUNT; - return err; -} - - -static int filter_cleanup(struct obd_device *obd) -{ - struct super_block *sb; - ENTRY; - - if (!list_empty(&obd->obd_exports)) { - CERROR("still has clients!\n"); - class_disconnect_all(obd); - if (!list_empty(&obd->obd_exports)) { - CERROR("still has exports after forced cleanup?\n"); - RETURN(-EBUSY); - } - } - - ldlm_namespace_free(obd->obd_namespace); - - sb = obd->u.filter.fo_sb; - if (!obd->u.filter.fo_sb) - RETURN(0); - - filter_post(obd); - - shrink_dcache_parent(sb->s_root); - unlock_kernel(); - mntput(obd->u.filter.fo_vfsmnt); - obd->u.filter.fo_sb = 0; - kfree(obd->u.filter.fo_fstype); - - lock_kernel(); - - MOD_DEC_USE_COUNT; - RETURN(0); -} - - -static void filter_from_inode(struct obdo *oa, struct inode *inode, int valid) -{ - int type = oa->o_mode & S_IFMT; - ENTRY; - - CDEBUG(D_INFO, "src inode %ld (%p), dst obdo %ld valid 0x%08x\n", - inode->i_ino, inode, (long)oa->o_id, valid); - /* Don't copy the inode number in place of the object ID */ - obdo_from_inode(oa, inode, valid); - oa->o_mode &= ~S_IFMT; - oa->o_mode |= type; - - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { - obd_rdev rdev = kdev_t_to_nr(inode->i_rdev); - oa->o_rdev = rdev; - oa->o_valid |= OBD_MD_FLRDEV; - } - - EXIT; -} - -static struct filter_file_data *filter_handle2ffd(struct lustre_handle *handle) -{ - struct filter_file_data *ffd = NULL; - ENTRY; - - if (!handle || !handle->addr) - RETURN(NULL); - - ffd = (struct filter_file_data *)(unsigned long)(handle->addr); - if (!kmem_cache_validate(filter_open_cache, (void *)ffd)) - RETURN(NULL); - - if (ffd->ffd_servercookie != handle->cookie) - RETURN(NULL); - - LASSERT(ffd->ffd_file->private_data == ffd); - RETURN(ffd); -} - -static struct dentry *__filter_oa2dentry(struct lustre_handle *conn, - struct obdo *oa, int locked,char *what) -{ - struct dentry *dentry = NULL; - - if (oa->o_valid & OBD_MD_FLHANDLE) { - struct lustre_handle *ost_handle = obdo_handle(oa); - struct filter_file_data *ffd = filter_handle2ffd(ost_handle); - - if (ffd) - dentry = dget(ffd->ffd_file->f_dentry); - } - - if (!dentry) { - struct obd_device *obd = class_conn2obd(conn); - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - RETURN(ERR_PTR(-EINVAL)); - } - dentry = filter_fid2dentry(obd, filter_parent(obd, oa->o_mode), - oa->o_id, oa->o_mode, locked); - } - - if (IS_ERR(dentry)) { - CERROR("%s error looking up object: "LPX64"\n", what, oa->o_id); - RETURN(dentry); - } - - if (!dentry->d_inode) { - CERROR("%s on non-existent object: "LPX64"\n", what, oa->o_id); - f_dput(dentry); - RETURN(ERR_PTR(-ENOENT)); - } - - return dentry; -} - -#define filter_oa2dentry(conn, oa, locked) __filter_oa2dentry(conn, oa, locked,\ - __FUNCTION__) - -static int filter_getattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md) -{ - struct dentry *dentry = NULL; - int rc = 0; - ENTRY; - - dentry = filter_oa2dentry(conn, oa, 0); - if (IS_ERR(dentry)) - RETURN(PTR_ERR(dentry)); - - filter_from_inode(oa, dentry->d_inode, oa->o_valid); - - f_dput(dentry); - RETURN(rc); -} - -static int filter_setattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md) -{ - struct obd_run_ctxt saved; - struct obd_device *obd = class_conn2obd(conn); - struct dentry *dentry; - struct iattr iattr; - struct inode *inode; - int rc; - ENTRY; - - dentry = filter_oa2dentry(conn, oa, 0); - - if (IS_ERR(dentry)) - RETURN(PTR_ERR(dentry)); - - iattr_from_obdo(&iattr, oa, oa->o_valid); - iattr.ia_mode = (iattr.ia_mode & ~S_IFMT) | S_IFREG; - inode = dentry->d_inode; - - lock_kernel(); - if (iattr.ia_valid & ATTR_SIZE) - down(&inode->i_sem); - push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - if (inode->i_op->setattr) - rc = inode->i_op->setattr(dentry, &iattr); - else - rc = inode_setattr(inode, &iattr); - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - if (iattr.ia_valid & ATTR_SIZE) { - up(&inode->i_sem); - oa->o_valid = OBD_MD_FLBLOCKS | OBD_MD_FLCTIME | OBD_MD_FLMTIME; - obdo_from_inode(oa, inode, oa->o_valid); - } - unlock_kernel(); - - f_dput(dentry); - RETURN(rc); -} - -static int filter_open(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea) -{ - struct obd_export *export; - struct lustre_handle *handle; - struct filter_file_data *ffd; - struct file *filp; - int rc = 0; - ENTRY; - - export = class_conn2export(conn); - if (!export) { - CDEBUG(D_IOCTL, "fatal: invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - filp = filter_obj_open(export, oa->o_id, oa->o_mode); - if (IS_ERR(filp)) - GOTO(out, rc = PTR_ERR(filp)); - - filter_from_inode(oa, filp->f_dentry->d_inode, oa->o_valid); - - ffd = filp->private_data; - handle = obdo_handle(oa); - handle->addr = (__u64)(unsigned long)ffd; - handle->cookie = ffd->ffd_servercookie; - oa->o_valid |= OBD_MD_FLHANDLE; - EXIT; -out: - return rc; -} /* filter_open */ - -static int filter_close(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea) -{ - struct obd_export *exp; - struct filter_file_data *ffd; - struct filter_export_data *fed; - int rc; - ENTRY; - - exp = class_conn2export(conn); - if (!exp) { - CDEBUG(D_IOCTL, "fatal: invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - if (!(oa->o_valid & OBD_MD_FLHANDLE)) { - CERROR("no handle for close of objid "LPX64"\n", oa->o_id); - RETURN(-EINVAL); - } - - ffd = filter_handle2ffd(obdo_handle(oa)); - if (!ffd) { - struct lustre_handle *handle = obdo_handle(oa); - CERROR("bad handle ("LPX64") or cookie ("LPX64") for close\n", - handle->addr, handle->cookie); - RETURN(-ESTALE); - } - - fed = &exp->exp_filter_data; - spin_lock(&fed->fed_lock); - list_del(&ffd->ffd_export_list); - spin_unlock(&fed->fed_lock); - - rc = filter_close_internal(exp->exp_obd, ffd); - - RETURN(rc); -} /* filter_close */ - -static int filter_create(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md **ea) -{ - struct obd_device *obd = class_conn2obd(conn); - char name[64]; - struct obd_run_ctxt saved; - struct dentry *new; - struct iattr; - ENTRY; - - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - if (!(oa->o_mode & S_IFMT)) { - CERROR("OBD %s, object "LPU64" has bad type: %o\n", - __FUNCTION__, oa->o_id, oa->o_mode); - return -ENOENT; - } - - oa->o_id = filter_next_id(obd); - - //filter_id(name, oa->o_id, oa->o_mode); - sprintf(name, LPU64, oa->o_id); - push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - new = simple_mknod(filter_parent(obd, oa->o_mode), name, oa->o_mode); - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - if (IS_ERR(new)) { - CERROR("Error mknod obj %s, err %ld\n", name, PTR_ERR(new)); - return -ENOENT; - } - - /* Set flags for fields we have set in the inode struct */ - oa->o_valid = OBD_MD_FLID | OBD_MD_FLBLKSZ | OBD_MD_FLBLOCKS | - OBD_MD_FLMTIME | OBD_MD_FLATIME | OBD_MD_FLCTIME; - filter_from_inode(oa, new->d_inode, oa->o_valid); - f_dput(new); - - return 0; -} - -static int filter_destroy(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea) -{ - struct obd_device *obd = class_conn2obd(conn); - struct dentry *dir_dentry, *object_dentry; - struct filter_dentry_data *fdd; - int rc; - ENTRY; - - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - CDEBUG(D_INODE, "destroying objid "LPX64"\n", oa->o_id); - - dir_dentry = filter_parent(obd, oa->o_mode); - down(&dir_dentry->d_inode->i_sem); - - object_dentry = filter_oa2dentry(conn, oa, 1); - if (IS_ERR(object_dentry)) - GOTO(out, rc = -ENOENT); - - fdd = object_dentry->d_fsdata; - if (fdd && atomic_read(&fdd->fdd_open_count)) { - if (!(fdd->fdd_flags & FILTER_FLAG_DESTROY)) { - fdd->fdd_flags |= FILTER_FLAG_DESTROY; - /* XXX put into PENDING directory in case of crash */ - CDEBUG(D_INODE, - "defer destroy of %dx open objid "LPX64"\n", - atomic_read(&fdd->fdd_open_count), oa->o_id); - } else - CDEBUG(D_INODE, - "repeat destroy of %dx open objid "LPX64"\n", - atomic_read(&fdd->fdd_open_count), oa->o_id); - GOTO(out_dput, rc = 0); - } - - rc = filter_destroy_internal(obd, dir_dentry, object_dentry); -out_dput: - f_dput(object_dentry); - - EXIT; -out: - up(&dir_dentry->d_inode->i_sem); - return rc; -} - -/* NB count and offset are used for punch, but not truncate */ -static int filter_truncate(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm, - obd_off start, obd_off end) -{ - int error; - ENTRY; - - if (end != OBD_OBJECT_EOF) - CERROR("PUNCH not supported, only truncate works\n"); - - CDEBUG(D_INODE, "calling truncate for object "LPX64", valid = %x, " - "o_size = "LPD64"\n", oa->o_id, oa->o_valid, start); - oa->o_size = start; - error = filter_setattr(conn, oa, NULL); - RETURN(error); -} - -static int filter_pgcache_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_export *export = class_conn2export(conn); - struct obd_run_ctxt saved; - struct super_block *sb; - int pnum; /* index to pages (bufs) */ - unsigned long retval; - int error; - struct file *file; - int pg; - ENTRY; - - if (!export) { - CDEBUG(D_IOCTL, "invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - sb = export->exp_obd->u.filter.fo_sb; - push_ctxt(&saved, &export->exp_obd->u.filter.fo_ctxt, NULL); - pnum = 0; /* pnum indexes buf 0..num_pages */ - - file = filter_obj_open(export, lsm->lsm_object_id, S_IFREG); - if (IS_ERR(file)) - GOTO(out, retval = PTR_ERR(file)); - - /* count doubles as retval */ - for (pg = 0; pg < oa_bufs; pg++) { - CDEBUG(D_INODE, "OP %d obdo pgno: (%d) (%ld,"LPU64 - ") off count ("LPU64",%d)\n", - cmd, pnum, file->f_dentry->d_inode->i_ino, - pga[pnum].off >> PAGE_CACHE_SHIFT, pga[pnum].off, - (int)pga[pnum].count); - if (cmd & OBD_BRW_WRITE) { - loff_t off; - char *buffer; - off = pga[pnum].off; - buffer = kmap(pga[pnum].pg); - retval = file->f_op->write(file, buffer, - pga[pnum].count, - &off); - kunmap(pga[pnum].pg); - CDEBUG(D_INODE, "retval %ld\n", retval); - } else { - loff_t off = pga[pnum].off; - char *buffer = kmap(pga[pnum].pg); - - if (off >= file->f_dentry->d_inode->i_size) { - memset(buffer, 0, pga[pnum].count); - retval = pga[pnum].count; - } else { - retval = file->f_op->read(file, buffer, - pga[pnum].count, &off); - } - kunmap(pga[pnum].pg); - - if (retval != pga[pnum].count) { - filp_close(file, 0); - GOTO(out, retval = -EIO); - } - CDEBUG(D_INODE, "retval %ld\n", retval); - } - pnum++; - } - /* sizes and blocks are set by generic_file_write */ - /* ctimes/mtimes will follow with a setattr call */ - filp_close(file, 0); - - /* XXX: do something with callback if it is set? */ - - EXIT; -out: - pop_ctxt(&saved, &export->exp_obd->u.filter.fo_ctxt, NULL); - error = (retval >= 0) ? 0 : retval; - return error; -} - -/* - * Calculate the number of buffer credits needed to write multiple pages in - * a single ext3/extN transaction. No, this shouldn't be here, but as yet - * ext3 doesn't have a nice API for calculating this sort of thing in advance. - * - * See comment above ext3_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 - * 1 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) - * 1 inode block - * 1 superblock - * 2 * EXT3_SINGLEDATA_TRANS_BLOCKS for the quota files - */ -static int ext3_credits_needed(struct super_block *sb, int objcount, - struct obd_ioobj *obj) -{ - struct obd_ioobj *o = obj; - int blockpp = 1 << (PAGE_CACHE_SHIFT - sb->s_blocksize_bits); - int addrpp = EXT3_ADDR_PER_BLOCK(sb) * blockpp; - int nbitmaps = 0; - int ngdblocks = 0; - int needed = objcount + 1; - int i; - - for (i = 0; i < objcount; i++, o++) { - int nblocks = o->ioo_bufcnt * blockpp; - int ndindirect = min(nblocks, addrpp + 1); - int nindir = nblocks + ndindirect + 1; - - nbitmaps += nindir + nblocks; - ngdblocks += nindir + nblocks; - - needed += nindir; - } - - /* Assumes ext3 and extN have same sb_info layout at the start. */ - if (nbitmaps > EXT3_SB(sb)->s_groups_count) - nbitmaps = EXT3_SB(sb)->s_groups_count; - if (ngdblocks > EXT3_SB(sb)->s_gdb_count) - ngdblocks = EXT3_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)) * - EXT3_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 *ext3_filter_journal_start(struct filter_obd *filter, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_remote *nb) -{ - journal_t *journal = NULL; - handle_t *handle = NULL; - int needed; - - /* It appears that some kernels have different values for - * EXT*_MAX_GROUP_LOADED (either 8 or 32), so we cannot - * assume anything after s_inode_bitmap_number is the same. - */ - if (!strcmp(filter->fo_fstype, "ext3")) - journal = EXT3_SB(filter->fo_sb)->s_journal; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - else if (!strcmp(filter->fo_fstype, "extN")) - journal = EXTN_SB(filter->fo_sb)->s_journal; -#endif - needed = ext3_credits_needed(filter->fo_sb, objcount, obj); - - /* 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 void *filter_journal_start(void **journal_save, - struct filter_obd *filter, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_remote *nb) -{ - void *handle = NULL; - - /* This may not be necessary - we probably never have a - * transaction started when we enter here, so we can - * remove the saving of the journal state entirely. - * For now leave it in just to see if it ever happens. - */ - *journal_save = current->journal_info; - if (*journal_save) { - CERROR("Already have handle %p???\n", *journal_save); - LBUG(); - current->journal_info = NULL; - } - - if (!strcmp(filter->fo_fstype, "ext3") || - !strcmp(filter->fo_fstype, "extN")) - handle = ext3_filter_journal_start(filter, objcount, obj, - niocount, nb); - return handle; -} - -static int ext3_filter_journal_stop(void *handle) -{ - int rc; - - /* We got a refcount on the handle for each call to prepare_write, - * so we can drop the "parent" handle here to avoid the need for - * osc to call back into filterobd to close the handle. The - * remaining references will be dropped in commit_write. - */ - lock_kernel(); - rc = journal_stop((handle_t *)handle); - unlock_kernel(); - - return rc; -} - -static int filter_journal_stop(void *journal_save, struct filter_obd *filter, - void *handle) -{ - int rc = 0; - - if (!strcmp(filter->fo_fstype, "ext3") || - !strcmp(filter->fo_fstype, "extN")) - rc = ext3_filter_journal_stop(handle); - - if (rc) - CERROR("error on journal stop: rc = %d\n", rc); - - current->journal_info = journal_save; - - return rc; -} - -static inline void lustre_put_page(struct page *page) -{ - kunmap(page); - page_cache_release(page); -} - - -static struct page * -lustre_get_page_read(struct inode *inode, struct niobuf_remote *rnb) -{ - unsigned long index = rnb->offset >> PAGE_SHIFT; - struct address_space *mapping = inode->i_mapping; - struct page *page; - int rc; - - page = read_cache_page(mapping, index, - (filler_t*)mapping->a_ops->readpage, NULL); - if (!IS_ERR(page)) { - wait_on_page(page); - kmap(page); - if (!PageUptodate(page)) { - CERROR("page index %lu not uptodate\n", index); - GOTO(err_page, rc = -EIO); - } - if (PageError(page)) { - CERROR("page index %lu has error\n", index); - GOTO(err_page, rc = -EIO); - } - } - return page; - -err_page: - lustre_put_page(page); - return ERR_PTR(rc); -} - -static struct page * -lustre_get_page_write(struct inode *inode, unsigned long index) -{ - struct address_space *mapping = inode->i_mapping; - struct page *page; - int rc; - - page = grab_cache_page(mapping, index); /* locked page */ - - if (!IS_ERR(page)) { - kmap(page); - /* Note: Called with "O" and "PAGE_SIZE" this is essentially - * a no-op for most filesystems, because we write the whole - * page. For partial-page I/O this will read in the page. - */ - rc = mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); - if (rc) { - CERROR("page index %lu, rc = %d\n", index, rc); - if (rc != -ENOSPC) - LBUG(); - GOTO(err_unlock, rc); - } - /* XXX not sure if we need this if we are overwriting page */ - if (PageError(page)) { - CERROR("error on page index %lu, rc = %d\n", index, rc); - LBUG(); - GOTO(err_unlock, rc = -EIO); - } - } - return page; - -err_unlock: - unlock_page(page); - lustre_put_page(page); - return ERR_PTR(rc); -} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -int waitfor_one_page(struct page *page) -{ - wait_on_page_locked(page); - return 0; -} -#endif - -static int lustre_commit_write(struct page *page, unsigned from, unsigned to) -{ - struct inode *inode = page->mapping->host; - int err; - - err = page->mapping->a_ops->commit_write(NULL, page, from, to); - if (!err && IS_SYNC(inode)) - err = waitfor_one_page(page); - //SetPageUptodate(page); // the client commit_write will do this - - SetPageReferenced(page); - unlock_page(page); - lustre_put_page(page); - return err; -} - -struct page *filter_get_page_write(struct inode *inode, - struct niobuf_remote *rnb, - struct niobuf_local *lnb, int *pglocked) -{ - unsigned long index = rnb->offset >> PAGE_SHIFT; - struct address_space *mapping = inode->i_mapping; - - struct page *page; - int rc; - - //ASSERT_PAGE_INDEX(index, GOTO(err, rc = -EINVAL)); - if (*pglocked) - page = grab_cache_page_nowait(mapping, index); /* locked page */ - else - page = grab_cache_page(mapping, index); /* locked page */ - - - /* This page is currently locked, so get a temporary page instead. */ - /* XXX I believe this is a very dangerous thing to do - consider if - * we had multiple writers for the same file (definitely the case - * if we are using this codepath). If writer A locks the page, - * writer B writes to a copy (as here), writer A drops the page - * lock, and writer C grabs the lock before B does, then B will - * later overwrite the data from C, even if C had LDLM locked - * and initiated the write after B did. - */ - if (!page) { - unsigned long addr; - CDEBUG(D_PAGE, "ino %ld page %ld locked\n", inode->i_ino,index); - addr = __get_free_pages(GFP_KERNEL, 0); /* locked page */ - if (!addr) { - CERROR("no memory for a temp page\n"); - LBUG(); - GOTO(err, rc = -ENOMEM); - } - /* XXX debugging */ - memset((void *)addr, 0xBA, PAGE_SIZE); - page = virt_to_page(addr); - kmap(page); - page->index = index; - lnb->flags |= N_LOCAL_TEMP_PAGE; - } else if (!IS_ERR(page)) { - (*pglocked)++; - kmap(page); - - rc = mapping->a_ops->prepare_write(NULL, page, - rnb->offset % PAGE_SIZE, - rnb->len); - if (rc) { - CERROR("page index %lu, rc = %d\n", index, rc); - if (rc != -ENOSPC) - LBUG(); - GOTO(err_unlock, rc); - } - /* XXX not sure if we need this if we are overwriting page */ - if (PageError(page)) { - CERROR("error on page index %lu, rc = %d\n", index, rc); - LBUG(); - GOTO(err_unlock, rc = -EIO); - } - } - return page; - -err_unlock: - unlock_page(page); - lustre_put_page(page); -err: - return ERR_PTR(rc); -} - -/* - * We need to balance prepare_write() calls with commit_write() calls. - * If the page has been prepared, but we have no data for it, we don't - * want to overwrite valid data on disk, but we still need to zero out - * data for space which was newly allocated. Like part of what happens - * in __block_prepare_write() for newly allocated blocks. - * - * XXX currently __block_prepare_write() creates buffers for all the - * pages, and the filesystems mark these buffers as BH_New if they - * were newly allocated from disk. We use the BH_New flag similarly. - */ -static int filter_commit_write(struct page *page, unsigned from, unsigned to, - int err) -{ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - if (err) { - unsigned block_start, block_end; - struct buffer_head *bh, *head = page->buffers; - unsigned blocksize = head->b_size; - void *addr = page_address(page); - - /* debugging: just seeing if this ever happens */ - CERROR("called filter_commit_write for obj %ld:%ld on err %d\n", - page->index, page->mapping->host->i_ino, err); - - /* Currently one buffer per page, but in the future... */ - for (bh = head, block_start = 0; bh != head || !block_start; - block_start = block_end, bh = bh->b_this_page) { - block_end = block_start + blocksize; - if (buffer_new(bh)) - memset(addr + block_start, 0, blocksize); - } - } -#endif - return lustre_commit_write(page, from, to); -} - -static int filter_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_run_ctxt saved; - struct obd_device *obd; - struct obd_ioobj *o = obj; - struct niobuf_remote *rnb = nb; - struct niobuf_local *lnb = res; - void *journal_save = NULL; - int pglocked = 0; - int rc = 0; - int i; - ENTRY; - - obd = class_conn2obd(conn); - if (!obd) { - CDEBUG(D_IOCTL, "invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - memset(res, 0, sizeof(*res) * niocount); - - push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - - if (cmd & OBD_BRW_WRITE) { - *desc_private = filter_journal_start(&journal_save, - &obd->u.filter, - objcount, obj, niocount, - nb); - if (IS_ERR(*desc_private)) - GOTO(out_ctxt, rc = PTR_ERR(*desc_private)); - } - - obd_kmap_get(niocount, 1); - - for (i = 0; i < objcount; i++, o++) { - struct dentry *dentry; - struct inode *inode; - int j; - - dentry = filter_fid2dentry(obd, filter_parent(obd, S_IFREG), - o->ioo_id, S_IFREG, 0); - if (IS_ERR(dentry)) - GOTO(out_clean, rc = PTR_ERR(dentry)); - inode = dentry->d_inode; - if (!inode) { - CERROR("trying to BRW to non-existent file "LPU64"\n", - o->ioo_id); - f_dput(dentry); - GOTO(out_clean, rc = -ENOENT); - } - - for (j = 0; j < o->ioo_bufcnt; j++, rnb++, lnb++) { - struct page *page; - - if (j == 0) - lnb->dentry = dentry; - else - lnb->dentry = dget(dentry); - - if (cmd & OBD_BRW_WRITE) - page = filter_get_page_write(inode, rnb, lnb, - &pglocked); - else - page = lustre_get_page_read(inode, rnb); - - if (IS_ERR(page)) { - f_dput(dentry); - GOTO(out_clean, rc = PTR_ERR(page)); - } - - lnb->addr = page_address(page); - lnb->offset = rnb->offset; - lnb->page = page; - lnb->len = rnb->len; - } - } - -out_stop: - if (cmd & OBD_BRW_WRITE) { - int err = filter_journal_stop(journal_save, &obd->u.filter, - *desc_private); - if (!rc) - rc = err; - } -out_ctxt: - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - RETURN(rc); -out_clean: - while (lnb-- > res) { - CERROR("error cleanup on brw\n"); - f_dput(lnb->dentry); - if (cmd & OBD_BRW_WRITE) - filter_commit_write(lnb->page, 0, PAGE_SIZE, rc); - else - lustre_put_page(lnb->page); - } - obd_kmap_put(niocount); - goto out_stop; -} - -static int filter_write_locked_page(struct niobuf_local *lnb) -{ - struct page *lpage; - int rc; - - lpage = lustre_get_page_write(lnb->dentry->d_inode, lnb->page->index); - if (IS_ERR(lpage)) { - /* It is highly unlikely that we would ever get an error here. - * The page we want to get was previously locked, so it had to - * have already allocated the space, and we were just writing - * over the same data, so there would be no hole in the file. - * - * XXX: possibility of a race with truncate could exist, need - * to check that. There are no guarantees w.r.t. - * write order even on a local filesystem, although the - * normal response would be to return the number of bytes - * successfully written and leave the rest to the app. - */ - rc = PTR_ERR(lpage); - CERROR("error getting locked page index %ld: rc = %d\n", - lnb->page->index, rc); - GOTO(out, rc); - } - - /* lpage is kmapped in lustre_get_page_write() above and kunmapped in - * lustre_commit_write() below, lnb->page was kmapped previously in - * filter_get_page_write() and kunmapped in lustre_put_page() below. - */ - memcpy(page_address(lpage), page_address(lnb->page), PAGE_SIZE); - rc = lustre_commit_write(lpage, 0, PAGE_SIZE); - if (rc) - CERROR("error committing locked page %ld: rc = %d\n", - lnb->page->index, rc); -out: - lustre_put_page(lnb->page); - - return rc; -} - -static int filter_commitrw(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_local *res, - void *private) -{ - struct obd_run_ctxt saved; - struct obd_ioobj *o; - struct niobuf_local *r; - struct obd_device *obd = class_conn2obd(conn); - void *journal_save; - int found_locked = 0; - int rc = 0; - int i; - ENTRY; - - push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - lock_kernel(); - journal_save = current->journal_info; - LASSERT(!journal_save); - - current->journal_info = private; - unlock_kernel(); - for (i = 0, o = obj, r = res; i < objcount; i++, o++) { - int j; - for (j = 0 ; j < o->ioo_bufcnt ; j++, r++) { - struct page *page = r->page; - - if (!page) - LBUG(); - - if (r->flags & N_LOCAL_TEMP_PAGE) { - found_locked++; - continue; - } - - if (cmd & OBD_BRW_WRITE) { - int err = filter_commit_write(page, 0, - r->len, 0); - - if (!rc) - rc = err; - } else - lustre_put_page(page); - - obd_kmap_put(1); - f_dput(r->dentry); - } - } - lock_kernel(); - current->journal_info = journal_save; - unlock_kernel(); - - if (!found_locked) - goto out_ctxt; - - for (i = 0, o = obj, r = res; i < objcount; i++, o++) { - int j; - for (j = 0 ; j < o->ioo_bufcnt ; j++, r++) { - int err; - if (!(r->flags & N_LOCAL_TEMP_PAGE)) - continue; - - err = filter_write_locked_page(r); - obd_kmap_put(1); - if (!rc) - rc = err; - f_dput(r->dentry); - } - } - -out_ctxt: - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - RETURN(rc); -} - -static int filter_statfs(struct lustre_handle *conn, struct obd_statfs *osfs) -{ - struct obd_device *obd = class_conn2obd(conn); - struct statfs sfs; - int rc; - - ENTRY; - rc = vfs_statfs(obd->u.filter.fo_sb, &sfs); - if (!rc) - statfs_pack(osfs, &sfs); - - return rc; -} - -static int filter_get_info(struct lustre_handle *conn, obd_count keylen, - void *key, obd_count *vallen, void **val) -{ - struct obd_device *obd; - ENTRY; - - obd = class_conn2obd(conn); - if (!obd) { - CDEBUG(D_IOCTL, "invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - if ( keylen == strlen("blocksize") && - memcmp(key, "blocksize", keylen) == 0 ) { - *vallen = sizeof(long); - *val = (void *)(long)obd->u.filter.fo_sb->s_blocksize; - RETURN(0); - } - - if ( keylen == strlen("blocksize_bits") && - memcmp(key, "blocksize_bits", keylen) == 0 ){ - *vallen = sizeof(long); - *val = (void *)(long)obd->u.filter.fo_sb->s_blocksize_bits; - RETURN(0); - } - - if ( keylen == strlen("root_ino") && - memcmp(key, "root_ino", keylen) == 0 ){ - *vallen = sizeof(obd_id); - *val = (void *)(obd_id)FILTER_ROOTINO; - RETURN(0); - } - - CDEBUG(D_IOCTL, "invalid key\n"); - RETURN(-EINVAL); -} - -int filter_copy_data(struct lustre_handle *dst_conn, struct obdo *dst, - struct lustre_handle *src_conn, struct obdo *src, - obd_size count, obd_off offset) -{ - struct page *page; - struct lov_stripe_md srcmd, dstmd; - unsigned long index = 0; - int err = 0; - - memset(&srcmd, 0, sizeof(srcmd)); - memset(&dstmd, 0, sizeof(dstmd)); - srcmd.lsm_object_id = src->o_id; - dstmd.lsm_object_id = dst->o_id; - - ENTRY; - CDEBUG(D_INFO, "src: ino "LPU64" blocks "LPU64", size "LPU64 - ", dst: ino "LPU64"\n", - src->o_id, src->o_blocks, src->o_size, dst->o_id); - page = alloc_page(GFP_USER); - if (page == NULL) - RETURN(-ENOMEM); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - while (TryLockPage(page)) - ___wait_on_page(page); -#else - wait_on_page_locked(page); -#endif - - /* XXX with brw vector I/O, we could batch up reads and writes here, - * all we need to do is allocate multiple pages to handle the I/Os - * and arrays to handle the request parameters. - */ - while (index < ((src->o_size + PAGE_SIZE - 1) >> PAGE_SHIFT)) { - struct brw_page pg; - struct obd_brw_set *set; - - set = obd_brw_set_new(); - if (set == NULL) { - err = -ENOMEM; - EXIT; - break; - } - - pg.pg = page; - pg.count = PAGE_SIZE; - pg.off = (page->index) << PAGE_SHIFT; - pg.flag = 0; - - page->index = index; - set->brw_callback = ll_brw_sync_wait; - err = obd_brw(OBD_BRW_READ, src_conn, &srcmd, 1, &pg, set); - obd_brw_set_free(set); - if (err) { - EXIT; - break; - } - - set = obd_brw_set_new(); - if (set == NULL) { - err = -ENOMEM; - EXIT; - break; - } - pg.flag = OBD_BRW_CREATE; - CDEBUG(D_INFO, "Read page %ld ...\n", page->index); - - set->brw_callback = ll_brw_sync_wait; - err = obd_brw(OBD_BRW_WRITE, dst_conn, &dstmd, 1, &pg, set); - obd_brw_set_free(set); - - /* XXX should handle dst->o_size, dst->o_blocks here */ - if (err) { - EXIT; - break; - } - - CDEBUG(D_INFO, "Wrote page %ld ...\n", page->index); - - index++; - } - dst->o_size = src->o_size; - dst->o_blocks = src->o_blocks; - dst->o_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS; - unlock_page(page); - __free_page(page); - - RETURN(err); -} -int filter_attach(struct obd_device *dev, obd_count len, void *data) -{ - return lprocfs_reg_obd(dev, status_var_nm_1, dev); -} - -int filter_detach(struct obd_device *dev) -{ - return lprocfs_dereg_obd(dev); -} -static struct obd_ops filter_obd_ops = { - o_attach: filter_attach, - o_detach: filter_detach, - o_get_info: filter_get_info, - o_setup: filter_setup, - o_cleanup: filter_cleanup, - o_connect: filter_connect, - o_disconnect: filter_disconnect, - o_statfs: filter_statfs, - o_getattr: filter_getattr, - o_create: filter_create, - o_setattr: filter_setattr, - o_destroy: filter_destroy, - o_open: filter_open, - o_close: filter_close, - o_brw: filter_pgcache_brw, - o_punch: filter_truncate, - o_preprw: filter_preprw, - o_commitrw: filter_commitrw -#if 0 - o_preallocate: filter_preallocate_inodes, - o_migrate: filter_migrate, - o_copy: filter_copy_data, - o_iterate: filter_iterate -#endif -}; - - -static int __init obdfilter_init(void) -{ - printk(KERN_INFO "Filtering OBD driver v0.001, info@clusterfs.com\n"); - filter_open_cache = kmem_cache_create("ll_filter_fdata", - sizeof(struct filter_file_data), - 0, 0, NULL, NULL); - if (!filter_open_cache) - RETURN(-ENOMEM); - - filter_dentry_cache = kmem_cache_create("ll_filter_dentry", - sizeof(struct filter_dentry_data), - 0, 0, NULL, NULL); - if (!filter_dentry_cache) { - kmem_cache_destroy(filter_open_cache); - RETURN(-ENOMEM); - } - - return class_register_type(&filter_obd_ops, status_class_var, - OBD_FILTER_DEVICENAME); -} - -static void __exit obdfilter_exit(void) -{ - class_unregister_type(OBD_FILTER_DEVICENAME); - if (kmem_cache_destroy(filter_dentry_cache)) - CERROR("couldn't free obdfilter dentry cache\n"); - if (kmem_cache_destroy(filter_open_cache)) - CERROR("couldn't free obdfilter open cache\n"); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Filtering OBD driver v1.0"); -MODULE_LICENSE("GPL"); - -module_init(obdfilter_init); -module_exit(obdfilter_exit); diff --git a/lustre/obdfilter/lproc_obdfilter.c b/lustre/obdfilter/lproc_obdfilter.c deleted file mode 100644 index e680784..0000000 --- a/lustre/obdfilter/lproc_obdfilter.c +++ /dev/null @@ -1,145 +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; - __u32 blk_size; - __u64 result; - - vfs_statfs(temp->u.filter.fo_sb, &mystats); - blk_size = mystats.f_bsize; - blk_size >>= 10; - result = mystats.f_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 statfs mystats; - int len = 0; - __u32 blk_size; - __u64 result; - - vfs_statfs(temp->u.filter.fo_sb, &mystats); - blk_size = mystats.f_bsize; - blk_size >>= 10; - result = mystats.f_bfree; - while(blk_size >>= 1){ - result <<= 1; - } - 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_filestotal(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; -} - -int rd_filegroups(char* page, char **start, off_t off, int count, int *eof, - void *data) -{ - return 0; -} -struct lprocfs_vars status_var_nm_1[] = { - {"status/uuid", rd_uuid, 0, 0}, - {"status/blocksize",rd_blksize, 0, 0}, - {"status/kbytestotal",rd_kbtotal, 0, 0}, - {"status/kbytesfree", rd_kbfree, 0, 0}, - {"status/filestotal", rd_filestotal, 0, 0}, - {"status/filesfree", rd_filesfree, 0, 0}, - {"status/filegroups", rd_filegroups, 0, 0}, - {"status/fstype", rd_fstype, 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; - int len = 0; - len += snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -struct lprocfs_vars status_class_var[] = { - {"status/num_refs", rd_numrefs, 0, 0}, - {0} -}; diff --git a/lustre/osc/.cvsignore b/lustre/osc/.cvsignore deleted file mode 100644 index e530020..0000000 --- a/lustre/osc/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/osc/Makefile.am b/lustre/osc/Makefile.am deleted file mode 100644 index 284c2d6..0000000 --- a/lustre/osc/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= - -MODULE = osc -modulefs_DATA = osc.o -EXTRA_PROGRAMS = osc - -LINX= obd_pack.c ll_pack.c client.c -osc_SOURCES = osc_request.c lproc_osc.c $(LINX) - -obd_pack.c: - test -e obd_pack.c || ln -sf $(top_srcdir)/lib/obd_pack.c -ll_pack.c: - test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c -client.c: - test -e client.c || ln -sf $(top_srcdir)/lib/client.c - -dist-hook: - list='$(LINX)'; for f in $$list; do rm -f $(distdir)/$$f; done - -include $(top_srcdir)/Rules diff --git a/lustre/osc/lproc_osc.c b/lustre/osc/lproc_osc.c deleted file mode 100644 index 58e9097..0000000 --- a/lustre/osc/lproc_osc.c +++ /dev/null @@ -1,119 +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_kbytestotal(char* page, char **start, off_t off, int count, int *eof, - void *data) -{ - return 0; -} - -int rd_kbytesfree(char* page, char **start, off_t off, int count, int *eof, - void *data) -{ - return 0; -} - -int rd_filestotal(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_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; - -} - -struct lprocfs_vars status_var_nm_1[] = { - {"status/uuid", rd_uuid, 0, 0}, - {"status/blocksize",rd_blksize, 0, 0}, - {"status/kbytestotal", rd_kbytestotal, 0, 0}, - {"status/kbytesfree", rd_kbytesfree, 0, 0}, - {"status/filestotal", rd_filestotal, 0, 0}, - {"status/filesfree", rd_filesfree, 0, 0}, - {"status/filegroups", rd_filegroups, 0, 0}, - {"status/ost_server_uuid", rd_server_uuid, 0, 0}, - {"status/ost_conn_uuid", rd_conn_uuid, 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; - int len = 0; - len += snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -struct lprocfs_vars status_class_var[] = { - {"status/num_refs", rd_numrefs, 0, 0}, - {0} -}; diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c deleted file mode 100644 index de403b5..0000000 --- a/lustre/osc/osc_request.c +++ /dev/null @@ -1,1029 +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. - * Author Peter Braam - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * For testing and management it is treated as an obd_device, - * although * it does not export a full OBD method table (the - * requests are coming * in over the wire, so object target modules - * do not have a full * method table.) - * - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_OSC - -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#include /* for mds_objid */ -#include -#include /* for IOC_LOV_SET_OSC_ACTIVE */ -#include -#include -#include -#include /* for OBD_FAIL_CHECK */ -#include /* for ll_i2info */ -#include /* for PTL_MD_MAX_IOV */ -#include - -extern struct lprocfs_vars status_var_nm_1[]; -extern struct lprocfs_vars status_class_var[]; - -static int osc_attach(struct obd_device *dev, obd_count len, void *data) -{ - return lprocfs_reg_obd(dev, status_var_nm_1, dev); -} - -static int osc_detach(struct obd_device *dev) -{ - return lprocfs_dereg_obd(dev); -} - -/* Pack OSC object metadata for shipment to the MDS. */ -static int osc_packmd(struct lustre_handle *conn, struct lov_mds_md **lmmp, - struct lov_stripe_md *lsm) -{ - int lmm_size; - - lmm_size = sizeof(**lmmp); - if (!lmmp) - RETURN(lmm_size); - - if (*lmmp && !lsm) { - OBD_FREE(*lmmp, lmm_size); - *lmmp = NULL; - RETURN(0); - } - - if (!*lmmp) { - OBD_ALLOC(*lmmp, lmm_size); - if (!*lmmp) - RETURN(-ENOMEM); - } - if (lsm) { - LASSERT(lsm->lsm_object_id); - (*lmmp)->lmm_object_id = (lsm->lsm_object_id); - } - - return lmm_size; -} - -static int osc_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp, - struct lov_mds_md *lmm) -{ - int lsm_size; - - lsm_size = sizeof(**lsmp); - if (!lsmp) - RETURN(lsm_size); - - if (*lsmp && !lmm) { - OBD_FREE(*lsmp, lsm_size); - *lsmp = NULL; - RETURN(0); - } - - if (!*lsmp) { - OBD_ALLOC(*lsmp, lsm_size); - if (!*lsmp) - RETURN(-ENOMEM); - } - - /* XXX endianness */ - if (lmm) { - (*lsmp)->lsm_object_id = (lmm->lmm_object_id); - LASSERT((*lsmp)->lsm_object_id); - } - - return lsm_size; -} - -static int osc_getattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md) -{ - struct ptlrpc_request *request; - struct ost_body *body; - int rc, size = sizeof(*body); - ENTRY; - - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_GETATTR, 1, - &size, NULL); - if (!request) - RETURN(-ENOMEM); - - body = lustre_msg_buf(request->rq_reqmsg, 0); -#warning FIXME: pack only valid fields instead of memcpy, endianness - memcpy(&body->oa, oa, sizeof(*oa)); - - request->rq_replen = lustre_msg_size(1, &size); - - rc = ptlrpc_queue_wait(request); - if (rc) { - CERROR("%s failed: rc = %d\n", __FUNCTION__, rc); - GOTO(out, rc); - } - - body = lustre_msg_buf(request->rq_repmsg, 0); - CDEBUG(D_INODE, "mode: %o\n", body->oa.o_mode); - if (oa) - memcpy(oa, &body->oa, sizeof(*oa)); - - EXIT; - out: - ptlrpc_req_finished(request); - return rc; -} - -static int osc_open(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md) -{ - struct ptlrpc_request *request; - struct ost_body *body; - int rc, size = sizeof(*body); - ENTRY; - - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_OPEN, 1, &size, - NULL); - if (!request) - RETURN(-ENOMEM); - - body = lustre_msg_buf(request->rq_reqmsg, 0); -#warning FIXME: pack only valid fields instead of memcpy, endianness - memcpy(&body->oa, oa, sizeof(*oa)); - - request->rq_replen = lustre_msg_size(1, &size); - - rc = ptlrpc_queue_wait(request); - if (rc) - GOTO(out, rc); - - body = lustre_msg_buf(request->rq_repmsg, 0); - CDEBUG(D_INODE, "mode: %o\n", body->oa.o_mode); - if (oa) - memcpy(oa, &body->oa, sizeof(*oa)); - - EXIT; - out: - ptlrpc_req_finished(request); - return rc; -} - -static int osc_close(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md) -{ - struct ptlrpc_request *request; - struct ost_body *body; - int rc, size = sizeof(*body); - ENTRY; - - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_CLOSE, 1, &size, - NULL); - if (!request) - RETURN(-ENOMEM); - - body = lustre_msg_buf(request->rq_reqmsg, 0); -#warning FIXME: pack only valid fields instead of memcpy, endianness - memcpy(&body->oa, oa, sizeof(*oa)); - - request->rq_replen = lustre_msg_size(1, &size); - - rc = ptlrpc_queue_wait(request); - if (rc) - GOTO(out, rc); - - body = lustre_msg_buf(request->rq_repmsg, 0); - CDEBUG(D_INODE, "mode: %o\n", body->oa.o_mode); - if (oa) - memcpy(oa, &body->oa, sizeof(*oa)); - - EXIT; - out: - ptlrpc_req_finished(request); - return rc; -} - -static int osc_setattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md) -{ - struct ptlrpc_request *request; - struct ost_body *body; - int rc, size = sizeof(*body); - ENTRY; - - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_SETATTR, 1, - &size, NULL); - if (!request) - RETURN(-ENOMEM); - - body = lustre_msg_buf(request->rq_reqmsg, 0); - memcpy(&body->oa, oa, sizeof(*oa)); - - request->rq_replen = lustre_msg_size(1, &size); - - rc = ptlrpc_queue_wait(request); - - ptlrpc_req_finished(request); - return rc; -} - -static int osc_create(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md **ea) -{ - struct ptlrpc_request *request; - struct ost_body *body; - struct lov_stripe_md *lsm; - int rc, size = sizeof(*body); - ENTRY; - - LASSERT(oa); - LASSERT(ea); - - lsm = *ea; - if (!lsm) { - rc = obd_alloc_memmd(conn, &lsm); - if (rc < 0) - RETURN(rc); - } - - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_CREATE, 1, &size, - NULL); - if (!request) - GOTO(out, rc = -ENOMEM); - - body = lustre_msg_buf(request->rq_reqmsg, 0); - memcpy(&body->oa, oa, sizeof(*oa)); - - request->rq_replen = lustre_msg_size(1, &size); - - rc = ptlrpc_queue_wait(request); - if (rc) - GOTO(out_req, rc); - - body = lustre_msg_buf(request->rq_repmsg, 0); - memcpy(oa, &body->oa, sizeof(*oa)); - - lsm->lsm_object_id = oa->o_id; - lsm->lsm_stripe_count = 0; - *ea = lsm; - EXIT; -out_req: - ptlrpc_req_finished(request); -out: - if (rc && !*ea) - obd_free_memmd(conn, &lsm); - return rc; -} - -static int osc_punch(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md, obd_size start, - obd_size end) -{ - struct ptlrpc_request *request; - struct ost_body *body; - int rc, size = sizeof(*body); - ENTRY; - - if (!oa) { - CERROR("oa NULL\n"); - RETURN(-EINVAL); - } - - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_PUNCH, 1, &size, - NULL); - if (!request) - RETURN(-ENOMEM); - - body = lustre_msg_buf(request->rq_reqmsg, 0); -#warning FIXME: pack only valid fields instead of memcpy, endianness, valid - memcpy(&body->oa, oa, sizeof(*oa)); - - /* overload the size and blocks fields in the oa with start/end */ - body->oa.o_size = HTON__u64(start); - body->oa.o_blocks = HTON__u64(end); - body->oa.o_valid |= HTON__u32(OBD_MD_FLSIZE | OBD_MD_FLBLOCKS); - - request->rq_replen = lustre_msg_size(1, &size); - - rc = ptlrpc_queue_wait(request); - if (rc) - GOTO(out, rc); - - body = lustre_msg_buf(request->rq_repmsg, 0); - memcpy(oa, &body->oa, sizeof(*oa)); - - EXIT; - out: - ptlrpc_req_finished(request); - return rc; -} - -static int osc_destroy(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea) -{ - struct ptlrpc_request *request; - struct ost_body *body; - int rc, size = sizeof(*body); - ENTRY; - - if (!oa) { - CERROR("oa NULL\n"); - RETURN(-EINVAL); - } - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_DESTROY, 1, - &size, NULL); - if (!request) - RETURN(-ENOMEM); - - body = lustre_msg_buf(request->rq_reqmsg, 0); -#warning FIXME: pack only valid fields instead of memcpy, endianness - memcpy(&body->oa, oa, sizeof(*oa)); - - request->rq_replen = lustre_msg_size(1, &size); - - rc = ptlrpc_queue_wait(request); - if (rc) - GOTO(out, rc); - - body = lustre_msg_buf(request->rq_repmsg, 0); - memcpy(oa, &body->oa, sizeof(*oa)); - - EXIT; - out: - ptlrpc_req_finished(request); - return rc; -} - -/* Our bulk-unmapping bottom half. */ -static void unmap_and_decref_bulk_desc(void *data) -{ - struct ptlrpc_bulk_desc *desc = data; - struct list_head *tmp; - ENTRY; - - /* This feels wrong to me. */ - list_for_each(tmp, &desc->bd_page_list) { - struct ptlrpc_bulk_page *bulk; - bulk = list_entry(tmp, struct ptlrpc_bulk_page, bp_link); - - kunmap(bulk->bp_page); - obd_kmap_put(1); - } - - ptlrpc_bulk_decref(desc); - EXIT; -} - -/* this is the callback function which is invoked by the Portals - * event handler associated with the bulk_sink queue and bulk_source queue. - */ -static void osc_ptl_ev_hdlr(struct ptlrpc_bulk_desc *desc) -{ - ENTRY; - - LASSERT(desc->bd_brw_set != NULL); - LASSERT(desc->bd_brw_set->brw_callback != NULL); - - desc->bd_brw_set->brw_callback(desc->bd_brw_set, CB_PHASE_FINISH); - - /* We can't kunmap the desc from interrupt context, so we do it from - * the bottom half above. */ - prepare_work(&desc->bd_queue, unmap_and_decref_bulk_desc, desc); - schedule_work(&desc->bd_queue); - - EXIT; -} - -static int osc_brw_read(struct lustre_handle *conn, struct lov_stripe_md *lsm, - obd_count page_count, struct brw_page *pga, - struct obd_brw_set *set) -{ - struct obd_import *imp = class_conn2cliimp(conn); - struct ptlrpc_connection *connection = imp->imp_connection; - struct ptlrpc_request *request = NULL; - struct ptlrpc_bulk_desc *desc = NULL; - struct ost_body *body; - int rc, size[3] = {sizeof(*body)}, mapped = 0; - void *iooptr, *nioptr; - __u32 xid; - ENTRY; - - size[1] = sizeof(struct obd_ioobj); - size[2] = page_count * sizeof(struct niobuf_remote); - - request = ptlrpc_prep_req(imp, OST_READ, 3, size, NULL); - if (!request) - RETURN(-ENOMEM); - - body = lustre_msg_buf(request->rq_reqmsg, 0); - - desc = ptlrpc_prep_bulk(connection); - if (!desc) - GOTO(out_req, rc = -ENOMEM); - desc->bd_portal = OST_BULK_PORTAL; - desc->bd_ptl_ev_hdlr = osc_ptl_ev_hdlr; - CDEBUG(D_PAGE, "desc = %p\n", desc); - - iooptr = lustre_msg_buf(request->rq_reqmsg, 1); - nioptr = lustre_msg_buf(request->rq_reqmsg, 2); - ost_pack_ioo(&iooptr, lsm, page_count); - /* end almost identical to brw_write case */ - - spin_lock(&imp->imp_lock); - xid = ++imp->imp_last_xid; /* single xid for all pages */ - spin_unlock(&imp->imp_lock); - - obd_kmap_get(page_count, 0); - - for (mapped = 0; mapped < page_count; mapped++) { - struct ptlrpc_bulk_page *bulk = ptlrpc_prep_bulk_page(desc); - if (bulk == NULL) - GOTO(out_unmap, rc = -ENOMEM); - - bulk->bp_xid = xid; /* single xid for all pages */ - - bulk->bp_buf = kmap(pga[mapped].pg); - bulk->bp_page = pga[mapped].pg; - bulk->bp_buflen = PAGE_SIZE; - ost_pack_niobuf(&nioptr, pga[mapped].off, pga[mapped].count, - pga[mapped].flag, bulk->bp_xid); - } - - /* - * Register the bulk first, because the reply could arrive out of order, - * and we want to be ready for the bulk data. - * - * One reference is released when brw_finish is complete, the other when - * the caller removes us from the "set" list. - * - * On error, we never do the brw_finish, so we handle all decrefs. - */ - if (OBD_FAIL_CHECK(OBD_FAIL_OSC_BRW_READ_BULK)) { - CERROR("obd_fail_loc=%x, skipping register_bulk\n", - OBD_FAIL_OSC_BRW_READ_BULK); - } else { - rc = ptlrpc_register_bulk(desc); - if (rc) - GOTO(out_unmap, rc); - obd_brw_set_add(set, desc); - } - - request->rq_replen = lustre_msg_size(1, size); - rc = ptlrpc_queue_wait(request); - - /* - * XXX: If there is an error during the processing of the callback, - * such as a timeout in a sleep that it performs, brw_finish - * will never get called, and we'll leak the desc, fail to kunmap - * things, cats will live with dogs. One solution would be to - * export brw_finish as osc_brw_finish, so that the timeout case - * and its kin could call it for proper cleanup. An alternative - * would be for an error return from the callback to cause us to - * clean up, but that doesn't help the truly async cases (like - * LOV), which will immediately return from their PHASE_START - * callback, before any such cleanup-requiring error condition can - * be detected. - */ - out_req: - ptlrpc_req_finished(request); - RETURN(rc); - - /* Clean up on error. */ -out_unmap: - while (mapped-- > 0) - kunmap(pga[mapped].pg); - obd_kmap_put(page_count); - ptlrpc_bulk_decref(desc); - goto out_req; -} - -static int osc_brw_write(struct lustre_handle *conn, struct lov_stripe_md *md, - obd_count page_count, struct brw_page *pga, - struct obd_brw_set *set) -{ - struct ptlrpc_connection *connection = - client_conn2cli(conn)->cl_import.imp_connection; - struct ptlrpc_request *request = NULL; - struct ptlrpc_bulk_desc *desc = NULL; - struct ost_body *body; - struct niobuf_local *local = NULL; - struct niobuf_remote *remote; - int rc, j, size[3] = {sizeof(*body)}, mapped = 0; - void *iooptr, *nioptr; - ENTRY; - - size[1] = sizeof(struct obd_ioobj); - size[2] = page_count * sizeof(*remote); - - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_WRITE, 3, size, - NULL); - if (!request) - RETURN(-ENOMEM); - - body = lustre_msg_buf(request->rq_reqmsg, 0); - - desc = ptlrpc_prep_bulk(connection); - if (!desc) - GOTO(out_req, rc = -ENOMEM); - desc->bd_portal = OSC_BULK_PORTAL; - desc->bd_ptl_ev_hdlr = osc_ptl_ev_hdlr; - CDEBUG(D_PAGE, "desc = %p\n", desc); - - iooptr = lustre_msg_buf(request->rq_reqmsg, 1); - nioptr = lustre_msg_buf(request->rq_reqmsg, 2); - ost_pack_ioo(&iooptr, md, page_count); - /* end almost identical to brw_read case */ - - OBD_ALLOC(local, page_count * sizeof(*local)); - if (!local) - GOTO(out_desc, rc = -ENOMEM); - - obd_kmap_get(page_count, 0); - - for (mapped = 0; mapped < page_count; mapped++) { - local[mapped].addr = kmap(pga[mapped].pg); - - CDEBUG(D_INFO, "kmap(pg) = %p ; pg->flags = %lx ; pg->count = " - "%d ; page %d of %d\n", - local[mapped].addr, pga[mapped].pg->flags, - page_count(pga[mapped].pg), - mapped, page_count - 1); - - local[mapped].offset = pga[mapped].off; - local[mapped].len = pga[mapped].count; - ost_pack_niobuf(&nioptr, pga[mapped].off, pga[mapped].count, - pga[mapped].flag, 0); - } - - size[1] = page_count * sizeof(*remote); - request->rq_replen = lustre_msg_size(2, size); - rc = ptlrpc_queue_wait(request); - if (rc) - GOTO(out_unmap, rc); - - nioptr = lustre_msg_buf(request->rq_repmsg, 1); - if (!nioptr) - GOTO(out_unmap, rc = -EINVAL); - - if (request->rq_repmsg->buflens[1] != size[1]) { - CERROR("buffer length wrong (%d vs. %d)\n", - request->rq_repmsg->buflens[1], size[1]); - GOTO(out_unmap, rc = -EINVAL); - } - - for (j = 0; j < page_count; j++) { - struct ptlrpc_bulk_page *bulk; - - ost_unpack_niobuf(&nioptr, &remote); - - bulk = ptlrpc_prep_bulk_page(desc); - if (!bulk) - GOTO(out_unmap, rc = -ENOMEM); - - bulk->bp_buf = (void *)(unsigned long)local[j].addr; - bulk->bp_buflen = local[j].len; - bulk->bp_xid = remote->xid; - bulk->bp_page = pga[j].pg; - } - - if (desc->bd_page_count != page_count) - LBUG(); - - if (OBD_FAIL_CHECK(OBD_FAIL_OSC_BRW_WRITE_BULK)) - GOTO(out_unmap, rc = 0); - - OBD_FREE(local, page_count * sizeof(*local)); - - /* One reference is released when brw_finish is complete, the other - * when the caller removes it from the "set" list. */ - obd_brw_set_add(set, desc); - rc = ptlrpc_send_bulk(desc); - - /* XXX: Mike, same question as in osc_brw_read. */ -out_req: - ptlrpc_req_finished(request); - RETURN(rc); - - /* Clean up on error. */ -out_unmap: - while (mapped-- > 0) - kunmap(pga[mapped].pg); - - obd_kmap_put(page_count); - - OBD_FREE(local, page_count * sizeof(*local)); -out_desc: - ptlrpc_bulk_decref(desc); - goto out_req; -} - -static int osc_brw(int cmd, struct lustre_handle *conn, - struct lov_stripe_md *md, obd_count page_count, - struct brw_page *pga, struct obd_brw_set *set) -{ - ENTRY; - - while (page_count) { - obd_count pages_per_brw; - int rc; - - if (page_count > PTL_MD_MAX_IOV) - pages_per_brw = PTL_MD_MAX_IOV; - else - pages_per_brw = page_count; - - if (cmd & OBD_BRW_WRITE) - rc = osc_brw_write(conn, md, pages_per_brw, pga, set); - else - rc = osc_brw_read(conn, md, pages_per_brw, pga, set); - - if (rc != 0) - RETURN(rc); - - page_count -= pages_per_brw; - pga += pages_per_brw; - } - RETURN(0); -} - -static int osc_enqueue(struct lustre_handle *connh, struct lov_stripe_md *lsm, - struct lustre_handle *parent_lock, - __u32 type, void *extentp, int extent_len, __u32 mode, - int *flags, void *callback, void *data, int datalen, - struct lustre_handle *lockh) -{ - __u64 res_id[RES_NAME_SIZE] = { lsm->lsm_object_id }; - struct obd_device *obddev = class_conn2obd(connh); - struct ldlm_extent *extent = extentp; - int rc; - ENTRY; - - /* Filesystem locks are given a bit of special treatment: if - * this is not a file size lock (which has end == -1), we - * fixup the lock to start and end on page boundaries. */ - if (extent->end != OBD_OBJECT_EOF) { - extent->start &= PAGE_MASK; - extent->end = (extent->end & PAGE_MASK) + PAGE_SIZE - 1; - } - - /* Next, search for already existing extent locks that will cover us */ - rc = ldlm_lock_match(obddev->obd_namespace, res_id, type, extent, - sizeof(extent), mode, lockh); - if (rc == 1) - /* We already have a lock, and it's referenced */ - RETURN(ELDLM_OK); - - /* If we're trying to read, we also search for an existing PW lock. The - * VFS and page cache already protect us locally, so lots of readers/ - * writers can share a single PW lock. - * - * There are problems with conversion deadlocks, so instead of - * converting a read lock to a write lock, we'll just enqueue a new - * one. - * - * At some point we should cancel the read lock instead of making them - * send us a blocking callback, but there are problems with canceling - * locks out from other users right now, too. */ - - if (mode == LCK_PR) { - rc = ldlm_lock_match(obddev->obd_namespace, res_id, type, - extent, sizeof(extent), LCK_PW, lockh); - if (rc == 1) { - /* FIXME: This is not incredibly elegant, but it might - * be more elegant than adding another parameter to - * lock_match. I want a second opinion. */ - ldlm_lock_addref(lockh, LCK_PR); - ldlm_lock_decref(lockh, LCK_PW); - - RETURN(ELDLM_OK); - } - } - - rc = ldlm_cli_enqueue(connh, NULL, obddev->obd_namespace, parent_lock, - res_id, type, extent, sizeof(extent), mode, flags, - ldlm_completion_ast, callback, data, datalen, - lockh); - RETURN(rc); -} - -static int osc_cancel(struct lustre_handle *oconn, struct lov_stripe_md *md, - __u32 mode, struct lustre_handle *lockh) -{ - ENTRY; - - ldlm_lock_decref(lockh, mode); - - RETURN(0); -} - -static int osc_cancel_unused(struct lustre_handle *connh, - struct lov_stripe_md *lsm, int flags) -{ - struct obd_device *obddev = class_conn2obd(connh); - __u64 res_id[RES_NAME_SIZE] = { lsm->lsm_object_id }; - - return ldlm_cli_cancel_unused(obddev->obd_namespace, res_id, flags); -} - -static int osc_statfs(struct lustre_handle *conn, struct obd_statfs *osfs) -{ - struct ptlrpc_request *request; - int rc, size = sizeof(*osfs); - ENTRY; - - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_STATFS, 0, NULL, - NULL); - if (!request) - RETURN(-ENOMEM); - - request->rq_replen = lustre_msg_size(1, &size); - - rc = ptlrpc_queue_wait(request); - if (rc) { - CERROR("%s failed: rc = %d\n", __FUNCTION__, rc); - GOTO(out, rc); - } - - obd_statfs_unpack(osfs, lustre_msg_buf(request->rq_repmsg, 0)); - - EXIT; - out: - ptlrpc_req_finished(request); - return rc; -} - -static int osc_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len, - void *karg, void *uarg) -{ - struct obd_device *obddev = class_conn2obd(conn); - struct obd_ioctl_data *data = karg; - int err = 0; - ENTRY; - - switch (cmd) { - case IOC_LDLM_TEST: { - err = ldlm_test(obddev, conn); - CERROR("-- done err %d\n", err); - GOTO(out, err); - } - case IOC_LDLM_REGRESS_START: { - unsigned int numthreads = 1; - unsigned int numheld = 10; - unsigned int numres = 10; - unsigned int numext = 10; - char *parse; - - if (data->ioc_inllen1) { - parse = data->ioc_inlbuf1; - if (*parse != '\0') { - while(isspace(*parse)) parse++; - numthreads = simple_strtoul(parse, &parse, 0); - while(isspace(*parse)) parse++; - } - if (*parse != '\0') { - while(isspace(*parse)) parse++; - numheld = simple_strtoul(parse, &parse, 0); - while(isspace(*parse)) parse++; - } - if (*parse != '\0') { - while(isspace(*parse)) parse++; - numres = simple_strtoul(parse, &parse, 0); - while(isspace(*parse)) parse++; - } - if (*parse != '\0') { - while(isspace(*parse)) parse++; - numext = simple_strtoul(parse, &parse, 0); - while(isspace(*parse)) parse++; - } - } - - err = ldlm_regression_start(obddev, conn, numthreads, - numheld, numres, numext); - - CERROR("-- done err %d\n", err); - GOTO(out, err); - } - case IOC_LDLM_REGRESS_STOP: { - err = ldlm_regression_stop(); - CERROR("-- done err %d\n", err); - GOTO(out, err); - } - case IOC_OSC_REGISTER_LOV: { - if (obddev->u.cli.cl_containing_lov) - GOTO(out, err = -EALREADY); - obddev->u.cli.cl_containing_lov = (struct obd_device *)karg; - GOTO(out, err); - } - case OBD_IOC_LOV_GET_CONFIG: { - char *buf; - struct lov_desc *desc; - obd_uuid_t *uuidp; - - buf = NULL; - len = 0; - if (obd_ioctl_getdata(&buf, &len, (void *)uarg)) - GOTO(out, err = -EINVAL); - - data = (struct obd_ioctl_data *)buf; - - if (sizeof(*desc) > data->ioc_inllen1) { - OBD_FREE(buf, len); - GOTO(out, err = -EINVAL); - } - - if (data->ioc_inllen2 < sizeof(*uuidp)) { - OBD_FREE(buf, len); - GOTO(out, err = -EINVAL); - } - - desc = (struct lov_desc *)data->ioc_inlbuf1; - desc->ld_tgt_count = 1; - desc->ld_active_tgt_count = 1; - desc->ld_default_stripe_count = 1; - desc->ld_default_stripe_size = 0; - desc->ld_default_stripe_offset = 0; - desc->ld_pattern = 0; - memcpy(desc->ld_uuid, obddev->obd_uuid, sizeof(*uuidp)); - - uuidp = (obd_uuid_t *)data->ioc_inlbuf2; - memcpy(uuidp, obddev->obd_uuid, sizeof(*uuidp)); - - err = copy_to_user((void *)uarg, buf, len); - if (err) - err = -EFAULT; - OBD_FREE(buf, len); - GOTO(out, err); - } - default: - CERROR ("osc_ioctl(): unrecognised ioctl %#lx\n", cmd); - GOTO(out, err = -ENOTTY); - } -out: - return err; -} - -static void set_osc_active(struct obd_import *imp, int active) -{ - struct obd_device *notify_obd = imp->imp_obd->u.cli.cl_containing_lov; - - if (notify_obd == NULL) - return; - - /* How gross is _this_? */ - if (!list_empty(¬ify_obd->obd_exports)) { - int rc; - struct lustre_handle fakeconn; - struct obd_ioctl_data ioc_data; - struct obd_export *exp = - list_entry(notify_obd->obd_exports.next, - struct obd_export, exp_obd_chain); - - fakeconn.addr = (__u64)(unsigned long)exp; - fakeconn.cookie = exp->exp_cookie; - ioc_data.ioc_inlbuf1 = imp->imp_obd->obd_uuid; - ioc_data.ioc_offset = active; - rc = obd_iocontrol(IOC_LOV_SET_OSC_ACTIVE, &fakeconn, - sizeof ioc_data, &ioc_data, NULL); - if (rc) - CERROR("disabling %s on LOV %p/%s: %d\n", - imp->imp_obd->obd_uuid, notify_obd, - notify_obd->obd_uuid, rc); - } else { - CDEBUG(D_HA, "No exports for obd %p/%s, can't notify about " - "%p\n", notify_obd, notify_obd->obd_uuid, - imp->imp_obd->obd_uuid); - } -} - - -/* XXX looks a lot like super.c:invalidate_request_list, don't it? */ -static void abort_inflight_for_import(struct obd_import *imp) -{ - struct list_head *tmp, *n; - - /* Make sure that no new requests get processed for this import. - * ptlrpc_queue_wait must (and does) hold imp_lock while testing this - * flag and then putting requests on sending_list or delayed_list. - */ - spin_lock(&imp->imp_lock); - imp->imp_flags |= IMP_INVALID; - spin_unlock(&imp->imp_lock); - - list_for_each_safe(tmp, n, &imp->imp_sending_list) { - struct ptlrpc_request *req = - list_entry(tmp, struct ptlrpc_request, rq_list); - - DEBUG_REQ(D_HA, req, "inflight"); - req->rq_flags |= PTL_RPC_FL_ERR; - wake_up(&req->rq_wait_for_rep); - } - - list_for_each_safe(tmp, n, &imp->imp_delayed_list) { - struct ptlrpc_request *req = - list_entry(tmp, struct ptlrpc_request, rq_list); - - DEBUG_REQ(D_HA, req, "aborting waiting req"); - req->rq_flags |= PTL_RPC_FL_ERR; - wake_up(&req->rq_wait_for_rep); - } -} - -static int osc_recover(struct obd_import *imp, int phase) -{ - int rc; - ENTRY; - - switch(phase) { - case PTLRPC_RECOVD_PHASE_PREPARE: { - struct ldlm_namespace *ns = imp->imp_obd->obd_namespace; - ldlm_namespace_cleanup(ns, 1 /* no network ops */); - abort_inflight_for_import(imp); - set_osc_active(imp, 0 /* inactive */); - RETURN(0); - } - case PTLRPC_RECOVD_PHASE_RECOVER: - imp->imp_flags &= ~IMP_INVALID; - rc = ptlrpc_reconnect_import(imp, OST_CONNECT); - if (rc) { - imp->imp_flags |= IMP_INVALID; - RETURN(rc); - } - set_osc_active(imp, 1 /* active */); - RETURN(0); - default: - RETURN(-EINVAL); - } -} - -static int osc_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct obd_import *imp = &obd->u.cli.cl_import; - imp->imp_recover = osc_recover; - return client_obd_connect(conn, obd, cluuid, recovd, recover); -} - -struct obd_ops osc_obd_ops = { - o_attach: osc_attach, - o_detach: osc_detach, - o_setup: client_obd_setup, - o_cleanup: client_obd_cleanup, - o_connect: osc_connect, - o_disconnect: client_obd_disconnect, - o_statfs: osc_statfs, - o_packmd: osc_packmd, - o_unpackmd: osc_unpackmd, - o_create: osc_create, - o_destroy: osc_destroy, - o_getattr: osc_getattr, - o_setattr: osc_setattr, - o_open: osc_open, - o_close: osc_close, - o_brw: osc_brw, - o_punch: osc_punch, - o_enqueue: osc_enqueue, - o_cancel: osc_cancel, - o_cancel_unused: osc_cancel_unused, - o_iocontrol: osc_iocontrol -}; - -static int __init osc_init(void) -{ - RETURN(class_register_type(&osc_obd_ops, status_class_var, - LUSTRE_OSC_NAME)); -} - -static void __exit osc_exit(void) -{ - class_unregister_type(LUSTRE_OSC_NAME); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Object Storage Client (OSC) v1.0"); -MODULE_LICENSE("GPL"); - -module_init(osc_init); -module_exit(osc_exit); diff --git a/lustre/ost/.cvsignore b/lustre/ost/.cvsignore deleted file mode 100644 index e530020..0000000 --- a/lustre/ost/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/ost/Makefile.am b/lustre/ost/Makefile.am deleted file mode 100644 index 3ad390a..0000000 --- a/lustre/ost/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= -MODULE = ost -modulefs_DATA = ost.o -EXTRA_PROGRAMS = ost - -LINX=obd_pack.c ll_pack.c target.c - -ll_pack.c: - test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c -obd_pack.c: - test -e obd_pack.c || ln -sf $(top_srcdir)/lib/obd_pack.c -target.c: - test -e target.c || ln -sf $(top_srcdir)/lib/target.c - -ost_SOURCES = ost_handler.c lproc_ost.c $(LINX) -dist-hook: - list='$(LINX)'; for f in $$list; do rm -f $(distdir)/$$f; done - -include $(top_srcdir)/Rules diff --git a/lustre/ost/lproc_ost.c b/lustre/ost/lproc_ost.c deleted file mode 100644 index 1fa1c59..0000000 --- a/lustre/ost/lproc_ost.c +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * 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_filestotal(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_filegroups(char* page, char **start, off_t off, int count, int *eof, - void *data) -{ - return 0; -} - -struct lprocfs_vars status_var_nm_1[] = { - {"status/uuid", rd_uuid, 0, 0}, - {"status/blocksize",rd_blksize, 0, 0}, - {"status/kbytesfree", rd_kbfree, 0, 0}, - {"status/kbytestotal", rd_kbtotal, 0, 0}, - {"status/filestotal", rd_filestotal, 0, 0}, - {"status/filesfree", rd_filesfree, 0, 0}, - {"status/filegroups", rd_filegroups, 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; - int len = 0; - len += snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -struct lprocfs_vars status_class_var[] = { - {"status/num_refs", rd_numrefs, 0, 0}, - {0} -}; - diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c deleted file mode 100644 index 2d47fcd..0000000 --- a/lustre/ost/ost_handler.c +++ /dev/null @@ -1,702 +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. - * Author: Peter J. Braam - * Author: Phil Schwan - * - * 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. - * - * Storage Target Handling functions - * Lustre Object Server Module (OST) - * - * This server is single threaded at present (but can easily be multi - * threaded). For testing and management it is treated as an - * obd_device, although it does not export a full OBD method table - * (the requests are coming in over the wire, so object target - * modules do not have a full method table.) - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_OST - -#include -#include -#include -#include -#include -#include - -extern struct lprocfs_vars status_var_nm_1[]; -extern struct lprocfs_vars status_class_var[]; - -static int ost_destroy(struct ptlrpc_request *req) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct ost_body *body; - int rc, size = sizeof(*body); - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, 0); - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - - req->rq_status = obd_destroy(conn, &body->oa, NULL); - RETURN(0); -} - -static int ost_getattr(struct ptlrpc_request *req) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct ost_body *body, *repbody; - int rc, size = sizeof(*body); - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, 0); - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - - repbody = lustre_msg_buf(req->rq_repmsg, 0); - /* FIXME: unpack only valid fields instead of memcpy, endianness */ - memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); - req->rq_status = obd_getattr(conn, &repbody->oa, NULL); - RETURN(0); -} - -static int ost_statfs(struct ptlrpc_request *req) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct obd_statfs *osfs; - int rc, size = sizeof(*osfs); - ENTRY; - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - - osfs = lustre_msg_buf(req->rq_repmsg, 0); - memset(osfs, 0, size); - - rc = obd_statfs(conn, osfs); - if (rc) { - CERROR("ost: statfs failed: rc %d\n", rc); - req->rq_status = rc; - RETURN(rc); - } - obd_statfs_pack(osfs, osfs); - - RETURN(0); -} - -static int ost_open(struct ptlrpc_request *req) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct ost_body *body, *repbody; - int rc, size = sizeof(*body); - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, 0); - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - - repbody = lustre_msg_buf(req->rq_repmsg, 0); - /* FIXME: unpack only valid fields instead of memcpy, endianness */ - memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); - req->rq_status = obd_open(conn, &repbody->oa, NULL); - RETURN(0); -} - -static int ost_close(struct ptlrpc_request *req) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct ost_body *body, *repbody; - int rc, size = sizeof(*body); - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, 0); - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - - repbody = lustre_msg_buf(req->rq_repmsg, 0); - /* FIXME: unpack only valid fields instead of memcpy, endianness */ - memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); - req->rq_status = obd_close(conn, &repbody->oa, NULL); - RETURN(0); -} - -static int ost_create(struct ptlrpc_request *req) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct ost_body *body, *repbody; - int rc, size = sizeof(*body); - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, 0); - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - - repbody = lustre_msg_buf(req->rq_repmsg, 0); - /* FIXME: unpack only valid fields instead of memcpy, endianness */ - memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); - req->rq_status = obd_create(conn, &repbody->oa, NULL); - RETURN(0); -} - -static int ost_punch(struct ptlrpc_request *req) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct ost_body *body, *repbody; - int rc, size = sizeof(*body); - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, 0); - - if ((NTOH__u32(body->oa.o_valid) & (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS))!= - (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) - RETURN(-EINVAL); - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - - repbody = lustre_msg_buf(req->rq_repmsg, 0); - /* FIXME: unpack only valid fields instead of memcpy, endianness */ - memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); - req->rq_status = obd_punch(conn, &repbody->oa, NULL, - repbody->oa.o_size, repbody->oa.o_blocks); - RETURN(0); -} - -static int ost_setattr(struct ptlrpc_request *req) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct ost_body *body, *repbody; - int rc, size = sizeof(*body); - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, 0); - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - - repbody = lustre_msg_buf(req->rq_repmsg, 0); - /* FIXME: unpack only valid fields instead of memcpy, endianness */ - memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); - req->rq_status = obd_setattr(conn, &repbody->oa, NULL); - RETURN(0); -} - -static int ost_bulk_timeout(void *data) -{ - struct ptlrpc_bulk_desc *desc = data; - - ENTRY; - recovd_conn_fail(desc->bd_connection); - RETURN(1); -} - -static int ost_brw_read(struct ptlrpc_request *req) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct ptlrpc_bulk_desc *desc; - void *tmp1, *tmp2, *end2; - struct niobuf_remote *remote_nb; - struct niobuf_local *local_nb = NULL; - struct obd_ioobj *ioo; - struct ost_body *body; - struct l_wait_info lwi; - void *desc_priv = NULL; - int rc, cmd, i, j, objcount, niocount, size = sizeof(*body); - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, 0); - tmp1 = lustre_msg_buf(req->rq_reqmsg, 1); - tmp2 = lustre_msg_buf(req->rq_reqmsg, 2); - end2 = (char *)tmp2 + req->rq_reqmsg->buflens[2]; - objcount = req->rq_reqmsg->buflens[1] / sizeof(*ioo); - niocount = req->rq_reqmsg->buflens[2] / sizeof(*remote_nb); - cmd = OBD_BRW_READ; - - if (OBD_FAIL_CHECK(OBD_FAIL_OST_BRW_READ_BULK)) - GOTO(out, rc = 0); - - for (i = 0; i < objcount; i++) { - ost_unpack_ioo(&tmp1, &ioo); - if (tmp2 + ioo->ioo_bufcnt > end2) { - LBUG(); - GOTO(out, rc = -EFAULT); - } - for (j = 0; j < ioo->ioo_bufcnt; j++) - ost_unpack_niobuf(&tmp2, &remote_nb); - } - - OBD_ALLOC(local_nb, sizeof(*local_nb) * niocount); - if (local_nb == NULL) - GOTO(out, rc = -ENOMEM); - - /* The unpackers move tmp1 and tmp2, so reset them before using */ - ioo = lustre_msg_buf(req->rq_reqmsg, 1); - remote_nb = lustre_msg_buf(req->rq_reqmsg, 2); - req->rq_status = obd_preprw(cmd, conn, objcount, ioo, niocount, - remote_nb, local_nb, &desc_priv); - - if (req->rq_status) - GOTO(out, rc = 0); - - desc = ptlrpc_prep_bulk(req->rq_connection); - if (desc == NULL) - GOTO(out_local, rc = -ENOMEM); - desc->bd_portal = OST_BULK_PORTAL; - - for (i = 0; i < niocount; i++) { - struct ptlrpc_bulk_page *bulk = ptlrpc_prep_bulk_page(desc); - - if (bulk == NULL) - GOTO(out_bulk, rc = -ENOMEM); - bulk->bp_xid = remote_nb[i].xid; - bulk->bp_buf = local_nb[i].addr; - bulk->bp_buflen = remote_nb[i].len; - } - - rc = ptlrpc_send_bulk(desc); - if (rc) - GOTO(out_bulk, rc); - - lwi = LWI_TIMEOUT(obd_timeout * HZ, ost_bulk_timeout, desc); - rc = l_wait_event(desc->bd_waitq, desc->bd_flags &PTL_BULK_FL_SENT, &lwi); - if (rc) { - LASSERT(rc == -ETIMEDOUT); - GOTO(out_bulk, rc); - } - - req->rq_status = obd_commitrw(cmd, conn, objcount, ioo, niocount, - local_nb, desc_priv); - - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - -out_bulk: - ptlrpc_free_bulk(desc); -out_local: - OBD_FREE(local_nb, sizeof(*local_nb) * niocount); -out: - if (rc) - ptlrpc_error(req->rq_svc, req); - else - ptlrpc_reply(req->rq_svc, req); - RETURN(rc); -} - -static int ost_brw_write(struct ptlrpc_request *req) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct ptlrpc_bulk_desc *desc; - struct niobuf_remote *remote_nb; - struct niobuf_local *local_nb, *lnb; - struct obd_ioobj *ioo; - struct ost_body *body; - int cmd, rc, i, j, objcount, niocount, size[2] = {sizeof(*body)}; - void *tmp1, *tmp2, *end2; - void *desc_priv = NULL; - int reply_sent = 0; - struct ptlrpc_service *srv; - struct l_wait_info lwi; - __u32 xid; - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, 0); - tmp1 = lustre_msg_buf(req->rq_reqmsg, 1); - tmp2 = lustre_msg_buf(req->rq_reqmsg, 2); - end2 = (char *)tmp2 + req->rq_reqmsg->buflens[2]; - objcount = req->rq_reqmsg->buflens[1] / sizeof(*ioo); - niocount = req->rq_reqmsg->buflens[2] / sizeof(*remote_nb); - cmd = OBD_BRW_WRITE; - - for (i = 0; i < objcount; i++) { - ost_unpack_ioo((void *)&tmp1, &ioo); - if (tmp2 + ioo->ioo_bufcnt > end2) { - rc = -EFAULT; - break; - } - for (j = 0; j < ioo->ioo_bufcnt; j++) - ost_unpack_niobuf((void *)&tmp2, &remote_nb); - } - - size[1] = niocount * sizeof(*remote_nb); - rc = lustre_pack_msg(2, size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - GOTO(out, rc); - remote_nb = lustre_msg_buf(req->rq_repmsg, 1); - - OBD_ALLOC(local_nb, niocount * sizeof(*local_nb)); - if (local_nb == NULL) - GOTO(out, rc = -ENOMEM); - - /* The unpackers move tmp1 and tmp2, so reset them before using */ - tmp1 = lustre_msg_buf(req->rq_reqmsg, 1); - tmp2 = lustre_msg_buf(req->rq_reqmsg, 2); - req->rq_status = obd_preprw(cmd, conn, objcount, tmp1, niocount, tmp2, - local_nb, &desc_priv); - if (req->rq_status) - GOTO(out_free, rc = 0); /* XXX is this correct? */ - - if (OBD_FAIL_CHECK(OBD_FAIL_OST_BRW_WRITE_BULK)) - GOTO(fail_preprw, rc = 0); - - desc = ptlrpc_prep_bulk(req->rq_connection); - if (desc == NULL) - GOTO(fail_preprw, rc = -ENOMEM); - desc->bd_ptl_ev_hdlr = NULL; - desc->bd_portal = OSC_BULK_PORTAL; - desc->bd_desc_private = desc_priv; - memcpy(&(desc->bd_conn), &conn, sizeof(conn)); - - srv = req->rq_obd->u.ost.ost_service; - spin_lock(&srv->srv_lock); - xid = srv->srv_xid++; /* single xid for all pages */ - spin_unlock(&srv->srv_lock); - - for (i = 0, lnb = local_nb; i < niocount; i++, lnb++) { - struct ptlrpc_bulk_page *bulk; - - bulk = ptlrpc_prep_bulk_page(desc); - if (bulk == NULL) - GOTO(fail_bulk, rc = -ENOMEM); - - bulk->bp_xid = xid; /* single xid for all pages */ - - bulk->bp_buf = lnb->addr; - bulk->bp_page = lnb->page; - bulk->bp_flags = lnb->flags; - bulk->bp_dentry = lnb->dentry; - bulk->bp_buflen = lnb->len; - bulk->bp_cb = NULL; - - /* this advances remote_nb */ - ost_pack_niobuf((void **)&remote_nb, lnb->offset, lnb->len, 0, - bulk->bp_xid); - } - - rc = ptlrpc_register_bulk(desc); - if (rc) - GOTO(fail_bulk, rc); - - reply_sent = 1; - ptlrpc_reply(req->rq_svc, req); - - lwi = LWI_TIMEOUT(obd_timeout * HZ, ost_bulk_timeout, desc); - rc = l_wait_event(desc->bd_waitq, desc->bd_flags & PTL_BULK_FL_RCVD, - &lwi); - if (rc) { - if (rc != -ETIMEDOUT) - LBUG(); - GOTO(fail_bulk, rc); - } - - rc = obd_commitrw(cmd, conn, objcount, tmp1, niocount, local_nb, - desc->bd_desc_private); - ptlrpc_free_bulk(desc); - EXIT; -out_free: - OBD_FREE(local_nb, niocount * sizeof(*local_nb)); -out: - if (!reply_sent) { - if (rc) { - OBD_FREE(req->rq_repmsg, req->rq_replen); - req->rq_repmsg = NULL; - ptlrpc_error(req->rq_svc, req); - } else - ptlrpc_reply(req->rq_svc, req); - } - return rc; - -fail_bulk: - ptlrpc_free_bulk(desc); -fail_preprw: - /* FIXME: how do we undo the preprw? */ - goto out_free; -} - -static int ost_handle(struct ptlrpc_request *req) -{ - int rc; - ENTRY; - - rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); - if (rc || OBD_FAIL_CHECK(OBD_FAIL_OST_HANDLE_UNPACK)) { - CERROR("lustre_ost: Invalid request\n"); - GOTO(out, rc); - } - - if (req->rq_reqmsg->opc != OST_CONNECT && - req->rq_export == NULL) { - CERROR("lustre_ost: operation %d on unconnected OST\n", - req->rq_reqmsg->opc); - GOTO(out, rc = -ENOTCONN); - } - - if (strcmp(req->rq_obd->obd_type->typ_name, "ost") != 0) - GOTO(out, rc = -EINVAL); - - switch (req->rq_reqmsg->opc) { - case OST_CONNECT: - CDEBUG(D_INODE, "connect\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_CONNECT_NET, 0); - rc = target_handle_connect(req); - break; - case OST_DISCONNECT: - CDEBUG(D_INODE, "disconnect\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_DISCONNECT_NET, 0); - rc = target_handle_disconnect(req); - break; - case OST_CREATE: - CDEBUG(D_INODE, "create\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_CREATE_NET, 0); - rc = ost_create(req); - break; - case OST_DESTROY: - CDEBUG(D_INODE, "destroy\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_DESTROY_NET, 0); - rc = ost_destroy(req); - break; - case OST_GETATTR: - CDEBUG(D_INODE, "getattr\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_GETATTR_NET, 0); - rc = ost_getattr(req); - break; - case OST_SETATTR: - CDEBUG(D_INODE, "setattr\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_SETATTR_NET, 0); - rc = ost_setattr(req); - break; - case OST_OPEN: - CDEBUG(D_INODE, "open\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_OPEN_NET, 0); - rc = ost_open(req); - break; - case OST_CLOSE: - CDEBUG(D_INODE, "close\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_CLOSE_NET, 0); - rc = ost_close(req); - break; - case OST_WRITE: - CDEBUG(D_INODE, "write\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_BRW_NET, 0); - rc = ost_brw_write(req); - /* ost_brw sends its own replies */ - RETURN(rc); - case OST_READ: - CDEBUG(D_INODE, "read\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_BRW_NET, 0); - rc = ost_brw_read(req); - /* ost_brw sends its own replies */ - RETURN(rc); - case OST_PUNCH: - CDEBUG(D_INODE, "punch\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_PUNCH_NET, 0); - rc = ost_punch(req); - break; - case OST_STATFS: - CDEBUG(D_INODE, "statfs\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_STATFS_NET, 0); - rc = ost_statfs(req); - break; - case LDLM_ENQUEUE: - CDEBUG(D_INODE, "enqueue\n"); - OBD_FAIL_RETURN(OBD_FAIL_LDLM_ENQUEUE, 0); - rc = ldlm_handle_enqueue(req); - break; - case LDLM_CONVERT: - CDEBUG(D_INODE, "convert\n"); - OBD_FAIL_RETURN(OBD_FAIL_LDLM_CONVERT, 0); - rc = ldlm_handle_convert(req); - break; - case LDLM_CANCEL: - CDEBUG(D_INODE, "cancel\n"); - OBD_FAIL_RETURN(OBD_FAIL_LDLM_CANCEL, 0); - rc = ldlm_handle_cancel(req); - break; - case LDLM_BL_CALLBACK: - case LDLM_CP_CALLBACK: - CDEBUG(D_INODE, "callback\n"); - CERROR("callbacks should not happen on OST\n"); - LBUG(); - OBD_FAIL_RETURN(OBD_FAIL_LDLM_BL_CALLBACK, 0); - break; - default: - req->rq_status = -ENOTSUPP; - rc = ptlrpc_error(req->rq_svc, req); - RETURN(rc); - } - - EXIT; -out: - //req->rq_status = rc; - if (rc) { - CERROR("ost: processing error (opcode=%d): %d\n", - req->rq_reqmsg->opc, rc); - ptlrpc_error(req->rq_svc, req); - } else { - CDEBUG(D_INODE, "sending reply\n"); - if (req->rq_repmsg == NULL) - CERROR("handler for opcode %d returned rc=0 without " - "creating rq_repmsg; needs to return rc != " - "0!\n", req->rq_reqmsg->opc); - ptlrpc_reply(req->rq_svc, req); - } - - return 0; -} - -/* mount the file system (secretly) */ -static int ost_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct obd_ioctl_data* data = buf; - struct ost_obd *ost = &obddev->u.ost; - struct obd_device *tgt; - int err; - int i; - 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, err = -EINVAL); - } - - err = obd_connect(&ost->ost_conn, tgt, NULL, NULL, NULL); - if (err) { - CERROR("fail to connect to device %d\n", data->ioc_dev); - GOTO(error_dec, err = -EINVAL); - } - - ost->ost_service = ptlrpc_init_svc(OST_NEVENTS, OST_NBUFS, - OST_BUFSIZE, OST_MAXREQSIZE, - OST_REQUEST_PORTAL, OSC_REPLY_PORTAL, - "self", ost_handle, "ost"); - if (!ost->ost_service) { - CERROR("failed to start service\n"); - GOTO(error_disc, err = -EINVAL); - } - - for (i = 0; i < OST_NUM_THREADS; i++) { - char name[32]; - sprintf(name, "ll_ost_%02d", i); - err = ptlrpc_start_thread(obddev, ost->ost_service, name); - if (err) { - CERROR("error starting thread #%d: rc %d\n", i, err); - GOTO(error_disc, err = -EINVAL); - } - } - - RETURN(0); - -error_disc: - obd_disconnect(&ost->ost_conn); -error_dec: - MOD_DEC_USE_COUNT; - RETURN(err); -} - -static int ost_cleanup(struct obd_device * obddev) -{ - struct ost_obd *ost = &obddev->u.ost; - int err; - - ENTRY; - - if ( !list_empty(&obddev->obd_exports) ) { - CERROR("still has clients!\n"); - RETURN(-EBUSY); - } - - ptlrpc_stop_all_threads(ost->ost_service); - ptlrpc_unregister_service(ost->ost_service); - - err = obd_disconnect(&ost->ost_conn); - if (err) { - CERROR("lustre ost: fail to disconnect device\n"); - RETURN(-EINVAL); - } - - MOD_DEC_USE_COUNT; - RETURN(0); -} -int ost_attach(struct obd_device *dev, obd_count len, void *data) -{ - return lprocfs_reg_obd(dev, status_var_nm_1, dev); -} - -int ost_detach(struct obd_device *dev) -{ - return lprocfs_dereg_obd(dev); - -} - - - -/* use obd ops to offer management infrastructure */ -static struct obd_ops ost_obd_ops = { - o_attach: ost_attach, - o_detach: ost_detach, - o_setup: ost_setup, - o_cleanup: ost_cleanup, -}; - -static int __init ost_init(void) -{ - int rc; - - rc = class_register_type(&ost_obd_ops, status_class_var, - LUSTRE_OST_NAME); - RETURN(rc); - -} - -static void __exit ost_exit(void) -{ - - class_unregister_type(LUSTRE_OST_NAME); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Object Storage Target (OST) v0.01"); -MODULE_LICENSE("GPL"); - -module_init(ost_init); -module_exit(ost_exit); diff --git a/lustre/patches/.cvsignore b/lustre/patches/.cvsignore deleted file mode 100644 index e530020..0000000 --- a/lustre/patches/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/patches/patch-2.4.18 b/lustre/patches/patch-2.4.18 deleted file mode 100644 index 4d7e278..0000000 --- a/lustre/patches/patch-2.4.18 +++ /dev/null @@ -1,1536 +0,0 @@ ---- lum-pristine/arch/ia64/mm/init.c Fri Nov 9 17:26:17 2001 -+++ lum/arch/ia64/mm/init.c Thu Aug 1 18:07:35 2002 -@@ -37,6 +37,12 @@ - - static unsigned long totalram_pages; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int - do_check_pgt_cache (int low, int high) - { ---- lum-pristine/arch/i386/mm/init.c Fri Dec 21 12:41:53 2001 -+++ lum/arch/i386/mm/init.c Thu Aug 1 18:07:35 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; ---- lum-pristine/drivers/block/blkpg.c Mon Feb 25 14:37:57 2002 -+++ lum/drivers/block/blkpg.c Thu Aug 1 18:07:35 2002 -@@ -294,3 +294,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); ---- lum-pristine/drivers/block/loop.c Fri Dec 21 12:41:53 2001 -+++ lum/drivers/block/loop.c Thu Aug 1 18:07:35 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) { ---- lum-pristine/drivers/ide/ide-disk.c Fri Dec 21 12:41:54 2001 -+++ lum/drivers/ide/ide-disk.c Thu Aug 1 18:07:35 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); ---- lum-pristine/fs/ext3/Makefile Fri Dec 21 12:41:55 2001 -+++ lum/fs/ext3/Makefile Thu Aug 1 18:07:35 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) ---- lum-pristine/fs/ext3/super.c Mon Feb 25 14:38:08 2002 -+++ lum/fs/ext3/super.c Thu Aug 1 18:07:35 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"); ---- lum-pristine/fs/jbd/commit.c Mon Feb 25 14:38:08 2002 -+++ lum/fs/jbd/commit.c Thu Aug 1 18:07:35 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); ---- lum-pristine/fs/jbd/journal.c Mon Feb 25 14:38:08 2002 -+++ lum/fs/jbd/journal.c Thu Aug 1 18:07:35 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); ---- lum-pristine/fs/jbd/transaction.c Mon Feb 25 14:38:08 2002 -+++ lum/fs/jbd/transaction.c Thu Aug 1 18:07:35 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 -@@ -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 ---- lum-pristine/include/linux/blkdev.h Mon Nov 26 08:29:17 2001 -+++ lum/include/linux/blkdev.h Mon Aug 12 11:48:39 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 ---- lum-pristine/include/linux/slab.h Fri Dec 21 12:42:04 2001 -+++ lum/include/linux/slab.h Mon Aug 12 11:48:38 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 *); ---- lum-pristine/include/linux/jbd.h Mon Feb 25 14:38:13 2002 -+++ lum/include/linux/jbd.h Mon Aug 12 11:50:09 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 *); ---- lum-pristine/kernel/ksyms.c Mon Feb 25 14:38:13 2002 -+++ lum/kernel/ksyms.c Thu Aug 1 18:07:35 2002 -@@ -271,6 +271,12 @@ - EXPORT_SYMBOL(lock_may_write); - EXPORT_SYMBOL(dcache_readdir); - -+/* lustre */ -+EXPORT_SYMBOL(panic_notifier_list); -+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); ---- lum-pristine/include/linux/dcache.h Thu Nov 22 14:46:18 2001 -+++ lum/include/linux/dcache.h Mon Aug 12 00:02:29 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 */ -@@ -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 *, struct lookup_intent *); - }; - - /* the dentry parameter passed to d_hash and d_compare is the parent ---- lum-pristine/include/linux/fs.h Mon Aug 12 11:02:53 2002 -+++ lum/include/linux/fs.h Mon Aug 12 11:48:38 2002 -@@ -536,6 +536,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; -@@ -779,7 +780,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 -@@ -840,6 +843,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 *); -@@ -986,7 +990,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 *); -@@ -1307,6 +1311,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 *)); -@@ -1317,6 +1322,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 *); ---- lum-pristine/fs/dcache.c Mon Feb 25 14:38:08 2002 -+++ lum/fs/dcache.c Thu Aug 1 18:07:35 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); ---- lum-pristine/fs/nfsd/vfs.c Fri Dec 21 12:41:55 2001 -+++ lum/fs/nfsd/vfs.c Thu Aug 1 18:07:35 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); ---- lum-pristine/fs/namei.c Mon Feb 25 14:38:09 2002 -+++ lum/fs/namei.c Mon Aug 12 11:47:56 2002 -@@ -94,6 +94,14 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct dentry *de, struct lookup_intent *it) -+{ -+ if (de->d_op && de->d_op->d_intent_release) -+ de->d_op->d_intent_release(de, it); -+ 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 +298,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 +318,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 +342,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; - } -@@ -445,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; -@@ -518,9 +546,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; -@@ -554,7 +582,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 +609,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; -@@ -607,7 +635,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; -@@ -630,12 +660,23 @@ - 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) -@@ -742,7 +786,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 +810,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 +831,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 +858,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 +890,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 +1041,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 +1057,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; -@@ -994,6 +1067,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 +1089,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 +1098,7 @@ - goto exit; - } - -+ it->it_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - error = vfs_create(dir->d_inode, dentry, -@@ -1139,8 +1219,10 @@ - return 0; - - exit_dput: -+ intent_release(dentry, it); - dput(dentry); - exit: -+ intent_release(nd->dentry, it); - path_release(nd); - return error; - -@@ -1160,6 +1242,8 @@ - */ - UPDATE_ATIME(dentry->d_inode); - error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) -+ intent_release(dentry, it); - dput(dentry); - if (error) - return error; -@@ -1181,13 +1265,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; - -@@ -1195,7 +1286,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) -@@ -1241,6 +1332,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; -@@ -1252,7 +1344,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); - - mode &= ~current->fs->umask; -@@ -1270,6 +1363,7 @@ - default: - error = -EINVAL; - } -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1310,6 +1404,7 @@ - { - int error = 0; - char * tmp; -+ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; - - tmp = getname(pathname); - error = PTR_ERR(tmp); -@@ -1321,11 +1416,12 @@ - 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)) { - error = vfs_mkdir(nd.dentry->d_inode, dentry, - mode & ~current->fs->umask); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1407,6 +1504,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_RMDIR }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1429,10 +1527,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); -@@ -1476,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)) -@@ -1489,14 +1590,15 @@ - 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 */ - if (nd.last.name[nd.last.len]) - goto slashes; - error = vfs_unlink(nd.dentry->d_inode, dentry); - exit2: -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1543,6 +1646,7 @@ - int error = 0; - char * from; - char * to; -+ struct lookup_intent it = { .it_op = IT_SYMLINK }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1557,10 +1661,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); -@@ -1626,6 +1732,7 @@ - int error; - char * from; - char * to; -+ struct lookup_intent it = { .it_op = IT_LINK }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1639,7 +1745,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)) -@@ -1648,10 +1755,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); -@@ -1694,7 +1803,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; -@@ -1754,6 +1864,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; -@@ -1775,7 +1887,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; - -@@ -1806,6 +1919,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; -@@ -1817,13 +1932,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); -@@ -1840,6 +1956,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)) -@@ -1868,7 +1985,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; -@@ -1884,18 +2003,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); // FIXME: release same intent twice!!! - dput(old_dentry); - exit3: - double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); ---- lum-pristine/fs/open.c Fri Oct 12 16:48:42 2001 -+++ lum/fs/open.c Sun Aug 11 15:26:29 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 +149,7 @@ - put_write_access(inode); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -235,8 +241,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 +270,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -279,8 +288,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; -@@ -306,6 +317,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -322,6 +334,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; -@@ -339,13 +352,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); - } - -@@ -361,6 +375,7 @@ - int error; - struct nameidata nd; - char *name; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - name = getname(filename); - error = PTR_ERR(name); -@@ -369,7 +384,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; -@@ -381,6 +397,7 @@ - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -421,6 +438,7 @@ - int error; - struct nameidata nd; - char *name; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - name = getname(filename); - error = PTR_ERR(name); -@@ -429,7 +447,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; -@@ -446,6 +465,7 @@ - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -490,8 +510,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; -@@ -511,6 +532,7 @@ - error = notify_change(nd.dentry, &newattrs); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -580,10 +602,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; -@@ -593,10 +618,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; -@@ -630,10 +658,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) -@@ -641,14 +675,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; -@@ -691,6 +726,7 @@ - } - f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); - -+ intent_release(dentry, it); - return f; - - cleanup_all: -@@ -705,11 +741,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. - */ ---- lum-pristine/fs/stat.c Thu Sep 13 19:04:43 2001 -+++ lum/fs/stat.c Mon Aug 12 00:04:39 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 +135,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 +153,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 +176,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 +195,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 +255,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 +342,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 +359,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; ---- lum-pristine/mm/slab.c Fri Dec 21 12:42:05 2001 -+++ lum/mm/slab.c Thu Aug 1 18:07:35 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.18-14 b/lustre/patches/patch-2.4.18-14 deleted file mode 100644 index e563f7b..0000000 --- a/lustre/patches/patch-2.4.18-14 +++ /dev/null @@ -1,1369 +0,0 @@ ---- linux-2.4.18-17.8.0-uml-pristine/include/linux/lustre_version.h Wed Dec 31 19:00:00 1969 -+++ linux-2.4.18-17.8.0-uml/include/linux/lustre_version.h Tue Nov 26 07:02:14 2002 -@@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 3 ---- linux-2.4.18-17.8.0-uml-pristine/arch/ia64/mm/init.c 2002-10-19 11:44:08.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/arch/ia64/mm/init.c 2002-10-19 11:44:51.000000000 -0600 -@@ -37,6 +37,12 @@ - - static unsigned long totalram_pages; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int - do_check_pgt_cache (int low, int high) - { ---- linux-2.4.18-17.8.0-uml-pristine/arch/i386/mm/init.c 2002-10-19 11:44:04.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/arch/i386/mm/init.c 2002-10-19 11:44:51.000000000 -0600 -@@ -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-2.4.18-17.8.0-uml-pristine/drivers/block/blkpg.c 2002-10-19 11:43:55.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/drivers/block/blkpg.c 2002-10-19 11:44:51.000000000 -0600 -@@ -297,3 +297,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-17.8.0-uml-pristine/drivers/block/loop.c 2002-10-19 11:43:55.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/drivers/block/loop.c 2002-10-19 11:44:51.000000000 -0600 -@@ -491,6 +491,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-17.8.0-uml-pristine/drivers/ide/ide-disk.c 2002-10-19 11:43:58.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/drivers/ide/ide-disk.c 2002-10-19 11:44:51.000000000 -0600 -@@ -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-17.8.0-uml-pristine/fs/ext3/Makefile 2002-10-19 11:43:53.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/fs/ext3/Makefile 2002-10-19 11:44:51.000000000 -0600 -@@ -9,6 +9,8 @@ - - O_TARGET := ext3.o - -+export-objs := super.o -+ - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o - obj-m := $(O_TARGET) ---- linux-2.4.18-17.8.0-uml-pristine/fs/ext3/super.c 2002-10-19 11:43:53.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/fs/ext3/super.c 2002-10-19 11:44:51.000000000 -0600 -@@ -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-17.8.0-uml-pristine/include/linux/slab.h 2002-10-19 11:43:54.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/include/linux/slab.h 2002-11-02 00:49:24.000000000 -0700 -@@ -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-17.8.0-uml-pristine/kernel/ksyms.c 2002-10-19 11:43:53.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/kernel/ksyms.c 2002-11-02 01:09:34.000000000 -0700 -@@ -292,6 +292,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); -@@ -306,6 +307,12 @@ - EXPORT_SYMBOL_GPL(nr_free_pages); - EXPORT_SYMBOL_GPL(page_cache_size); - -+/* lustre */ -+EXPORT_SYMBOL(panic_notifier_list); -+EXPORT_SYMBOL(pagecache_lock_cacheline); -+EXPORT_SYMBOL(do_kern_mount); -+EXPORT_SYMBOL(kmem_cache_validate); -+ - /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ - EXPORT_SYMBOL(default_llseek); - EXPORT_SYMBOL(dentry_open); ---- linux-2.4.18-17.8.0-uml-pristine/include/linux/dcache.h 2002-10-19 11:43:54.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/include/linux/dcache.h 2002-11-02 00:49:24.000000000 -0700 -@@ -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 */ - void * d_extra_attributes; /* TUX-specific data */ -@@ -91,6 +120,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-2.4.18-17.8.0-uml-pristine/include/linux/fs.h 2002-10-19 11:43:54.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/include/linux/fs.h 2002-11-02 00:49:24.000000000 -0700 -@@ -576,6 +576,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; -@@ -836,7 +837,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 -@@ -897,6 +900,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 *); -@@ -907,6 +911,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 *); -@@ -1046,6 +1052,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 -@@ -1380,6 +1387,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 *)); -@@ -1391,6 +1399,8 @@ - extern struct dentry * lookup_hash(struct qstr *, struct dentry *); - #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) - #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) -+#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) -+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) - - extern void inode_init_once(struct inode *); - extern void iput(struct inode *); -@@ -1491,6 +1501,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-2.4.18-17.8.0-uml-pristine/fs/dcache.c 2002-10-19 11:43:53.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/fs/dcache.c 2002-10-31 13:10:34.000000000 -0700 -@@ -150,6 +150,8 @@ - unhash_it: - list_del_init(&dentry->d_hash); - -+ -+ - kill_it: { - struct dentry *parent; - list_del(&dentry->d_child); -@@ -645,6 +647,7 @@ - dentry->d_fsdata = NULL; - dentry->d_extra_attributes = NULL; - dentry->d_mounted = 0; -+ dentry->d_it = NULL; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); ---- linux-2.4.18-17.8.0-uml-pristine/fs/nfsd/vfs.c 2002-10-19 11:43:53.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/fs/nfsd/vfs.c 2002-10-19 11:44:51.000000000 -0600 -@@ -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-17.8.0-uml-pristine/fs/namei.c 2002-10-19 11:43:53.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/fs/namei.c 2002-11-02 01:02:26.000000000 -0700 -@@ -1,3 +1,6 @@ -+ -+ -+ - /* - * linux/fs/namei.c - * -@@ -94,6 +97,14 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct dentry *de, struct lookup_intent *it) -+{ -+ if (de->d_op && de->d_op->d_intent_release) -+ de->d_op->d_intent_release(de, it); -+ -+} -+ -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -260,10 +271,19 @@ - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -281,7 +301,8 @@ - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; -@@ -300,6 +321,9 @@ - result = ERR_PTR(-ENOMEM); - if (dentry) { - lock_kernel(); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -321,6 +345,12 @@ - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ result = ERR_PTR(-ENOENT); -+ } - } - return result; - } -@@ -334,7 +364,8 @@ - * Without that kind of total limit, nasty chains of consecutive - * symlinks can cause almost arbitrarily long lookups. - */ --static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) -+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, -+ struct lookup_intent *it) - { - int err; - if (current->link_count >= max_recursive_link) -@@ -348,10 +379,14 @@ - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -- err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -+ intent_release(dentry, it); - path_release(nd); - return -ELOOP; - } -@@ -449,7 +484,8 @@ - * - * We expect 'base' to be positive and a directory. - */ --int link_path_walk(const char * name, struct nameidata *nd) -+int link_path_walk_it(const char *name, struct nameidata *nd, -+ struct lookup_intent *it) - { - struct dentry *dentry; - struct inode *inode; -@@ -526,12 +562,12 @@ - break; - } - /* This does the actual lookups.. */ -- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - if (!dentry) { - err = -EWOULDBLOCKIO; - if (atomic) - break; -- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -548,8 +584,8 @@ - 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; -@@ -565,7 +601,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 */ -@@ -592,12 +628,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; -@@ -606,8 +642,10 @@ - ; - inode = dentry->d_inode; - if ((lookup_flags & LOOKUP_FOLLOW) -- && inode && inode->i_op && inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ && inode && inode->i_op && -+ (inode->i_op->follow_link || -+ inode->i_op->follow_link2)) { -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -621,7 +659,8 @@ - goto no_inode; - if (lookup_flags & LOOKUP_DIRECTORY) { - err = -ENOTDIR; -- if (!inode->i_op || !inode->i_op->lookup) -+ if (!inode->i_op || (!inode->i_op->lookup && -+ !inode->i_op->lookup2)) - break; - } - goto return_base; -@@ -663,10 +702,21 @@ - return err; - } - -+int link_path_walk(const char * name, struct nameidata *nd) -+{ -+ return link_path_walk_it(name, nd, NULL); -+} -+ -+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) -+{ -+ current->total_link_count = 0; -+ return link_path_walk_it(name, nd, it); -+} -+ - int path_walk(const char * name, struct nameidata *nd) - { - current->total_link_count = 0; -- return link_path_walk(name, nd); -+ return link_path_walk_it(name, nd, NULL); - } - - /* SMP-safe */ -@@ -751,6 +801,17 @@ - } - - /* SMP-safe */ -+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it) -+{ -+ int error = 0; -+ if (path_init(path, flags, nd)) -+ error = path_walk_it(path, nd, it); -+ return error; -+} -+ -+ -+/* SMP-safe */ - int path_lookup(const char *path, unsigned flags, struct nameidata *nd) - { - int error = 0; -@@ -779,7 +840,8 @@ - * needs parent already locked. Doesn't follow mounts. - * SMP-safe. - */ --struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, -+ struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -802,13 +864,16 @@ - goto out; - } - -- dentry = cached_lookup(base, name, 0); -+ dentry = cached_lookup(base, name, 0, it); - if (!dentry) { - struct dentry *new = d_alloc(base, name); - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; - lock_kernel(); -+ if (inode->i_op->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -820,6 +885,12 @@ - return dentry; - } - -+struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+{ -+ return lookup_hash_it(name, base, NULL); -+} -+ -+ - /* SMP-safe */ - struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) - { -@@ -841,7 +912,7 @@ - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash_it(&this, base, NULL); - access: - return ERR_PTR(-EACCES); - } -@@ -872,6 +943,23 @@ - return err; - } - -+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it) -+{ -+ char *tmp; -+ int err; -+ -+ tmp = getname(name); -+ err = PTR_ERR(tmp); -+ if (!IS_ERR(tmp)) { -+ err = 0; -+ if (path_init(tmp, flags, nd)) -+ err = path_walk_it(tmp, nd, it); -+ putname(tmp); -+ } -+ return err; -+} -+ - /* - * It's inline, so penalty for filesystems that don't use sticky bit is - * minimal. -@@ -1010,7 +1098,8 @@ - * for symlinks (where the permissions are checked later). - * SMP-safe - */ --int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) -+int open_namei_it(const char *pathname, int flag, int mode, -+ struct nameidata *nd, struct lookup_intent *it) - { - int acc_mode, error = 0; - struct inode *inode; -@@ -1024,7 +1113,7 @@ - * The simplest case - just a plain lookup. - */ - if (!(flag & O_CREAT)) { -- error = path_lookup(pathname, lookup_flags(flag), nd); -+ error = path_lookup_it(pathname, lookup_flags(flag), nd, it); - if (error) - return error; - dentry = nd->dentry; -@@ -1034,6 +1123,10 @@ - /* - * Create - we need to know the parent. - */ -+ if (it) { -+ it->it_mode = mode; -+ it->it_op |= IT_CREAT; -+ } - error = path_lookup(pathname, LOOKUP_PARENT, nd); - if (error) - return error; -@@ -1049,7 +1142,7 @@ - - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - - do_last: - error = PTR_ERR(dentry); -@@ -1058,6 +1151,7 @@ - goto exit; - } - -+ it->it_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - error = vfs_create(dir->d_inode, dentry, -@@ -1091,7 +1185,8 @@ - error = -ENOENT; - if (!dentry->d_inode) - goto exit_dput; -- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) -+ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || -+ dentry->d_inode->i_op->follow_link2)) - goto do_link; - - dput(nd->dentry); -@@ -1177,8 +1272,10 @@ - return 0; - - exit_dput: -+ intent_release(dentry, it); - dput(dentry); - exit: -+ intent_release(nd->dentry, it); - path_release(nd); - return error; - -@@ -1197,7 +1294,12 @@ - * are done. Procfs-like symlinks just set LAST_BIND. - */ - UPDATE_ATIME(dentry->d_inode); -- error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ error = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) -+ intent_release(dentry, it); - dput(dentry); - if (error) - return error; -@@ -1219,13 +1321,20 @@ - } - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - putname(nd->last.name); - goto do_last; - } - -+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd) -+{ -+ return open_namei_it(pathname, flag, mode, nd, NULL); -+} -+ -+ - /* SMP-safe */ --static struct dentry *lookup_create(struct nameidata *nd, int is_dir) -+static struct dentry *lookup_create(struct nameidata *nd, int is_dir, -+ struct lookup_intent *it) - { - struct dentry *dentry; - -@@ -1233,7 +1342,7 @@ - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - if (IS_ERR(dentry)) - goto fail; - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1279,6 +1388,7 @@ - char * tmp; - struct dentry * dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode }; - - if (S_ISDIR(mode)) - return -EPERM; -@@ -1289,7 +1399,7 @@ - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(dentry); - - mode &= ~current->fs->umask; -@@ -1307,6 +1417,7 @@ - default: - error = -EINVAL; - } -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1347,6 +1458,7 @@ - { - int error = 0; - char * tmp; -+ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; - - tmp = getname(pathname); - error = PTR_ERR(tmp); -@@ -1357,11 +1469,12 @@ - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 1); -+ dentry = lookup_create(&nd, 1, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_mkdir(nd.dentry->d_inode, dentry, - mode & ~current->fs->umask); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1445,6 +1558,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_RMDIR }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1466,10 +1580,11 @@ - goto exit1; - } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1513,6 +1628,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_UNLINK }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1525,7 +1641,7 @@ - if (nd.last_type != LAST_NORM) - goto exit1; - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1533,6 +1649,7 @@ - goto slashes; - error = vfs_unlink(nd.dentry->d_inode, dentry); - exit2: -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1579,6 +1696,7 @@ - int error = 0; - char * from; - char * to; -+ struct lookup_intent it = { .it_op = IT_SYMLINK }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1592,10 +1710,12 @@ - error = path_lookup(to, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ it.it_data = from; -+ dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_symlink(nd.dentry->d_inode, dentry, from); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1660,6 +1780,7 @@ - { - int error; - char * to; -+ struct lookup_intent it = { .it_op = IT_LINK }; - - to = getname(newname); - error = PTR_ERR(to); -@@ -1667,7 +1788,7 @@ - struct dentry *new_dentry; - struct nameidata nd, old_nd; - -- error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd); -+ error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, &it); - if (error) - goto exit; - error = path_lookup(to, LOOKUP_PARENT, &nd); -@@ -1676,10 +1797,12 @@ - error = -EXDEV; - if (old_nd.mnt != nd.mnt) - goto out_release; -- new_dentry = lookup_create(&nd, 0); -+ it.it_op = IT_LINK2; -+ new_dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(new_dentry); - if (!IS_ERR(new_dentry)) { - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); -+ intent_release(new_dentry, &it); - dput(new_dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1720,7 +1843,8 @@ - * locking]. - */ - int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - struct inode *target; -@@ -1778,6 +1902,7 @@ - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - if (target) { - if (!error) - target->i_flags |= S_DEAD; -@@ -1799,7 +1924,8 @@ - } - - int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - -@@ -1830,6 +1956,7 @@ - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - double_up(&old_dir->i_zombie, &new_dir->i_zombie); - if (error) - return error; -@@ -1841,13 +1968,14 @@ - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - if (S_ISDIR(old_dentry->d_inode->i_mode)) -- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); - else -- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); - if (!error) { - if (old_dir == new_dir) - inode_dir_notify(old_dir, DN_RENAME); -@@ -1864,6 +1992,7 @@ - int error = 0; - struct dentry * old_dir, * new_dir; - struct dentry * old_dentry, *new_dentry; -+ struct lookup_intent it = { .it_op = IT_RENAME }; - struct nameidata oldnd, newnd; - - error = path_lookup(oldname, LOOKUP_PARENT, &oldnd); -@@ -1889,7 +2018,7 @@ - - double_lock(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -1905,18 +2034,21 @@ - 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, NULL); - dput(new_dentry); - exit4: -+ intent_release(old_dentry, &it); - dput(old_dentry); - exit3: - double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); -@@ -1965,7 +2097,8 @@ - } - - static inline int --__vfs_follow_link(struct nameidata *nd, const char *link) -+__vfs_follow_link(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) - { - int res = 0; - char *name; -@@ -1978,7 +2111,7 @@ - /* weird __emul_prefix() stuff did it */ - goto out; - } -- res = link_path_walk(link, nd); -+ res = link_path_walk_it(link, nd, it); - out: - if (current->link_count || res || nd->last_type!=LAST_NORM) - return res; -@@ -2000,7 +2133,13 @@ - - int vfs_follow_link(struct nameidata *nd, const char *link) - { -- return __vfs_follow_link(nd, link); -+ return __vfs_follow_link(nd, link, NULL); -+} -+ -+int vfs_follow_link_it(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) -+{ -+ return __vfs_follow_link(nd, link, it); - } - - /* get the link contents into pagecache */ -@@ -2042,7 +2181,7 @@ - { - struct page *page = NULL; - char *s = page_getlink(dentry, &page); -- int res = __vfs_follow_link(nd, s); -+ int res = __vfs_follow_link(nd, s, NULL); - if (page) { - kunmap(page); - page_cache_release(page); ---- linux-2.4.18-17.8.0-uml-pristine/fs/open.c 2002-10-19 11:43:53.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/fs/open.c 2002-10-19 11:44:51.000000000 -0600 -@@ -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) - { -@@ -118,12 +121,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; -@@ -168,6 +172,7 @@ - put_write_access(inode); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -259,8 +264,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; -@@ -286,6 +292,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -303,8 +310,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; -@@ -331,6 +339,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -347,6 +356,7 @@ - int old_fsuid, old_fsgid; - kernel_cap_t old_cap; - int res; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ - return -EINVAL; -@@ -364,13 +374,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); - } - -@@ -385,8 +396,11 @@ - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); -+ error = __user_walk_it(filename, -+ LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, -+ &nd, &it); - if (error) - goto out; - -@@ -397,6 +411,7 @@ - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -436,9 +451,10 @@ - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -- LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); -+ error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -+ LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it); - if (error) - goto out; - -@@ -454,6 +470,7 @@ - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -498,8 +515,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; -@@ -519,6 +537,7 @@ - error = notify_change(nd.dentry, &newattrs); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -588,10 +607,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; -@@ -601,10 +622,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; -@@ -638,10 +661,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) -@@ -649,18 +678,19 @@ - if (namei_flags & O_TRUNC) - namei_flags |= 2; - -- error = open_namei(filename, namei_flags, mode, &nd); -- if (!error) -- return dentry_open(nd.dentry, nd.mnt, flags); -+ error = open_namei_it(filename, namei_flags, mode, &nd, &it); -+ if (error) -+ return ERR_PTR(error); - -- return ERR_PTR(error); -+ return dentry_open_it(nd.dentry, nd.mnt, flags, &it); - } - - extern ssize_t do_readahead(struct file *file, unsigned long index, unsigned long nr); - /* for files over a certains size it doesn't pay to do readahead on open */ - #define READAHEAD_CUTOFF 48000 - --struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it) - { - struct file * f; - struct inode *inode; -@@ -711,6 +741,7 @@ - do_readahead(f, 0, (48 * 1024) >> PAGE_SHIFT); - - -+ intent_release(dentry, it); - return f; - - cleanup_all: -@@ -725,11 +756,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-2.4.18-17.8.0-uml-pristine/fs/stat.c 2002-10-19 11:43:53.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/fs/stat.c 2002-10-19 11:44:51.000000000 -0600 -@@ -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. - */ -@@ -104,10 +105,12 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk(name, &nd); -+ error = user_path_walk_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -117,10 +120,12 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk_link(name, &nd); -+ error = user_path_walk_link_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; ---- linux-2.4.18-17.8.0-uml-pristine/mm/slab.c 2002-10-19 11:43:54.000000000 -0600 -+++ linux-2.4.18-17.8.0-uml/mm/slab.c 2002-10-19 11:44:51.000000000 -0600 -@@ -1208,6 +1208,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.18-alpha b/lustre/patches/patch-2.4.18-alpha deleted file mode 100644 index 59be47e..0000000 --- a/lustre/patches/patch-2.4.18-alpha +++ /dev/null @@ -1,16 +0,0 @@ -diff -ruN linux/arch/alpha/mm/init.c linux-2.4.18-lustre/arch/alpha/mm/init.c ---- linux/arch/alpha/mm/init.c Thu Sep 20 21:02:03 2001 -+++ linux-2.4.18-lustre/arch/alpha/mm/init.c Tue Aug 6 12:37:55 2002 -@@ -46,6 +46,12 @@ - struct pgtable_cache_struct quicklists; - #endif - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - pgd_t * - get_pgd_slow(void) - { diff --git a/lustre/patches/patch-2.4.18-chaos12 b/lustre/patches/patch-2.4.18-chaos12 deleted file mode 100644 index 57a6d09..0000000 --- a/lustre/patches/patch-2.4.18-chaos12 +++ /dev/null @@ -1,1521 +0,0 @@ ---- linux-2.4.18-lustre12-pristine/arch/ia64/mm/init.c Wed Jun 26 00:15:21 2002 -+++ linux-2.4.18-lustre12/arch/ia64/mm/init.c Tue Aug 13 11:13:09 2002 -@@ -37,6 +37,12 @@ - - static unsigned long totalram_pages; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int - do_check_pgt_cache (int low, int high) - { ---- linux-2.4.18-lustre12-pristine/arch/i386/mm/init.c Wed Jun 26 00:15:21 2002 -+++ linux-2.4.18-lustre12/arch/i386/mm/init.c Tue Aug 13 11:13:09 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-2.4.18-lustre12-pristine/drivers/block/blkpg.c Tue May 7 20:33:10 2002 -+++ linux-2.4.18-lustre12/drivers/block/blkpg.c Tue Aug 13 11:13:08 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-lustre12-pristine/drivers/block/loop.c Tue May 7 19:48:59 2002 -+++ linux-2.4.18-lustre12/drivers/block/loop.c Tue Aug 13 11:13:08 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-lustre12-pristine/drivers/ide/ide-disk.c Tue May 7 18:43:35 2002 -+++ linux-2.4.18-lustre12/drivers/ide/ide-disk.c Tue Aug 13 11:13:08 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-lustre12-pristine/fs/ext3/Makefile Tue May 7 17:53:46 2002 -+++ linux-2.4.18-lustre12/fs/ext3/Makefile Tue Aug 13 11:13:08 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-lustre12-pristine/fs/ext3/super.c Tue May 7 19:43:17 2002 -+++ linux-2.4.18-lustre12/fs/ext3/super.c Tue Aug 13 11:13:08 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-lustre12-pristine/fs/jbd/commit.c Tue May 7 18:39:35 2002 -+++ linux-2.4.18-lustre12/fs/jbd/commit.c Tue Aug 13 11:13:08 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-lustre12-pristine/fs/jbd/journal.c Wed Jun 26 00:16:17 2002 -+++ linux-2.4.18-lustre12/fs/jbd/journal.c Tue Aug 13 11:13:08 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-lustre12-pristine/fs/jbd/transaction.c Tue Jun 18 15:53:27 2002 -+++ linux-2.4.18-lustre12/fs/jbd/transaction.c Tue Aug 13 11:13:08 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-lustre12-pristine/include/linux/blkdev.h Wed Jun 26 00:16:30 2002 -+++ linux-2.4.18-lustre12/include/linux/blkdev.h Tue Aug 13 11:13:08 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-2.4.18-lustre12-pristine/include/linux/slab.h Wed Jun 26 00:16:34 2002 -+++ linux-2.4.18-lustre12/include/linux/slab.h Tue Aug 13 11:13:09 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-lustre12-pristine/include/linux/jbd.h Tue May 7 19:43:17 2002 -+++ linux-2.4.18-lustre12/include/linux/jbd.h Tue Aug 13 11:13:08 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-lustre12-pristine/kernel/ksyms.c Wed Jun 26 00:16:38 2002 -+++ linux-2.4.18-lustre12/kernel/ksyms.c Tue Aug 13 11:13:08 2002 -@@ -306,6 +306,12 @@ - EXPORT_SYMBOL(lock_may_write); - EXPORT_SYMBOL(dcache_readdir); - -+/* lustre */ -+EXPORT_SYMBOL(panic_notifier_list); -+EXPORT_SYMBOL(pagecache_lock_cacheline); -+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-2.4.18-lustre12-pristine/include/linux/dcache.h Tue May 7 18:22:37 2002 -+++ linux-2.4.18-lustre12/include/linux/dcache.h Tue Aug 13 11:13:09 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-lustre12-pristine/include/linux/fs.h Wed Jun 26 00:16:31 2002 -+++ linux-2.4.18-lustre12/include/linux/fs.h Tue Aug 13 11:13:09 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-lustre12-pristine/fs/dcache.c Wed Jun 26 00:16:14 2002 -+++ linux-2.4.18-lustre12/fs/dcache.c Tue Aug 13 11:13:09 2002 -@@ -645,6 +645,7 @@ - dentry->d_fsdata = NULL; - dentry->d_extra_attributes = NULL; - dentry->d_mounted = 0; -+ dentry->d_it = NULL; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); ---- linux-2.4.18-lustre12-pristine/fs/nfsd/vfs.c Wed Jun 26 00:16:24 2002 -+++ linux-2.4.18-lustre12/fs/nfsd/vfs.c Tue Aug 13 11:13:09 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-lustre12-pristine/fs/namei.c Wed Jun 26 00:16:14 2002 -+++ linux-2.4.18-lustre12/fs/namei.c Tue Aug 13 11:18:48 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 +298,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 +318,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 +342,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; - } -@@ -447,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; -@@ -524,12 +553,12 @@ - break; - } - /* This does the actual lookups.. */ -- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - if (!dentry) { - err = -EWOULDBLOCKIO; - if (atomic) - break; -- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -563,7 +592,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 +619,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 +648,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 +681,7 @@ - } - } - return_base: -+ nd->dentry->d_it = it; - return 0; - out_dput: - dput(dentry); -@@ -658,15 +689,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 +794,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 +833,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 +857,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 +878,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 +905,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 +936,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 +1091,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 +1106,21 @@ - * 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_mode = mode; -+ it->it_op |= IT_CREAT; -+ } - error = path_lookup(pathname, LOOKUP_PARENT, nd); - if (error) - return error; -@@ -1047,7 +1136,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 +1145,8 @@ - goto exit; - } - -+ dentry->d_it = it; -+ dentry->d_it->it_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - error = vfs_create(dir->d_inode, dentry, -@@ -1175,8 +1266,10 @@ - return 0; - - exit_dput: -+ intent_release(dentry); - dput(dentry); - exit: -+ intent_release(nd->dentry); - path_release(nd); - return error; - -@@ -1196,6 +1289,8 @@ - */ - UPDATE_ATIME(dentry->d_inode); - error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) -+ intent_release(dentry); - dput(dentry); - if (error) - return error; -@@ -1217,13 +1312,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 +1333,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 +1379,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; -@@ -1287,11 +1390,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 +1409,7 @@ - default: - error = -EINVAL; - } -+ intent_release(dentry); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1345,6 +1450,7 @@ - { - int error = 0; - char * tmp; -+ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; - - tmp = getname(pathname); - error = PTR_ERR(tmp); -@@ -1355,11 +1461,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 +1547,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_RMDIR }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1460,10 +1569,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 +1618,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_UNLINK }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1519,14 +1631,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 +1687,7 @@ - int error = 0; - char * from; - char * to; -+ struct lookup_intent it = { .it_op = IT_SYMLINK }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1586,10 +1701,13 @@ - error = path_lookup(to, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ it.it_data = from; -+ dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { -+ dentry->d_it = ⁢ - error = vfs_symlink(nd.dentry->d_inode, dentry, from); -+ intent_release(dentry); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1654,6 +1771,7 @@ - { - int error; - char * to; -+ struct lookup_intent it = { .it_op = IT_LINK }; - - to = getname(newname); - error = PTR_ERR(to); -@@ -1670,10 +1788,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 +1834,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 +1889,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 +1916,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 +1944,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 +1961,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 +1985,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; - - error = path_lookup(oldname, LOOKUP_PARENT, &oldnd); -@@ -1883,7 +2011,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,18 +2027,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); - dput(new_dentry); - exit4: -+ intent_release(old_dentry); - dput(old_dentry); - exit3: - double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); ---- linux-2.4.18-lustre12-pristine/fs/open.c Wed Jun 26 00:16:14 2002 -+++ linux-2.4.18-lustre12/fs/open.c Tue Aug 13 11:19:36 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); - - int vfs_statfs(struct super_block *sb, struct statfs *buf) - { -@@ -118,14 +120,16 @@ - 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; -+ nd.dentry->d_it = ⁢ - inode = nd.dentry->d_inode; - - /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ -@@ -168,6 +172,7 @@ - put_write_access(inode); - - dput_and_out: -+ intent_release(nd.dentry); - path_release(&nd); - out: - return error; -@@ -259,10 +264,12 @@ - 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; -+ nd.dentry->d_it = ⁢ - inode = nd.dentry->d_inode; - - error = -EROFS; -@@ -286,6 +293,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry); - path_release(&nd); - out: - return error; -@@ -303,11 +311,13 @@ - 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; -+ nd.dentry->d_it = ⁢ - inode = nd.dentry->d_inode; - - error = -EROFS; -@@ -330,6 +340,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry); - path_release(&nd); - out: - return error; -@@ -346,6 +357,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; -@@ -363,13 +375,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 +397,15 @@ - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); -+ error = __user_walk_it(filename, -+ LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, -+ &nd, &it); - if (error) - goto out; - -+ nd.dentry->d_it = ⁢ - error = permission(nd.dentry->d_inode,MAY_EXEC); - if (error) - goto dput_and_out; -@@ -396,6 +411,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 +451,14 @@ - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -- LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); -+ error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -+ LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it); - if (error) - goto out; - -+ nd.dentry->d_it = ⁢ - error = permission(nd.dentry->d_inode,MAY_EXEC); - if (error) - goto dput_and_out; -@@ -453,6 +471,7 @@ - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(nd.dentry); - path_release(&nd); - out: - return error; -@@ -497,12 +516,14 @@ - 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; - -+ nd.dentry->d_it = ⁢ - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; -@@ -518,6 +539,7 @@ - error = notify_change(nd.dentry, &newattrs); - - dput_and_out: -+ intent_release(nd.dentry); - path_release(&nd); - out: - return error; -@@ -587,10 +609,13 @@ - { - 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) { -+ nd.dentry->d_it = ⁢ - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry); - path_release(&nd); - } - return error; -@@ -600,10 +625,13 @@ - { - 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) { -+ nd.dentry->d_it = ⁢ - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry); - path_release(&nd); - } - return error; -@@ -637,10 +665,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) -@@ -648,14 +681,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; -@@ -698,6 +731,7 @@ - } - f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); - -+ intent_release(dentry); - return f; - - cleanup_all: -@@ -712,11 +746,17 @@ - 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-lustre12-pristine/fs/stat.c Tue May 7 19:40:30 2002 -+++ linux-2.4.18-lustre12/fs/stat.c Tue Aug 13 11:13:09 2002 -@@ -13,6 +13,7 @@ - - #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_op = IT_GETATTR }; - -- error = user_path_walk(name, &nd); -+ error = user_path_walk_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry); - path_release(&nd); - } - return error; -@@ -117,10 +121,12 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk_link(name, &nd); -+ error = user_path_walk_link_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry); - path_release(&nd); - } - return error; ---- linux-2.4.18-lustre12-pristine/mm/slab.c Wed Jun 26 00:16:40 2002 -+++ linux-2.4.18-lustre12/mm/slab.c Tue Aug 13 11:13:09 2002 -@@ -1207,6 +1207,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) ---- linux-2.4.18-lustre12-pristine/scripts/mkspec Wed Jun 26 00:16:49 2002 -+++ linux-2.4.18-lustre12/scripts/mkspec Tue Aug 13 11:13:09 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-chaos13 b/lustre/patches/patch-2.4.18-chaos13 deleted file mode 100644 index d193e4d..0000000 --- a/lustre/patches/patch-2.4.18-chaos13 +++ /dev/null @@ -1,12 +0,0 @@ ---- linux-2.4.18-lustre13-3/drivers/qsnet1/qsw/kernel_linux.c Wed Jun 26 15:40:06 2002 -+++ linux-2.4.18-lustre13-4/drivers/qsnet1/qsw/kernel_linux.c Fri Aug 23 08:42:57 2002 -@@ -225,7 +225,8 @@ kmem_to_phys(void *ptr) - uintptr_t phys, virt = (uintptr_t)ptr; - pte_t *pte; - -- if ((((unsigned long) ptr) >= VMALLOC_START && ((unsigned long) ptr) < VMALLOC_END)) -+ if (((((unsigned long) ptr) >= VMALLOC_START && ((unsigned long) ptr) < VMALLOC_END)) || -+ ((((unsigned long) ptr) >= PKMAP_BASE && ((unsigned long) ptr) < (PKMAP_BASE + LAST_PKMAP * PAGE_SIZE)))) - { - pte = find_pte_k(virt); - ASSERT(pte && !pte_none(*pte)); diff --git a/lustre/patches/patch-2.4.18-chaos22 b/lustre/patches/patch-2.4.18-chaos22 deleted file mode 100644 index c40d4ea..0000000 --- a/lustre/patches/patch-2.4.18-chaos22 +++ /dev/null @@ -1,165 +0,0 @@ -diff -ru lum-2.4.18-um30/fs/ext3/balloc.c uml-2.4.18-12.5/fs/ext3/balloc.c ---- lum-2.4.18-um30/fs/ext3/balloc.c Mon Feb 25 12:38:08 2002 -+++ uml-2.4.18-12.5/fs/ext3/balloc.c Thu Sep 19 13:40:11 2002 -@@ -276,7 +276,8 @@ - } - lock_super (sb); - es = sb->u.ext3_sb.s_es; -- if (block < le32_to_cpu(es->s_first_data_block) || -+ if (block < le32_to_cpu(es->s_first_data_block) || -+ block + count < block || - (block + count) > le32_to_cpu(es->s_blocks_count)) { - ext3_error (sb, "ext3_free_blocks", - "Freeing blocks not in datazone - " -@@ -309,17 +310,6 @@ - if (!gdp) - goto error_return; - -- if (in_range (le32_to_cpu(gdp->bg_block_bitmap), block, count) || -- in_range (le32_to_cpu(gdp->bg_inode_bitmap), block, count) || -- in_range (block, le32_to_cpu(gdp->bg_inode_table), -- sb->u.ext3_sb.s_itb_per_group) || -- in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table), -- sb->u.ext3_sb.s_itb_per_group)) -- ext3_error (sb, "ext3_free_blocks", -- "Freeing blocks in system zones - " -- "Block = %lu, count = %lu", -- block, count); -- - /* - * We are about to start releasing blocks in the bitmap, - * so we need undo access. -@@ -345,14 +335,24 @@ - if (err) - goto error_return; - -- for (i = 0; i < count; i++) { -+ for (i = 0; i < count; i++, block++) { -+ if (block == le32_to_cpu(gdp->bg_block_bitmap) || -+ block == le32_to_cpu(gdp->bg_inode_bitmap) || -+ in_range(block, le32_to_cpu(gdp->bg_inode_table), -+ sb->u.ext2_sb.s_itb_per_group)) { -+ ext3_error(sb, __FUNCTION__, -+ "Freeing block in system zone - block = %lu", -+ block); -+ continue; -+ } -+ - /* - * An HJ special. This is expensive... - */ - #ifdef CONFIG_JBD_DEBUG - { - struct buffer_head *debug_bh; -- debug_bh = sb_get_hash_table(sb, block + i); -+ debug_bh = sb_get_hash_table(sb, block); - if (debug_bh) { - BUFFER_TRACE(debug_bh, "Deleted!"); - if (!bh2jh(bitmap_bh)->b_committed_data) -@@ -365,9 +365,8 @@ - #endif - BUFFER_TRACE(bitmap_bh, "clear bit"); - if (!ext3_clear_bit (bit + i, bitmap_bh->b_data)) { -- ext3_error (sb, __FUNCTION__, -- "bit already cleared for block %lu", -- block + i); -+ ext3_error(sb, __FUNCTION__, -+ "bit already cleared for block %lu", block); - BUFFER_TRACE(bitmap_bh, "bit already cleared"); - } else { - dquot_freed_blocks++; -@@ -415,7 +417,6 @@ - if (!err) err = ret; - - if (overflow && !err) { -- block += count; - count = overflow; - goto do_more; - } -@@ -575,6 +577,7 @@ - - ext3_debug ("goal=%lu.\n", goal); - -+repeat: - /* - * First, test whether the goal block is free. - */ -@@ -684,10 +686,21 @@ - if (tmp == le32_to_cpu(gdp->bg_block_bitmap) || - tmp == le32_to_cpu(gdp->bg_inode_bitmap) || - in_range (tmp, le32_to_cpu(gdp->bg_inode_table), -- sb->u.ext3_sb.s_itb_per_group)) -- ext3_error (sb, "ext3_new_block", -- "Allocating block in system zone - " -- "block = %u", tmp); -+ EXT3_SB(sb)->s_itb_per_group)) { -+ ext3_error(sb, __FUNCTION__, -+ "Allocating block in system zone - block = %u", tmp); -+ -+ /* Note: This will potentially use up one of the handle's -+ * buffer credits. Normally we have way too many credits, -+ * so that is OK. In _very_ rare cases it might not be OK. -+ * We will trigger an assertion if we run out of credits, -+ * and we will have to do a full fsck of the filesystem - -+ * better than randomly corrupting filesystem metadata. -+ */ -+ ext3_set_bit(j, bh->b_data); -+ goto repeat; -+ } -+ - - /* The superblock lock should guard against anybody else beating - * us to this point! */ -diff -ru lum-2.4.18-um30/fs/ext3/namei.c uml-2.4.18-12.5/fs/ext3/namei.c ---- lum-2.4.18-um30/fs/ext3/namei.c Fri Nov 9 15:25:04 2001 -+++ uml-2.4.18-12.5/fs/ext3/namei.c Thu Sep 19 13:40:11 2002 -@@ -354,8 +355,8 @@ - */ - dir->i_mtime = dir->i_ctime = CURRENT_TIME; - dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -- ext3_mark_inode_dirty(handle, dir); - dir->i_version = ++event; -+ ext3_mark_inode_dirty(handle, dir); - BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); - ext3_journal_dirty_metadata(handle, bh); - brelse(bh); -@@ -464,8 +465,8 @@ - inode->i_op = &ext3_file_inode_operations; - inode->i_fop = &ext3_file_operations; - inode->i_mapping->a_ops = &ext3_aops; -- ext3_mark_inode_dirty(handle, inode); - err = ext3_add_nondir(handle, dentry, inode); -+ ext3_mark_inode_dirty(handle, inode); - } - ext3_journal_stop(handle, dir); - return err; -@@ -489,8 +490,8 @@ - err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - init_special_inode(inode, mode, rdev); -- ext3_mark_inode_dirty(handle, inode); - err = ext3_add_nondir(handle, dentry, inode); -+ ext3_mark_inode_dirty(handle, inode); - } - ext3_journal_stop(handle, dir); - return err; -@@ -933,8 +934,8 @@ - inode->i_size = l-1; - } - inode->u.ext3_i.i_disksize = inode->i_size; -- ext3_mark_inode_dirty(handle, inode); - err = ext3_add_nondir(handle, dentry, inode); -+ ext3_mark_inode_dirty(handle, inode); - out_stop: - ext3_journal_stop(handle, dir); - return err; -@@ -970,8 +971,8 @@ - ext3_inc_count(handle, inode); - atomic_inc(&inode->i_count); - -- ext3_mark_inode_dirty(handle, inode); - err = ext3_add_nondir(handle, dentry, inode); -+ ext3_mark_inode_dirty(handle, inode); - ext3_journal_stop(handle, dir); - return err; - } diff --git a/lustre/patches/patch-2.4.18-chaos25 b/lustre/patches/patch-2.4.18-chaos25 deleted file mode 100644 index 2d534f5..0000000 --- a/lustre/patches/patch-2.4.18-chaos25 +++ /dev/null @@ -1,1447 +0,0 @@ ---- linux-2.4.18-17.8.0-uml-pristine/include/linux/lustre_version.h Wed Dec 31 19:00:00 1969 -+++ linux-2.4.18-17.8.0-uml/include/linux/lustre_version.h Tue Nov 26 07:02:14 2002 -@@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 3 ---- kernel-2.4.18-pristine/arch/ia64/mm/init.c 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/arch/ia64/mm/init.c 2002-10-14 14:08:23.000000000 -0600 -@@ -37,6 +37,12 @@ - - static unsigned long totalram_pages; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int - do_check_pgt_cache (int low, int high) - { ---- kernel-2.4.18-pristine/arch/i386/mm/init.c 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/arch/i386/mm/init.c 2002-10-14 14:08:23.000000000 -0600 -@@ -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; ---- kernel-2.4.18-pristine/drivers/block/blkpg.c 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/drivers/block/blkpg.c 2002-10-14 14:08:23.000000000 -0600 -@@ -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); ---- kernel-2.4.18-pristine/drivers/block/loop.c 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/drivers/block/loop.c 2002-10-14 14:08:23.000000000 -0600 -@@ -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) { ---- kernel-2.4.18-pristine/drivers/ide/ide-disk.c 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/drivers/ide/ide-disk.c 2002-10-14 14:08:23.000000000 -0600 -@@ -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); - ---- kernel-2.4.18-pristine/fs/ext3/Makefile 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/fs/ext3/Makefile 2002-10-14 14:08:23.000000000 -0600 -@@ -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) ---- kernel-2.4.18-pristine/fs/ext3/super.c 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/fs/ext3/super.c 2002-10-14 14:08:23.000000000 -0600 -@@ -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"); ---- kernel-2.4.18-pristine/include/linux/slab.h 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/include/linux/slab.h 2002-10-14 14:08:23.000000000 -0600 -@@ -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 *); ---- kernel-2.4.18-pristine/kernel/ksyms.c 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/kernel/ksyms.c 2002-10-14 14:08:23.000000000 -0600 -@@ -306,6 +306,12 @@ - EXPORT_SYMBOL(lock_may_write); - EXPORT_SYMBOL(dcache_readdir); - -+/* lustre */ -+EXPORT_SYMBOL(panic_notifier_list); -+EXPORT_SYMBOL(pagecache_lock_cacheline); -+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); ---- kernel-2.4.18-pristine/include/linux/dcache.h 2002-10-14 13:51:28.000000000 -0600 -+++ kernel-2.4.18/include/linux/dcache.h 2002-10-14 14:08:23.000000000 -0600 -@@ -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 - * -@@ -79,6 +107,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 */ -@@ -92,6 +121,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 ---- kernel-2.4.18-pristine/include/linux/fs.h 2002-10-14 13:47:27.000000000 -0600 -+++ kernel-2.4.18/include/linux/fs.h 2002-10-14 14:08:23.000000000 -0600 -@@ -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 *); ---- kernel-2.4.18-pristine/fs/dcache.c 2002-10-14 13:47:27.000000000 -0600 -+++ kernel-2.4.18/fs/dcache.c 2002-10-14 14:08:23.000000000 -0600 -@@ -645,6 +645,7 @@ - dentry->d_fsdata = NULL; - dentry->d_extra_attributes = NULL; - dentry->d_mounted = 0; -+ dentry->d_it = NULL; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); ---- kernel-2.4.18-pristine/fs/nfsd/vfs.c 2002-10-14 13:47:27.000000000 -0600 -+++ kernel-2.4.18/fs/nfsd/vfs.c 2002-10-14 14:08:23.000000000 -0600 -@@ -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); ---- kernel-2.4.18-pristine/fs/namei.c 2002-10-14 13:56:44.000000000 -0600 -+++ kernel-2.4.18/fs/namei.c 2002-10-14 14:08:23.000000000 -0600 -@@ -94,6 +94,14 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct dentry *de, struct lookup_intent *it) -+{ -+ if (de->d_op && de->d_op->d_intent_release) -+ de->d_op->d_intent_release(de, it); -+ -+} -+ -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -260,10 +268,19 @@ - * 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 +298,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 +318,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 +342,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; - } -@@ -447,7 +474,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 +552,12 @@ - break; - } - /* This does the actual lookups.. */ -- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - if (!dentry) { - err = -EWOULDBLOCKIO; - if (atomic) - break; -- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -563,7 +591,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 +618,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 +647,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; -@@ -661,10 +690,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 */ -@@ -749,6 +789,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 +828,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 +852,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 +873,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 +900,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 +931,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,7 +1101,7 @@ - * The simplest case - just a plain lookup. - */ - if (!(flag & O_CREAT)) { -- error = path_lookup(pathname, lookup_flags(flag), nd); -+ error = path_lookup_it(pathname, lookup_flags(flag), nd, it); - if (error) - return error; - dentry = nd->dentry; -@@ -1032,6 +1111,10 @@ - /* - * Create - we need to know the parent. - */ -+ if (it) { -+ it->it_mode = mode; -+ it->it_op |= IT_CREAT; -+ } - error = path_lookup(pathname, LOOKUP_PARENT, nd); - if (error) - return error; -@@ -1047,7 +1130,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 +1139,7 @@ - goto exit; - } - -+ it->it_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - error = vfs_create(dir->d_inode, dentry, -@@ -1175,8 +1259,10 @@ - return 0; - - exit_dput: -+ intent_release(dentry, it); - dput(dentry); - exit: -+ intent_release(nd->dentry, it); - path_release(nd); - return error; - -@@ -1196,6 +1282,8 @@ - */ - UPDATE_ATIME(dentry->d_inode); - error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) -+ intent_release(dentry, it); - dput(dentry); - if (error) - return error; -@@ -1217,13 +1305,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; - -@@ -1231,7 +1326,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 +1372,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; -@@ -1287,7 +1383,7 @@ - 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; -@@ -1305,6 +1401,7 @@ - default: - error = -EINVAL; - } -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1345,6 +1442,7 @@ - { - int error = 0; - char * tmp; -+ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; - - tmp = getname(pathname); - error = PTR_ERR(tmp); -@@ -1355,11 +1453,12 @@ - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 1); -+ dentry = lookup_create(&nd, 1, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_mkdir(nd.dentry->d_inode, dentry, - mode & ~current->fs->umask); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1439,6 +1538,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_RMDIR }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1460,10 +1560,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); -@@ -1507,6 +1608,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_UNLINK }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1519,7 +1621,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 */ -@@ -1527,6 +1629,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); -@@ -1573,6 +1676,7 @@ - int error = 0; - char * from; - char * to; -+ struct lookup_intent it = { .it_op = IT_SYMLINK }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1586,10 +1690,12 @@ - error = path_lookup(to, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ it.it_data = from; -+ dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_symlink(nd.dentry->d_inode, dentry, from); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1654,6 +1760,7 @@ - { - int error; - char * to; -+ struct lookup_intent it = { .it_op = IT_LINK }; - - to = getname(newname); - error = PTR_ERR(to); -@@ -1661,7 +1768,7 @@ - struct dentry *new_dentry; - struct nameidata nd, old_nd; - -- error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd); -+ error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, &it); - if (error) - goto exit; - error = path_lookup(to, LOOKUP_PARENT, &nd); -@@ -1670,10 +1778,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); -@@ -1715,7 +1822,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; -@@ -1773,6 +1881,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; -@@ -1794,7 +1903,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; - -@@ -1825,6 +1935,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; -@@ -1836,13 +1947,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); -@@ -1859,6 +1971,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; - - error = path_lookup(oldname, LOOKUP_PARENT, &oldnd); -@@ -1884,7 +1997,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; -@@ -1900,18 +2013,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); // FIXME: release same intent twice!!! - dput(old_dentry); - exit3: - double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); ---- kernel-2.4.18-pristine/fs/open.c 2002-10-14 13:47:27.000000000 -0600 -+++ kernel-2.4.18/fs/open.c 2002-10-14 14:08:23.000000000 -0600 -@@ -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) - { -@@ -118,12 +121,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; -@@ -168,6 +172,7 @@ - put_write_access(inode); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -259,8 +264,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; -@@ -286,6 +292,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -303,8 +310,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; -@@ -330,6 +338,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -346,6 +355,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; -@@ -363,13 +373,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); - } - -@@ -384,8 +395,11 @@ - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); -+ error = __user_walk_it(filename, -+ LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, -+ &nd, &it); - if (error) - goto out; - -@@ -396,6 +410,7 @@ - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -435,9 +450,10 @@ - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -- LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); -+ error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -+ LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it); - if (error) - goto out; - -@@ -453,6 +469,7 @@ - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -497,8 +514,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; -@@ -518,6 +536,7 @@ - error = notify_change(nd.dentry, &newattrs); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -587,10 +606,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; -@@ -600,10 +621,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; -@@ -637,10 +660,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) -@@ -648,14 +677,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); -- -- return ERR_PTR(error); -+ error = open_namei_it(filename, namei_flags, mode, &nd, &it); -+ if (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; -@@ -698,6 +728,7 @@ - } - f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); - -+ intent_release(dentry, it); - return f; - - cleanup_all: -@@ -712,11 +743,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. - */ ---- kernel-2.4.18-pristine/fs/stat.c 2002-10-14 13:47:27.000000000 -0600 -+++ kernel-2.4.18/fs/stat.c 2002-10-14 14:08:23.000000000 -0600 -@@ -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. - */ -@@ -104,10 +105,12 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk(name, &nd); -+ error = user_path_walk_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -117,10 +120,12 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk_link(name, &nd); -+ error = user_path_walk_link_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; ---- kernel-2.4.18-pristine/mm/slab.c 2002-10-14 13:47:27.000000000 -0600 -+++ kernel-2.4.18/mm/slab.c 2002-10-14 14:08:23.000000000 -0600 -@@ -1207,6 +1207,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) ---- kernel-2.4.18-pristine/fs/jbd/commit.c 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/fs/jbd/commit.c 2002-10-14 14:08:23.000000000 -0600 -@@ -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,6 +588,7 @@ - descriptor = journal_get_descriptor_buffer(journal); - if (!descriptor) { - __journal_abort_hard(journal); -+ unlock_journal(journal); - goto skip_commit; - } - -@@ -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); ---- kernel-2.4.18-pristine/fs/jbd/journal.c 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/fs/jbd/journal.c 2002-10-14 14:08:23.000000000 -0600 -@@ -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); ---- kernel-2.4.18-pristine/fs/jbd/transaction.c 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/fs/jbd/transaction.c 2002-10-14 14:08:23.000000000 -0600 -@@ -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); -@@ -1319,6 +1328,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 -@@ -1383,7 +1414,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 ---- kernel-2.4.18-pristine/include/linux/jbd.h 2002-10-14 13:47:20.000000000 -0600 -+++ kernel-2.4.18/include/linux/jbd.h 2002-10-14 14:08:23.000000000 -0600 -@@ -257,6 +257,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 -@@ -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,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 *); diff --git a/lustre/patches/patch-2.4.18-um b/lustre/patches/patch-2.4.18-um deleted file mode 100644 index 6e1e345..0000000 --- a/lustre/patches/patch-2.4.18-um +++ /dev/null @@ -1,49 +0,0 @@ ---- lum-pristine/arch/um/kernel/mem.c Mon Aug 12 11:05:20 2002 -+++ lum/arch/um/kernel/mem.c Thu Aug 1 18:07:35 2002 -@@ -527,6 +527,21 @@ - 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; -@@ -542,12 +558,14 @@ - return(region); - } - } -- panic("No region found for page"); -+ //panic("No region found for page"); - return(NULL); - } - - struct page *page_mem_map(struct page *page) - { -+ if (!page_region(page, NULL)) -+ return NULL; - return((struct page *) page_region(page, NULL)->mem_map); - } - -@@ -564,7 +582,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 --git a/lustre/patches/ubd-io-fail-2.4.18 b/lustre/patches/ubd-io-fail-2.4.18 deleted file mode 100644 index 56c3742..0000000 --- a/lustre/patches/ubd-io-fail-2.4.18 +++ /dev/null @@ -1,34 +0,0 @@ ---- lum/arch/um/drivers/ubd.c.orig Wed Mar 13 14:04:59 2002 -+++ lum/arch/um/drivers/ubd.c Thu Mar 28 23:39:15 2002 -@@ -693,14 +697,23 @@ - spin_unlock(&io_request_lock); - return(1); - } -- if((req->cmd == WRITE) && -- ((dev->openflags & O_ACCMODE) == O_RDONLY)){ -- printk("Write attempted on readonly ubd device %d\n", -- minor(req->rq_dev)); -- spin_lock(&io_request_lock); -- end_request(0); -- spin_unlock(&io_request_lock); -- return(1); -+ if (req->cmd == WRITE) { -+#ifdef CONFIG_DEV_RDONLY -+ if (dev_check_rdonly(req->rq_dev)) { -+ spin_lock(&io_request_lock); -+ end_request(1); -+ spin_unlock(&io_request_lock); -+ return(0); -+ } -+#endif -+ if ((dev->openflags & O_ACCMODE) == O_RDONLY) { -+ printk("Write attempted on readonly ubd device %d\n", -+ minor(req->rq_dev)); -+ spin_lock(&io_request_lock); -+ end_request(0); -+ spin_unlock(&io_request_lock); -+ return(1); -+ } - } - - block = req->sector; diff --git a/lustre/ptlrpc/.cvsignore b/lustre/ptlrpc/.cvsignore deleted file mode 100644 index 067f05c..0000000 --- a/lustre/ptlrpc/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -tags -TAGS diff --git a/lustre/ptlrpc/Makefile.am b/lustre/ptlrpc/Makefile.am deleted file mode 100644 index dd3f9d8..0000000 --- a/lustre/ptlrpc/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= - -MODULE = ptlrpc -modulefs_DATA = ptlrpc.o -EXTRA_PROGRAMS = ptlrpc - -ptlrpc_SOURCES = recovd.c recover.c connection.c rpc.c events.c service.c client.c niobuf.c pack_generic.c lproc_ptlrpc.c - -include $(top_srcdir)/Rules diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c deleted file mode 100644 index 4ab7903..0000000 --- a/lustre/ptlrpc/client.c +++ /dev/null @@ -1,812 +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_RPC - -#include -#include -#include -#include -#include - -void ptlrpc_init_client(int req_portal, int rep_portal, char *name, - struct ptlrpc_client *cl) -{ - cl->cli_request_portal = req_portal; - cl->cli_reply_portal = rep_portal; - cl->cli_name = name; -} - -__u8 *ptlrpc_req_to_uuid(struct ptlrpc_request *req) -{ - return req->rq_connection->c_remote_uuid; -} - -struct ptlrpc_connection *ptlrpc_uuid_to_connection(obd_uuid_t uuid) -{ - struct ptlrpc_connection *c; - struct lustre_peer peer; - int err; - - err = kportal_uuid_to_peer(uuid, &peer); - if (err != 0) { - CERROR("cannot find peer %s!\n", uuid); - return NULL; - } - - c = ptlrpc_get_connection(&peer, uuid); - if (c) { - memcpy(c->c_remote_uuid, uuid, sizeof(c->c_remote_uuid)); - c->c_epoch++; - } - - CDEBUG(D_INFO, "%s -> %p\n", uuid, c); - - return c; -} - -void ptlrpc_readdress_connection(struct ptlrpc_connection *conn,obd_uuid_t uuid) -{ - struct lustre_peer peer; - int err; - - err = kportal_uuid_to_peer(uuid, &peer); - if (err != 0) { - CERROR("cannot find peer %s!\n", uuid); - return; - } - - memcpy(&conn->c_peer, &peer, sizeof(peer)); - return; -} - -struct ptlrpc_bulk_desc *ptlrpc_prep_bulk(struct ptlrpc_connection *conn) -{ - struct ptlrpc_bulk_desc *desc; - - OBD_ALLOC(desc, sizeof(*desc)); - if (desc != NULL) { - desc->bd_connection = ptlrpc_connection_addref(conn); - atomic_set(&desc->bd_refcount, 1); - init_waitqueue_head(&desc->bd_waitq); - INIT_LIST_HEAD(&desc->bd_page_list); - INIT_LIST_HEAD(&desc->bd_set_chain); - ptl_set_inv_handle(&desc->bd_md_h); - ptl_set_inv_handle(&desc->bd_me_h); - } - - return desc; -} - -int ptlrpc_bulk_error(struct ptlrpc_bulk_desc *desc) -{ - int rc = 0; - if (desc->bd_flags & PTL_RPC_FL_TIMEOUT) { - rc = (desc->bd_flags & PTL_RPC_FL_INTR ? -ERESTARTSYS : - -ETIMEDOUT); - } - return rc; -} - -struct ptlrpc_bulk_page *ptlrpc_prep_bulk_page(struct ptlrpc_bulk_desc *desc) -{ - struct ptlrpc_bulk_page *bulk; - - OBD_ALLOC(bulk, sizeof(*bulk)); - if (bulk != NULL) { - bulk->bp_desc = desc; - list_add_tail(&bulk->bp_link, &desc->bd_page_list); - desc->bd_page_count++; - } - return bulk; -} - -void ptlrpc_free_bulk(struct ptlrpc_bulk_desc *desc) -{ - struct list_head *tmp, *next; - ENTRY; - if (desc == NULL) { - EXIT; - return; - } - - LASSERT(list_empty(&desc->bd_set_chain)); - - list_for_each_safe(tmp, next, &desc->bd_page_list) { - struct ptlrpc_bulk_page *bulk; - bulk = list_entry(tmp, struct ptlrpc_bulk_page, bp_link); - ptlrpc_free_bulk_page(bulk); - } - - ptlrpc_put_connection(desc->bd_connection); - - OBD_FREE(desc, sizeof(*desc)); - EXIT; -} - -void ptlrpc_free_bulk_page(struct ptlrpc_bulk_page *bulk) -{ - ENTRY; - if (bulk == NULL) { - EXIT; - return; - } - - list_del(&bulk->bp_link); - bulk->bp_desc->bd_page_count--; - OBD_FREE(bulk, sizeof(*bulk)); - EXIT; -} - -static int ll_sync_brw_timeout(void *data) -{ - struct obd_brw_set *set = data; - struct list_head *tmp; - int failed = 0; - ENTRY; - - LASSERT(set); - - set->brw_flags |= PTL_RPC_FL_TIMEOUT; - - list_for_each(tmp, &set->brw_desc_head) { - struct ptlrpc_bulk_desc *desc = - list_entry(tmp, struct ptlrpc_bulk_desc, bd_set_chain); - - /* Skip descriptors that were completed successfully. */ - if (desc->bd_flags & (PTL_BULK_FL_RCVD | PTL_BULK_FL_SENT)) - continue; - - LASSERT(desc->bd_connection); - - /* If PtlMDUnlink succeeds, then it hasn't completed yet. If it - * fails, the bulk finished _just_ in time (after the timeout - * fired but before we got this far) and we'll let it live. - */ - if (PtlMDUnlink(desc->bd_md_h) != 0) { - CERROR("Near-miss on OST %s -- need to adjust " - "obd_timeout?\n", - desc->bd_connection->c_remote_uuid); - continue; - } - - CERROR("IO of %d pages to/from %s:%d (conn %p) timed out\n", - desc->bd_page_count, desc->bd_connection->c_remote_uuid, - desc->bd_portal, desc->bd_connection); - - /* This one will "never" arrive, don't wait for it. */ - if (atomic_dec_and_test(&set->brw_refcount)) - wake_up(&set->brw_waitq); - - if (class_signal_connection_failure) - class_signal_connection_failure(desc->bd_connection); - else - failed = 1; - } - - /* 0 = We go back to sleep, until we're resumed or interrupted */ - /* 1 = We can't be recovered, just abort the syscall with -ETIMEDOUT */ - RETURN(failed); -} - -static int ll_sync_brw_intr(void *data) -{ - struct obd_brw_set *set = data; - - ENTRY; - set->brw_flags |= PTL_RPC_FL_INTR; - RETURN(1); /* ignored, as of this writing */ -} - -int ll_brw_sync_wait(struct obd_brw_set *set, int phase) -{ - struct l_wait_info lwi; - struct list_head *tmp, *next; - int rc = 0; - ENTRY; - - switch(phase) { - case CB_PHASE_START: - lwi = LWI_TIMEOUT_INTR(obd_timeout * HZ, ll_sync_brw_timeout, - ll_sync_brw_intr, set); - rc = l_wait_event(set->brw_waitq, - atomic_read(&set->brw_refcount) == 0, &lwi); - - list_for_each_safe(tmp, next, &set->brw_desc_head) { - struct ptlrpc_bulk_desc *desc = - list_entry(tmp, struct ptlrpc_bulk_desc, - bd_set_chain); - list_del_init(&desc->bd_set_chain); - ptlrpc_bulk_decref(desc); - } - break; - case CB_PHASE_FINISH: - if (atomic_dec_and_test(&set->brw_refcount)) - wake_up(&set->brw_waitq); - break; - default: - LBUG(); - } - - RETURN(rc); -} - -struct ptlrpc_request *ptlrpc_prep_req(struct obd_import *imp, int opcode, - int count, int *lengths, char **bufs) -{ - struct ptlrpc_connection *conn = imp->imp_connection; - struct ptlrpc_request *request; - int rc; - ENTRY; - - OBD_ALLOC(request, sizeof(*request)); - if (!request) { - CERROR("request allocation out of memory\n"); - RETURN(NULL); - } - - rc = lustre_pack_msg(count, lengths, bufs, - &request->rq_reqlen, &request->rq_reqmsg); - if (rc) { - CERROR("cannot pack request %d\n", rc); - OBD_FREE(request, sizeof(*request)); - RETURN(NULL); - } - - request->rq_level = LUSTRE_CONN_FULL; - request->rq_type = PTL_RPC_MSG_REQUEST; - request->rq_import = imp; - - /* XXX FIXME bug 625069 */ - request->rq_request_portal = imp->imp_client->cli_request_portal; - request->rq_reply_portal = imp->imp_client->cli_reply_portal; - - request->rq_connection = ptlrpc_connection_addref(conn); - - INIT_LIST_HEAD(&request->rq_list); - atomic_set(&request->rq_refcount, 1); - - spin_lock(&imp->imp_lock); - request->rq_xid = HTON__u32(++imp->imp_last_xid); - spin_unlock(&imp->imp_lock); - - request->rq_reqmsg->magic = PTLRPC_MSG_MAGIC; - request->rq_reqmsg->version = PTLRPC_MSG_VERSION; - request->rq_reqmsg->opc = HTON__u32(opcode); - request->rq_reqmsg->flags = 0; - - ptlrpc_hdl2req(request, &imp->imp_handle); - RETURN(request); -} - -static void __ptlrpc_free_req(struct ptlrpc_request *request, int locked) -{ - ENTRY; - if (request == NULL) { - EXIT; - return; - } - - if (atomic_read(&request->rq_refcount) != 0) { - CERROR("freeing request %p (%d->%s:%d) with refcount %d\n", - request, request->rq_reqmsg->opc, - request->rq_connection->c_remote_uuid, - request->rq_import->imp_client->cli_request_portal, - request->rq_refcount); - /* LBUG(); */ - } - - if (request->rq_repmsg != NULL) { - OBD_FREE(request->rq_repmsg, request->rq_replen); - request->rq_repmsg = NULL; - request->rq_reply_md.start = NULL; - } - if (request->rq_reqmsg != NULL) { - OBD_FREE(request->rq_reqmsg, request->rq_reqlen); - request->rq_reqmsg = NULL; - } - - if (request->rq_import) { - if (!locked) - spin_lock(&request->rq_import->imp_lock); - list_del_init(&request->rq_list); - if (!locked) - spin_unlock(&request->rq_import->imp_lock); - } - - ptlrpc_put_connection(request->rq_connection); - OBD_FREE(request, sizeof(*request)); - EXIT; -} - -void ptlrpc_free_req(struct ptlrpc_request *request) -{ - __ptlrpc_free_req(request, 0); -} - -static int __ptlrpc_req_finished(struct ptlrpc_request *request, int locked) -{ - ENTRY; - if (request == NULL) - RETURN(1); - - if (atomic_dec_and_test(&request->rq_refcount)) { - __ptlrpc_free_req(request, locked); - RETURN(1); - } - - DEBUG_REQ(D_INFO, request, "refcount now %u", - atomic_read(&request->rq_refcount)); - RETURN(0); -} - -void ptlrpc_req_finished(struct ptlrpc_request *request) -{ - __ptlrpc_req_finished(request, 0); -} - -static int ptlrpc_check_reply(struct ptlrpc_request *req) -{ - int rc = 0; - - ENTRY; - if (req->rq_repmsg != NULL) { - req->rq_transno = NTOH__u64(req->rq_repmsg->transno); - req->rq_flags |= PTL_RPC_FL_REPLIED; - GOTO(out, rc = 1); - } - - if (req->rq_flags & PTL_RPC_FL_RESEND) { - ENTRY; - DEBUG_REQ(D_ERROR, req, "RESEND:"); - GOTO(out, rc = 1); - } - - if (req->rq_flags & PTL_RPC_FL_ERR) { - ENTRY; - DEBUG_REQ(D_ERROR, req, "ABORTED:"); - GOTO(out, rc = 1); - } - - if (req->rq_flags & PTL_RPC_FL_RESTART) { - DEBUG_REQ(D_ERROR, req, "RESTART:"); - GOTO(out, rc = 1); - } - EXIT; - out: - DEBUG_REQ(D_NET, req, "rc = %d for", rc); - return rc; -} - -static int ptlrpc_check_status(struct ptlrpc_request *req) -{ - int err; - ENTRY; - - err = req->rq_repmsg->status; - if (req->rq_repmsg->type == NTOH__u32(PTL_RPC_MSG_ERR)) { - DEBUG_REQ(D_ERROR, req, "type == PTL_RPC_MSG_ERR"); - RETURN(err ? err : -EINVAL); - } - - if (err < 0) { - DEBUG_REQ(D_ERROR, req, "status is %d", err); - } else if (err > 0) { - /* XXX: translate this error from net to host */ - DEBUG_REQ(D_INFO, req, "status is %d", err); - } - - RETURN(err); -} - -static void ptlrpc_cleanup_request_buf(struct ptlrpc_request *request) -{ - OBD_FREE(request->rq_reqmsg, request->rq_reqlen); - request->rq_reqmsg = NULL; - request->rq_reqlen = 0; -} - -/* Abort this request and cleanup any resources associated with it. */ -static int ptlrpc_abort(struct ptlrpc_request *request) -{ - /* First remove the ME for the reply; in theory, this means - * that we can tear down the buffer safely. */ - PtlMEUnlink(request->rq_reply_me_h); - OBD_FREE(request->rq_reply_md.start, request->rq_replen); - request->rq_repmsg = NULL; - request->rq_replen = 0; - return 0; -} - -/* caller must hold imp->imp_lock */ -void ptlrpc_free_committed(struct obd_import *imp) -{ - struct list_head *tmp, *saved; - struct ptlrpc_request *req; - ENTRY; - -#ifndef __arch_um__ - LASSERT(spin_is_locked(&imp->imp_lock)); -#endif - - CDEBUG(D_HA, "committing for xid "LPU64", last_committed "LPU64"\n", - imp->imp_peer_last_xid, imp->imp_peer_committed_transno); - - list_for_each_safe(tmp, saved, &imp->imp_replay_list) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - - if (req->rq_flags & PTL_RPC_FL_REPLAY) { - DEBUG_REQ(D_HA, req, "keeping (FL_REPLAY)"); - continue; - } - - /* not yet committed */ - if (req->rq_transno > imp->imp_peer_committed_transno) { - DEBUG_REQ(D_HA, req, "stopping search"); - break; - } - - DEBUG_REQ(D_HA, req, "committing (last_committed "LPU64")", - imp->imp_peer_committed_transno); - __ptlrpc_req_finished(req, 1); - } - - EXIT; - return; -} - -void ptlrpc_cleanup_client(struct obd_import *imp) -{ - struct list_head *tmp, *saved; - struct ptlrpc_request *req; - struct ptlrpc_connection *conn = imp->imp_connection; - ENTRY; - - LASSERT(conn); - - spin_lock(&imp->imp_lock); - list_for_each_safe(tmp, saved, &imp->imp_replay_list) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - - /* XXX we should make sure that nobody's sleeping on these! */ - DEBUG_REQ(D_HA, req, "cleaning up from sending list"); - list_del_init(&req->rq_list); - req->rq_import = NULL; - __ptlrpc_req_finished(req, 0); - } - spin_unlock(&imp->imp_lock); - - EXIT; - return; -} - -void ptlrpc_continue_req(struct ptlrpc_request *req) -{ - ENTRY; - DEBUG_REQ(D_HA, req, "continuing delayed request"); - req->rq_reqmsg->addr = req->rq_import->imp_handle.addr; - req->rq_reqmsg->cookie = req->rq_import->imp_handle.cookie; - wake_up(&req->rq_wait_for_rep); - EXIT; -} - -void ptlrpc_resend_req(struct ptlrpc_request *req) -{ - ENTRY; - DEBUG_REQ(D_HA, req, "resending"); - req->rq_reqmsg->addr = req->rq_import->imp_handle.addr; - req->rq_reqmsg->cookie = req->rq_import->imp_handle.cookie; - req->rq_status = -EAGAIN; - req->rq_level = LUSTRE_CONN_RECOVD; - req->rq_flags |= PTL_RPC_FL_RESEND; - req->rq_flags &= ~PTL_RPC_FL_TIMEOUT; - wake_up(&req->rq_wait_for_rep); - EXIT; -} - -void ptlrpc_restart_req(struct ptlrpc_request *req) -{ - ENTRY; - DEBUG_REQ(D_HA, req, "restarting (possibly-)completed request"); - req->rq_status = -ERESTARTSYS; - req->rq_flags |= PTL_RPC_FL_RESTART; - req->rq_flags &= ~PTL_RPC_FL_TIMEOUT; - wake_up(&req->rq_wait_for_rep); - EXIT; -} - -static int expired_request(void *data) -{ - struct ptlrpc_request *req = data; - - ENTRY; - if (!req) { - CERROR("NULL req!"); - LBUG(); - RETURN(0); - } - - DEBUG_REQ(D_ERROR, req, "timeout"); - req->rq_flags |= PTL_RPC_FL_TIMEOUT; - - if (!req->rq_import) { - DEBUG_REQ(D_ERROR, req, "NULL import"); - LBUG(); - RETURN(0); - } - - if (!req->rq_import->imp_connection) { - DEBUG_REQ(D_ERROR, req, "NULL connection"); - LBUG(); - RETURN(0); - } - - if (!req->rq_import->imp_connection->c_recovd_data.rd_recovd) - RETURN(1); - - req->rq_timeout = 0; - recovd_conn_fail(req->rq_import->imp_connection); - -#if 0 - /* If this request is for recovery or other primordial tasks, - * don't go back to sleep. - */ - if (req->rq_level < LUSTRE_CONN_FULL) - RETURN(1); -#endif - RETURN(0); -} - -static int interrupted_request(void *data) -{ - struct ptlrpc_request *req = data; - ENTRY; - req->rq_flags |= PTL_RPC_FL_INTR; - RETURN(1); /* ignored, as of this writing */ -} - -/* If the import has been invalidated (such as by an OST failure), the - * request must fail with -EIO. - * - * Must be called with imp_lock held, will drop it if it returns -EIO. - */ -#define EIO_IF_INVALID(req) \ -if (req->rq_import->imp_flags & IMP_INVALID) { \ - DEBUG_REQ(D_ERROR, req, "IMP_INVALID:"); \ - spin_unlock(&imp->imp_lock); \ - RETURN(-EIO); \ -} - -int ptlrpc_queue_wait(struct ptlrpc_request *req) -{ - int rc = 0; - struct l_wait_info lwi; - struct obd_import *imp = req->rq_import; - struct ptlrpc_connection *conn = imp->imp_connection; - ENTRY; - - init_waitqueue_head(&req->rq_wait_for_rep); - - /* for distributed debugging */ - req->rq_reqmsg->status = HTON__u32(current->pid); - CDEBUG(D_RPCTRACE, "Sending RPC pid:xid:nid:opc %d:"LPU64":%x:%d\n", - NTOH__u32(req->rq_reqmsg->status), req->rq_xid, - conn->c_peer.peer_nid, NTOH__u32(req->rq_reqmsg->opc)); - - if (req->rq_level > imp->imp_level) { - spin_lock(&imp->imp_lock); - EIO_IF_INVALID(req); - list_del(&req->rq_list); - list_add_tail(&req->rq_list, &imp->imp_delayed_list); - spin_unlock(&imp->imp_lock); - - DEBUG_REQ(D_HA, req, "\"%s\" waiting for recovery: (%d < %d)", - current->comm, req->rq_level, imp->imp_level); - lwi = LWI_INTR(NULL, NULL); - rc = l_wait_event(req->rq_wait_for_rep, - (req->rq_level <= imp->imp_level) || - (req->rq_flags & PTL_RPC_FL_ERR), &lwi); - - spin_lock(&imp->imp_lock); - list_del_init(&req->rq_list); - spin_unlock(&imp->imp_lock); - - if (req->rq_flags & PTL_RPC_FL_ERR) - RETURN(-EIO); - - if (rc) - RETURN(rc); - - CERROR("process %d resumed\n", current->pid); - } - resend: - req->rq_timeout = obd_timeout; - spin_lock(&imp->imp_lock); - EIO_IF_INVALID(req); - - LASSERT(list_empty(&req->rq_list)); - list_add_tail(&req->rq_list, &imp->imp_sending_list); - spin_unlock(&imp->imp_lock); - rc = ptl_send_rpc(req); - if (rc) { - CDEBUG(D_HA, "error %d, opcode %d, need recovery\n", rc, - req->rq_reqmsg->opc); - /* sleep for a jiffy, then trigger recovery */ - lwi = LWI_TIMEOUT_INTR(1, expired_request, - interrupted_request, req); - } else { - DEBUG_REQ(D_NET, req, "-- sleeping"); - lwi = LWI_TIMEOUT_INTR(req->rq_timeout * HZ, expired_request, - interrupted_request, req); - } - l_wait_event(req->rq_wait_for_rep, ptlrpc_check_reply(req), &lwi); - DEBUG_REQ(D_NET, req, "-- done sleeping"); - - spin_lock(&imp->imp_lock); - list_del_init(&req->rq_list); - spin_unlock(&imp->imp_lock); - - if (req->rq_flags & PTL_RPC_FL_ERR) { - ptlrpc_abort(req); - GOTO(out, rc = -EIO); - } - - /* Don't resend if we were interrupted. */ - if ((req->rq_flags & (PTL_RPC_FL_RESEND | PTL_RPC_FL_INTR)) == - PTL_RPC_FL_RESEND) { - req->rq_flags &= ~PTL_RPC_FL_RESEND; - DEBUG_REQ(D_HA, req, "resending: "); - goto resend; - } - - if (req->rq_flags & PTL_RPC_FL_INTR) { - if (!(req->rq_flags & PTL_RPC_FL_TIMEOUT)) - LBUG(); /* should only be interrupted if we timed out */ - /* Clean up the dangling reply buffers */ - ptlrpc_abort(req); - GOTO(out, rc = -EINTR); - } - - if (req->rq_flags & PTL_RPC_FL_TIMEOUT) - GOTO(out, rc = -ETIMEDOUT); - - if (!(req->rq_flags & PTL_RPC_FL_REPLIED)) - GOTO(out, rc = req->rq_status); - - rc = lustre_unpack_msg(req->rq_repmsg, req->rq_replen); - if (rc) { - CERROR("unpack_rep failed: %d\n", rc); - GOTO(out, rc); - } -#if 0 - /* FIXME: Enable when BlueArc makes new release */ - if (req->rq_repmsg->type != PTL_RPC_MSG_REPLY && - req->rq_repmsg->type != PTL_RPC_MSG_ERR) { - CERROR("invalid packet type received (type=%u)\n", - req->rq_repmsg->type); - LBUG(); - GOTO(out, rc = -EINVAL); - } -#endif - CDEBUG(D_NET, "got rep "LPU64"\n", req->rq_xid); - if (req->rq_repmsg->status == 0) - CDEBUG(D_NET, "--> buf %p len %d status %d\n", req->rq_repmsg, - req->rq_replen, req->rq_repmsg->status); - - - if (req->rq_import->imp_flags & IMP_REPLAYABLE) { - spin_lock(&imp->imp_lock); - if (req->rq_flags & PTL_RPC_FL_REPLAY || req->rq_transno != 0) { - /* Balanced in ptlrpc_free_committed, usually. */ - atomic_inc(&req->rq_refcount); - list_add_tail(&req->rq_list, &imp->imp_replay_list); - } - - if (req->rq_transno > imp->imp_max_transno) { - imp->imp_max_transno = req->rq_transno; - } else if (req->rq_transno != 0 && - imp->imp_level == LUSTRE_CONN_FULL) { - CERROR("got transno "LPD64" after "LPD64": recovery " - "may not work\n", req->rq_transno, - imp->imp_max_transno); - } - - /* Replay-enabled imports return commit-status information. */ - imp->imp_peer_last_xid = req->rq_repmsg->last_xid; - imp->imp_peer_committed_transno = - req->rq_repmsg->last_committed; - ptlrpc_free_committed(imp); - spin_unlock(&imp->imp_lock); - } - - rc = ptlrpc_check_status(req); - - EXIT; - out: - return rc; -} - -#undef EIO_IF_INVALID - -int ptlrpc_replay_req(struct ptlrpc_request *req) -{ - int rc = 0, old_level, old_status = 0; - // struct ptlrpc_client *cli = req->rq_import->imp_client; - struct l_wait_info lwi; - ENTRY; - - init_waitqueue_head(&req->rq_wait_for_rep); - DEBUG_REQ(D_NET, req, ""); - - req->rq_timeout = obd_timeout; - req->rq_reqmsg->addr = req->rq_import->imp_handle.addr; - req->rq_reqmsg->cookie = req->rq_import->imp_handle.cookie; - - /* temporarily set request to RECOVD level (reset at out:) */ - old_level = req->rq_level; - if (req->rq_flags & PTL_RPC_FL_REPLIED) - old_status = req->rq_repmsg->status; - req->rq_level = LUSTRE_CONN_RECOVD; - rc = ptl_send_rpc(req); - if (rc) { - CERROR("error %d, opcode %d\n", rc, req->rq_reqmsg->opc); - ptlrpc_cleanup_request_buf(req); - // up(&cli->cli_rpc_sem); - GOTO(out, rc = -rc); - } - - CDEBUG(D_OTHER, "-- sleeping\n"); - lwi = LWI_INTR(NULL, NULL); /* XXX needs timeout, nested recovery */ - l_wait_event(req->rq_wait_for_rep, ptlrpc_check_reply(req), &lwi); - CDEBUG(D_OTHER, "-- done\n"); - - // up(&cli->cli_rpc_sem); - - if (!(req->rq_flags & PTL_RPC_FL_REPLIED)) { - CERROR("Unknown reason for wakeup\n"); - /* XXX Phil - I end up here when I kill obdctl */ - ptlrpc_abort(req); - GOTO(out, rc = -EINTR); - } - - rc = lustre_unpack_msg(req->rq_repmsg, req->rq_replen); - if (rc) { - CERROR("unpack_rep failed: %d\n", rc); - GOTO(out, rc); - } - - CDEBUG(D_NET, "got rep "LPD64"\n", req->rq_xid); - - /* let the callback do fixups, possibly including in the request */ - if (req->rq_replay_cb) - req->rq_replay_cb(req); - - if ((req->rq_flags & PTL_RPC_FL_REPLIED) && - req->rq_repmsg->status != old_status) { - DEBUG_REQ(D_HA, req, "status %d, old was %d", - req->rq_repmsg->status, old_status); - } - - out: - req->rq_level = old_level; - RETURN(rc); -} diff --git a/lustre/ptlrpc/connection.c b/lustre/ptlrpc/connection.c deleted file mode 100644 index 2182591..0000000 --- a/lustre/ptlrpc/connection.c +++ /dev/null @@ -1,169 +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_RPC - -#include -#include -#include - -static spinlock_t conn_lock; -static struct list_head conn_list; -static struct list_head conn_unused_list; - -/* If UUID is NULL, c->c_remote_uuid must be all zeroes - * If UUID is non-NULL, c->c_remote_uuid must match. */ -static int match_connection_uuid(struct ptlrpc_connection *c, obd_uuid_t uuid) -{ - obd_uuid_t zero_uuid = {0}; - - if (uuid) - return memcmp(c->c_remote_uuid, uuid, sizeof(uuid)); - - return memcmp(c->c_remote_uuid, zero_uuid, sizeof(zero_uuid)); -} - -struct ptlrpc_connection *ptlrpc_get_connection(struct lustre_peer *peer, - obd_uuid_t uuid) -{ - struct list_head *tmp, *pos; - struct ptlrpc_connection *c; - ENTRY; - - CDEBUG(D_INFO, "peer is %08x %08lx %08lx\n", - peer->peer_nid, peer->peer_ni.nal_idx, peer->peer_ni.handle_idx); - - spin_lock(&conn_lock); - list_for_each(tmp, &conn_list) { - c = list_entry(tmp, struct ptlrpc_connection, c_link); - if (memcmp(peer, &c->c_peer, sizeof(*peer)) == 0 && - !match_connection_uuid(c, uuid)) { - ptlrpc_connection_addref(c); - GOTO(out, c); - } - } - - list_for_each_safe(tmp, pos, &conn_unused_list) { - c = list_entry(tmp, struct ptlrpc_connection, c_link); - if (memcmp(peer, &c->c_peer, sizeof(*peer)) == 0 && - !match_connection_uuid(c, uuid)) { - ptlrpc_connection_addref(c); - list_del(&c->c_link); - list_add(&c->c_link, &conn_list); - GOTO(out, c); - } - } - - /* FIXME: this should be a slab once we can validate slab addresses - * without OOPSing */ - OBD_ALLOC(c, sizeof(*c)); - if (c == NULL) - GOTO(out, c); - - c->c_generation = 1; - c->c_epoch = 1; - c->c_bootcount = 0; - c->c_flags = 0; - if (uuid) - strcpy(c->c_remote_uuid, uuid); - INIT_LIST_HEAD(&c->c_imports); - INIT_LIST_HEAD(&c->c_exports); - INIT_LIST_HEAD(&c->c_sb_chain); - INIT_LIST_HEAD(&c->c_recovd_data.rd_managed_chain); - INIT_LIST_HEAD(&c->c_delayed_head); - atomic_set(&c->c_refcount, 0); - ptlrpc_connection_addref(c); - spin_lock_init(&c->c_lock); - - memcpy(&c->c_peer, peer, sizeof(c->c_peer)); - list_add(&c->c_link, &conn_list); - - EXIT; - out: - spin_unlock(&conn_lock); - return c; -} - -int ptlrpc_put_connection(struct ptlrpc_connection *c) -{ - int rc = 0; - ENTRY; - - if (c == NULL) { - CERROR("NULL connection\n"); - RETURN(0); - } - - CDEBUG(D_INFO, "connection=%p refcount %d\n", - c, atomic_read(&c->c_refcount) - 1); - if (atomic_dec_and_test(&c->c_refcount)) { - recovd_conn_unmanage(c); - spin_lock(&conn_lock); - list_del(&c->c_link); - list_add(&c->c_link, &conn_unused_list); - spin_unlock(&conn_lock); - rc = 1; - } - if (atomic_read(&c->c_refcount) < 0) - CERROR("connection %p refcount %d!\n", - c, atomic_read(&c->c_refcount)); - - RETURN(rc); -} - -struct ptlrpc_connection *ptlrpc_connection_addref(struct ptlrpc_connection *c) -{ - ENTRY; - CDEBUG(D_INFO, "connection=%p refcount %d\n", - c, atomic_read(&c->c_refcount) + 1); - atomic_inc(&c->c_refcount); - RETURN(c); -} - -void ptlrpc_init_connection(void) -{ - INIT_LIST_HEAD(&conn_list); - INIT_LIST_HEAD(&conn_unused_list); - conn_lock = SPIN_LOCK_UNLOCKED; -} - -void ptlrpc_cleanup_connection(void) -{ - struct list_head *tmp, *pos; - struct ptlrpc_connection *c; - - spin_lock(&conn_lock); - list_for_each_safe(tmp, pos, &conn_unused_list) { - c = list_entry(tmp, struct ptlrpc_connection, c_link); - list_del(&c->c_link); - OBD_FREE(c, sizeof(*c)); - } - list_for_each_safe(tmp, pos, &conn_list) { - c = list_entry(tmp, struct ptlrpc_connection, c_link); - CERROR("Connection %p/%s has refcount %d (nid=%lu)\n", - c, c->c_remote_uuid, atomic_read(&c->c_refcount), - (unsigned long)c->c_peer.peer_nid); - list_del(&c->c_link); - OBD_FREE(c, sizeof(*c)); - } - spin_unlock(&conn_lock); -} diff --git a/lustre/ptlrpc/events.c b/lustre/ptlrpc/events.c deleted file mode 100644 index 0bdf0d8..0000000 --- a/lustre/ptlrpc/events.c +++ /dev/null @@ -1,288 +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_RPC - -#include -#include -#include - -ptl_handle_eq_t request_out_eq, reply_in_eq, reply_out_eq, bulk_source_eq, - bulk_sink_eq; -static const ptl_handle_ni_t *socknal_nip = NULL, *toenal_nip = NULL, - *qswnal_nip = NULL, *gmnal_nip = NULL; - -/* - * Free the packet when it has gone out - */ -static int request_out_callback(ptl_event_t *ev) -{ - struct ptlrpc_request *req = ev->mem_desc.user_ptr; - ENTRY; - - /* requests always contiguous */ - LASSERT((ev->mem_desc.options & PTL_MD_IOV) == 0); - - if (ev->type != PTL_EVENT_SENT) { - // XXX make sure we understand all events, including ACK's - CERROR("Unknown event %d\n", ev->type); - LBUG(); - } - - /* this balances the atomic_inc in ptl_send_rpc */ - ptlrpc_req_finished(req); - RETURN(1); -} - - -/* - * Free the packet when it has gone out - */ -static int reply_out_callback(ptl_event_t *ev) -{ - ENTRY; - - /* replies always contiguous */ - LASSERT((ev->mem_desc.options & PTL_MD_IOV) == 0); - - if (ev->type == PTL_EVENT_SENT) { - OBD_FREE(ev->mem_desc.start, ev->mem_desc.length); - } else { - // XXX make sure we understand all events, including ACK's - CERROR("Unknown event %d\n", ev->type); - LBUG(); - } - - RETURN(1); -} - -/* - * Wake up the thread waiting for the reply once it comes in. - */ -static int reply_in_callback(ptl_event_t *ev) -{ - struct ptlrpc_request *req = ev->mem_desc.user_ptr; - ENTRY; - - /* replies always contiguous */ - LASSERT((ev->mem_desc.options & PTL_MD_IOV) == 0); - - if (req->rq_xid == 0x5a5a5a5a5a5a5a5a) { - CERROR("Reply received for freed request! Probably a missing " - "ptlrpc_abort()\n"); - LBUG(); - } - - if (req->rq_xid != ev->match_bits) { - CERROR("Reply packet for wrong request\n"); - LBUG(); - } - - if (ev->type == PTL_EVENT_PUT) { - req->rq_repmsg = ev->mem_desc.start + ev->offset; - barrier(); - wake_up(&req->rq_wait_for_rep); - } else { - // XXX make sure we understand all events, including ACK's - CERROR("Unknown event %d\n", ev->type); - LBUG(); - } - - RETURN(1); -} - -int request_in_callback(ptl_event_t *ev) -{ - struct ptlrpc_request_buffer_desc *rqbd = ev->mem_desc.user_ptr; - struct ptlrpc_service *service = rqbd->rqbd_service; - - /* requests always contiguous */ - LASSERT((ev->mem_desc.options & PTL_MD_IOV) == 0); - /* we only enable puts */ - LASSERT(ev->type == PTL_EVENT_PUT); - LASSERT(atomic_read(&service->srv_nrqbds_receiving) > 0); - LASSERT(atomic_read(&rqbd->rqbd_refcount) > 0); - - if (ev->rlength != ev->mlength) - CERROR("Warning: Possibly truncated rpc (%d/%d)\n", - ev->mlength, ev->rlength); - - if (ptl_is_valid_handle(&ev->unlinked_me)) { - /* This is the last request to be received into this - * request buffer. We don't bump the refcount, since the - * thread servicing this event is effectively taking over - * portals' reference. - */ -#warning ev->unlinked_me.nal_idx is not set properly in a callback - LASSERT(ev->unlinked_me.handle_idx==rqbd->rqbd_me_h.handle_idx); - - /* we're off the air */ - /* we'll probably start dropping packets in portals soon */ - if (atomic_dec_and_test(&service->srv_nrqbds_receiving)) - CERROR("All request buffers busy\n"); - } else { - /* +1 ref for service thread */ - atomic_inc(&rqbd->rqbd_refcount); - } - - wake_up(&service->srv_waitq); - - return 0; -} - -static int bulk_source_callback(ptl_event_t *ev) -{ - struct ptlrpc_bulk_desc *desc = ev->mem_desc.user_ptr; - struct ptlrpc_bulk_page *bulk; - struct list_head *tmp; - struct list_head *next; - ENTRY; - - CDEBUG(D_NET, "got %s event %d\n", - (ev->type == PTL_EVENT_SENT) ? "SENT" : - (ev->type == PTL_EVENT_ACK) ? "ACK" : "UNEXPECTED", ev->type); - - LASSERT(ev->type == PTL_EVENT_SENT || ev->type == PTL_EVENT_ACK); - - LASSERT(atomic_read(&desc->bd_source_callback_count) > 0 && - atomic_read(&desc->bd_source_callback_count) <= 2); - - /* 1 fragment for each page always */ - LASSERT(ev->mem_desc.niov == desc->bd_page_count); - - if (atomic_dec_and_test(&desc->bd_source_callback_count)) { - list_for_each_safe(tmp, next, &desc->bd_page_list) { - bulk = list_entry(tmp, struct ptlrpc_bulk_page, - bp_link); - - if (bulk->bp_cb != NULL) - bulk->bp_cb(bulk); - } - desc->bd_flags |= PTL_BULK_FL_SENT; - wake_up(&desc->bd_waitq); - if (desc->bd_ptl_ev_hdlr != NULL) - desc->bd_ptl_ev_hdlr(desc); - } - - RETURN(0); -} - -static int bulk_sink_callback(ptl_event_t *ev) -{ - struct ptlrpc_bulk_desc *desc = ev->mem_desc.user_ptr; - struct ptlrpc_bulk_page *bulk; - struct list_head *tmp; - struct list_head *next; - ptl_size_t total = 0; - ENTRY; - - if (ev->type == PTL_EVENT_PUT) { - /* put with zero offset */ - LASSERT(ev->offset == 0); - /* used iovs */ - LASSERT((ev->mem_desc.options & PTL_MD_IOV) != 0); - /* 1 fragment for each page always */ - LASSERT(ev->mem_desc.niov == desc->bd_page_count); - - list_for_each_safe (tmp, next, &desc->bd_page_list) { - bulk = list_entry(tmp, struct ptlrpc_bulk_page, - bp_link); - - total += bulk->bp_buflen; - - if (bulk->bp_cb != NULL) - bulk->bp_cb(bulk); - } - - LASSERT(ev->mem_desc.length == total); - - desc->bd_flags |= PTL_BULK_FL_RCVD; - wake_up(&desc->bd_waitq); - if (desc->bd_ptl_ev_hdlr != NULL) - desc->bd_ptl_ev_hdlr(desc); - } else { - CERROR("Unexpected event type!\n"); - LBUG(); - } - - RETURN(1); -} - -int ptlrpc_init_portals(void) -{ - int rc; - ptl_handle_ni_t ni; - - /* Use the qswnal if it's there */ - if ((qswnal_nip = inter_module_get("kqswnal_ni")) != NULL) - ni = *qswnal_nip; - else if ((gmnal_nip = inter_module_get("kgmnal_ni")) != NULL) - ni = *gmnal_nip; - else if ((socknal_nip = inter_module_get("ksocknal_ni")) != NULL) - ni = *socknal_nip; - else if ((toenal_nip = inter_module_get("ktoenal_ni")) != NULL) - ni = *toenal_nip; - else { - CERROR("get_ni failed: is a NAL module loaded?\n"); - return -EIO; - } - - rc = PtlEQAlloc(ni, 1024, request_out_callback, &request_out_eq); - if (rc != PTL_OK) - CERROR("PtlEQAlloc failed: %d\n", rc); - - rc = PtlEQAlloc(ni, 1024, reply_out_callback, &reply_out_eq); - if (rc != PTL_OK) - CERROR("PtlEQAlloc failed: %d\n", rc); - - rc = PtlEQAlloc(ni, 1024, reply_in_callback, &reply_in_eq); - if (rc != PTL_OK) - CERROR("PtlEQAlloc failed: %d\n", rc); - - rc = PtlEQAlloc(ni, 1024, bulk_source_callback, &bulk_source_eq); - if (rc != PTL_OK) - CERROR("PtlEQAlloc failed: %d\n", rc); - - rc = PtlEQAlloc(ni, 1024, bulk_sink_callback, &bulk_sink_eq); - if (rc != PTL_OK) - CERROR("PtlEQAlloc failed: %d\n", rc); - - return rc; -} - -void ptlrpc_exit_portals(void) -{ - PtlEQFree(request_out_eq); - PtlEQFree(reply_out_eq); - PtlEQFree(reply_in_eq); - PtlEQFree(bulk_source_eq); - PtlEQFree(bulk_sink_eq); - - if (qswnal_nip != NULL) - inter_module_put("kqswnal_ni"); - if (socknal_nip != NULL) - inter_module_put("ksocknal_ni"); - if (gmnal_nip != NULL) - inter_module_put("kgmnal_ni"); - if (toenal_nip != NULL) - inter_module_put("ktoenal_ni"); -} diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c deleted file mode 100644 index a778b57..0000000 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ /dev/null @@ -1,52 +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; -} - -struct lprocfs_vars status_var_nm_1[] = { - {"status/uuid", rd_uuid, 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; - int len = 0; - len += snprintf(page, count, "%d\n", class->typ_refcnt); - return len; -} - -struct lprocfs_vars status_class_var[] = { - {"status/num_refs", rd_numrefs, 0, 0}, - {0} -}; diff --git a/lustre/ptlrpc/niobuf.c b/lustre/ptlrpc/niobuf.c deleted file mode 100644 index c2c2b32..0000000 --- a/lustre/ptlrpc/niobuf.c +++ /dev/null @@ -1,488 +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_RPC - -#include -#include -#include -#include - -extern ptl_handle_eq_t request_out_eq, reply_in_eq, reply_out_eq, - bulk_source_eq, bulk_sink_eq; - -static int ptl_send_buf(struct ptlrpc_request *request, - struct ptlrpc_connection *conn, int portal) -{ - int rc; - ptl_process_id_t remote_id; - ptl_handle_md_t md_h; - - LASSERT(conn); - - request->rq_req_md.user_ptr = request; - - switch (request->rq_type) { - case PTL_RPC_MSG_REQUEST: - request->rq_reqmsg->type = HTON__u32(request->rq_type); - request->rq_req_md.start = request->rq_reqmsg; - request->rq_req_md.length = request->rq_reqlen; - request->rq_req_md.eventq = request_out_eq; - break; - case PTL_RPC_MSG_ERR: - case PTL_RPC_MSG_REPLY: - request->rq_repmsg->type = HTON__u32(request->rq_type); - request->rq_req_md.start = request->rq_repmsg; - request->rq_req_md.length = request->rq_replen; - request->rq_req_md.eventq = reply_out_eq; - break; - default: - LBUG(); - return -1; /* notreached */ - } - request->rq_req_md.threshold = 1; - request->rq_req_md.options = PTL_MD_OP_PUT; - request->rq_req_md.user_ptr = request; - - rc = PtlMDBind(conn->c_peer.peer_ni, request->rq_req_md, &md_h); - if (rc != 0) { - CERROR("PtlMDBind failed: %d\n", rc); - LBUG(); - return rc; - } - - remote_id.nid = conn->c_peer.peer_nid; - remote_id.pid = 0; - - CDEBUG(D_NET, "Sending %d bytes to portal %d, xid "LPD64"\n", - request->rq_req_md.length, portal, request->rq_xid); - - if (!portal) - LBUG(); - rc = PtlPut(md_h, PTL_NOACK_REQ, remote_id, portal, 0, request->rq_xid, - 0, 0); - if (rc != PTL_OK) { - CERROR("PtlPut("LPU64", %d, "LPD64") failed: %d\n", - remote_id.nid, portal, request->rq_xid, rc); - PtlMDUnlink(md_h); - } - - return rc; -} - -static inline struct iovec * -ptlrpc_get_bulk_iov (struct ptlrpc_bulk_desc *desc) -{ - struct iovec *iov; - - if (desc->bd_page_count <= sizeof (desc->bd_iov)/sizeof (struct iovec)) - return (desc->bd_iov); - - OBD_ALLOC (iov, desc->bd_page_count * sizeof (struct iovec)); - if (iov == NULL) - LBUG(); - - return (iov); -} - -static inline void -ptlrpc_put_bulk_iov (struct ptlrpc_bulk_desc *desc, struct iovec *iov) -{ - if (desc->bd_page_count <= sizeof (desc->bd_iov)/sizeof (struct iovec)) - return; - - OBD_FREE (iov, desc->bd_page_count * sizeof (struct iovec)); -} - -int ptlrpc_send_bulk(struct ptlrpc_bulk_desc *desc) -{ - int rc; - struct list_head *tmp, *next; - ptl_process_id_t remote_id; - __u32 xid = 0; - struct iovec *iov; - ENTRY; - - iov = ptlrpc_get_bulk_iov (desc); - if (iov == NULL) - RETURN (-ENOMEM); - - desc->bd_md.start = iov; - desc->bd_md.niov = 0; - desc->bd_md.length = 0; - desc->bd_md.eventq = bulk_source_eq; - desc->bd_md.threshold = 2; /* SENT and ACK */ - desc->bd_md.options = PTL_MD_OP_PUT | PTL_MD_IOV; - desc->bd_md.user_ptr = desc; - - atomic_set(&desc->bd_source_callback_count, 2); - - list_for_each_safe(tmp, next, &desc->bd_page_list) { - struct ptlrpc_bulk_page *bulk; - bulk = list_entry(tmp, struct ptlrpc_bulk_page, bp_link); - - LASSERT(desc->bd_md.niov < desc->bd_page_count); - - if (desc->bd_md.niov == 0) - xid = bulk->bp_xid; - LASSERT(xid == bulk->bp_xid); /* should all be the same */ - - iov[desc->bd_md.niov].iov_base = bulk->bp_buf; - iov[desc->bd_md.niov].iov_len = bulk->bp_buflen; - desc->bd_md.niov++; - desc->bd_md.length += bulk->bp_buflen; - } - - LASSERT(desc->bd_md.niov == desc->bd_page_count); - LASSERT(desc->bd_md.niov != 0); - - rc = PtlMDBind(desc->bd_connection->c_peer.peer_ni, desc->bd_md, - &desc->bd_md_h); - - ptlrpc_put_bulk_iov (desc, iov); /*move down to reduce latency to send*/ - - if (rc != PTL_OK) { - CERROR("PtlMDBind failed: %d\n", rc); - LBUG(); - RETURN(rc); - } - - remote_id.nid = desc->bd_connection->c_peer.peer_nid; - remote_id.pid = 0; - - CDEBUG(D_NET, "Sending %u pages %u bytes to portal %d nid "LPX64" pid " - "%d xid %d\n", desc->bd_md.niov, desc->bd_md.length, - desc->bd_portal, remote_id.nid, remote_id.pid, xid); - - rc = PtlPut(desc->bd_md_h, PTL_ACK_REQ, remote_id, - desc->bd_portal, 0, xid, 0, 0); - if (rc != PTL_OK) { - CERROR("PtlPut("LPU64", %d, %d) failed: %d\n", - remote_id.nid, desc->bd_portal, xid, rc); - PtlMDUnlink(desc->bd_md_h); - LBUG(); - RETURN(rc); - } - - RETURN(0); -} - -int ptlrpc_register_bulk(struct ptlrpc_bulk_desc *desc) -{ - struct list_head *tmp, *next; - int rc; - __u32 xid = 0; - struct iovec *iov; - ptl_process_id_t source_id; - ENTRY; - - if (desc->bd_page_count > PTL_MD_MAX_IOV) { - CERROR("iov longer than %d pages not supported (count=%d)\n", - PTL_MD_MAX_IOV, desc->bd_page_count); - RETURN(-EINVAL); - } - - iov = ptlrpc_get_bulk_iov (desc); - if (iov == NULL) - return (-ENOMEM); - - desc->bd_md.start = iov; - desc->bd_md.niov = 0; - desc->bd_md.length = 0; - desc->bd_md.threshold = 1; - desc->bd_md.options = PTL_MD_OP_PUT | PTL_MD_IOV; - desc->bd_md.user_ptr = desc; - desc->bd_md.eventq = bulk_sink_eq; - - list_for_each_safe(tmp, next, &desc->bd_page_list) { - struct ptlrpc_bulk_page *bulk; - bulk = list_entry(tmp, struct ptlrpc_bulk_page, bp_link); - - LASSERT(desc->bd_md.niov < desc->bd_page_count); - - if (desc->bd_md.niov == 0) - xid = bulk->bp_xid; - LASSERT(xid == bulk->bp_xid); /* should all be the same */ - - iov[desc->bd_md.niov].iov_base = bulk->bp_buf; - iov[desc->bd_md.niov].iov_len = bulk->bp_buflen; - desc->bd_md.niov++; - desc->bd_md.length += bulk->bp_buflen; - } - - LASSERT(desc->bd_md.niov == desc->bd_page_count); - LASSERT(desc->bd_md.niov != 0); - - source_id.nid = desc->bd_connection->c_peer.peer_nid; - source_id.pid = PTL_PID_ANY; - - rc = PtlMEAttach(desc->bd_connection->c_peer.peer_ni, - desc->bd_portal, source_id, xid, 0, - PTL_UNLINK, PTL_INS_AFTER, &desc->bd_me_h); - - if (rc != PTL_OK) { - CERROR("PtlMEAttach failed: %d\n", rc); - LBUG(); - GOTO(cleanup, rc); - } - - rc = PtlMDAttach(desc->bd_me_h, desc->bd_md, PTL_UNLINK, - &desc->bd_md_h); - if (rc != PTL_OK) { - CERROR("PtlMDAttach failed: %d\n", rc); - LBUG(); - GOTO(cleanup, rc); - } - - ptlrpc_put_bulk_iov (desc, iov); - - CDEBUG(D_NET, "Setup bulk sink buffers: %u pages %u bytes, xid %u, " - "portal %u\n", desc->bd_md.niov, desc->bd_md.length, - xid, desc->bd_portal); - - RETURN(0); - - cleanup: - ptlrpc_put_bulk_iov (desc, iov); - ptlrpc_abort_bulk(desc); - - return rc; -} - -int ptlrpc_abort_bulk(struct ptlrpc_bulk_desc *desc) -{ - /* This should be safe: these handles are initialized to be - * invalid in ptlrpc_prep_bulk() */ - PtlMDUnlink(desc->bd_md_h); - PtlMEUnlink(desc->bd_me_h); - - return 0; -} - -void obd_brw_set_add(struct obd_brw_set *set, struct ptlrpc_bulk_desc *desc) -{ - atomic_inc(&desc->bd_refcount); - atomic_inc(&set->brw_refcount); - desc->bd_brw_set = set; - list_add(&desc->bd_set_chain, &set->brw_desc_head); -} - -struct obd_brw_set *obd_brw_set_new(void) -{ - struct obd_brw_set *set; - - OBD_ALLOC(set, sizeof(*set)); - - if (set != NULL) { - init_waitqueue_head(&set->brw_waitq); - INIT_LIST_HEAD(&set->brw_desc_head); - atomic_set(&set->brw_refcount, 0); - } - - return set; -} - -void obd_brw_set_free(struct obd_brw_set *set) -{ - struct list_head *tmp, *next; - ENTRY; - - if (!list_empty(&set->brw_desc_head)) { - EXIT; - return; - } - - list_for_each_safe(tmp, next, &set->brw_desc_head) { - struct ptlrpc_bulk_desc *desc = - list_entry(tmp, struct ptlrpc_bulk_desc, bd_set_chain); - - CERROR("Unfinished bulk descriptor: %p\n", desc); - - ptlrpc_abort_bulk(desc); - } - OBD_FREE(set, sizeof(*set)); - EXIT; - return; -} - -int ptlrpc_reply(struct ptlrpc_service *svc, struct ptlrpc_request *req) -{ - if (req->rq_repmsg == NULL) { - CERROR("bad: someone called ptlrpc_reply when they meant " - "ptlrpc_error\n"); - return -EINVAL; - } - - /* FIXME: we need to increment the count of handled events */ - if (req->rq_type != PTL_RPC_MSG_ERR) - req->rq_type = PTL_RPC_MSG_REPLY; - //req->rq_repmsg->conn = req->rq_connection->c_remote_conn; - //req->rq_repmsg->token = req->rq_connection->c_remote_token; - req->rq_repmsg->status = HTON__u32(req->rq_status); - return ptl_send_buf(req, req->rq_connection, svc->srv_rep_portal); -} - -int ptlrpc_error(struct ptlrpc_service *svc, struct ptlrpc_request *req) -{ - int rc; - ENTRY; - - if (req->rq_repmsg) { - CERROR("req already has repmsg\n"); - LBUG(); - } - - rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - - req->rq_type = PTL_RPC_MSG_ERR; - - rc = ptlrpc_reply(svc, req); - RETURN(rc); -} - -int ptl_send_rpc(struct ptlrpc_request *request) -{ - int rc; - char *repbuf; - ptl_process_id_t source_id; - - ENTRY; - - if (request->rq_type != PTL_RPC_MSG_REQUEST) { - CERROR("wrong packet type sent %d\n", - NTOH__u32(request->rq_reqmsg->type)); - LBUG(); - RETURN(EINVAL); - } - - source_id.nid = request->rq_connection->c_peer.peer_nid; - source_id.pid = PTL_PID_ANY; - - /* add a ref, which will be balanced in request_out_callback */ - atomic_inc(&request->rq_refcount); - if (request->rq_replen != 0) { - /* request->rq_repmsg is set only when the reply comes in, in - * client_packet_callback() */ - if (request->rq_reply_md.start) { - PtlMEUnlink(request->rq_reply_me_h); - OBD_FREE(request->rq_reply_md.start, - request->rq_replen); - /* If we're resending, rq_repmsg needs to be NULLed out - * again so that ptlrpc_check_reply doesn't trip early. - */ - request->rq_repmsg = NULL; - } - OBD_ALLOC(repbuf, request->rq_replen); - if (!repbuf) { - LBUG(); - RETURN(ENOMEM); - } - - rc = PtlMEAttach(request->rq_connection->c_peer.peer_ni, - request->rq_reply_portal,/* XXX FIXME bug 625069 */ - source_id, request->rq_xid, 0, PTL_UNLINK, - PTL_INS_AFTER, &request->rq_reply_me_h); - if (rc != PTL_OK) { - CERROR("PtlMEAttach failed: %d\n", rc); - LBUG(); - GOTO(cleanup, rc); - } - - request->rq_reply_md.start = repbuf; - request->rq_reply_md.length = request->rq_replen; - request->rq_reply_md.threshold = 1; - request->rq_reply_md.options = PTL_MD_OP_PUT; - request->rq_reply_md.user_ptr = request; - request->rq_reply_md.eventq = reply_in_eq; - - rc = PtlMDAttach(request->rq_reply_me_h, request->rq_reply_md, - PTL_UNLINK, NULL); - if (rc != PTL_OK) { - CERROR("PtlMDAttach failed: %d\n", rc); - LBUG(); - GOTO(cleanup2, rc); - } - - CDEBUG(D_NET, "Setup reply buffer: %u bytes, xid "LPU64 - ", portal %u\n", - request->rq_replen, request->rq_xid, - request->rq_reply_portal); - } - - /* Clear any flags that may be present from previous sends, - * except for REPLAY. */ - request->rq_flags &= PTL_RPC_FL_REPLAY; - rc = ptl_send_buf(request, request->rq_connection, - request->rq_request_portal); - RETURN(rc); - - cleanup2: - PtlMEUnlink(request->rq_reply_me_h); - cleanup: - OBD_FREE(repbuf, request->rq_replen); - // up(&request->rq_client->cli_rpc_sem); - - return rc; -} - -void ptlrpc_link_svc_me(struct ptlrpc_request_buffer_desc *rqbd) -{ - struct ptlrpc_service *service = rqbd->rqbd_service; - static ptl_process_id_t match_id = {PTL_NID_ANY, PTL_PID_ANY}; - int rc; - ptl_md_t dummy; - ptl_handle_md_t md_h; - - LASSERT(atomic_read(&rqbd->rqbd_refcount) == 0); - - /* Attach the leading ME on which we build the ring */ - rc = PtlMEAttach(service->srv_self.peer_ni, service->srv_req_portal, - match_id, 0, ~0, - PTL_UNLINK, PTL_INS_AFTER, &rqbd->rqbd_me_h); - if (rc != PTL_OK) { - CERROR("PtlMEAttach failed: %d\n", rc); - LBUG(); - } - - dummy.start = rqbd->rqbd_buffer; - dummy.length = service->srv_buf_size; - dummy.max_size = service->srv_max_req_size; - dummy.threshold = PTL_MD_THRESH_INF; - dummy.options = PTL_MD_OP_PUT | PTL_MD_MAX_SIZE | PTL_MD_AUTO_UNLINK; - dummy.user_ptr = rqbd; - dummy.eventq = service->srv_eq_h; - - atomic_inc(&service->srv_nrqbds_receiving); - atomic_set(&rqbd->rqbd_refcount, 1); /* 1 ref for portals */ - - rc = PtlMDAttach(rqbd->rqbd_me_h, dummy, PTL_UNLINK, &md_h); - if (rc != PTL_OK) { - CERROR("PtlMDAttach failed: %d\n", rc); - LBUG(); -#warning proper cleanup required - PtlMEUnlink (rqbd->rqbd_me_h); - atomic_set(&rqbd->rqbd_refcount, 0); - atomic_dec(&service->srv_nrqbds_receiving); - } -} diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c deleted file mode 100644 index 49d79dc..0000000 --- a/lustre/ptlrpc/pack_generic.c +++ /dev/null @@ -1,138 +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. - * - * (Un)packing of OST requests - * - */ - -#define DEBUG_SUBSYSTEM S_RPC - -#include -#include - -int lustre_pack_msg(int count, int *lens, char **bufs, int *len, - struct lustre_msg **msg) -{ - char *ptr; - struct lustre_msg *m; - int size = 0, i; - - for (i = 0; i < count; i++) - size += size_round(lens[i]); - - *len = size_round(sizeof(*m) + count * sizeof(__u32)) + size; - - OBD_ALLOC(*msg, *len); - if (!*msg) - RETURN(-ENOMEM); - - m = *msg; - m->bufcount = HTON__u32(count); - for (i = 0; i < count; i++) - m->buflens[i] = HTON__u32(lens[i]); - - ptr = (char *)m + size_round(sizeof(*m) + count * sizeof(__u32)); - for (i = 0; i < count; i++) { - char *tmp = NULL; - if (bufs) - tmp = bufs[i]; - LOGL(tmp, lens[i], ptr); - } - - return 0; -} - -/* This returns the size of the buffer that is required to hold a lustre_msg - * with the given sub-buffer lengths. */ -int lustre_msg_size(int count, int *lengths) -{ - int size = 0, i; - - for (i = 0; i < count; i++) - size += size_round(lengths[i]); - - size += size_round(sizeof(struct lustre_msg) + count * sizeof(__u32)); - - return size; -} - -int lustre_unpack_msg(struct lustre_msg *m, int len) -{ - int required_len, i; - ENTRY; - - required_len = size_round(sizeof(*m)); - if (len < required_len) - RETURN(-EINVAL); - - m->opc = NTOH__u32(m->opc); - m->status = NTOH__u32(m->status); - m->type = NTOH__u32(m->type); - m->bufcount = NTOH__u32(m->bufcount); - m->last_xid = NTOH__u64(m->last_xid); - m->last_committed = NTOH__u64(m->last_committed); - - required_len = size_round(sizeof(*m) + m->bufcount * sizeof(__u32)); - if (len < required_len) - RETURN(-EINVAL); - - for (i = 0; i < m->bufcount; i++) { - m->buflens[i] = NTOH__u32(m->buflens[i]); - required_len += size_round(m->buflens[i]); - } - - if (len < required_len) { - CERROR("len: %d, required_len %d\n", len, required_len); - RETURN(-EINVAL); - } - - RETURN(0); -} - -void *lustre_msg_buf(struct lustre_msg *m, int n) -{ - int i, offset; - - if (!m) { - CERROR("no message buffer!\n"); - LBUG(); - return NULL; - } - - if (n < 0 || n >= m->bufcount) { - CERROR("referencing bad sub buffer in %p (want %d, count %d)!\n", - m, n, m->bufcount); - LBUG(); - return NULL; - } - - if (m->buflens[n] == 0) { - CERROR("zero-length buffer requested for buffer %d in %p\n", n, - m); - return NULL; - } - - offset = size_round(sizeof(*m) + m->bufcount * sizeof(__u32)); - - for (i = 0; i < n; i++) - offset += size_round(m->buflens[i]); - - return (char *)m + offset; -} diff --git a/lustre/ptlrpc/recovd.c b/lustre/ptlrpc/recovd.c deleted file mode 100644 index 0bbc4b0..0000000 --- a/lustre/ptlrpc/recovd.c +++ /dev/null @@ -1,361 +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 DEBUG_SUBSYSTEM S_RPC - -#include -#include -#include - -/* dump_connection_list, but shorter for nicer debugging logs */ -static void d_c_l(struct list_head *head) -{ - int sanity = 0; - struct list_head *tmp; - - list_for_each(tmp, head) { - struct ptlrpc_connection *conn = - list_entry(tmp, struct ptlrpc_connection, - c_recovd_data.rd_managed_chain); - CDEBUG(D_HA, " %p = %s (%d/%d)\n", conn, conn->c_remote_uuid, - conn->c_recovd_data.rd_phase, - conn->c_recovd_data.rd_next_phase); - if (sanity++ > 1000) - LBUG(); - } -} - -static void dump_lists(struct recovd_obd *recovd) -{ - CDEBUG(D_HA, "managed: \n"); - d_c_l(&recovd->recovd_managed_items); - CDEBUG(D_HA, "troubled: \n"); - d_c_l(&recovd->recovd_troubled_items); -} - -void recovd_conn_manage(struct ptlrpc_connection *conn, - struct recovd_obd *recovd, ptlrpc_recovery_cb_t recover) -{ - struct recovd_data *rd = &conn->c_recovd_data; - ENTRY; - if (!recovd || !recover) { - EXIT; - return; - } - - if (!list_empty(&rd->rd_managed_chain)) { - if (rd->rd_recovd == recovd && rd->rd_recover == recover) { - CDEBUG(D_HA, "conn %p/%s already setup for recovery\n", - conn, conn->c_remote_uuid); - EXIT; - return; - } - CDEBUG(D_HA, - "conn %p/%s has recovery items %p/%p, making %p/%p\n", - conn, conn->c_remote_uuid, rd->rd_recovd, rd->rd_recover, - recovd, recover); - spin_lock(&rd->rd_recovd->recovd_lock); - list_del_init(&rd->rd_managed_chain); - spin_unlock(&rd->rd_recovd->recovd_lock); - } - - rd->rd_recovd = recovd; - rd->rd_recover = recover; - rd->rd_phase = RD_IDLE; - rd->rd_next_phase = RD_TROUBLED; - - spin_lock(&recovd->recovd_lock); - list_add(&rd->rd_managed_chain, &recovd->recovd_managed_items); - dump_lists(recovd); - spin_unlock(&recovd->recovd_lock); - - EXIT; -} - -void recovd_conn_unmanage(struct ptlrpc_connection *conn) -{ - struct recovd_data *rd = &conn->c_recovd_data; - struct recovd_obd *recovd = rd->rd_recovd; - ENTRY; - - if (recovd) { - spin_lock(&recovd->recovd_lock); - list_del_init(&rd->rd_managed_chain); - rd->rd_recovd = NULL; - spin_unlock(&recovd->recovd_lock); - } - /* should be safe enough, right? */ - rd->rd_recover = NULL; - rd->rd_next_phase = RD_IDLE; - rd->rd_next_phase = RD_TROUBLED; -} - -void recovd_conn_fail(struct ptlrpc_connection *conn) -{ - struct recovd_data *rd = &conn->c_recovd_data; - struct recovd_obd *recovd = rd->rd_recovd; - ENTRY; - - if (!recovd) { - CERROR("no recovd for connection %p\n", conn); - EXIT; - return; - } - - spin_lock(&recovd->recovd_lock); - if (rd->rd_phase == RD_TROUBLED || rd->rd_phase == RD_PREPARING) { - CDEBUG(D_HA, "connection %p to %s already in recovery\n", - conn, conn->c_remote_uuid); - spin_unlock(&recovd->recovd_lock); - EXIT; - return; - } - - CERROR("connection %p to %s (%08x %08lx %08lx) failed\n", conn, - conn->c_remote_uuid, conn->c_peer.peer_nid, - conn->c_peer.peer_ni.nal_idx, conn->c_peer.peer_ni.handle_idx); - list_del(&rd->rd_managed_chain); - list_add_tail(&rd->rd_managed_chain, &recovd->recovd_troubled_items); - if (rd->rd_phase != RD_IDLE) { - CDEBUG(D_HA, - "connection %p to %s failed in recovery: restarting\n", - conn, conn->c_remote_uuid); - /* XXX call callback with PHASE_FAILED? */ - rd->rd_next_phase = RD_TROUBLED; - } - rd->rd_phase = RD_TROUBLED; - dump_lists(recovd); - spin_unlock(&recovd->recovd_lock); - - wake_up(&recovd->recovd_waitq); - - EXIT; -} - -void recovd_conn_fixed(struct ptlrpc_connection *conn) -{ - struct recovd_data *rd = &conn->c_recovd_data; - ENTRY; - - CDEBUG(D_HA, "connection %p (now to %s) fixed\n", - conn, conn->c_remote_uuid); - spin_lock(&rd->rd_recovd->recovd_lock); - list_del(&rd->rd_managed_chain); - rd->rd_phase = RD_IDLE; - rd->rd_next_phase = RD_TROUBLED; - list_add(&rd->rd_managed_chain, &rd->rd_recovd->recovd_managed_items); - dump_lists(rd->rd_recovd); - spin_unlock(&rd->rd_recovd->recovd_lock); - - EXIT; -} - -static int recovd_check_event(struct recovd_obd *recovd) -{ - int rc = 0; - struct list_head *tmp; - - ENTRY; - - spin_lock(&recovd->recovd_lock); - - if (recovd->recovd_state == RECOVD_STOPPING) - GOTO(out, rc = 1); - - list_for_each(tmp, &recovd->recovd_troubled_items) { - - struct recovd_data *rd = list_entry(tmp, struct recovd_data, - rd_managed_chain); - - if (rd->rd_phase == rd->rd_next_phase || - rd->rd_phase == RD_FAILED) - GOTO(out, rc = 1); - } - - out: - spin_unlock(&recovd->recovd_lock); - RETURN(rc); -} - -static int recovd_handle_event(struct recovd_obd *recovd) -{ - struct list_head *tmp, *n; - int rc = 0; - ENTRY; - - spin_lock(&recovd->recovd_lock); - - dump_lists(recovd); - - /* - * We use _safe here because one of the callbacks, expecially - * FAILURE or PREPARED, could move list items around. - */ - list_for_each_safe(tmp, n, &recovd->recovd_troubled_items) { - struct recovd_data *rd = list_entry(tmp, struct recovd_data, - rd_managed_chain); - - if (rd->rd_phase != RD_FAILED && - rd->rd_phase != rd->rd_next_phase) - continue; - - switch (rd->rd_phase) { - case RD_FAILED: - cb_failed: /* must always reach here with recovd_lock held! */ - CERROR("recovery FAILED for rd %p (conn %p): %d\n", - rd, class_rd2conn(rd), rc); - - spin_unlock(&recovd->recovd_lock); - (void)rd->rd_recover(rd, PTLRPC_RECOVD_PHASE_FAILURE); - spin_lock(&recovd->recovd_lock); - break; - - case RD_TROUBLED: - if (!rd->rd_recover) { - CERROR("no rd_recover for rd %p (conn %p)\n", - rd, class_rd2conn(rd)); - rc = -EINVAL; - break; - } - CERROR("starting recovery for rd %p (conn %p)\n", - rd, class_rd2conn(rd)); - rd->rd_phase = RD_PREPARING; - rd->rd_next_phase = RD_PREPARED; - - spin_unlock(&recovd->recovd_lock); - rc = rd->rd_recover(rd, PTLRPC_RECOVD_PHASE_PREPARE); - spin_lock(&recovd->recovd_lock); - if (rc) - goto cb_failed; - - break; - - case RD_PREPARED: - - CERROR("recovery prepared for rd %p (conn %p)\n", - rd, class_rd2conn(rd)); - rd->rd_phase = RD_RECOVERING; - rd->rd_next_phase = RD_RECOVERED; - - spin_unlock(&recovd->recovd_lock); - rc = rd->rd_recover(rd, PTLRPC_RECOVD_PHASE_RECOVER); - spin_lock(&recovd->recovd_lock); - if (rc) - goto cb_failed; - - break; - - case RD_RECOVERED: - rd->rd_phase = RD_IDLE; - rd->rd_next_phase = RD_TROUBLED; - - CERROR("recovery complete for rd %p (conn %p)\n", - rd, class_rd2conn(rd)); - break; - - default: - break; - } - } - spin_unlock(&recovd->recovd_lock); - RETURN(0); -} - -static int recovd_main(void *arg) -{ - struct recovd_obd *recovd = (struct recovd_obd *)arg; - - ENTRY; - - lock_kernel(); - daemonize(); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - sigfillset(¤t->blocked); - recalc_sigpending(); -#else - spin_lock_irq(¤t->sigmask_lock); - sigfillset(¤t->blocked); - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); -#endif - - sprintf(current->comm, "lustre_recovd"); - unlock_kernel(); - - /* Signal that the thread is running. */ - recovd->recovd_thread = current; - recovd->recovd_state = RECOVD_READY; - wake_up(&recovd->recovd_ctl_waitq); - - /* And now, loop forever on requests. */ - while (1) { - wait_event(recovd->recovd_waitq, recovd_check_event(recovd)); - if (recovd->recovd_state == RECOVD_STOPPING) - break; - recovd_handle_event(recovd); - } - - recovd->recovd_thread = NULL; - recovd->recovd_state = RECOVD_STOPPED; - wake_up(&recovd->recovd_ctl_waitq); - CDEBUG(D_HA, "mgr exiting process %d\n", current->pid); - RETURN(0); -} - -int recovd_setup(struct recovd_obd *recovd) -{ - int rc; - - ENTRY; - - INIT_LIST_HEAD(&recovd->recovd_managed_items); - INIT_LIST_HEAD(&recovd->recovd_troubled_items); - spin_lock_init(&recovd->recovd_lock); - - init_waitqueue_head(&recovd->recovd_waitq); - init_waitqueue_head(&recovd->recovd_recovery_waitq); - init_waitqueue_head(&recovd->recovd_ctl_waitq); - - rc = kernel_thread(recovd_main, (void *)recovd, - CLONE_VM | CLONE_FS | CLONE_FILES); - if (rc < 0) { - CERROR("cannot start thread\n"); - RETURN(-EINVAL); - } - wait_event(recovd->recovd_ctl_waitq, - recovd->recovd_state == RECOVD_READY); - - ptlrpc_recovd = recovd; - class_signal_connection_failure = recovd_conn_fail; - - RETURN(0); -} - -int recovd_cleanup(struct recovd_obd *recovd) -{ - ENTRY; - spin_lock(&recovd->recovd_lock); - recovd->recovd_state = RECOVD_STOPPING; - wake_up(&recovd->recovd_waitq); - spin_unlock(&recovd->recovd_lock); - - wait_event(recovd->recovd_ctl_waitq, - (recovd->recovd_state == RECOVD_STOPPED)); - RETURN(0); -} - -struct recovd_obd *ptlrpc_recovd; diff --git a/lustre/ptlrpc/recover.c b/lustre/ptlrpc/recover.c deleted file mode 100644 index acdecf8..0000000 --- a/lustre/ptlrpc/recover.c +++ /dev/null @@ -1,277 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Portal-RPC reconnection and replay operations, for use in recovery. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copyright (C) 1996 Peter J. Braam - * Copyright (C) 1999 Stelias Computing Inc. - * Copyright (C) 1999 Seagate Technology Inc. - * Copyright (C) 2001 Mountain View Data, Inc. - * Copyright (C) 2002 Cluster File Systems, Inc. - * - */ - -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_RPC - -#include -#include -#include - -int ptlrpc_reconnect_import(struct obd_import *imp, int rq_opc) -{ - struct obd_device *obd = imp->imp_obd; - struct client_obd *cli = &obd->u.cli; - int size[] = { sizeof(cli->cl_target_uuid), sizeof(obd->obd_uuid) }; - char *tmp[] = {cli->cl_target_uuid, obd->obd_uuid }; - struct ptlrpc_connection *conn = imp->imp_connection; - struct lustre_handle old_hdl; - struct ptlrpc_request *request; - struct obd_export *ldlmexp; - int rc; - - request = ptlrpc_prep_req(imp, rq_opc, 2, size, tmp); - request->rq_level = LUSTRE_CONN_NEW; - request->rq_replen = lustre_msg_size(0, NULL); - /* - * This address is the export that represents our client-side LDLM - * service (for ASTs). We should only have one on this list, so we - * just grab the first one. - * - * XXX tear down export, call class_obd_connect? - */ - ldlmexp = list_entry(obd->obd_exports.next, struct obd_export, - exp_obd_chain); - request->rq_reqmsg->addr = (__u64)(unsigned long)ldlmexp; - request->rq_reqmsg->cookie = ldlmexp->exp_cookie; - rc = ptlrpc_queue_wait(request); - switch (rc) { - case EALREADY: - case -EALREADY: - /* already connected! */ - memset(&old_hdl, 0, sizeof(old_hdl)); - if (!memcmp(&old_hdl.addr, &request->rq_repmsg->addr, - sizeof (old_hdl.addr)) && - !memcmp(&old_hdl.cookie, &request->rq_repmsg->cookie, - sizeof (old_hdl.cookie))) { - CERROR("%s@%s didn't like our handle %Lx/%Lx, failed\n", - cli->cl_target_uuid, conn->c_remote_uuid, - (__u64)(unsigned long)ldlmexp, - ldlmexp->exp_cookie); - GOTO(out_disc, rc = -ENOTCONN); - } - - old_hdl.addr = request->rq_repmsg->addr; - old_hdl.cookie = request->rq_repmsg->cookie; - if (memcmp(&imp->imp_handle, &old_hdl, sizeof(old_hdl))) { - CERROR("%s@%s changed handle from %Lx/%Lx to %Lx/%Lx; " - "copying, but this may foreshadow disaster\n", - cli->cl_target_uuid, conn->c_remote_uuid, - old_hdl.addr, old_hdl.cookie, - imp->imp_handle.addr, imp->imp_handle.cookie); - imp->imp_handle.addr = request->rq_repmsg->addr; - imp->imp_handle.cookie = request->rq_repmsg->cookie; - GOTO(out_disc, rc = EALREADY); - } - - CERROR("reconnected to %s@%s after partition\n", - cli->cl_target_uuid, conn->c_remote_uuid); - GOTO(out_disc, rc = EALREADY); - case 0: - old_hdl = imp->imp_handle; - imp->imp_handle.addr = request->rq_repmsg->addr; - imp->imp_handle.cookie = request->rq_repmsg->cookie; - CERROR("now connected to %s@%s (%Lx/%Lx, was %Lx/%Lx)!\n", - cli->cl_target_uuid, conn->c_remote_uuid, - imp->imp_handle.addr, imp->imp_handle.cookie, - old_hdl.addr, old_hdl.cookie); - GOTO(out_disc, rc = 0); - default: - CERROR("cannot connect to %s@%s: rc = %d\n", - cli->cl_target_uuid, conn->c_remote_uuid, rc); - GOTO(out_disc, rc = -ENOTCONN); /* XXX preserve rc? */ - } - - out_disc: - ptlrpc_req_finished(request); - return rc; -} - -int ptlrpc_run_recovery_upcall(struct ptlrpc_connection *conn) -{ - char *argv[3]; - char *envp[3]; - int rc; - - ENTRY; - argv[0] = obd_recovery_upcall; - argv[1] = conn->c_remote_uuid; - argv[2] = NULL; - - envp[0] = "HOME=/"; - envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; - envp[2] = NULL; - - rc = call_usermodehelper(argv[0], argv, envp); - if (rc < 0) { - CERROR("Error invoking recovery upcall %s for %s: %d\n", - argv[0], argv[1], rc); - CERROR("Check /proc/sys/lustre/recovery_upcall?\n"); - } else { - CERROR("Invoked upcall %s for connection %s\n", - argv[0], argv[1]); - } - - /* - * We don't want to make this a "failed" recovery, because the system - * administrator -- or, perhaps, tester -- may well be able to rescue - * things by running the correct upcall. - */ - RETURN(0); -} - -int ptlrpc_replay(struct obd_import *imp, int send_last_flag) -{ - int rc = 0; - struct list_head *tmp, *pos; - struct ptlrpc_request *req; - __u64 committed = imp->imp_peer_committed_transno; - ENTRY; - - /* It might have committed some after we last spoke, so make sure we - * get rid of them now. - */ - spin_lock(&imp->imp_lock); - - ptlrpc_free_committed(imp); - - CDEBUG(D_HA, "import %p from %s has committed "LPD64"\n", - imp, imp->imp_obd->u.cli.cl_target_uuid, committed); - - list_for_each(tmp, &imp->imp_replay_list) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - DEBUG_REQ(D_HA, req, "RETAINED: "); - } - - list_for_each_safe(tmp, pos, &imp->imp_replay_list) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - - if (req->rq_transno == imp->imp_max_transno && - send_last_flag) { - req->rq_reqmsg->flags |= MSG_LAST_REPLAY; - DEBUG_REQ(D_HA, req, "LAST_REPLAY:"); - } else { - DEBUG_REQ(D_HA, req, "REPLAY:"); - } - - rc = ptlrpc_replay_req(req); - req->rq_reqmsg->flags &= ~MSG_LAST_REPLAY; - - if (rc) { - CERROR("recovery replay error %d for req %Ld\n", - rc, req->rq_xid); - GOTO(out, rc); - } - } - - out: - spin_unlock(&imp->imp_lock); - return rc; -} - -#define NO_RESEND 0 /* No action required. */ -#define RESEND 1 /* Resend required. */ -#define RESEND_IGNORE 2 /* Resend, ignore the reply (already saw it). */ -#define RESTART 3 /* Have to restart the call, sorry! */ - -static int resend_type(struct ptlrpc_request *req, __u64 committed) -{ - if (req->rq_transno < committed) { - if (req->rq_flags & PTL_RPC_FL_REPLIED) { - /* Saw the reply and it was committed, no biggie. */ - DEBUG_REQ(D_HA, req, "NO_RESEND"); - return NO_RESEND; - } - /* Request committed, but no reply: have to restart. */ - return RESTART; - } - - if (req->rq_flags & PTL_RPC_FL_REPLIED) { - /* Saw reply, so resend and ignore new reply. */ - return RESEND_IGNORE; - } - - /* Didn't see reply either, so resend. */ - return RESEND; - -} - -int ptlrpc_resend(struct obd_import *imp) -{ - int rc = 0; - struct list_head *tmp, *pos; - struct ptlrpc_request *req; - __u64 committed = imp->imp_peer_committed_transno; - - ENTRY; - - spin_lock(&imp->imp_lock); - list_for_each(tmp, &imp->imp_sending_list) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - DEBUG_REQ(D_HA, req, "SENDING: "); - } - - list_for_each_safe(tmp, pos, &imp->imp_sending_list) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - - switch(resend_type(req, committed)) { - case NO_RESEND: - break; - - case RESTART: - DEBUG_REQ(D_HA, req, "RESTART:"); - ptlrpc_restart_req(req); - break; - - case RESEND_IGNORE: - DEBUG_REQ(D_HA, req, "RESEND_IGNORE:"); - rc = ptlrpc_replay_req(req); - if (rc) { - DEBUG_REQ(D_ERROR, req, "error %d resending:", - rc); - ptlrpc_restart_req(req); /* might as well */ - } - break; - - case RESEND: - DEBUG_REQ(D_HA, req, "RESEND:"); - ptlrpc_resend_req(req); - break; - - default: - LBUG(); - } - } - - RETURN(rc); -} - -void ptlrpc_wake_delayed(struct obd_import *imp) -{ - struct list_head *tmp, *pos; - struct ptlrpc_request *req; - - spin_lock(&imp->imp_lock); - list_for_each_safe(tmp, pos, &imp->imp_delayed_list) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - DEBUG_REQ(D_HA, req, "waking:"); - wake_up(&req->rq_wait_for_rep); - } - spin_unlock(&imp->imp_lock); -} diff --git a/lustre/ptlrpc/rpc.c b/lustre/ptlrpc/rpc.c deleted file mode 100644 index eb6acb1..0000000 --- a/lustre/ptlrpc/rpc.c +++ /dev/null @@ -1,283 +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 -#define DEBUG_SUBSYSTEM S_RPC - -#include -#include -#include -#include -#include -#include -#include -#include - - - -extern int ptlrpc_init_portals(void); -extern void ptlrpc_exit_portals(void); - -extern struct lprocfs_vars status_var_nm_1[]; -extern struct lprocfs_vars status_class_var[]; - -int connmgr_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct recovd_obd *recovd = &obddev->u.recovd; - int err; - ENTRY; - - MOD_INC_USE_COUNT; - memset(recovd, 0, sizeof(*recovd)); - - err = recovd_setup(recovd); - if (err) { - MOD_DEC_USE_COUNT; - RETURN(err); - } - - RETURN(0); -} - -int connmgr_cleanup(struct obd_device *dev) -{ - struct recovd_obd *recovd = &dev->u.recovd; - int err; - - err = recovd_cleanup(recovd); - if (err) - LBUG(); - - MOD_DEC_USE_COUNT; - RETURN(0); -} - -int connmgr_iocontrol(unsigned int cmd, struct lustre_handle *hdl, int len, void *karg, - void *uarg) -{ - struct ptlrpc_connection *conn = NULL; - struct obd_device *obd = class_conn2obd(hdl); - struct recovd_obd *recovd = &obd->u.recovd; - struct obd_ioctl_data *data = karg; - struct list_head *tmp; - int rc = 0; - - ENTRY; - - if (cmd != OBD_IOC_RECOVD_NEWCONN && cmd != OBD_IOC_RECOVD_FAILCONN) - RETURN(-EINVAL); /* XXX ENOSYS? */ - - /* Find the connection that's been rebuilt or has failed. */ - spin_lock(&recovd->recovd_lock); - list_for_each(tmp, &recovd->recovd_troubled_items) { - conn = list_entry(tmp, struct ptlrpc_connection, - c_recovd_data.rd_managed_chain); - - LASSERT(conn->c_recovd_data.rd_recovd == recovd); /* sanity */ - - if (!strcmp(conn->c_remote_uuid, data->ioc_inlbuf1)) - break; - conn = NULL; - } - - if (!conn) { - if (cmd == OBD_IOC_RECOVD_NEWCONN) - GOTO(out, rc = -EINVAL); - /* XXX macroize/inline and share with loop above */ - list_for_each(tmp, &recovd->recovd_managed_items) { - conn = list_entry(tmp, struct ptlrpc_connection, - c_recovd_data.rd_managed_chain); - - LASSERT(conn->c_recovd_data.rd_recovd == recovd); - - if (!strcmp(conn->c_remote_uuid, data->ioc_inlbuf1)) - break; - conn = NULL; - } - if (!conn) - GOTO(out, rc = -EINVAL); - } - - if (cmd == OBD_IOC_RECOVD_FAILCONN) { - spin_unlock(&recovd->recovd_lock); - recovd_conn_fail(conn); - spin_lock(&recovd->recovd_lock); - - /* Jump straight to the "failed" phase of recovery. */ - conn->c_recovd_data.rd_phase = RD_FAILED; - goto out; - } - - - /* else (NEWCONN) */ - spin_lock(&conn->c_lock); - - /* whatever happens, reset the INVALID flag */ - conn->c_flags &= ~CONN_INVALID; - - /* XXX is this a good check? should we allow readdressing of - * XXX conns that aren't in recovery? - */ - if (conn->c_recovd_data.rd_phase != RD_PREPARING) { - spin_unlock(&conn->c_lock); - GOTO(out, rc = -EALREADY); - } - - if (data->ioc_inllen2) { - CERROR("conn %p UUID change %s -> %s\n", - conn, conn->c_remote_uuid, data->ioc_inlbuf2); - strcpy(conn->c_remote_uuid, data->ioc_inlbuf2); - } else { - CERROR("conn %p UUID %s reconnected\n", conn, - conn->c_remote_uuid); - } - ptlrpc_readdress_connection(conn, conn->c_remote_uuid); - spin_unlock(&conn->c_lock); - - conn->c_recovd_data.rd_phase = RD_PREPARED; - wake_up(&recovd->recovd_waitq); - out: - spin_unlock(&recovd->recovd_lock); - RETURN(rc); -} - -static int connmgr_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); -} - -int connmgr_attach(struct obd_device *dev, obd_count len, void *data) -{ - return lprocfs_reg_obd(dev, status_var_nm_1, dev); -} - -int conmgr_detach(struct obd_device *dev) -{ - return lprocfs_dereg_obd(dev); -} -/* use obd ops to offer management infrastructure */ -static struct obd_ops recovd_obd_ops = { - o_attach: connmgr_attach, - o_detach: conmgr_detach, - o_setup: connmgr_setup, - o_cleanup: connmgr_cleanup, - o_iocontrol: connmgr_iocontrol, - o_connect: connmgr_connect, - o_disconnect: class_disconnect -}; - -static int __init ptlrpc_init(void) -{ - int rc; - rc = ptlrpc_init_portals(); - if (rc) - RETURN(rc); - ptlrpc_init_connection(); - rc = class_register_type(&recovd_obd_ops, status_class_var, - LUSTRE_HA_NAME); - if (rc) - RETURN(rc); - ptlrpc_put_connection_superhack = ptlrpc_put_connection; - return 0; -} - -static void __exit ptlrpc_exit(void) -{ - class_unregister_type(LUSTRE_HA_NAME); - ptlrpc_exit_portals(); - ptlrpc_cleanup_connection(); -} - -/* recovd.c */ -EXPORT_SYMBOL(ptlrpc_recovd); -EXPORT_SYMBOL(recovd_conn_fail); -EXPORT_SYMBOL(recovd_conn_manage); -EXPORT_SYMBOL(recovd_conn_fixed); -EXPORT_SYMBOL(recovd_setup); -EXPORT_SYMBOL(recovd_cleanup); - -/* connection.c */ -EXPORT_SYMBOL(ptlrpc_readdress_connection); -EXPORT_SYMBOL(ptlrpc_get_connection); -EXPORT_SYMBOL(ptlrpc_put_connection); -EXPORT_SYMBOL(ptlrpc_connection_addref); -EXPORT_SYMBOL(ptlrpc_init_connection); -EXPORT_SYMBOL(ptlrpc_cleanup_connection); - -/* niobuf.c */ -EXPORT_SYMBOL(ptlrpc_send_bulk); -EXPORT_SYMBOL(ptlrpc_register_bulk); -EXPORT_SYMBOL(ptlrpc_abort_bulk); -EXPORT_SYMBOL(ptlrpc_reply); -EXPORT_SYMBOL(ptlrpc_error); -EXPORT_SYMBOL(ptlrpc_resend_req); -EXPORT_SYMBOL(ptl_send_rpc); -EXPORT_SYMBOL(ptlrpc_link_svc_me); -EXPORT_SYMBOL(obd_brw_set_free); -EXPORT_SYMBOL(obd_brw_set_new); -EXPORT_SYMBOL(obd_brw_set_add); - -/* client.c */ -EXPORT_SYMBOL(ptlrpc_init_client); -EXPORT_SYMBOL(ptlrpc_cleanup_client); -EXPORT_SYMBOL(ptlrpc_req_to_uuid); -EXPORT_SYMBOL(ptlrpc_uuid_to_connection); -EXPORT_SYMBOL(ptlrpc_queue_wait); -EXPORT_SYMBOL(ptlrpc_continue_req); -EXPORT_SYMBOL(ptlrpc_replay_req); -EXPORT_SYMBOL(ptlrpc_restart_req); -EXPORT_SYMBOL(ptlrpc_prep_req); -EXPORT_SYMBOL(ptlrpc_free_req); -EXPORT_SYMBOL(ptlrpc_req_finished); -EXPORT_SYMBOL(ptlrpc_prep_bulk); -EXPORT_SYMBOL(ptlrpc_free_bulk); -EXPORT_SYMBOL(ptlrpc_prep_bulk_page); -EXPORT_SYMBOL(ptlrpc_free_bulk_page); -EXPORT_SYMBOL(ll_brw_sync_wait); - -/* service.c */ -EXPORT_SYMBOL(ptlrpc_init_svc); -EXPORT_SYMBOL(ptlrpc_stop_all_threads); -EXPORT_SYMBOL(ptlrpc_start_thread); -EXPORT_SYMBOL(ptlrpc_unregister_service); - -/* pack_generic.c */ -EXPORT_SYMBOL(lustre_pack_msg); -EXPORT_SYMBOL(lustre_msg_size); -EXPORT_SYMBOL(lustre_unpack_msg); -EXPORT_SYMBOL(lustre_msg_buf); - -/* recover.c */ -EXPORT_SYMBOL(ptlrpc_run_recovery_upcall); -EXPORT_SYMBOL(ptlrpc_reconnect_import); -EXPORT_SYMBOL(ptlrpc_replay); -EXPORT_SYMBOL(ptlrpc_resend); -EXPORT_SYMBOL(ptlrpc_wake_delayed); - -MODULE_AUTHOR("Cluster File Systems, Inc "); -MODULE_DESCRIPTION("Lustre Request Processor v1.0"); -MODULE_LICENSE("GPL"); - -module_init(ptlrpc_init); -module_exit(ptlrpc_exit); diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c deleted file mode 100644 index 1688ff9..0000000 --- a/lustre/ptlrpc/service.c +++ /dev/null @@ -1,442 +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_RPC - -#include -#include -#include - -extern int request_in_callback(ptl_event_t *ev); - -static int ptlrpc_check_event(struct ptlrpc_service *svc, - struct ptlrpc_thread *thread, ptl_event_t *event) -{ - int rc; - ENTRY; - - spin_lock(&svc->srv_lock); - - if (thread->t_flags & SVC_STOPPING) - GOTO(out, rc = 1); - - LASSERT ((thread->t_flags & SVC_EVENT) == 0); - LASSERT (ptl_is_valid_handle (&svc->srv_eq_h)); - - rc = PtlEQGet(svc->srv_eq_h, event); - switch (rc) - { - case PTL_OK: - thread->t_flags |= SVC_EVENT; - GOTO(out, rc = 1); - - case PTL_EQ_EMPTY: - GOTO(out, rc = 0); - - default: - CERROR("BUG: PtlEQGet returned %d\n", rc); - LBUG(); - } - out: - spin_unlock(&svc->srv_lock); - return rc; -} - -struct ptlrpc_service * -ptlrpc_init_svc(__u32 nevents, __u32 nbufs, - __u32 bufsize, __u32 max_req_size, - int req_portal, int rep_portal, - obd_uuid_t uuid, svc_handler_t handler, char *name) -{ - int err; - int rc, i; - struct ptlrpc_service *service; - ENTRY; - - OBD_ALLOC(service, sizeof(*service)); - if (!service) - RETURN(NULL); - - service->srv_name = name; - spin_lock_init(&service->srv_lock); - INIT_LIST_HEAD(&service->srv_threads); - init_waitqueue_head(&service->srv_waitq); - - service->srv_max_req_size = max_req_size; - service->srv_buf_size = bufsize; - INIT_LIST_HEAD(&service->srv_rqbds); - service->srv_nrqbds = 0; - atomic_set(&service->srv_nrqbds_receiving, 0); - - service->srv_rep_portal = rep_portal; - service->srv_req_portal = req_portal; - service->srv_handler = handler; - - err = kportal_uuid_to_peer(uuid, &service->srv_self); - if (err) { - CERROR("%s: cannot get peer for uuid '%s'\n", name, uuid); - OBD_FREE(service, sizeof(*service)); - RETURN(NULL); - } - - rc = PtlEQAlloc(service->srv_self.peer_ni, nevents, - request_in_callback, &(service->srv_eq_h)); - - if (rc != PTL_OK) { - CERROR("%s: PtlEQAlloc failed: %d\n", name, rc); - OBD_FREE(service, sizeof(*service)); - RETURN(NULL); - } - - for (i = 0; i < nbufs; i++) { - struct ptlrpc_request_buffer_desc *rqbd; - - OBD_ALLOC(rqbd, sizeof(*rqbd)); - if (rqbd == NULL) - GOTO(failed, NULL); - - rqbd->rqbd_service = service; - ptl_set_inv_handle(&rqbd->rqbd_me_h); - atomic_set(&rqbd->rqbd_refcount, 0); - OBD_ALLOC(rqbd->rqbd_buffer, service->srv_buf_size); - if (rqbd->rqbd_buffer == NULL) { - OBD_FREE(rqbd, sizeof(*rqbd)); - GOTO(failed, NULL); - } - list_add(&rqbd->rqbd_list, &service->srv_rqbds); - service->srv_nrqbds++; - - ptlrpc_link_svc_me(rqbd); - } - - CDEBUG(D_NET, "Starting service listening on portal %d (eq: %p)\n", - service->srv_req_portal, service->srv_eq_h.handle_idx); - - RETURN(service); -failed: - ptlrpc_unregister_service(service); - return NULL; -} - -static int handle_incoming_request(struct obd_device *obddev, - struct ptlrpc_service *svc, - ptl_event_t *event, - struct ptlrpc_request *request) -{ - struct ptlrpc_request_buffer_desc *rqbd = event->mem_desc.user_ptr; - int rc; - - /* FIXME: If we move to an event-driven model, we should put the request - * on the stack of mds_handle instead. */ - - LASSERT (atomic_read (&rqbd->rqbd_refcount) > 0); - LASSERT ((event->mem_desc.options & PTL_MD_IOV) == 0); - LASSERT (rqbd->rqbd_service == svc); - LASSERT (rqbd->rqbd_buffer == event->mem_desc.start); - LASSERT (event->offset + event->mlength <= svc->srv_buf_size); - - memset(request, 0, sizeof(*request)); - request->rq_svc = svc; - request->rq_obd = obddev; - request->rq_xid = event->match_bits; - request->rq_reqmsg = event->mem_desc.start + event->offset; - request->rq_reqlen = event->mlength; - - rc = -EINVAL; - - if (request->rq_reqlen < sizeof(struct lustre_msg)) { - CERROR("incomplete request (%d): ptl %d from "LPX64" xid " - LPD64"\n", - request->rq_reqlen, svc->srv_req_portal, - event->initiator.nid, request->rq_xid); - goto out; - } - - CDEBUG(D_RPCTRACE, "Handling RPC pid:xid:nid:opc %d:" - LPX64":%x:%d\n", - NTOH__u32(request->rq_reqmsg->status), - request->rq_xid, - event->initiator.nid, - NTOH__u32(request->rq_reqmsg->opc)); - - if (NTOH__u32(request->rq_reqmsg->type) != PTL_RPC_MSG_REQUEST) { - CERROR("wrong packet type received (type=%u)\n", - request->rq_reqmsg->type); - goto out; - } - - if (request->rq_reqmsg->magic != PTLRPC_MSG_MAGIC) { - CERROR("wrong lustre_msg magic %d: ptl %d from "LPX64" xid " - LPD64"\n", - request->rq_reqmsg->magic, svc->srv_req_portal, - event->initiator.nid, request->rq_xid); - goto out; - } - - if (request->rq_reqmsg->version != PTLRPC_MSG_VERSION) { - CERROR("wrong lustre_msg version %d: ptl %d from "LPX64" xid " - LPD64"\n", - request->rq_reqmsg->version, svc->srv_req_portal, - event->initiator.nid, request->rq_xid); - goto out; - } - - CDEBUG(D_NET, "got req "LPD64" (md: %p + %d)\n", request->rq_xid, - event->mem_desc.start, event->offset); - - request->rq_peer.peer_nid = event->initiator.nid; - /* FIXME: this NI should be the incoming NI. - * We don't know how to find that from here. */ - request->rq_peer.peer_ni = svc->srv_self.peer_ni; - - request->rq_export = class_conn2export((struct lustre_handle *) - request->rq_reqmsg); - - if (request->rq_export) { - request->rq_connection = request->rq_export->exp_connection; - ptlrpc_connection_addref(request->rq_connection); - } else { - /* create a (hopefully temporary) connection that will be used - * to send the reply if this call doesn't create an export. - * XXX revisit this when we revamp ptlrpc */ - request->rq_connection = - ptlrpc_get_connection(&request->rq_peer, NULL); - } - - rc = svc->srv_handler(request); - ptlrpc_put_connection(request->rq_connection); - - out: - if (atomic_dec_and_test (&rqbd->rqbd_refcount)) /* last reference? */ - ptlrpc_link_svc_me (rqbd); - - return rc; -} - -/* Don't use daemonize, it removes fs struct from new thread (bug 418) */ -static void ptlrpc_daemonize(void) -{ - exit_mm(current); - - current->session = 1; - current->pgrp = 1; - current->tty = NULL; - - exit_files(current); -} - -static int ptlrpc_main(void *arg) -{ - struct ptlrpc_svc_data *data = (struct ptlrpc_svc_data *)arg; - struct obd_device *obddev = data->dev; - struct ptlrpc_service *svc = data->svc; - struct ptlrpc_thread *thread = data->thread; - struct ptlrpc_request *request; - ptl_event_t *event; - int rc = 0; - - ENTRY; - - lock_kernel(); - ptlrpc_daemonize(); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - sigfillset(¤t->blocked); - recalc_sigpending(); -#else - spin_lock_irq(¤t->sigmask_lock); - sigfillset(¤t->blocked); - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); -#endif - -#ifdef __arch_um__ - sprintf(current->comm, "%s|%d", data->name,current->thread.extern_pid); -#else - strcpy(current->comm, data->name); -#endif - unlock_kernel(); - - OBD_ALLOC(event, sizeof(*event)); - if (!event) - GOTO(out, rc = -ENOMEM); - OBD_ALLOC(request, sizeof(*request)); - if (!request) - GOTO(out_event, rc = -ENOMEM); - - /* Record that the thread is running */ - thread->t_flags = SVC_RUNNING; - wake_up(&thread->t_ctl_waitq); - - /* XXX maintain a list of all managed devices: insert here */ - - /* And now, loop forever on requests */ - while (1) { - wait_event(svc->srv_waitq, - ptlrpc_check_event(svc, thread, event)); - - if (thread->t_flags & SVC_STOPPING) { - spin_lock(&svc->srv_lock); - thread->t_flags &= ~SVC_STOPPING; - spin_unlock(&svc->srv_lock); - - EXIT; - break; - } - - if (thread->t_flags & SVC_EVENT) { - spin_lock(&svc->srv_lock); - thread->t_flags &= ~SVC_EVENT; - spin_unlock(&svc->srv_lock); - - rc = handle_incoming_request(obddev, svc, event, - request); - continue; - } - - CERROR("unknown break in service"); - LBUG(); - EXIT; - break; - } - - OBD_FREE(request, sizeof(*request)); -out_event: - OBD_FREE(event, sizeof(*event)); -out: - thread->t_flags = SVC_STOPPED; - wake_up(&thread->t_ctl_waitq); - - CDEBUG(D_NET, "service thread exiting, process %d: rc = %d\n", - current->pid, rc); - return rc; -} - -static void ptlrpc_stop_thread(struct ptlrpc_service *svc, - struct ptlrpc_thread *thread) -{ - spin_lock(&svc->srv_lock); - thread->t_flags = SVC_STOPPING; - spin_unlock(&svc->srv_lock); - - wake_up(&svc->srv_waitq); - wait_event(thread->t_ctl_waitq, (thread->t_flags & SVC_STOPPED)); -} - -void ptlrpc_stop_all_threads(struct ptlrpc_service *svc) -{ - spin_lock(&svc->srv_lock); - while (!list_empty(&svc->srv_threads)) { - struct ptlrpc_thread *thread; - thread = list_entry(svc->srv_threads.next, struct ptlrpc_thread, - t_link); - spin_unlock(&svc->srv_lock); - ptlrpc_stop_thread(svc, thread); - spin_lock(&svc->srv_lock); - list_del(&thread->t_link); - OBD_FREE(thread, sizeof(*thread)); - } - spin_unlock(&svc->srv_lock); -} - -int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc, - char *name) -{ - struct ptlrpc_svc_data d; - struct ptlrpc_thread *thread; - int rc; - ENTRY; - - OBD_ALLOC(thread, sizeof(*thread)); - if (thread == NULL) { - LBUG(); - RETURN(-ENOMEM); - } - init_waitqueue_head(&thread->t_ctl_waitq); - - d.dev = dev; - d.svc = svc; - d.name = name; - d.thread = thread; - - spin_lock(&svc->srv_lock); - list_add(&thread->t_link, &svc->srv_threads); - spin_unlock(&svc->srv_lock); - - rc = kernel_thread(ptlrpc_main, (void *) &d, CLONE_VM | CLONE_FILES); - if (rc < 0) { - CERROR("cannot start thread\n"); - OBD_FREE(thread, sizeof(*thread)); - RETURN(rc); - } - wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_RUNNING); - - RETURN(0); -} - -int ptlrpc_unregister_service(struct ptlrpc_service *service) -{ - int rc; - - LASSERT (list_empty (&service->srv_threads)); - - /* XXX We could reply (with failure) to all buffered requests - * _after_ unlinking _all_ the request buffers, but _before_ - * freeing them. - */ - - while (!list_empty (&service->srv_rqbds)) { - struct ptlrpc_request_buffer_desc *rqbd = - list_entry (service->srv_rqbds.next, - struct ptlrpc_request_buffer_desc, - rqbd_list); - - list_del (&rqbd->rqbd_list); - - LASSERT (atomic_read (&rqbd->rqbd_refcount) > 0); - /* refcount could be anything; it's possible for the - * buffers to continued to get filled after all the server - * threads exited. But we know they _have_ exited. - */ - - (void) PtlMEUnlink(rqbd->rqbd_me_h); - /* The callback handler could have unlinked this ME already - * (we're racing with her) but it's safe to ensure it _has_ - * been unlinked. - */ - - OBD_FREE (rqbd->rqbd_buffer, service->srv_buf_size); - OBD_FREE (rqbd, sizeof (*rqbd)); - service->srv_nrqbds--; - } - - LASSERT (service->srv_nrqbds == 0); - - rc = PtlEQFree(service->srv_eq_h); - if (rc) - CERROR("PtlEQFree failed: %d\n", rc); - - OBD_FREE(service, sizeof(*service)); - if (rc) - LBUG(); - return rc; -} diff --git a/lustre/scripts/.cvsignore b/lustre/scripts/.cvsignore deleted file mode 100644 index 104ddf7..0000000 --- a/lustre/scripts/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -.Xrefs -lustre.spec -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS diff --git a/lustre/scripts/Makefile.am b/lustre/scripts/Makefile.am deleted file mode 100644 index 199f5be..0000000 --- a/lustre/scripts/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -EXTRA_DIST = license-status maketags.sh lustre.spec version_tag.pl $(initd_SCRIPTS) -initddir = $(sysconfdir)/init.d -initd_SCRIPTS = lustre -include $(top_srcdir)/Rules - diff --git a/lustre/scripts/dodiff.sh b/lustre/scripts/dodiff.sh deleted file mode 100755 index 899415d..0000000 --- a/lustre/scripts/dodiff.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -for f in `cat $1` ; do - diff -u $2-pristine/$f $2/$f -done diff --git a/lustre/scripts/license-status b/lustre/scripts/license-status deleted file mode 100755 index 5407b91..0000000 --- a/lustre/scripts/license-status +++ /dev/null @@ -1,26 +0,0 @@ -#! /bin/sh -# license-status - Display the status of files in the current directory -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution -# -# Gordon Matzigkeit , 2001-09-27 - -for f in `find . -type f | sort`; do - case "$f" in - *~ | *.orig | *.gz | */config.* | *.o | \ - */CVS/* | */.cvsignore | */.depfiles/* | \ - */COPYING | */ChangeLog) - continue - ;; - esac - - if head -20 "$f" | egrep -e 'GNU' > /dev/null; then - echo "gpled $f" - elif head -20 "$f" | egrep -e '\([Cc]\)' > /dev/null; then - echo "copyrighted $f" - else - echo "bare $f" - fi -done | sort diff --git a/lustre/scripts/lustre b/lustre/scripts/lustre deleted file mode 100755 index b62dc4c..0000000 --- a/lustre/scripts/lustre +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/sh -# -# 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: lconf -# config: /etc/lustre/config.xml -# pidfile: /var/run/lustre.pid - -SERVICE=lustre -LOCK=/var/lock/subsys/$SERVICE - -: ${LUSTRE_CFG:=/etc/lustre/lustre.cfg} -[ -f ${LUSTRE_CFG} ] && . ${LUSTRE_CFG} - -: ${LUSTRE_CONFIG_XML:=/etc/lustre/config.xml} -: ${LCONF:=/usr/sbin/lconf} -: ${LCONF_START_ARGS:="${LUSTRE_CONFIG_XML}"} -: ${LCONF_STOP_ARGS:="--force --cleanup ${LUSTRE_CONFIG_XML}"} - -# 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 - -[ -x ${LCONF} -a -f ${LUSTRE_CONFIG_XML} ] || exit 0 - -start() { - echo -n "Starting $SERVICE: " - ${LCONF} ${LCONF_START_ARGS} - RETVAL=$? - echo $SERVICE - [ $RETVAL -eq 0 ] && touch $LOCK -} - -stop() { - echo -n "Shutting down $SERVICE: " - ${LCONF} ${LCONF_STOP_ARGS} - 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/lustre.spec.in b/lustre/scripts/lustre.spec.in deleted file mode 100644 index 2b5b786..0000000 --- a/lustre/scripts/lustre.spec.in +++ /dev/null @@ -1,128 +0,0 @@ -# lustre.spec -%define version HEAD -%define kversion @RELEASE@ -%define linuxdir @LINUX@ -%define portalsdir @PORTALS@ -%define portalslibdir @PORTALSLIB@ -Release: 0208282230chaos - -Summary: Lustre Lite File System -Name: lustre-lite -Version: %{version} -Copyright: GPL -Group: Utilities/System -Requires: lustre-modules, PyXML -BuildRoot: /var/tmp/lustre-%{version}-root -Source: ftp://ftp.lustre.com/pub/lustre/lustre-%{version}.tar.gz - -%description -The Lustre Lite Cluster File System: kernel drivers for file system, -servers and utilities. - -%package -n lustre-modules -Summary: Kernel Lustre drivers for Linux %{kversion} -Requires: portals-modules -Group: Development/Kernel - -%description -n lustre-modules -Lustre file System, server and network drivers for Linux %{kversion}. - -%package -n lustre-source -Summary: Object-Based Disk storage driver source -Group: Development/Kernel - -%description -n lustre-source -Lustre Lite Source for further development - -%package -n lustre-doc -Summary: Documentation and sample configuration files -Group: Documentation -# FIXME: BuildArch overrides all the packages in rpm 4.0.4-7x -#BuildArch: noarch - -%description -n lustre-doc -Documentation and sample configuration files for Lustre - -%prep -%setup -qn lustre-%{version} - -%build -rm -rf $RPM_BUILD_ROOT - -# Set an explicit path to our Linux tree, if we can. -./configure --with-linux='%{linuxdir}' --with-portals='%{portalsdir}' --with-portalslib='%{portalslibdir}' -make - -%install -make install prefix=$RPM_BUILD_ROOT - -# Create the pristine source directory. -mkdir -p $RPM_BUILD_ROOT/usr/src -rm -f lustre-source -ln -s $RPM_BUILD_ROOT/usr/src lustre-source -make distdir distdir=lustre-source/lustre-%{version} - -%files -%attr(-, root, root) /usr/sbin/lmc -%attr(-, root, root) /usr/sbin/lctl -%attr(-, root, root) /usr/sbin/lconf -%attr(-, root, root) /usr/lib/lustre/examples/llmount.sh -%attr(-, root, root) /usr/lib/lustre/examples/llmountcleanup.sh -%attr(-, root, root) /usr/lib/lustre/examples/llecho.sh -%attr(-, root, root) /usr/lib/lustre/examples/local.sh -%attr(-, root, root) /usr/lib/lustre/examples/uml.sh -%attr(-, root, root) /usr/lib/lustre/examples/lov.sh -%attr(-, root, root) /etc/init.d/lustre - -%files -n lustre-doc -%attr(-, root, root) %doc COPYING FDL -%attr(-, root, root) %doc doc/lustre.pdf doc/lustre-HOWTO.txt -%attr(-, root, root) %doc tests/client-echo.cfg tests/client-mount.cfg -%attr(-, root, root) %doc tests/client-mount2.cfg -%attr(-, root, root) %doc tests/elan-client.cfg tests/elan-server.cfg -%attr(-, root, root) %doc tests/ldlm.cfg tests/lustre.cfg -%attr(-, root, root) %doc tests/mds.cfg tests/net-client.cfg -%attr(-, root, root) %doc tests/net-local.cfg tests/net-server.cfg -%attr(-, root, root) %doc tests/obdecho.cfg tests/obdfilter.cfg - -%files -n lustre-modules -%attr(-, root, root) %doc COPYING -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/extN.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/ldlm.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/llite.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/mdc.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/mds.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/mds_extN.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/obdclass.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/obdecho.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/obdfilter.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/lov.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/osc.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/ost.o -%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/ptlrpc.o - -%files -n lustre-source -%attr(-, root, root) /usr/src/lustre-%{version} - -%post -if [ ! -e /dev/obd ]; then - mknod /dev/obd c 10 241 -fi -depmod -ae || exit 0 - -grep -q obdclass /etc/modules.conf || \ - echo 'alias char-major-10-241 obdclass' >> /etc/modules.conf - -grep -q '/dev/obd' /etc/modules.conf || \ - echo 'alias /dev/obd obdclass' >> /etc/modules.conf - -grep -q '/dev/lustre' /etc/modules.conf || \ - echo 'alias /dev/lustre obdclass' >> /etc/modules.conf - -%postun -depmod -ae || exit 0 - -%clean -#rm -rf $RPM_BUILD_ROOT - -# end of file 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 a92fef4..0000000 --- a/lustre/scripts/version_tag.pl +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/perl -# -*- Mode: perl; indent-tabs-mode: nil; cperl-indent-level: 4 -*- - -use strict; -use diagnostics; -use IO::File; -use Time::Local; - -my $pristine = 1; -my $kernver; - -sub get_tag() -{ - my $tag; - - my $tagfile = new IO::File; - if (!$tagfile->open("CVS/Tag")) { - return "HEAD"; - } else { - my $tmp = <$tagfile>; - $tagfile->close(); - - $tmp =~ m/T(.*)/; - return $1; - } -} - -sub get_latest_mtime() -{ - my %months=("Jan" => 0, "Feb" => 1, "Mar" => 2, "Apr" => 3, "May" => 4, - "Jun" => 5, "Jul" => 6, "Aug" => 7, "Sep" => 8, "Oct" => 9, - "Nov" => 10, "Dec" => 11); - - my $last_mtime = 0; - my @entries = `find . -name Entries`; - my $entry_file; - foreach $entry_file (@entries) { - chomp($entry_file); - my $entry = new IO::File; - if (!$entry->open($entry_file)) { - die "unable to open $entry_file: $!\n"; - } - my $line; - while (defined($line = <$entry>)) { - chomp($line); - #print "line: $line\n"; - my ($junk, $file, $version, $date) = split(/\//, $line); - - #print "junk: $junk\nfile: $file\nver: $version\ndate: $date\n"; - #print "last_mtime: " . localtime($last_mtime) . "\n"; - - if ($junk eq "D" || - $file eq "lustre.spec.in" || - $file !~ m/\.(c|h|am|in)$/) { - next; - } - - my $cur_dir = $entry_file; - $cur_dir =~ s/\/CVS\/Entries$//; - my @statbuf = stat("$cur_dir/$file"); - my $mtime = $statbuf[9]; - my $local_date = gmtime($mtime); - if ($local_date ne $date && - $file ne "lustre.spec.in") { - #print "$file : " . localtime($mtime) . "\n"; - $pristine = 0; - } - - if ($mtime > $last_mtime) { - $last_mtime = $mtime; - } - - if ($date) { - my @t = split(/ +/, $date); - if (int(@t) != 5) { - #print "skipping: $date\n"; - next; - } - my ($hours, $min, $sec) = split(/:/, $t[3]); - my ($mon, $mday, $year) = ($t[1], $t[2], $t[4]); - my $secs = 0; - $mon = $months{$mon}; - $secs = timelocal($sec, $min, $hours, $mday, $mon, $year); - if ($secs > $last_mtime) { - $last_mtime = $secs; - } - } - } - $entry->close(); - } - return $last_mtime; -} - -sub get_linuxdir() -{ - my $config = new IO::File; - my ($line, $dir); - if (!$config->open("Makefile")) { - die "Run ./configure first\n"; - } - while (defined($line = <$config>)) { - chomp($line); - if ($line =~ /LINUX = (.*)/) { - $dir = $1; - last; - } - } - $config->close(); - my $ver = new IO::File; - if (!$ver->open("$dir/include/linux/version.h")) { - die "Run make dep on $dir\n"; - } - while(defined($line = <$ver>)) { - $line =~ /\#define UTS_RELEASE "(.*)"/; - if ($1) { - $kernver = $1; - last; - } - } - $ver->close(); - chomp($kernver); - $dir =~ s/\//\./g; - return $dir; -} - -sub generate_ver($$$) -{ - my $tag = shift; - my $mtime = shift; - my $linuxdir = shift; - - #print "localtime: " . localtime($mtime) . "\n"; - - my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = - localtime($mtime); - $year += 1900; - $mon++; - my $show_last = sprintf("%04d%02d%02d%02d%02d%02d", $year, $mon, $mday, - $hour, $min, $sec); - - print "#define BUILD_VERSION \""; - if ($pristine) { - print "$tag-$show_last-PRISTINE-$linuxdir-$kernver\"\n"; - } else { - print "$tag-$show_last-CHANGED-$linuxdir-$kernver\"\n"; - } -} - -if ($ARGV[0]) { - chdir($ARGV[0]); -} -my $linuxdir = get_linuxdir(); -my $tag = get_tag(); -my $mtime = get_latest_mtime(); -generate_ver($tag, $mtime, $linuxdir); - -exit(0); diff --git a/lustre/tests/.cvsignore b/lustre/tests/.cvsignore deleted file mode 100644 index 5563923..0000000 --- a/lustre/tests/.cvsignore +++ /dev/null @@ -1,29 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS -openunlink -testreq -truncate -directio -openme -writeme -mcreate -munlink -tchmod -toexcl -fsx -test_brw -newfile -openclose -createdestroy -createmany -mkdirmany -lovstripe -*.xml -stat -setuid diff --git a/lustre/tests/Makefile.am b/lustre/tests/Makefile.am deleted file mode 100644 index f09b85c..0000000 --- a/lustre/tests/Makefile.am +++ /dev/null @@ -1,50 +0,0 @@ -# Lustre test Makefile -DEFS= -CPPFLAGS = -I. -I$(PORTALS)/include -I$(top_srcdir)/include -D_LARGEFILE64_SOURCE -CFLAGS := -g -Wall -# LDADD = -lldap -# LDADD := -lreadline -ltermcap # -lefence -EXTRA_DIST = $(pkgexample_SCRIPTS) $(noinst_SCRIPTS) $(noinst_DATA) \ - common.sh lustre.cfg \ - client-echo.cfg elan-server.cfg net-client.cfg obdecho.cfg \ - client-mount.cfg ldlm.cfg net-local.cfg obdfilter.cfg \ - client-mount2.cfg lustre.cfg net-server.cfg sanity.sh \ - rundbench \ - elan-client.cfg mds.cfg trivial.sh -pkgexampledir = '${exec_prefix}/usr/lib/$(PACKAGE)/examples' -pkgexample_SCRIPTS = llmount.sh llmountcleanup.sh llecho.sh local.sh uml.sh lov.sh -noinst_SCRIPTS = llsetup.sh llrsetup.sh llcleanup.sh -noinst_DATA = lustre.cfg -noinst_SCRIPTS += fs.sh intent-test.sh intent-test2.sh leak_finder.pl \ - lldlm.sh llecho.sh llext3.sh llmodules.sh llmount-client.sh \ - llmount-server.sh llmount.sh llmountcleanup.sh llrext3.sh \ - llrmount.sh llsimple.sh mdcreq.sh mdcreqcleanup.sh \ - ostreq.sh runfailure-client-mds-recover.sh runfailure-mds \ - runfailure-net runfailure-ost runiozone runregression-net.sh \ - runtests runvmstat snaprun.sh tbox.sh common.sh -noinst_PROGRAMS = openunlink testreq truncate directio openme writeme mcreate -noinst_PROGRAMS += munlink tchmod toexcl fsx test_brw openclose createdestroy -noinst_PROGRAMS += lovstripe stat createmany mkdirmany setuid # ldaptest - -# ldaptest_SOURCES = ldaptest.c -tchmod_SOURCES = tchmod.c -toexcl_SOURCES = toexcl.c -testreq_SOURCES = testreq.c -mcreate_SOURCES = mcreate.c -munlink_SOURCES = munlink.c -truncate_SOURCES = truncate.c -directio_SOURCES = directio.c -openunlink_SOURCES = openunlink.c -openme_SOURCES = openme.c -writeme_SOURCES = writeme.c -fsx_SOURCES = fsx.c -test_brw_SOURCES = test_brw.c -openclose_SOURCES = openclose.c -createdestroy_SOURCES = createdestroy.c -lovstripe_SOURCES = lovstripe.c -stat_SOURCES = stat.c -createmany_SOURCES = createmany.c -mkdirmany_SOURCES = mkdirmany.c -setuid_SOURCES = setuid.c - -include $(top_srcdir)/Rules diff --git a/lustre/tests/README b/lustre/tests/README deleted file mode 100644 index 00634a7..0000000 --- a/lustre/tests/README +++ /dev/null @@ -1,85 +0,0 @@ -1. How to build .xml configs: -The various .xml configs in the tests/ directory are built by running the -corresponding .sh script. The .sh script runs a series of lmc (Lustre make -config) commands in order to build up an XML file. It is much easier to -simply edit a .sh script and rebuild your XML config file than trying to -edit the XML directly. - -For a loopback setup with a mounted filesystem, you could do something like: - - sh local.sh - ../utils/lconf --reformat local.xml - -This will configure an MDS, an OBD/OST, and a filesystem client all running -on the same system and communicating over the TCP loopback interface. If -the --reformat option is given, then the OST and MDS devices will be -formatted. This is required the first time you set up the system, or if -you think you have corrupted the filesystems after you hit a bug. - -A more complex configuration, using a separate host for each of the MDS, -OBD/OST, and filesystem client functions is in uml.sh. It configures 3 -systems, and the OST system (uml2) serves up multiple OST devices, and -the client accesses these via a logical object volume (LOV) driver (which -essentially stripes both of the OST devices into a single storage device. - -This configuration could be run on any 3 systems with the following commands: - - sh uml.sh - system1# ../utils/lconf --reformat --node uml1 uml.xml - system2# ../utils/lconf --reformat --node uml2 uml.xml - system3# ../utils/lconf --node uml3 uml.xml - -The "--node " parameter tells lconf to use the configuration for -the node "name" in the XML configuration file. If the hostnames were -already "uml1", "uml2", and "uml3", then the "--node" parameter would -not need to be given. The internals of lconf and portals handle the -configuration details for setting up netowrking. - -2. runregression-net.sh and runregression-brw.sh - -This test performs raw block and attribute requests against a real or -"null" OST device. It is useful for generating isolated load on the -OST device, while avoiding the need to run tests through the filesystem. -This can be useful for testing the network part of Lustre in isolation, -or doing RPC and bulk I/O performance tests against an OST. - -If things are alright it goes through a series of tests single threaded, -multithreaded, using getattr and brw (both read and write, with single -page and vector I/O, doing basic data checking of each page). - -You can create a simple echo client by running the "llecho.sh" to -run the tests locally (over TCP loopback), or edit llecho.sh to -specify the SERVER and CLIENT names. You would then set up as normal: - - # if you are using a remote server, first run: - server# ../utils/lconf echo.xml - -Configure the client (or if you are running a single system only): - - client# ../utils/lconf echo.xml - client# sh runregression-net.sh - -3. runtests - -The runtests script does a series of simple file-based tests using a -filesystem. You need to have an XML file as appropriate for your setup -(one or more hosts, including an MDS, one or more OSTs, and a mountpoint). -If the MDS and/or OST is on a remote machine, configure them first: - - ../utils/lconf --reformat .xml - -On the client machine, the runtests script needs the XML configuration -file as a command-line parameter, as it mounts and unmounts the filesystem -several times during the test in order to verify that the data is still -there as expected (ensures that it makes it to disk instead of just into -the filesystem cache). If you are running on only a single machine, you -can just use runtests directly. If this is only a client machine, the ---reformat parameter is not needed (it will not do anything). - - sh runtests [--reformat] .xml - -This creates a few simple files and directories first, and then untars -a copy of the /etc filesystem into the Lustre filesystem. It then does -data verification both before and after the filesystem is remounted, and -finally deletes all of the files and verifies that the amount of space -left in the filesystem is (nearly) the same as it was before the test. diff --git a/lustre/tests/acceptance-small.sh b/lustre/tests/acceptance-small.sh deleted file mode 100755 index 06c4a84..0000000 --- a/lustre/tests/acceptance-small.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/sh -# script which _must_ complete successfully (at minimum) before checkins to -# the CVS HEAD are allowed. -set -vxe - -[ "$CONFIGS" ] || CONFIGS="local lov" -[ "$THREADS" ] || THREADS=1 -[ "$SIZE" ] || SIZE=20480 -[ "$RSIZE" ] || RSIZE=64 -[ "$UID" ] || UID=1000 -[ "$MNT" ] || MNT=/mnt/lustre -[ "$TMP" ] || TMP=/tmp -[ "$COUNT" ] || COUNT=1000 -[ "$DEBUG_OFF" ] || DEBUG_OFF="eval echo 0 > /proc/sys/portals/debug" - -for NAME in $CONFIGS; do - export NAME - [ -e $NAME.sh ] && sh $NAME.sh - [ ! -e $NAME.xml ] && echo "no config '$NAME.xml'" 1>&2 && exit 1 - - if [ "$RUNTESTS" != "no" ]; then - sh runtests - fi - - mount | grep $MNT || sh llmount.sh - [ "$SANITY" != "no" ] && sh sanity.sh - if [ "$DBENCH" != "no" ]; then - $DEBUG_OFF - sh rundbench 1 - sh llmountcleanup.sh - sh llrmount.sh - if [ $THREADS -gt 1 ]; then - sh rundbench $THREADS - sh llmountcleanup.sh - sh llrmount.sh - fi - rm -f /mnt/lustre/client.txt - fi - chown $UID $MNT && chmod 700 $MNT - if [ "$BONNIE" != "no" ]; then - $DEBUG_OFF - bonnie++ -s 0 -n 10 -u $UID -d $MNT - sh llmountcleanup.sh - sh llrmount.sh - fi - IOZONE_OPTS="-i 0 -i 1 -i 2 -+d -r $RSIZE -s $SIZE" - IOZONE_FILE="-f $MNT/iozone" - if [ "$IOZONE" != "no" ]; then - $DEBUG_OFF - iozone $IOZONE_OPTS $IOZONE_FILE - sh llmountcleanup.sh - sh llrmount.sh - fi - if [ "$IOZONE_DIR" != "no" ]; then - $DEBUG_OFF - iozone -I $IOZONE_OPTS $IOZONE_FILE.odir - IOZVER=`iozone -v | awk '/Revision:/ { print $3 }' | tr -d '.'` - sh llmountcleanup.sh - sh llrmount.sh - if [ "$THREADS" -gt 1 -a "$IOZVER" -ge 3145 ]; then - $DEBUG_OFF - THREAD=1 - IOZONE_FILE="-F " - SIZE=`expr $SIZE / $THREADS` - while [ $THREAD -le $THREADS ]; do - IOZONE_FILE="$IOZONE_FILE $MNT/iozone.$THREAD" - THREAD=`expr $THREAD + 1` - done - iozone -I $IOZONE_OPTS -t $THREADS $IOZONE_FILE - sh llmountcleanup.sh - sh llrmount.sh - elif [ $IOZVER -lt 3145 ]; then - VER=`iozone -v | awk '/Revision:/ { print $3 }'` - echo "iozone $VER too old for multi-threaded tests" - fi - fi - if [ "$FSX" != "no" ]; then - $DEBUG_OFF - ./fsx -c 50 -p 1000 -P $TMP -l 1024000 -N $(($COUNT * 100)) $MNT/fsxfile - sh llmountcleanup.sh - #sh llrmount.sh - fi - mount | grep $MNT && sh llmountcleanup.sh -done diff --git a/lustre/tests/ba-echo.sh b/lustre/tests/ba-echo.sh deleted file mode 100644 index a3b97cd..0000000 --- a/lustre/tests/ba-echo.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -config=${1:-ba-echo.xml} - -LMC="save_cmd" -LMC_REAL="../../lustre/utils/lmc -m $config" - -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 - -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 -${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 b81455f..0000000 --- a/lustre/tests/ba-mount.sh +++ /dev/null @@ -1,53 +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" - -TCPBUF=1048576 -OST=${OST:-ba-ost-1} -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 $MDS tcp -${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 -${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 -${LMC} --node client --mtpt /mnt/lustre mds1 OSC_$OST - -$LMC_REAL --batch $BATCH -rm -f $BATCH diff --git a/lustre/tests/client-echo.cfg b/lustre/tests/client-echo.cfg deleted file mode 100644 index 83856ec..0000000 --- a/lustre/tests/client-echo.cfg +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -# Config file for setting up a client to talk to an echo OST -SETUP_OSC=y 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/client-mount2.cfg b/lustre/tests/client-mount2.cfg deleted file mode 100644 index cb210c8..0000000 --- a/lustre/tests/client-mount2.cfg +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -# Config file for mounting a client Lustre filesystem -MDC_NAMES="MDCDEV1 MDCDEV2" -OSC_NAMES="OSCDEV1 OSCDEV2" -SETUP_MDC=y -SETUP_OSC=y -MT1="/mnt/lustre1 OSCDEV1 MDCDEV1" -MT2="/mnt/lustre2 OSCDEV2 MDCDEV2" -MOUNT_LIST="MT1 MT2" -SETUP_MOUNT=y diff --git a/lustre/tests/common.sh b/lustre/tests/common.sh deleted file mode 100644 index 34e3b83..0000000 --- a/lustre/tests/common.sh +++ /dev/null @@ -1,713 +0,0 @@ -#!/bin/sh -export PATH=$PATH:/sbin:/usr/sbin - -[ -d /r ] && R=/r - -# check if running in source directory -# will probably need to create variable for each module. -if [ -f $SRCDIR/Makefile.am ]; then - USEDEV=yes - PORTALS=$SRCDIR/../../portals - LUSTRE=$SRCDIR/.. - - PTLCTL=$LUSTRE/utils/lctl - DBGCTL=$LUSTRE/utils/lctl - ACCEPTOR=$PORTALS/linux/utils/acceptor - - OBDCTL=$LUSTRE/utils/lctl -else - USEDEV=no - # should have configure set the paths here - BINDIR=/usr/sbin - PORTALS=/lib/modules - LUSTRE=/lib/modules - - PTLCTL=$BINDIR/lctl - DBGCTL=$BINDIR/lctl - ACCEPTOR=$BINDIR/acceptor - OBDCTL=$BINDIR/lctl -fi - -LOOPNUM=0; export LOOPNUM -if [ -b /dev/loop0 ]; then - LOOP=/dev/loop -elif [ -b /dev/loop/0 ]; then - LOOP=/dev/loop/ -else - echo "Cannot find /dev/loop0 or /dev/loop/0" 1>&2 && exit -1 -fi - -do_insmod() { - MODULE=$1 - BASE=`echo $MODULE | sed -e "s^.*/^^" -e "s/\.o$//"` - - lsmod | grep -q "\<$BASE\>" && return 0 - [ "$MODULE" ] || fail "usage: $0 " - - if [ "$USEDEV" = "yes" ]; then - [ -f $MODULE ] || echo "$0: module '$MODULE' not found" 1>&2 - insmod $MODULE - else - modprobe $BASE - fi -} - -do_rmmod() { - MODULE=$1 - [ "$MODULE" ] || fail "usage: $0 " - lsmod | grep -q $MODULE || return 0 - rmmod $MODULE || lsmod | sed "s/^/$MODULE failed: /" -} - -# Return the next unused loop device on stdout and in the $LOOPDEV -# environment variable. -next_loop_dev() { - NEXT= - while [ -b ${LOOP}${LOOPNUM} ]; do - LOOPDEV=${LOOP}${LOOPNUM} - losetup ${LOOPDEV} > /dev/null 2>&1 || NEXT=${LOOPDEV} - LOOPNUM=`expr ${LOOPNUM} + 1` - [ "$NEXT" ] && echo ${NEXT} && break - done -} - -# Create a new filesystem. If we are using a loopback device, we check -# for existing "template" filesystems instead of creating a new one, -# because it is _much_ faster to gunzip the empty filesystem instead of -# creating a new one from scratch. Conversely, if we are creating a -# filesystem on a device we use mkfs, because that only writes sparsely -# to the device. The empty filesystems are also highly compressed (1000:1) -# so they don't take too much space. -# -new_fs_usage() { - echo "new_fs {device | file} [size]" 1>&2 - exit -1 -} -new_fs () { - EFILE="$1_$3.gz" - MKFS="mkfs.$1" - MKFSOPT="-b 4096" - - [ "$1" = "ext3" ] && MKFS="mkfs.ext2 -j" - if [ "$1" = "extN" ]; then - MKFS="mkfs.ext2 -j" - EFILE="ext3_$3.gz" - fi - - if [ -b "$2" ]; then - [ $# -lt 2 -o $# -gt 3 ] && new_fs_usage - - PM="/proc/mounts" - [ -r "$PM" ] || PM="/etc/mtab" - - grep "$2 " $PM 1>&2 && echo "$0: $2 is in $PM!" 1>&2 && exit -1 - - $MKFS $MKFSOPT $2 $3 || exit -1 - LOOPDEV=$2 # Not really a loop device - else - [ $# -ne 3 ] && new_fs_usage - - if [ -r "$EFILE" ]; then - echo "using prepared filesystem $EFILE for $2" - zcat "$EFILE" > $2 || exit -1 - sync - else - echo "creating new sparse filesystem on $2" - dd if=/dev/zero of=$2 bs=1k seek=$3 count=1 1>&2 || exit -1 - $MKFS $MKFSOPT -F $2 1>&2 || exit -1 - fi - LOOPDEV=`next_loop_dev` - losetup ${LOOPDEV} $2 1>&2 || exit -1 - fi - - # Enable hash-indexed directories for extN filesystems - [ "$1" = "extN" ] && echo "feature FEATURE_C5" | debugfs -w $2 -} - -# Set up to use an existing filesystem. We take the same parameters as -# new_fs, even though we only use the and parameters, to -# make it easy to convert between new_fs and old_fs in testing scripts. -old_fs () { - [ -e $2 ] || exit -1 - - if [ -b "$2" ]; then - LOOPDEV=$2 # Not really a loop device - else - LOOPDEV=`next_loop_dev` - losetup ${LOOPDEV} $2 1>&2 || exit -1 - fi -} - -list_mods() { - $DBGCTL modules > $R/tmp/ogdb - echo "The GDB module script is in $R/tmp/ogdb" - [ "$DEBUG_WAIT" = "yes" ] && echo -n "Press ENTER to continue" && read < /dev/tty - return 0 -} - -# start acceptor for a given network and port. -# not all networks need an acceptor -start_acceptor() { - case $NETWORK in - elan) [ "$PORT" ] && fail "$0: NETWORK is elan but PORT is set" - ;; - tcp) [ "$PORT" ] || fail "$0: NETWORK is tcp but PORT is not set" - $ACCEPTOR -r 1048576 -s 1048576 $PORT - ;; - *) fail "$0: unknown NETWORK '$NETWORK'" ;; - esac - -} - -# We need at least one setup file to be given. It can be passed on -# the command-line, or it can be found in the home directory, or it -# can even be sourced into the current shell environment. -setup_opts() { - DEF=/etc/lustre/lustre.cfg - if [ "$#" = 0 -a -r $DEF ]; then - . $DEF && SETUP=y - fi - - for CFG in "$@" ; do - case $CFG in - *.cfg) [ -r "$CFG" ] && . $CFG && SETUP=y ;; - *) echo "unknown option '$CFG'" 1>&2 - esac - done - - if [ "$SETUP" != "y" ]; then - echo "error: no config file on command-line and no $DEF" 1>&2 - exit -1 - fi - - [ "$MDC_NAMES" ] || export MDC_NAMES=MDCDEV - [ "$OSC_NAMES" ] || export OSC_NAMES=OSCDEV - [ -z "$MOUNT_LIST" -a "$OSCMT" ] && export MOUNT_LIST="MT" && export MT="$OSCMT OSCDEV MDCDEV" -} - -setup_variables() { - [ -z "$OSTNODE" ] && OSTNODE=$SERVER - [ -z "$MDSNODE" ] && MDSNODE=$SERVER - [ -z "$DLM" ] && DLM=$SERVER -} - -setup_portals() { - setup_variables - - if egrep -q "ksocknal|kqswnal" /proc/modules; then - echo "$0: portals already appears to be set up, skipping" - return 0 - fi - - if [ -z "$NETWORK" -o -z "$LOCALHOST" ]; then - echo "$0: NETWORK or LOCALHOST is not set" 1>&2 - exit -1 - fi - - if [ -z "$OSTNODE" -a -z "$MDSNODE" -a -z "$DLM" ]; then - echo "$0: SERVER (or OSTNODE and MDSNODE and DLM) not set" 1>&2 - exit -1 - fi - - [ -c /dev/portals ] || mknod /dev/portals c 10 240 - - do_insmod $PORTALS/linux/oslib/portals.o || exit -1 - #do_insmod $PORTALS/linux/router/kptlrouter.o || exit -1 - - case $NETWORK in - elan) do_insmod $PORTALS/linux/rqswnal/kqswnal.o || exit -1 - MYNID= - RECV_MEM= - SEND_MEM= - ;; - tcp) do_insmod $PORTALS/linux/socknal/ksocknal.o || exit -1 - MYNID="mynid $LOCALHOST" - RECV_MEM="recv_mem 1048576" - SEND_MEM="send_mem 1048576" - ;; - *) fail "$0: unknown NETWORK '$NETWORK'" ;; - esac - - start_acceptor - - $PTLCTL <<- EOF - network $NETWORK - $SEND_MEM - $RECV_MEM - $MYNID - connect $DLM $PORT - add_uuid $DLM $DLM - add_uuid self $LOCALHOST - quit - EOF - - if [ "$SETUP_MDS" -o "$SETUP_MDC" ]; then - $PTLCTL <<- EOF - network $NETWORK - connect $MDSNODE $PORT - add_uuid $MDSNODE $MDSNODE - quit - EOF - fi - - - if [ "$SETUP_OST" -o "$SETUP_OSC" ]; then - $PTLCTL <<- EOF - network $NETWORK - connect $OSTNODE $PORT - add_uuid $OSTNODE $OSTNODE - quit - EOF - fi -} - -setup_lustre() { - [ -c /dev/obd ] || mknod /dev/obd c 10 241 - - do_insmod $LUSTRE/obdclass/obdclass.o || exit -1 - do_insmod $LUSTRE/ptlrpc/ptlrpc.o || exit -1 - do_insmod $LUSTRE/ldlm/ldlm.o || exit -1 - do_insmod $LUSTRE/extN/extN.o || \ - echo "info: can't load extN.o module, not fatal if using ext3" - do_insmod $LUSTRE/mds/mds.o || exit -1 - #do_insmod $LUSTRE/mds/mds_ext2.o || exit -1 - #do_insmod $LUSTRE/mds/mds_ext3.o || exit -1 - do_insmod $LUSTRE/mds/mds_extN.o || \ - echo "info: can't load mds_extN.o module, needs extN.o" - do_insmod $LUSTRE/obdecho/obdecho.o || exit -1 - #do_insmod $LUSTRE/obdext2/obdext2.o || exit -1 - do_insmod $LUSTRE/obdfilter/obdfilter.o || exit -1 - do_insmod $LUSTRE/ost/ost.o || exit -1 - do_insmod $LUSTRE/osc/osc.o || exit -1 - do_insmod $LUSTRE/mdc/mdc.o || exit -1 - do_insmod $LUSTRE/lov/lov.o || exit -1 - do_insmod $LUSTRE/llite/llite.o || exit -1 - - echo "$R/tmp/lustre-log" > /proc/sys/portals/debug_path - - if $OBDCTL name2dev RPCDEV > /dev/null 2>&1; then - echo "$0: RPCDEV is already configured, skipping" - return 0 - fi - list_mods - - $OBDCTL <<- EOF || return $? - newdev - attach ptlrpc RPCDEV - setup - quit - EOF - - [ -d /mnt/lustre ] || mkdir /mnt/lustre -} - -setup_ldlm() { - [ "$SETUP_LDLM" = "y" ] || return 0 - - [ -c /dev/portals ] || mknod /dev/portals c 10 240 - - $OBDCTL <<- EOF || return $? - newdev - attach ldlm LDLMDEV LDLMUUID - setup - quit - EOF -} - -find_devno() { - if [ -z "$1" ]; then - echo "usage: $0 " 1>&2 - return -1 - fi - - $OBDCTL name2dev $1 -} - -setup_mds() { - [ "$SETUP_MDS" = "y" ] || return 0 - - if [ -z "$MDSFS" -o -z "$MDSDEV" ]; then - echo "error: setup_mds: MDSFS or MDSDEV unset" 1>&2 - return -1 - fi - - [ "$1" ] && DO_FS=$1 - if [ "$DO_FS" != "new_fs" -a "$DO_FS" != "old_fs" ]; then - echo "usage: setup_mds {new_fs|old_fs}" 1>&2 - return -1 - fi - - if $OBDCTL name2dev MDSDEV > /dev/null 2>&1; then - echo "$0: MDSDEV is already configured" - return 0 - fi - - $DO_FS ${MDSFS} ${MDSDEV} ${MDSSIZE} - MDS=${LOOPDEV} - - $OBDCTL <<- EOF || return $? - newdev - attach mds MDSDEV MDSUUID - setup ${MDS} ${MDSFS} - quit - EOF -} - -setup_mds_lov() { - [ "$SETUP_MDS" = "y" ] || return 0 - - if [ -z "$LOVUUID" ]; then - echo "No LOV configured" - return - fi - - $OBDCTL <<- EOF || return $? - name2dev MDSDEV - connect - lov_setconfig ${LOVUUID} 1 65536 0 OSCDEV-`hostname` - disconnect - quit - EOF -} - - -setup_ost() { - [ "$SETUP_OST" = "y" ] || return 0 - - if [ -z "$OSTTYPE" ]; then - echo "error: setup_ost: OSTTYPE unset" 1>&2 - return -1 - fi - - case $OSTTYPE in - obdecho) OBD= - OBDARG= - NEED_FS=n - ;; - obdext2) OBDARG= - NEED_FS=y - ;; - obdfilter) OBDARG=$OSTFS - NEED_FS=y - ;; - *) echo "error: setup_ost: unknown OSTTYPE '$OSTTYPE'" 1>&2 - return -1 - ;; - esac - - if $OBDCTL name2dev OBDDEV > /dev/null 2>&1; then - echo "$0: OBDDEV is already configured" - return 0 - fi - - if [ "$NEED_FS" = "y" ]; then - [ "$1" ] && DO_FS=$1 - if [ -z "$OSTFS" -o -z "$OSTDEV" ]; then - echo "error: setup_ost: OSTFS or OSTDEV unset" 1>&2 - return -1 - fi - - if [ "$DO_FS" != "new_fs" -a "$DO_FS" != "old_fs" ]; then - echo "usage: setup_ost {new_fs|old_fs}" 1>&2 - return -1 - fi - - $DO_FS ${OSTFS} ${OSTDEV} ${OSTSIZE} - OBD=${LOOPDEV} - fi - - $OBDCTL <<- EOF || return $? - newdev - attach ${OSTTYPE} OBDDEV OBDUUID - setup ${OBD} ${OBDARG} - quit - EOF - - $OBDCTL <<- EOF || return $? - newdev - attach ost OSTDEV OSTUUID - setup OBDUUID - quit - EOF -} - -setup_server() { - #setup_mds $1 && setup_mds_lov $1 && setup_ost $1 - setup_mds $1 && setup_ost $1 -} - -setup_osc() { - [ "$SETUP_OSC" != "y" ] && return 0 - [ "$OSC_NAMES" ] || OSC_NAMES=OSCDEV - - for THEOSC in $OSC_NAMES ; do - if $OBDCTL name2dev $THEOSC > /dev/null 2>&1; then - echo "$0: OSCDEV is already configured" - continue - fi - - [ -z "$OBD_UUID" ] && OBD_UUID="OBDUUID" - $OBDCTL <<- EOF || return $rc - newdev - attach osc $THEOSC ${THEOSC}-`hostname` - setup $OBD_UUID $OSTNODE - quit - EOF - done -} - -setup_mdc() { - [ "$SETUP_MDC" != "y" ] && return 0 - [ "$MDC_NAMES" ] || MDC_NAMES=MDCDEV - - for THEMDC in $MDC_NAMES ; do - if $OBDCTL name2dev $THEMDC > /dev/null 2>&1; then - echo "$0: MDCDEV is already configured" - continue - fi - - $OBDCTL <<- EOF || return $? - newdev - attach mdc $THEMDC ${THEMDC}-`hostname` - setup MDSUUID $MDSNODE - quit - EOF - done -} - -setup_lov () { - [ "$SETUP_MDC" != "y" ] && return 0 - - if [ -z "$LOVUUID" ]; then - echo "No LOV configured" - return - fi - - $OBDCTL <<- EOF || return $? - newdev - attach lov LOVNAME ${LOVUUID} - setup MDCDEV-`hostname` - quit - EOF -} - - -setup_mount() { - [ "$SETUP_MOUNT" != "y" ] && return 0 - - [ "$MOUNT_LIST" ] || fail "error: $0: MOUNT_LIST unset" - - for THEMOUNT in $MOUNT_LIST; do - eval "echo \$$THEMOUNT" | while read MTPT THEOSC THEMDC; do - if mount | grep -q $MTPT; then - echo "$0: $MTPT is already mounted" - return 0 - fi - - [ ! -d $MTPT ] && mkdir $MTPT - echo mount -t lustre_lite -o osc=${THEOSC}-`hostname`,mdc=${THEMDC}-`hostname` none $MTPT - mount -t lustre_lite -o osc=${THEOSC}-`hostname`,mdc=${THEMDC}-`hostname` none $MTPT - done - done -} - -setup_client() { - # setup_osc && setup_mdc && setup_lov && setup_mount - setup_osc && setup_mdc && setup_mount -} - -DEBUG_ON="echo 0xffffffff > /proc/sys/portals/debug" -DEBUG_OFF="echo 0 > /proc/sys/portals/debug" - -debug_server_off() { - echo "Turn OFF debug" && eval "$DEBUG_OFF" -} - -debug_server_on() { - echo "Turn ON debug" && eval "$DEBUG_ON" -} - -debug_client_off() { - echo "Turning OFF debug on client" && eval "$DEBUG_OFF" -} - -debug_client_on() { - echo "Turning ON debug on client" && eval "$DEBUG_ON" -} - -cleanup_portals() { - [ -z "$NETWORK" ] && NETWORK=tcp - - setup_variables - - $PTLCTL <<- EOF - network $NETWORK - disconnect - del_uuid self - del_uuid $MDSNODE - del_uuid $OSTNODE - del_uuid $DLM - quit - EOF - - do_rmmod ldlm - do_rmmod ptlrpc - do_rmmod obdclass - - do_rmmod kqswnal - do_rmmod ksocknal - do_rmmod kptlrouter - - [ "$TIME" ] && $DBGCTL debug_kernel $R/tmp/debug.5.$TIME - - do_rmmod portals -} - -cleanup_lustre() { - killall acceptor - - do_rmmod llite - do_rmmod lov - do_rmmod mdc - do_rmmod osc - - do_rmmod mds_extN - do_rmmod mds_ext3 - do_rmmod mds_ext2 - do_rmmod mds - do_rmmod ost - do_rmmod obdecho - do_rmmod obdfilter - do_rmmod obdext2 - do_rmmod extN - - losetup -d ${LOOP}0 - losetup -d ${LOOP}1 - losetup -d ${LOOP}2 -} - -cleanup_ldlm() { - [ "$SETUP" -a -z "$SETUP_LDLM" ] && return 0 - - LDLMDEVNO=`find_devno LDLMDEV` - if [ "$LDLMDEVNO" ]; then - $OBDCTL <<- EOF - device $LDLMDEVNO - cleanup - detach - quit - EOF - fi -} - -cleanup_mds() { - [ "$SETUP" -a -z "$SETUP_MDS" ] && return 0 - - MDSDEVNO=`find_devno MDSDEV` - if [ "$MDSDEVNO" ]; then - $OBDCTL <<- EOF - device $MDSDEVNO - cleanup - detach - quit - EOF - fi -} - -cleanup_ost() { - [ "$SETUP" -a -z "$SETUP_OST" ] && return 0 - - OSTDEVNO=`find_devno OSTDEV` - if [ "$OSTDEVNO" ]; then - $OBDCTL <<- EOF - device $OSTDEVNO - cleanup - detach - quit - EOF - fi - - OBDDEVNO=`find_devno OBDDEV` - if [ "$OBDDEVNO" ]; then - $OBDCTL <<- EOF - device $OBDDEVNO - cleanup - detach - quit - EOF - fi -} - -cleanup_server() { - cleanup_ost && cleanup_mds -} - -cleanup_mount() { - [ "$SETUP_MOUNT" != "y" ] && return 0 - - [ "$MOUNT_LIST" ] || fail "error: $0: MOUNT_LIST unset" - - for THEMOUNT in $MOUNT_LIST; do - eval "echo \$$THEMOUNT" | while read MTPT THEOSC THEMDC; do - if [ "`mount | grep $MTPT`" ]; then - umount $MTPT || fail "unable to unmount $MTPT" - fi - done - done -} - -cleanup_osc() { - [ "$SETUP" -a -z "$SETUP_OSC" ] && return 0 - [ "$OSC_NAMES" ] || OSC_NAMES=OSCDEV - - for THEOSC in $OSC_NAMES ; do - OSCDEVNO=`find_devno $THEOSC` - if [ "$OSCDEVNO" ]; then - $OBDCTL <<- EOF - device $OSCDEVNO - cleanup - detach - quit - EOF - fi - done -} - -cleanup_mdc() { - [ "$SETUP" -a -z "$SETUP_MDC" ] && return 0 - [ "$MDC_NAMES" ] || MDC_NAMES=MDCDEV - - for THEMDC in $MDC_NAMES ; do - MDCDEVNO=`find_devno $THEMDC` - if [ "$MDCDEVNO" ]; then - $OBDCTL <<- EOF - device $MDCDEVNO - cleanup - detach - quit - EOF - fi - done -} - -cleanup_rpc() { - RPCDEVNO=`find_devno RPCDEV` - if [ "$RPCDEVNO" ]; then - $OBDCTL <<- EOF - device $RPCDEVNO - cleanup - detach - quit - EOF - fi -} - -cleanup_client() { - cleanup_mount && cleanup_osc && cleanup_mdc && cleanup_rpc -} - -fail() { - echo "ERROR: $1" 1>&2 - [ $2 ] && RC=$2 || RC=1 - exit $RC -} diff --git a/lustre/tests/create.pl b/lustre/tests/create.pl deleted file mode 100644 index 341d31b..0000000 --- a/lustre/tests/create.pl +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/perl -use Getopt::Long; - -GetOptions("silent!"=> \$silent); - -my $mtpt = shift || usage(); -my $mount_count = shift || usage(); -my $i = shift || usage(); -my $files = 5; -my $mcreate = 0; # should we use mcreate or open? - -sub usage () { - print "Usage: $0 \n"; - print "example: $0 /mnt/lustre 2 50\n"; - print " will test in /mnt/lustre1 and /mnt/lustre2\n"; - print " $0 /mnt/lustre -1 50\n"; - print " will test in /mnt/lustre only\n"; - exit; -} - -sub do_open($) { - my $path = shift; - - if ($mcreate) { - my $tmp = `./mcreate $path`; - if ($tmp) { - print "Creating $path [" . $$."]...\n" if !$silent; - $tmp =~ /.*error: (.*)\n/; - print "Create done [$$] $path: $!\n" if !$silent; - } else { - print "Create done [$$] $path: Success\n"if !$silent; - } - } else { - print "Opening $path [" . $$."]...\n"if !$silent; - open(FH, ">$path") || die "open($PATH): $!"; - print "Open done [$$] $path: Success\n"if !$silent; - close(FH) || die; - } -} - -while ($i--) { - my $which = ""; - if ($mount_count > 0) { - $which = int(rand() * $mount_count) + 1; - } - $d = int(rand() * $files); - do_open("$mtpt$which/$d"); - - if ($mount_count > 0) { - $which = int(rand() * $mount_count) + 1; - } - $d = int(rand() * $files); - $path = "$mtpt$which/$d"; - print "Unlink $path start [" . $$."]...\n"if !$silent; - if (unlink($path)) { - print "Unlink done [$$] $path: Success\n"if !$silent; - } else { - print "Unlink done [$$] $path: $!\n"if !$silent; - } -} -print "Done.\n"; diff --git a/lustre/tests/createdestroy.c b/lustre/tests/createdestroy.c deleted file mode 100644 index f1e7f4b..0000000 --- a/lustre/tests/createdestroy.c +++ /dev/null @@ -1,224 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int thread; - -#define BAD_VERBOSE (-999999999) - -#define difftime(a, b) \ - ((double)(a)->tv_sec - (b)->tv_sec + \ - ((double)((a)->tv_usec - (b)->tv_usec) / 1000000)) - -static char *cmdname(char *func) -{ - static char buf[512]; - - if (thread) { - sprintf(buf, "%s-%d", func, thread); - return buf; - } - - return func; -} - -static int be_verbose(int verbose, struct timeval *next_time, - unsigned long num, unsigned long *next_num, int num_total) -{ - struct timeval now; - - if (!verbose) - return 0; - - if (next_time != NULL) - gettimeofday(&now, NULL); - - /* A positive verbosity means to print every X iterations */ - if (verbose > 0 && - (next_num == NULL || num >= *next_num || num >= num_total)) { - *next_num += verbose; - if (next_time) { - next_time->tv_sec = now.tv_sec - verbose; - next_time->tv_usec = now.tv_usec; - } - return 1; - } - - /* A negative verbosity means to print at most each X seconds */ - if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0){ - next_time->tv_sec = now.tv_sec - verbose; - next_time->tv_usec = now.tv_usec; - if (next_num) - *next_num = num; - return 1; - } - - return 0; -} - -static int get_verbose(char *func, const char *arg) -{ - int verbose; - char *end; - - if (!arg || arg[0] == 'v') - verbose = 1; - else if (arg[0] == 's' || arg[0] == 'q') - verbose = 0; - else { - verbose = (int)strtoul(arg, &end, 0); - if (*end) { - fprintf(stderr, "%s: error: bad verbose option '%s'\n", - func, arg); - return BAD_VERBOSE; - } - } - - if (verbose < 0) - printf("Print status every %d seconds\n", -verbose); - else if (verbose == 1) - printf("Print status every operation\n"); - else if (verbose > 1) - printf("Print status every %d operations\n", verbose); - - return verbose; -} - -int main(int argc, char *argv[]) -{ - char filename[1024]; - int verbose = 0; - unsigned long count, i; - int threads = 0; - char *end; - int rc; - - if (argc < 3 || argc > 5) { - fprintf(stderr, - "usage: %s [verbose [threads]]\n", - argv[0]); - exit(1); - } - - count = strtoul(argv[2], &end, 0); - if (*end) { - fprintf(stderr, "%s: error: bad iteration count '%s'\n", - argv[0], argv[1]); - exit(2); - } - if (argc == 4) { - verbose = get_verbose(argv[0], argv[3]); - if (verbose == BAD_VERBOSE) - exit(2); - } - if (argc == 5) { - threads = strtoul(argv[4], &end, 0); - if (*end) { - fprintf(stderr, "%s: error: bad thread count '%s'\n", - argv[0], argv[1]); - exit(2); - } - } - - for (i = 1; i <= threads; i++) { - rc = fork(); - if (rc < 0) { - fprintf(stderr, "%s: error: #%ld - %s\n", - cmdname(argv[0]), i, strerror(rc = errno)); - break; - } else if (rc == 0) { - thread = i; - break; - } else - printf("%s: thread #%ld (PID %d) started\n", - cmdname(argv[0]), i, rc); - rc = 0; - } - - if (threads && thread == 0) { /* parent process */ - int live_threads = threads; - - while (live_threads > 0) { - int status; - pid_t ret; - - ret = waitpid(0, &status, 0); - if (ret == 0) { - continue; - } - - if (ret < 0) { - fprintf(stderr, "%s: error: wait - %s\n", - argv[0], strerror(errno)); - if (!rc) - rc = errno; - } else { - /* - * This is a hack. We _should_ be able to use - * WIFEXITED(status) to see if there was an - * error, but it appears to be broken and it - * always returns 1 (OK). See wait(2). - */ - int err = WEXITSTATUS(status); - if (err || WIFSIGNALED(status)) - fprintf(stderr, - "%s: error: PID %d had rc=%d\n", - argv[0], ret, err); - if (!rc) - rc = err; - - live_threads--; - } - } - } else { - struct timeval start, end, next_time; - unsigned long next_count; - double diff; - - gettimeofday(&start, NULL); - next_time.tv_sec = start.tv_sec - verbose; - next_time.tv_usec = start.tv_usec; - - for (i = 0, next_count = verbose; i < count; i++) { - if (threads) - sprintf(filename, "%s-%d-%ld", - argv[1], thread, i); - else - sprintf(filename, "%s-%ld", argv[1], i); - - rc = mknod(filename, S_IFREG, 0); - if (rc < 0) { - fprintf(stderr, "%s: error: mknod(%s): %s\n", - cmdname(argv[0]), filename, - strerror(errno)); - rc = errno; - break; - } - if (unlink(filename) < 0) { - fprintf(stderr, "%s: error: unlink(%s): %s\n", - cmdname(argv[0]), filename, - strerror(errno)); - rc = errno; - break; - } - if (be_verbose(verbose, &next_time,i,&next_count,count)) - printf("%s: number %ld\n", cmdname(argv[0]), i); - } - - gettimeofday(&end, NULL); - diff = difftime(&end, &start); - - printf("%s: %ldx2 files in %.4gs (%.4g ops/s): rc = %d: %s", - cmdname(argv[0]), i, diff, (double)i * 2 / diff, - rc, ctime(&end.tv_sec)); - } - return rc; -} diff --git a/lustre/tests/createmany.c b/lustre/tests/createmany.c deleted file mode 100644 index 77015a6..0000000 --- a/lustre/tests/createmany.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#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; - } - if ((i % 10000) == 0) - printf(" - created %d (time %ld)\n", i, time(0)); - } - 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 120b605..0000000 --- a/lustre/tests/elan-client.cfg +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# Config file for setting up a remote server with a real OST -NETWORK=elan -LOCALHOST=5 -SERVER=4 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/ext2_10000.gz b/lustre/tests/ext2_10000.gz deleted file mode 100644 index e700ad021894b9a311eb82fd2870eb3c9cdc906d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10228 zcmb2|=HR%vaG?zob4dxqn;U!eSOO*39vG*qmaT1ZTO6b;6zI8a!R3I6H@qEQIgLS& zm|_}q&DS|UXA|L?8?@PRQEu%d7Dy(_#d2gn%aeCUM^)t?tJ2CuQz1xW+TvI)B z&-`!Zt>1p$@U+NXZkcZxuN`~+^-_UlPCpg7BX?b~x|gx#-ASwSI%RpU?Uq;8<$f#r z_bq8}QRP3Ay*qvuE&Ig4@Zs~U|Ic?$nRxC0e_ur{P6h@Bp1Ie{yFPOEuLrU}wD-Jv zxrnB!AVDZsDko(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7 zfzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@Rz!Cxt x+rK@S01|h&@c;Tg14b-LMukR0U^E0qLtr!nMnhn@gus4=%TYIi864&?007gFqXqx~ diff --git a/lustre/tests/ext2_25000.gz b/lustre/tests/ext2_25000.gz deleted file mode 100644 index 122ed792d8accfd9ecbcf02cec89ffe4acc137c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25136 zcmeI(-%Ha`7{~FWfsRTdkba{uqZ>oUqLirgBB>TMu>!M5Z$vV35xY<_S`BPER*NwN zEtv(eEpXwOl9f&(Rw27c=+|&gyKvyj<=8L7zD@s$ki9<_=kQz{&Us$f&nY&_WV>c< zM{+kbwP}?N%7Y4pLPP>bPrt1x%nMo0)znY4ZrfgcV!*A}-*p?^eHDhfcBfom4o&^`v z)*XMY2OXaaQ(f_9$IP_P4Zrqu0NVj{#aVdl4H9JakGJ9BBT~{iz-H-keKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0;re+sxF6L;3`H%nJb>`sCJ0tg_000IagfB*sr zAbs{bQetzbQvk+B(T_)RlZ-)0HfB*srAbh L_r^wH>&*EFvEw*O diff --git a/lustre/tests/ext3_10000.gz b/lustre/tests/ext3_10000.gz deleted file mode 100644 index b372fbdeaf91970c5b33eb16ade22e901894745b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12172 zcmeIzeNYo;8UXNAPQZakJIv`doMjwZJ;#e5r7Krxw2VC{dQl*fzy=bnD6-4PC@$1! zNExs3Ivk?s2W>2Z@|A?_rie>wAYkh$wTQJPyIbPL)N+dK3c|sP1d<%R|8C~~@y{FI z=bv|;d7pXTd4A73^F~*OhE`GM-dPZ|=fi`s;`Qt1L-6=6=DfV8;_CgH>WKVjq4_8N zc6xFCs+3hDFP~VGn0`7be^FD^!p6=-(TH3$QuI>OE?p>V=f(zoz3rD6?4DQys zMYb(C+)A-zlD37mkjSXF2$ylRM*mdj_s0e{X#%glHU31e+xaovCO4lEM$KOX;`s%x zs)gp0!FthKKJ|2n(9j(g(-HXE7!&R)sKjlbl^zv$xQ|G7FPuL(U{0Egm<-sGeFgrA z`TWRN;p=}jzwZ1`_GuvKmztWK*y+!cr_gcFk_G;*1n01C<^Ot0IxJzn`g!7+C$ndR zQHVCUzT9AvqU~N)p-SnTM*Cdm4x$jb>mtfi?=lfwGP!v)Gl9BIZXJa?sWE=Yn=+bq zm{yTxqq14LoF8!YEH(yl_1-LB*J5Hbdnewq*c!ur6K_6F>}G$ACyrYq*`<76eA_nj zDNccHsfAmp5iF@TD~}q)w$&-W&-C}ul+)~ zERL39CGK<^U5FiargS_j*Z~=Ix>oxXl^^d&7pik&GL!b%xJ2Yzu6Kf*v!k0B9BDb z*PJ!Tk0L^EeFgcu$dp8+Ax=?x1N8_>s>)ImZOCI$%ME-2nKRU{uzbR|(b<1wzF&CKURhYDWz7I|vb)zDK4+4L2-nnM|m(N;X7) z2$f4yBkA|}Glnl$m{QP7hOTZ{<~$8$NOK09mwD1aG+SRqZWv5^i7bRR;CroB=C@E@ ze?|%O4piK)@EB*%3iyj9=8w5^dzU>^AkO%Pe zRvIBSc$&uqp*Y;xt>m0`QiZFdoO&{?F#DXdnat8!H(15&EV-vJL&{NWiZA&}*IKJgJKFQA6>(^K+*`Mu= zYw$kyU-paTISM)h!*XN{jbU1MYL6+3Yqno0GAX$ZyJO6lz!CP&G1Fnr#&_DSW7ZJ% zD~<6rBANZ(tCh&BnMgiYlChnMVt@&UcK7dy zWquE#{qlB(L5~~SADXYA=MA=pt;Nnc@?CLe81*&Z4>vBsuOk!i#j}=TDxEwimi5sG z_))l9Zu~Xc1YePxGD4IC&+}t~S|9)ffB+Bx0zd!=00AHX1b_e#00KY&2mk>f00e*l z5C8%|00;m9AOHkj00BQP`NQkK^!f5sfQ$=&0XhaP0s$ZZ1b_e#00J+vz}&)}%Xj4n I-u+zgZ_NV*-2eap diff --git a/lustre/tests/fs.sh b/lustre/tests/fs.sh deleted file mode 100644 index b158c6e..0000000 --- a/lustre/tests/fs.sh +++ /dev/null @@ -1,27 +0,0 @@ -#! /bin/bash -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution -#!/bin/sh - -R=/r - -insmod /lib/modules/2.4.17/kernel/drivers/block/loop.o -dd if=/dev/zero of=/tmp/fs bs=1024 count=10000 -mke2fs -b 4096 -F /tmp/fs -losetup /dev/loop/0 /tmp/fs - -insmod $R/usr/src/lustre/obdclass/obdclass.o -insmod $R/usr/src/lustre/obdext2/obdext2.o -mknod /dev/obd c 10 241 - -$R/usr/src/lustre/utils/obdctl < -#include -#if defined(_UWIN) || defined(__linux__) -# include -# include -# include -# include -# include -#endif -#include -#include -#ifndef MAP_FILE -# define MAP_FILE 0 -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -#define NUMPRINTCOLUMNS 32 /* # columns of data to print on each line */ - -/* - * A log entry is an operation and a bunch of arguments. - */ - -struct log_entry { - int operation; - struct timeval tv; - int args[3]; -}; - -#define LOGSIZE 1000 - -struct log_entry oplog[LOGSIZE]; /* the log */ -int logptr = 0; /* current position in log */ -int logcount = 0; /* total ops */ - -/* - * Define operations - */ - -#define OP_READ 1 -#define OP_WRITE 2 -#define OP_TRUNCATE 3 -#define OP_CLOSEOPEN 4 -#define OP_MAPREAD 5 -#define OP_MAPWRITE 6 -#define OP_SKIPPED 7 - -int page_size; -int page_mask; - -char *original_buf; /* a pointer to the original data */ -char *good_buf; /* a pointer to the correct data */ -char *temp_buf; /* a pointer to the current data */ -char *fname; /* name of our test file */ -char logfile[1024]; /* name of our log file */ -char goodfile[1024]; /* name of our test file */ -int fd; /* fd for our test file */ - -off_t file_size = 0; -off_t biggest = 0; -char state[256]; -unsigned long testcalls = 0; /* calls to function "test" */ - -unsigned long simulatedopcount = 0; /* -b flag */ -int closeprob = 0; /* -c flag */ -int debug = 0; /* -d flag */ -unsigned long debugstart = 0; /* -D flag */ -unsigned long maxfilelen = 256 * 1024; /* -l flag */ -int sizechecks = 1; /* -n flag disables them */ -int maxoplen = 64 * 1024; /* -o flag */ -int quiet = 0; /* -q flag */ -unsigned long progressinterval = 0; /* -p flag */ -int readbdy = 1; /* -r flag */ -int style = 0; /* -s flag */ -int truncbdy = 1; /* -t flag */ -int writebdy = 1; /* -w flag */ -long monitorstart = -1; /* -m flag */ -long monitorend = -1; /* -m flag */ -int lite = 0; /* -L flag */ -long numops = -1; /* -N flag */ -int randomoplen = 1; /* -O flag disables it */ -int seed = 1; /* -S flag */ -int mapped_writes = 1; /* -W flag disables */ -int mapped_reads = 1; /* -R flag disables it */ -int fsxgoodfd = 0; -FILE * fsxlogf = NULL; -int badoff = -1; -int closeopen = 0; - - -void -vwarnc(code, fmt, ap) - int code; - const char *fmt; - va_list ap; -{ - fprintf(stderr, "fsx: "); - if (fmt != NULL) { - vfprintf(stderr, fmt, ap); - fprintf(stderr, ": "); - } - fprintf(stderr, "%s\n", strerror(code)); -} - - -void -warn(const char * fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vwarnc(errno, fmt, ap); - va_end(ap); -} - - -void -prt(char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vfprintf(stdout, fmt, args); - if (fsxlogf) - vfprintf(fsxlogf, fmt, args); - va_end(args); -} - -void -prterr(char *prefix) -{ - prt("%s%s%s\n", prefix, prefix ? ": " : "", strerror(errno)); -} - - -void -log4(int operation, int arg0, int arg1, int arg2, struct timeval *tv) -{ - struct log_entry *le; - - le = &oplog[logptr]; - le->tv = *tv; - le->operation = operation; - if (closeopen) - le->operation = ~ le->operation; - le->args[0] = arg0; - le->args[1] = arg1; - le->args[2] = arg2; - logptr++; - logcount++; - if (logptr >= LOGSIZE) - logptr = 0; -} - - -void -logdump(void) -{ - int i, count, down; - struct log_entry *lp; - - prt("LOG DUMP (%d total operations):\n", logcount); - if (logcount < LOGSIZE) { - i = 0; - count = logcount; - } else { - i = logptr; - count = LOGSIZE; - } - for ( ; count > 0; count--) { - int opnum; - - opnum = i+1 + (logcount/LOGSIZE)*LOGSIZE; - lp = &oplog[i]; - prt("%d(%d mod 256): %lu.%lu ", opnum, opnum%256, - lp->tv.tv_sec, lp->tv.tv_usec); - if ((closeopen = lp->operation < 0)) - lp->operation = ~ lp->operation; - - switch (lp->operation) { - case OP_MAPREAD: - prt("MAPREAD\t0x%x thru 0x%x\t(0x%x bytes)", - lp->args[0], lp->args[0] + lp->args[1] - 1, - lp->args[1]); - if (badoff >= lp->args[0] && badoff < - lp->args[0] + lp->args[1]) - prt("\t***RRRR***"); - break; - case OP_MAPWRITE: - prt("MAPWRITE 0x%x thru 0x%x\t(0x%x bytes)", - lp->args[0], lp->args[0] + lp->args[1] - 1, - lp->args[1]); - if (badoff >= lp->args[0] && badoff < - lp->args[0] + lp->args[1]) - prt("\t******WWWW"); - break; - case OP_READ: - prt("READ\t0x%x thru 0x%x\t(0x%x bytes)", - lp->args[0], lp->args[0] + lp->args[1] - 1, - lp->args[1]); - if (badoff >= lp->args[0] && - badoff < lp->args[0] + lp->args[1]) - prt("\t***RRRR***"); - break; - case OP_WRITE: - prt("WRITE\t0x%x thru 0x%x\t(0x%x bytes)", - lp->args[0], lp->args[0] + lp->args[1] - 1, - lp->args[1]); - if (lp->args[0] > lp->args[2]) - prt(" HOLE"); - else if (lp->args[0] + lp->args[1] > lp->args[2]) - prt(" EXTEND"); - if ((badoff >= lp->args[0] || badoff >=lp->args[2]) && - badoff < lp->args[0] + lp->args[1]) - prt("\t***WWWW"); - break; - case OP_TRUNCATE: - down = lp->args[0] < lp->args[1]; - prt("TRUNCATE %s\tfrom 0x%x to 0x%x", - down ? "DOWN" : "UP", lp->args[1], lp->args[0]); - if (badoff >= lp->args[!down] && - badoff < lp->args[!!down]) - prt("\t******WWWW"); - break; - case OP_SKIPPED: - prt("SKIPPED (no operation)"); - break; - default: - prt("BOGUS LOG ENTRY (operation code = %d)!", - lp->operation); - } - if (closeopen) - prt("\n\t\tCLOSE/OPEN"); - prt("\n"); - i++; - if (i == LOGSIZE) - i = 0; - } -} - - -void -save_buffer(char *buffer, off_t bufferlength, int fd) -{ - off_t ret; - ssize_t byteswritten; - - if (fd <= 0 || bufferlength == 0) - return; - - if (bufferlength > SSIZE_MAX) { - prt("fsx flaw: overflow in save_buffer\n"); - exit(67); - } - if (lite) { - off_t size_by_seek = lseek(fd, (off_t)0, SEEK_END); - if (size_by_seek == (off_t)-1) - prterr("save_buffer: lseek eof"); - else if (bufferlength > size_by_seek) { - warn("save_buffer: .fsxgood file too short... will -save 0x%llx bytes instead of 0x%llx\n", (unsigned long long)size_by_seek, - (unsigned long long)bufferlength); - bufferlength = size_by_seek; - } - } - - ret = lseek(fd, (off_t)0, SEEK_SET); - if (ret == (off_t)-1) - prterr("save_buffer: lseek 0"); - - byteswritten = write(fd, buffer, (size_t)bufferlength); - if (byteswritten != bufferlength) { - if (byteswritten == -1) - prterr("save_buffer write"); - else - warn("save_buffer: short write, 0x%x bytes instead -of 0x%llx\n", - (unsigned)byteswritten, - (unsigned long long)bufferlength); - } -} - - -void -report_failure(int status) -{ - logdump(); - - if (fsxgoodfd) { - if (good_buf) { - save_buffer(good_buf, file_size, fsxgoodfd); - prt("Correct content saved for comparison\n"); - prt("(maybe hexdump \"%s\" vs \"%s\")\n", - fname, goodfile); - } - close(fsxgoodfd); - } - exit(status); -} - - -#define short_at(cp) ((unsigned short)((*((unsigned char *)(cp)) << 8) | \ - *(((unsigned char *)(cp)) + 1))) - -void -check_buffers(unsigned offset, unsigned size) -{ - unsigned char c, t; - unsigned i = 0; - unsigned n = 0; - unsigned op = 0; - unsigned bad = 0; - - if (memcmp(good_buf + offset, temp_buf, size) != 0) { - prt("READ BAD DATA: offset = 0x%x, size = 0x%x\n", - offset, size); - prt("OFFSET\tGOOD\tBAD\tRANGE\n"); - while (size > 0) { - c = good_buf[offset]; - t = temp_buf[i]; - if (c != t) { - if (n == 0) { - bad = short_at(&temp_buf[i]); - prt("0x%5x\t0x%04x\t0x%04x", offset, - short_at(&good_buf[offset]), bad); - op = temp_buf[offset & 1 ? i+1 : i]; - } - n++; - badoff = offset; - } - offset++; - i++; - size--; - } - if (n) { - prt("\t0x%5x\n", n); - if (bad) - prt("operation# (mod 256) for the bad data -may be %u\n", ((unsigned)op & 0xff)); - else - prt("operation# (mod 256) for the bad data -unknown, check HOLE and EXTEND ops\n"); - } else - prt("????????????????\n"); - report_failure(110); - } -} - - -void -check_size(void) -{ - struct stat statbuf; - off_t size_by_seek; - - if (fstat(fd, &statbuf)) { - prterr("check_size: fstat"); - statbuf.st_size = -1; - } - size_by_seek = lseek(fd, (off_t)0, SEEK_END); - if (file_size != statbuf.st_size || file_size != size_by_seek) { - prt("Size error: expected 0x%llx stat 0x%llx seek 0x%llx\n", - (unsigned long long)file_size, - (unsigned long long)statbuf.st_size, - (unsigned long long)size_by_seek); - report_failure(120); - } -} - - -void -check_trunc_hack(void) -{ - struct stat statbuf; - - ftruncate(fd, (off_t)0); - ftruncate(fd, (off_t)100000); - fstat(fd, &statbuf); - if (statbuf.st_size != (off_t)100000) { - prt("no extend on truncate! not posix!\n"); - exit(130); - } - ftruncate(fd, 0); -} - - -void -doread(unsigned offset, unsigned size) -{ - struct timeval t; - off_t ret; - unsigned iret; - - offset -= offset % readbdy; - gettimeofday(&t, NULL); - if (size == 0) { - if (!quiet && testcalls > simulatedopcount) - prt("skipping zero size read\n"); - log4(OP_SKIPPED, OP_READ, offset, size, &t); - return; - } - if (size + offset > file_size) { - if (!quiet && testcalls > simulatedopcount) - prt("skipping seek/read past end of file\n"); - log4(OP_SKIPPED, OP_READ, offset, size, &t); - return; - } - - log4(OP_READ, offset, size, 0, &t); - - if (testcalls <= simulatedopcount) - return; - - if (!quiet && ((progressinterval && - testcalls % progressinterval == 0) || - (debug && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend)))))) - prt("%lu %lu.%lu read\t0x%x thru\t0x%x\t(0x%x bytes)\n", - testcalls, t.tv_sec, t.tv_usec, offset, offset + size - 1, - size); - ret = lseek(fd, (off_t)offset, SEEK_SET); - if (ret == (off_t)-1) { - prterr("doread: lseek"); - report_failure(140); - } - iret = read(fd, temp_buf, size); - if (iret != size) { - if (iret == -1) - prterr("doread: read"); - else - prt("short read: 0x%x bytes instead of 0x%x\n", - iret, size); - report_failure(141); - } - check_buffers(offset, size); -} - - -void -domapread(unsigned offset, unsigned size) -{ - struct timeval t; - unsigned pg_offset; - unsigned map_size; - char *p; - - offset -= offset % readbdy; - gettimeofday(&t, NULL); - if (size == 0) { - if (!quiet && testcalls > simulatedopcount) - prt("skipping zero size read\n"); - log4(OP_SKIPPED, OP_MAPREAD, offset, size, &t); - return; - } - if (size + offset > file_size) { - if (!quiet && testcalls > simulatedopcount) - prt("skipping seek/read past end of file\n"); - log4(OP_SKIPPED, OP_MAPREAD, offset, size, &t); - return; - } - - log4(OP_MAPREAD, offset, size, 0, &t); - - if (testcalls <= simulatedopcount) - return; - - if (!quiet && ((progressinterval && - testcalls % progressinterval == 0) || - (debug && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend)))))) - prt("%lu %lu.%lu mapread\t0x%x thru\t0x%x\t(0x%x bytes)\n", - testcalls, t.tv_sec, t.tv_usec, offset, offset + size - 1, - size); - - pg_offset = offset & page_mask; - map_size = pg_offset + size; - - if ((p = (char *)mmap(0, map_size, PROT_READ, MAP_FILE | MAP_SHARED, fd, - (off_t)(offset - pg_offset))) == (char *)-1) { - prterr("domapread: mmap"); - report_failure(190); - } - memcpy(temp_buf, p + pg_offset, size); - if (munmap(p, map_size) != 0) { - prterr("domapread: munmap"); - report_failure(191); - } - - check_buffers(offset, size); -} - - -void -gendata(char *original_buf, char *good_buf, unsigned offset, unsigned size) -{ - while (size--) { - good_buf[offset] = testcalls % 256; - if (offset % 2) - good_buf[offset] += original_buf[offset]; - offset++; - } -} - - -void -dowrite(unsigned offset, unsigned size) -{ - struct timeval t; - off_t ret; - unsigned iret; - - offset -= offset % writebdy; - gettimeofday(&t, NULL); - if (size == 0) { - if (!quiet && testcalls > simulatedopcount) - prt("skipping zero size write\n"); - log4(OP_SKIPPED, OP_WRITE, offset, size, &t); - return; - } - - log4(OP_WRITE, offset, size, file_size, &t); - - gendata(original_buf, good_buf, offset, size); - if (file_size < offset + size) { - if (file_size < offset) - memset(good_buf + file_size, '\0', offset - file_size); - file_size = offset + size; - if (lite) { - warn("Lite file size bug in fsx!"); - report_failure(149); - } - } - - if (testcalls <= simulatedopcount) - return; - - if (!quiet && ((progressinterval && - testcalls % progressinterval == 0) || - (debug && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend)))))) - prt("%lu %lu.%lu write\t0x%x thru\t0x%x\t(0x%x bytes)\n", - testcalls, t.tv_sec, t.tv_usec, offset, offset + size - 1, - size); - ret = lseek(fd, (off_t)offset, SEEK_SET); - if (ret == (off_t)-1) { - prterr("dowrite: lseek"); - report_failure(150); - } - iret = write(fd, good_buf + offset, size); - if (iret != size) { - if (iret == -1) - prterr("dowrite: write"); - else - prt("short write: 0x%x bytes instead of 0x%x\n", - iret, size); - report_failure(151); - } -} - - -void -domapwrite(unsigned offset, unsigned size) -{ - struct timeval t; - unsigned pg_offset; - unsigned map_size; - off_t cur_filesize; - char *p; - - offset -= offset % writebdy; - gettimeofday(&t, NULL); - if (size == 0) { - if (!quiet && testcalls > simulatedopcount) - prt("skipping zero size write\n"); - log4(OP_SKIPPED, OP_MAPWRITE, offset, size, &t); - return; - } - cur_filesize = file_size; - - log4(OP_MAPWRITE, offset, size, 0, &t); - - gendata(original_buf, good_buf, offset, size); - if (file_size < offset + size) { - if (file_size < offset) - memset(good_buf + file_size, '\0', offset - file_size); - file_size = offset + size; - if (lite) { - warn("Lite file size bug in fsx!"); - report_failure(200); - } - } - - if (testcalls <= simulatedopcount) - return; - - if (!quiet && ((progressinterval && - testcalls % progressinterval == 0) || - (debug && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend)))))) - prt("%lu %lu.%lu mapwrite\t0x%x thru\t0x%x\t(0x%x bytes)\n", - testcalls, t.tv_sec, t.tv_usec, offset, offset + size - 1, - size); - - if (file_size > cur_filesize) { - if (ftruncate(fd, file_size) == -1) { - prterr("domapwrite: ftruncate"); - exit(201); - } - } - pg_offset = offset & page_mask; - map_size = pg_offset + size; - - if ((p = (char *)mmap(0, map_size, PROT_READ | PROT_WRITE, - MAP_FILE | MAP_SHARED, fd, - (off_t)(offset - pg_offset))) == (char *)-1) { - prterr("domapwrite: mmap"); - report_failure(202); - } - memcpy(p + pg_offset, good_buf + offset, size); - if (msync(p, map_size, 0) != 0) { - prterr("domapwrite: msync"); - report_failure(203); - } - if (munmap(p, map_size) != 0) { - prterr("domapwrite: munmap"); - report_failure(204); - } -} - - -void -dotruncate(unsigned size) -{ - struct timeval t; - int oldsize = file_size; - - size -= size % truncbdy; - gettimeofday(&t, NULL); - if (size > biggest) { - biggest = size; - if (!quiet && testcalls > simulatedopcount) - prt("truncating to largest ever: 0x%x\n", size); - } - - log4(OP_TRUNCATE, size, (unsigned)file_size, 0, &t); - - if (size > file_size) - memset(good_buf + file_size, '\0', size - file_size); - file_size = size; - - if (testcalls <= simulatedopcount) - return; - - if ((progressinterval && testcalls % progressinterval == 0) || - (debug && (monitorstart == -1 || monitorend == -1 || - size <= monitorend))) - prt("%lu %lu.%lu trunc\tfrom 0x%x to 0x%x\n", - testcalls, t.tv_sec, t.tv_usec, oldsize, size); - if (ftruncate(fd, (off_t)size) == -1) { - prt("ftruncate1: %x\n", size); - prterr("dotruncate: ftruncate"); - report_failure(160); - } -} - - -void -writefileimage() -{ - ssize_t iret; - - if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) { - prterr("writefileimage: lseek"); - report_failure(171); - } - iret = write(fd, good_buf, file_size); - if ((off_t)iret != file_size) { - if (iret == -1) - prterr("writefileimage: write"); - else - prt("short write: 0x%x bytes instead of 0x%llx\n", - iret, (unsigned long long)file_size); - report_failure(172); - } - if (lite ? 0 : ftruncate(fd, file_size) == -1) { - prt("ftruncate2: %llx\n", (unsigned long long)file_size); - prterr("writefileimage: ftruncate"); - report_failure(173); - } -} - - -void -docloseopen(void) -{ - struct timeval t; - - if (testcalls <= simulatedopcount) - return; - - log4(OP_CLOSEOPEN, file_size, (unsigned)file_size, 0, &t); - - gettimeofday(&t, NULL); - if (debug) - prt("%lu %lu.%lu close/open\n", testcalls, t.tv_sec, t.tv_usec); - if (close(fd)) { - prterr("docloseopen: close"); - report_failure(180); - } - fd = open(fname, O_RDWR, 0); - if (fd < 0) { - prterr("docloseopen: open"); - report_failure(181); - } -} - - -void -test(void) -{ - unsigned long offset; - unsigned long size = maxoplen; - unsigned long rv = random(); - unsigned long op = rv % (3 + !lite + mapped_writes); - - /* turn off the map read if necessary */ - - if (op == 2 && !mapped_reads) - op = 0; - - if (simulatedopcount > 0 && testcalls == simulatedopcount) - writefileimage(); - - testcalls++; - - if (closeprob) - closeopen = (rv >> 3) < (1 << 28) / closeprob; - - if (debugstart > 0 && testcalls >= debugstart) - debug = 1; - - if (!quiet && testcalls < simulatedopcount && testcalls % 100000 == 0) - prt("%lu...\n", testcalls); - - /* - * READ: op = 0 - * WRITE: op = 1 - * MAPREAD: op = 2 - * TRUNCATE: op = 3 - * MAPWRITE: op = 3 or 4 - */ - if (lite ? 0 : op == 3 && (style & 1) == 0) /* vanilla truncate? */ - dotruncate(random() % maxfilelen); - else { - if (randomoplen) - size = random() % (maxoplen+1); - if (lite ? 0 : op == 3) - dotruncate(size); - else { - offset = random(); - if (op == 1 || op == (lite ? 3 : 4)) { - offset %= maxfilelen; - if (offset + size > maxfilelen) - size = maxfilelen - offset; - if (op != 1) - domapwrite(offset, size); - else - dowrite(offset, size); - } else { - if (file_size) - offset %= file_size; - else - offset = 0; - if (offset + size > file_size) - size = file_size - offset; - if (op != 0) - domapread(offset, size); - else - doread(offset, size); - } - } - } - if (sizechecks && testcalls > simulatedopcount) - check_size(); - if (closeopen) - docloseopen(); -} - - -void -cleanup(sig) - int sig; -{ - if (sig) - prt("signal %d\n", sig); - prt("testcalls = %lu\n", testcalls); - exit(sig); -} - - -void -usage(void) -{ - fprintf(stdout, "usage: %s", - "fsx [-dnqLOW] [-b opnum] [-c Prob] [-l flen] [-m -start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t -truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] -fname\n\ - -b opnum: beginning operation number (default 1)\n\ - -c P: 1 in P chance of file close+open at each op (default infinity)\n\ - -d: debug output for all operations\n\ - -l flen: the upper bound on file size (default 262144)\n\ - -m startop:endop: monitor (print debug output) specified byte range -(default 0:infinity)\n\ - -n: no verifications of file size\n\ - -o oplen: the upper bound on operation size (default 65536)\n\ - -p progressinterval: debug output at specified operation interval\n\ - -q: quieter operation\n\ - -r readbdy: 4096 would make reads page aligned (default 1)\n\ - -s style: 1 gives smaller truncates (default 0)\n\ - -t truncbdy: 4096 would make truncates page aligned (default 1)\n\ - -w writebdy: 4096 would make writes page aligned (default 1)\n\ - -D startingop: debug output starting at specified operation\n\ - -L: fsxLite - no file creations & no file size changes\n\ - -N numops: total # operations to do (default infinity)\n\ - -O: use oplen (see -o flag) for every op (default random)\n\ - -P: save .fsxlog and .fsxgood files in dirpath (default ./)\n\ - -S seed: for random # generator (default 1) 0 gets timestamp\n\ - -W: mapped write operations DISabled\n\ - -R: read() system calls only (mapped reads disabled)\n\ - fname: this filename is REQUIRED (no default)\n"); - exit(90); -} - - -int -getnum(char *s, char **e) -{ - int ret = -1; - - *e = (char *) 0; - ret = strtol(s, e, 0); - if (*e) - switch (**e) { - case 'b': - case 'B': - ret *= 512; - *e = *e + 1; - break; - case 'k': - case 'K': - ret *= 1024; - *e = *e + 1; - break; - case 'm': - case 'M': - ret *= 1024*1024; - *e = *e + 1; - break; - case 'w': - case 'W': - ret *= 4; - *e = *e + 1; - break; - } - return (ret); -} - - -static const char *basename(const char *path) -{ - char *c = strrchr(path, '/'); - - return c ? c++ : path; -} - -int -main(int argc, char **argv) -{ - int i, style, ch; - char *endp; - int dirpath = 0; - - goodfile[0] = 0; - logfile[0] = 0; - - page_size = getpagesize(); - page_mask = page_size - 1; - - setvbuf(stdout, (char *)0, _IOLBF, 0); /* line buffered stdout */ - - while ((ch = getopt(argc, argv, "b:c:dl:m:no:p:qr:s:t:w:D:LN:OP:RS:W")) - != EOF) - switch (ch) { - case 'b': - simulatedopcount = getnum(optarg, &endp); - if (!quiet) - fprintf(stdout, "Will begin at operation -%ld\n", - simulatedopcount); - if (simulatedopcount == 0) - usage(); - simulatedopcount -= 1; - break; - case 'c': - closeprob = getnum(optarg, &endp); - if (!quiet) - fprintf(stdout, - "Chance of close/open is 1 in %d\n", - closeprob); - if (closeprob <= 0) - usage(); - break; - case 'd': - debug = 1; - break; - case 'l': - maxfilelen = getnum(optarg, &endp); - if (maxfilelen <= 0) - usage(); - break; - case 'm': - monitorstart = getnum(optarg, &endp); - if (monitorstart < 0) - usage(); - if (!endp || *endp++ != ':') - usage(); - monitorend = getnum(endp, &endp); - if (monitorend < 0) - usage(); - if (monitorend == 0) - monitorend = -1; /* aka infinity */ - debug = 1; - case 'n': - sizechecks = 0; - break; - case 'o': - maxoplen = getnum(optarg, &endp); - if (maxoplen <= 0) - usage(); - break; - case 'p': - progressinterval = getnum(optarg, &endp); - if (progressinterval < 0) - usage(); - break; - case 'q': - quiet = 1; - break; - case 'r': - readbdy = getnum(optarg, &endp); - if (readbdy <= 0) - usage(); - break; - case 's': - style = getnum(optarg, &endp); - if (style < 0 || style > 1) - usage(); - break; - case 't': - truncbdy = getnum(optarg, &endp); - if (truncbdy <= 0) - usage(); - break; - case 'w': - writebdy = getnum(optarg, &endp); - if (writebdy <= 0) - usage(); - break; - case 'D': - debugstart = getnum(optarg, &endp); - if (debugstart < 1) - usage(); - break; - case 'L': - lite = 1; - break; - case 'N': - numops = getnum(optarg, &endp); - if (numops < 0) - usage(); - break; - case 'O': - randomoplen = 0; - break; - case 'P': - strncpy(goodfile, optarg, sizeof(goodfile)); - strcat(goodfile, "/"); - strncpy(logfile, optarg, sizeof(logfile)); - strcat(logfile, "/"); - dirpath = 1; - break; - case 'R': - mapped_reads = 0; - break; - case 'S': - seed = getnum(optarg, &endp); - if (seed == 0) - seed = time(0) % 10000; - if (!quiet) - fprintf(stdout, "Seed set to %d\n", seed); - if (seed < 0) - usage(); - break; - case 'W': - mapped_writes = 0; - if (!quiet) - fprintf(stdout, "mapped writes DISABLED\n"); - break; - - default: - usage(); - /* NOTREACHED */ - } - argc -= optind; - argv += optind; - if (argc != 1) - usage(); - fname = argv[0]; - - signal(SIGHUP, cleanup); - signal(SIGINT, cleanup); - signal(SIGPIPE, cleanup); - signal(SIGALRM, cleanup); - signal(SIGTERM, cleanup); - signal(SIGXCPU, cleanup); - signal(SIGXFSZ, cleanup); - signal(SIGVTALRM, cleanup); - signal(SIGUSR1, cleanup); - signal(SIGUSR2, cleanup); - - initstate(seed, state, 256); - setstate(state); - fd = open(fname, O_RDWR|(lite ? 0 : O_CREAT|O_TRUNC), 0666); - if (fd < 0) { - prterr(fname); - exit(91); - } - strncat(goodfile, dirpath ? basename(fname) : fname, 256); - strcat (goodfile, ".fsxgood"); - fsxgoodfd = open(goodfile, O_RDWR|O_CREAT|O_TRUNC, 0666); - if (fsxgoodfd < 0) { - prterr(goodfile); - exit(92); - } - strncat(logfile, dirpath ? basename(fname) : fname, 256); - strcat (logfile, ".fsxlog"); - fsxlogf = fopen(logfile, "w"); - if (fsxlogf == NULL) { - prterr(logfile); - exit(93); - } - if (lite) { - off_t ret; - file_size = maxfilelen = lseek(fd, (off_t)0, SEEK_END); - if (file_size == (off_t)-1) { - prterr(fname); - warn("main: lseek eof"); - exit(94); - } - ret = lseek(fd, (off_t)0, SEEK_SET); - if (ret == (off_t)-1) { - prterr(fname); - warn("main: lseek 0"); - exit(95); - } - } - original_buf = (char *) malloc(maxfilelen); - for (i = 0; i < maxfilelen; i++) - original_buf[i] = random() % 256; - good_buf = (char *) malloc(maxfilelen); - memset(good_buf, '\0', maxfilelen); - temp_buf = (char *) malloc(maxoplen); - memset(temp_buf, '\0', maxoplen); - if (lite) { /* zero entire existing file */ - ssize_t written; - - written = write(fd, good_buf, (size_t)maxfilelen); - if (written != maxfilelen) { - if (written == -1) { - prterr(fname); - warn("main: error on write"); - } else - warn("main: short write, 0x%x bytes instead -of 0x%x\n", - (unsigned)written, maxfilelen); - exit(98); - } - } else - check_trunc_hack(); - - while (numops == -1 || numops--) - test(); - - if (close(fd)) { - prterr("close"); - report_failure(99); - } - prt("All operations completed A-OK!\n"); - - exit(0); - return 0; -} diff --git a/lustre/tests/intent-test.sh b/lustre/tests/intent-test.sh deleted file mode 100755 index 9113f17..0000000 --- a/lustre/tests/intent-test.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/bin/bash -x - -MTPT=/mnt/lustre - -remount() { - umount $MTPT || exit -1 - debugctl clear - mount -t lustre_lite -o osc=OSCDEV-UUID,mdc=MDCDEV-UUID none $MTPT -} - -# Test mkdir -mkdir $MTPT/dir -mkdir $MTPT/dir2 - -# Test mkdir on existing directory -mkdir $MTPT/dir - -remount - -# Test mkdir on existing directory with no locks already held -mkdir $MTPT/dir - -remount - -# Use mknod to create a file -./mcreate $MTPT/file -# ...on an existing file. -./mcreate $MTPT/file - -remount - -# Use mknod to create a file with no locks already held -./mcreate $MTPT/file - -remount - -ls -l $MTPT/file - -remount - -cat $MTPT/file -./mcreate $MTPT/file2 -cat $MTPT/file2 -./mcreate $MTPT/file3 - -remount - -./tchmod 777 $MTPT/file3 - -remount - -./mcreate $MTPT/file4 -./tchmod 777 $MTPT/file4 - -remount - -ls -l $MTPT/file4 -./tchmod 777 $MTPT/file4 - -remount - -cat $MTPT/file4 -./tchmod 777 $MTPT/file4 - -remount - -touch $MTPT/file5 -touch $MTPT/file6 -touch $MTPT/file5 - -remount - -touch $MTPT/file5 - -remount - -echo foo >> $MTPT/file -cat $MTPT/file - -remount - -cat $MTPT/file - -echo foo >> $MTPT/iotest -echo bar >> $MTPT/iotest -cat $MTPT/iotest - -remount - -cat $MTPT/iotest -echo baz >> $MTPT/iotest - -remount - -ls $MTPT - -remount - -mkdir $MTPT/new -ls $MTPT - -remount - -ls $MTPT -mkdir $MTPT/newer -ls $MTPT - -remount - -cat $MTPT/iotest -echo "Testing truncation..." -echo foo > $MTPT/iotest -echo bar >> $MTPT/iotest -cat $MTPT/iotest -echo "trucating to 4 bytes now..." -./truncate $MTPT/iotest 4 -cat $MTPT/iotest - -remount - -ls $MTPT -rmdir $MTPT/foo diff --git a/lustre/tests/intent-test2.sh b/lustre/tests/intent-test2.sh deleted file mode 100644 index 428039c..0000000 --- a/lustre/tests/intent-test2.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash - -SRCDIR="`dirname $0`" -. $SRCDIR/common.sh - -setup_opts "$@" - -set -vx - -MTPT1=/mnt/lustre1 -MTPT2=/mnt/lustre2 - -remount() { - umount $MTPT1 || exit -1 - umount $MTPT2 || exit -1 - debugctl clear - setup_mount || fail "cannot remount /mnt/lustre" -} - -fail() { - echo "unexpected failure" - exit -1 -} - -[ "`mount | grep $MTPT1`" ] || . llsetup.sh "$@" || exit -1 - -mkdir $MTPT1/dir1 || fail -echo "Next mkdir should fail" -mkdir $MTPT2/dir1 && fail -mkdir $MTPT2/dir2 || fail -echo "Next mkdirs should fail" -mkdir $MTPT1/dir2 && fail - -remount - -echo "Next 2 mkdir should fail" -mkdir $MTPT2/dir1 && fail -mkdir $MTPT1/dir2 && fail - -./mcreate $MTPT2/file1 -echo "Next mcreate should fail" -./mcreate $MTPT2/file1 && fail -./mcreate $MTPT2/file2 || fail -echo "Next mcreate should fail" -./mcreate $MTPT1/file2 && fail - -remount - -echo "Next 2 mcreates should fail" -./mcreate $MTPT2/file1 && fail -./mcreate $MTPT1/file2 && fail - -rmdir $MTPT1/dir2 || fail -echo "Next rmdir should fail" -rmdir $MTPT2/dir2 && fail -rmdir $MTPT2/dir1 || fail - -remount - -echo "Next rpmdir should fail" - -echo "File I/O: you should see increasing sequences of contiguous numbers" -echo 1 >> $MTPT1/file1 -cat $MTPT2/file1 -echo 2 >> $MTPT2/file1 -cat $MTPT1/file1 -echo 3 >> $MTPT2/file1 -cat $MTPT1/file1 -echo 4 >> $MTPT1/file1 -cat $MTPT1/file1 diff --git a/lustre/tests/ldaptest.c b/lustre/tests/ldaptest.c deleted file mode 100644 index c1a7499..0000000 --- a/lustre/tests/ldaptest.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - LDAP *ld; - int err; - - ld = ldap_init("localhost", 389); - if (!ld) { - fprintf(stderr, "ldap_init: %s\n", strerror(errno)); - exit(1); - } - - err = ldap_bind_s(ld, "cn=Manager,dc=lustre,dc=cfs", "secret", - LDAP_AUTH_SIMPLE); - if (err) { - fprintf(stderr, "ldap_bind: %s\n", ldap_err2string(err)); - exit(1); - } - - - - -} diff --git a/lustre/tests/ldlm.cfg b/lustre/tests/ldlm.cfg deleted file mode 100644 index 054f983..0000000 --- a/lustre/tests/ldlm.cfg +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -# Config file for setting up the lock manager -SETUP_LDLM=y diff --git a/lustre/tests/leak_finder.pl b/lustre/tests/leak_finder.pl deleted file mode 100644 index fbf1d00..0000000 --- a/lustre/tests/leak_finder.pl +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/perl -w - -use IO::Handle; - -STDOUT->autoflush(1); -STDERR->autoflush(1); - -my ($line, $memory); -my $debug_line = 0; - -while ($line = <>) { - $debug_line++; - my ($file, $func, $lno, $name, $size, $addr, $type); - if ($line =~ m/^.*\((.*):(\d+):(.*)\(\) (\d+ \| )?\d+\+\d+\): [vk](.*) '(.*)': (\d+) at (.*) \(tot .*$/) { - $file = $1; - $lno = $2; - $func = $3; - $type = $5; - $name = $6; - $size = $7; - $addr = $8; - printf("%8s %6d bytes at %s called %s (%s:%s:%d)\n", $type, $size, - $addr, $name, $file, $func, $lno); - } else { - next; - } - - if ($type eq 'malloced') { - $memory->{$addr}->{name} = $name; - $memory->{$addr}->{size} = $size; - $memory->{$addr}->{file} = $file; - $memory->{$addr}->{func} = $func; - $memory->{$addr}->{lno} = $lno; - $memory->{$addr}->{debug_line} = $debug_line; - } else { - if (!defined($memory->{$addr})) { - print STDERR "*** Free without malloc ($size bytes at $addr, $file:$func:$lno)\n"; - next; - } - my ($oldname, $oldsize, $oldfile, $oldfunc, $oldlno) = $memory->{$addr}; - - if ($memory->{$addr}->{size} != $size) { - print STDERR "*** Free different size ($memory->{$addr}->{size} alloced, $size freed).\n"; - print STDERR " malloc at $memory->{$addr}->{file}:$memory->{$addr}->{func}:$memory->{$addr}->{lno}, free at $file:$func:$lno\n"; - next; - } - - delete $memory->{$addr}; - } -} - -# Sort leak output by allocation time -my @sorted = sort { - return $memory->{$a}->{debug_line} <=> $memory->{$b}->{debug_line}; -} keys(%{$memory}); - -my $key; -foreach $key (@sorted) { - my ($oldname, $oldsize, $oldfile, $oldfunc, $oldlno) = $memory->{$key}; - print STDERR "*** Leak: $memory->{$key}->{size} bytes allocated at $key ($memory->{$key}->{file}:$memory->{$key}->{func}:$memory->{$key}->{lno}, debug file line $memory->{$key}->{debug_line})\n"; -} - -print "Done.\n"; diff --git a/lustre/tests/llcleanup.sh b/lustre/tests/llcleanup.sh deleted file mode 100755 index b718e93..0000000 --- a/lustre/tests/llcleanup.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -SRCDIR="`dirname $0`/" -[ -f $SRCDIR/common.sh ] || SRCDIR="/lib/lustre" - -. $SRCDIR/common.sh - -setup_opts "$@" - -TIME=`date +'%s'` - -$DBGCTL debug_kernel /tmp/debug.1.$TIME -cleanup_client -$DBGCTL debug_kernel /tmp/debug.2.$TIME -cleanup_server - -cleanup_ldlm -cleanup_lustre -cleanup_portals diff --git a/lustre/tests/lldlm.sh b/lustre/tests/lldlm.sh deleted file mode 100755 index 58da470..0000000 --- a/lustre/tests/lldlm.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -SRCDIR="`dirname $0`/" -. $SRCDIR/common.sh - -export DEBUG_WAIT=yes -. $SRCDIR/llsetup.sh $SRCDIR/net-local.cfg $SRCDIR/ldlm.cfg $SRCDIR/obdecho.cfg $SRCDIR/client-echo.cfg || exit 2 - -cat < /proc/sys/portals/debug_path - -list_mods - - diff --git a/lustre/tests/llmount-client.sh b/lustre/tests/llmount-client.sh deleted file mode 100644 index 503f93f..0000000 --- a/lustre/tests/llmount-client.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -SRCDIR="`dirname $0`/" -. $SRCDIR/common.sh - -export DEBUG_WAIT=yes -. $SRCDIR/llsetup.sh $SRCDIR/net-client.cfg $SRCDIR/ldlm.cfg $SRCDIR/client-mount.cfg || exit 2 - -debug_client_on -#debug_client_off diff --git a/lustre/tests/llmount-server.sh b/lustre/tests/llmount-server.sh deleted file mode 100644 index d31f033..0000000 --- a/lustre/tests/llmount-server.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -SRCDIR="`dirname $0`/" -. $SRCDIR/common.sh - -export DEBUG_WAIT=yes -. $SRCDIR/llsetup.sh $SRCDIR/net-server.cfg $SRCDIR/ldlm.cfg $SRCDIR/mds.cfg $SRCDIR/obdfilter.cfg || exit 2 - -debug_client_on -#debug_client_off diff --git a/lustre/tests/llmount.sh b/lustre/tests/llmount.sh deleted file mode 100755 index eb4618b..0000000 --- a/lustre/tests/llmount.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# suggested boilerplate for test script - -LCONF=${LCONF:-../utils/lconf} -NAME=${NAME:-local} - -config=$NAME.xml -mkconfig=./$NAME.sh - -if [ ! -f $config -o $mkconfig -nt $config ]; then - sh $mkconfig $config || exit 1 -fi - -${LCONF} --reformat --gdb $config || exit 2 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 <&2 - mv $TMP/debug $TMP/debug.`date +%s` - #exit -1 -fi -BUSY=`dmesg | grep -i destruct` -if [ "$BUSY" ]; then - echo "$BUSY" 1>&2 - #exit -2 -fi diff --git a/lustre/tests/llmountcleanup2-hack.sh b/lustre/tests/llmountcleanup2-hack.sh deleted file mode 100644 index b2996cf..0000000 --- a/lustre/tests/llmountcleanup2-hack.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -umount /mnt/lustre2 -umount /mnt/lustre1 -../utils/lctl < -#include -#include -#include -#include -#include -#include - - -/****************** Custom includes ********************/ -#include -#include - - -/****************** Functions ******************/ -int write_file(char *name, struct lov_mds_md *striping, int bufsize, - char *buf1, char *buf2); - - -/************************ Main **********************/ - -#define STRIPE_SIZE 128 * 1024 - -int main(int argc, char *argv[]) -{ - struct lov_mds_md a_striping; - long bufsize = sizeof(long) * STRIPE_SIZE; - char *rbuf, *wbuf; - int data, *dp; - int result; - - rbuf = malloc(bufsize); - wbuf = malloc(bufsize); - if (!rbuf || !wbuf) { - fprintf(stderr, "%s: unable to allocate buffers\n", argv[0]); - return 1; - } - - /* Initialize to an easily-verified pattern */ - for (data = 0, dp = (int *)wbuf; data < STRIPE_SIZE; data++, dp++) - *dp = data; - - /* Init defaults on striping info */ - a_striping.lmm_magic = LOV_MAGIC; - a_striping.lmm_stripe_size = STRIPE_SIZE; - a_striping.lmm_stripe_pattern = 0; - - /* Write file for OST1 only */ - /* Start at OST 0, and use only 1 OST */ - a_striping.lmm_stripe_offset = 0; - a_striping.lmm_stripe_count = 1; - - result = write_file("/mnt/lustre/ost1", &a_striping, bufsize, - wbuf, rbuf); - - if (result < 0) - goto out; - - /* Write file for OST2 only */ - /* Start at OST 1, and use only 1 OST */ - a_striping.lmm_stripe_offset = 1; - a_striping.lmm_stripe_count = 1; - - result = write_file("/mnt/lustre/ost2", &a_striping, bufsize, - wbuf, rbuf); - - if (result < 0) - goto out; - - /* Write file across both OST1 and OST2 */ - /* Start at OST 0, and use only 2 OSTs */ - a_striping.lmm_stripe_offset = 0; - a_striping.lmm_stripe_count = 2; - - result = write_file("/mnt/lustre/ost1and2", &a_striping, bufsize, - wbuf, rbuf); - - if (result < 0) - goto out; - -out: - free(rbuf); - free(wbuf); - return result; -} - - -int write_file(char *name, struct lov_mds_md *striping, int bufsize, - char *wbuf, char *rbuf) -{ - int fd, result; - - printf("opening %s\n", name); - 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)); - return -errno; - } - - printf("setting stripe data on %s\n", name); - result = ioctl(fd, LL_IOC_LOV_SETSTRIPE, striping); - if (result < 0) { - fprintf(stderr, "\nError on ioctl for '%s' (%d): %s\n", - name, fd, strerror(errno)); - close(fd); - return -errno; - } - - /* Write bogus data */ - printf("writing data to %s\n", name); - result = write(fd, wbuf, bufsize); - if (result < 0) { - fprintf(stderr, "\nerror: writing data to '%s' (%d): %s\n", - name, fd, strerror(errno)); - close(fd); - return -errno; - } - - if (result != bufsize) { - fprintf(stderr, "\nerror: short write to '%s' (%d): %d != %d\n", - name, fd, result, bufsize); - close(fd); - return -1; - } - - /* Seek to beginning again */ - printf("seeking in %s\n", name); - result = lseek(fd, 0, SEEK_SET); - if (result < 0) { - fprintf(stderr, "\nerror: seeking to beginning '%s' (%d): %s\n", - name, fd, strerror(errno)); - close(fd); - return -errno; - } - - /* Read bogus data back */ - printf("reading data from %s\n", name); - result = read(fd, rbuf, bufsize); - if (result < 0) { - fprintf(stderr, "\nerror: reading data from '%s' (%d): %s\n", - name, fd, strerror(errno)); - close(fd); - return -errno; - } - - if (result != bufsize) { - fprintf(stderr,"\nerror: short read from '%s' (%d): %d != %d\n", - name, fd, result, bufsize); - close(fd); - return -1; - } - - if (memcmp(wbuf, rbuf, bufsize)) { - fprintf(stderr, "\nerror: comparing data in '%s' (%d): %s\n", - name, fd, strerror(errno)); - close(fd); - return -1; - } - - close(fd); - - return 0; -} diff --git a/lustre/tests/lustre.cfg b/lustre/tests/lustre.cfg deleted file mode 100644 index cc97b1b..0000000 --- a/lustre/tests/lustre.cfg +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -### REMOVE THE FOLLOWING LINES IN ORDER TO TEST LUSTRE WITH THIS CONFIG ### -echo "lustre: edit /etc/lustre/lustre.cfg to enable, exiting" 1>&2 -exit 1 - -# Common configuration options -# Config file for setting up a local OST and MDS server -NETWORK=tcp -LOCALHOST=`hostname` -SERVER=$LOCALHOST -OSTNODE=$LOCALHOST -CLIENTS=* -PORT=988 - -# Set up the lock manager (required) -SETUP_LDLM=y - -#case `echo $LOCALHOST | sed "s/\.[^|]*//"` in -case $LOCALHOST in -$SERVER) - # Config for setting up a metadata server - MDSFS=extN - MDSDEV=/tmp/mds - MDSSIZE=50000 - SETUP_MDS=y - ;; -esac - -case $LOCALHOST in -$OSTNODE) - # Config for setting up an object storage target with obdfilter - OSTDEV=/tmp/ost - OSTSIZE=200000 - OSTFS=extN - OSTTYPE=obdfilter - SETUP_OST=y - ;; -esac - -case $LOCALHOST in -$CLIENTS) - # Config for setting up a client filesystem mount - SETUP_MDC=y - SETUP_OSC=y - OSCMT=/mnt/lustre - SETUP_MOUNT=y - ;; -esac diff --git a/lustre/tests/mcr-individual-ost-nogw-config.sh b/lustre/tests/mcr-individual-ost-nogw-config.sh deleted file mode 100755 index 0aae281..0000000 --- a/lustre/tests/mcr-individual-ost-nogw-config.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -config=${1:-echo-no-gw.xml} - -LMC="save_cmd" -LMC_REAL="../../lustre/utils/lmc -m $config" - -# TCP/IP servers -SERVER_START=0 -SERVER_CNT=62 - -TCPBUF=1048576 - -h2ip () { - echo "${1}" -} -BATCH=/tmp/lmc-batch.$$ -save_cmd() { - echo "$@" >> $BATCH -} - -[ -f $config ] && rm $config - -# Client node -${LMC} --node client --tcpbuf $TCPBUF --net '*' tcp || exit 1 - -# this is crude, but effective -let server_per_gw=($SERVER_CNT / $GW_CNT ) -let tot_server=$server_per_gw*$GW_CNT - -let server=$SERVER_START -while (( $server < $SERVER_CNT + SERVER_START )); -do - echo "server: $server" - OST=ba$server - # server node - ${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp || exit 1 - # the device on the server - ${LMC} --node $OST --obdtype=obdecho --ost || exit 3 - # osc on client - ${LMC} --node client --osc OSC_$OST - let server=$server+1 -done - -$LMC_REAL --batch $BATCH -rm -f $BATCH diff --git a/lustre/tests/mcr-mds-failover-config.sh b/lustre/tests/mcr-mds-failover-config.sh deleted file mode 100755 index 8a42c3d..0000000 --- a/lustre/tests/mcr-mds-failover-config.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh - -LMC=/usr/local/cfs/lustre/utils/lmc -# LMC="echo lmc" -CONFIG=mcr-mds-failover.xml -LUSTRE_QUERY=/usr/local/cfs/lustre-failover/lustre-query -GW_NODE=mcr21 -CLIENT_ELAN=`hostname | sed s/[^0-9]*//;` -OST_BA=ba50 -OST_UUID=10400010-5dec-11c2-0b5f-00301700041a -MDS_DEVICE=/dev/sda3 -MDS_SIZE=500000 -TCPBUF=1048576 - -MDSNODES=`$LUSTRE_QUERY -h emcri -s id=mds -f` -ACTIVEMDS=`$LUSTRE_QUERY -h emcri -s id=mds -a` - -echo "MDS nodes: $MDSNODES, active: $ACTIVEMDS" - -h2elan () { - echo $1 | sed 's/[^0-9]*//g' -} - -h2ip () { - echo "${1}" -} - - -# create client node -$LMC -o $CONFIG --node client --net '*' elan -$LMC -m $CONFIG --router --node mcr21 --tcpbuf $TCPBUF --net `h2ip $GW_NODE` tcp -$LMC -m $CONFIG --router --node mcr21 --net `h2elan $GW_NODE` elan -$LMC -m $CONFIG --node $GW_NODE --route elan `h2elan $GW_NODE` $CLIENT_ELAN - -# create MDS node entries -for mds in $MDSNODES; do - elanaddr=`$LUSTRE_QUERY -h emcri -s id=$mds -e` - $LMC -m $CONFIG --node $mds --net $elanaddr elan - $LMC -m $CONFIG --node $mds --mds mds_$mds $MDS_DEVICE $MDS_SIZE -done - -# create OST node entry -$LMC -m $CONFIG --node $OST_BA --tcpbuf $TCPBUF --net $OST_BA tcp -$LMC -m $CONFIG --node $OST_BA --obduuid $OST_UUID --ost bluearc -$LMC -m $CONFIG --node $GW_NODE --route tcp `h2ip $GW_NODE` $OST_BA - -# mount -$LMC -m $CONFIG --node client --mtpt /mnt/lustre mds_$ACTIVEMDS OSC_$OST_BA diff --git a/lustre/tests/mcr-routed-config.sh b/lustre/tests/mcr-routed-config.sh deleted file mode 100755 index f66335e..0000000 --- a/lustre/tests/mcr-routed-config.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/bash - -BASE=`hostname | sed "s/[i0-9]*$//"` -[ $BASE = "mcr" ] && OSTBASE=${OSTBASE:-ba} || OSTBASE=${OSTBASE:-ba-ost-} - -config=${1:-$BASE.xml} - -BATCH=/tmp/lmc-batch.$$ -save_cmd() { - echo "$@" >> $BATCH -} - -LMC="save_cmd" -LMC_REAL="../../lustre/utils/lmc -m $config" - -# TCP/IP servers -SERVER_START=0 -SERVER_CNT=64 -GW_START=0 -GW_CNT=32 -MDS=${BASE}23 -UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt} - -echo "MDS: $MDS" - -# This is needed for to create route for elan network -CLIENT_LO=36 -CLIENT_HI=155 - -TCPBUF=1048576 - -h2elan () { - echo $1 | sed 's/[^0-9]*//g' -} - -h2ip () { - echo "${1}" -} - -# map gateway NN to host NN (assumes mcr[22-25] are not gateways) -gw2node() { - [ $1 -gt 21 ] && echo $(($1 + 4)) || echo $1 -} - -[ -f $config ] && rm $config - -${LMC} --node $MDS --net `h2elan $MDS` elan || exit 1 -${LMC} --node $MDS --mds mds1 /tmp/mds1 100000 || exit 1 -${LMC} --lov lov1 mds1 65536 1 0 - -# Client node -#${LMC} --node client --tcpbuf $TCPBUF --net '*' tcp || exit 1 -${LMC} --node client --net '*' elan || exit 1 -${LMC} --node client --mtpt /mnt/lustre mds1 lov1 - -# this is crude, but effective -let server_per_gw=($SERVER_CNT / $GW_CNT ) -let tot_server=$server_per_gw*$GW_CNT -echo "Allocating $server_per_gw OSTs per gateway." -echo "For a total of $tot_server Blue Arc OSTs" - -let gw=$GW_START -let server=$SERVER_START -while (( $gw < $GW_CNT + GW_START )); -do - gwnode=$BASE`gw2node $gw` - echo "Router: $gwnode" - ${LMC} --router --node $gwnode --tcpbuf $TCPBUF --net `h2ip $gwnode` tcp || exit 1 - ${LMC} --node $gwnode --net `h2elan $gwnode` elan|| exit 1 - ${LMC} --node $gwnode --route elan `h2elan $gwnode` `h2elan $CLIENT_LO` `h2elan $CLIENT_HI` || exit 2 - - let i=0 - while (( $i < $server_per_gw )); - do - OST=${OSTBASE}$server - echo "server: $OST" - 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 || exit 1 - # the device on the server - ${LMC} --lov lov1 --node $OST $OBD_UUID --ost bluearc || exit 3 - # route to server - ${LMC} --node $gwnode --route tcp `h2ip $gwnode` $OST || exit 2 - let server=$server+1 - let i=$i+1 - done - - let gw=$gw+1 -done - -$LMC_REAL --batch $BATCH -rm -f $BATCH diff --git a/lustre/tests/mcr.sh b/lustre/tests/mcr.sh deleted file mode 100755 index c7f7919..0000000 --- a/lustre/tests/mcr.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -config=${1:-mcr.xml} - -LMC="../utils/lmc -m $config" - -# TCP/IP servers -SERVERS="ba-ost-1 ba-ost-2" -ROUTER=dev5 - -# Elan clients -CLIENT_LO=dev2 -CLIENT_HI=dev25 - -TCPBUF=1048576 - - -h2elan () { - echo $1 | sed 's/[^0-9]*//g' -} - -h2ip () { - echo "${1}" -} - -[ -f $config ] && rm $config - -# Client node -${LMC} --node client --net '*' elan || exit 1 -# Router node -${LMC} --router --node $ROUTER --tcpbuf $TCPBUF --net `h2ip $ROUTER` tcp || exit 1 -${LMC} --node $ROUTER --net `h2elan $ROUTER` elan|| exit 1 -${LMC} --node $ROUTER --route elan `h2elan $ROUTER` `h2elan $CLIENT_LO` `h2elan $CLIENT_HI` || exit 2 - -for s in $SERVERS - do - # server node - ${LMC} --node $s --tcpbuf $TCPBUF --net $s tcp || exit 1 - # route to server - ${LMC} --node $ROUTER --route tcp `h2ip $ROUTER` $s || exit 2 - # the device on the server - ${LMC} --node $s --obdtype=obdecho --ost || exit 3 - # attach to the device on the client (this would normally be a moun) - ${LMC} --node client --osc OSC_$s || exit 4 -done diff --git a/lustre/tests/mcrlov.sh b/lustre/tests/mcrlov.sh deleted file mode 100755 index 35ba323..0000000 --- a/lustre/tests/mcrlov.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -config=${1:-mcrlov.xml} - -LMC="../utils/lmc -m $config" - -# TCP/IP servers -SERVERS="ba-ost-1 ba-ost-2" -ROUTER=dev5 -MDS=dev7 -TMP=${TMP:-/tmp} - -# Elan clients -CLIENT_LO=dev2 -CLIENT_HI=dev25 - -TCPBUF=1048576 - - -h2elan () { - echo $1 | sed 's/[^0-9]*//g' -} - -h2ip () { - echo "${1}" -} - -[ -f $config ] && rm $config - -# Client node -${LMC} --node client --net '*' elan || exit 1 -# Router node -${LMC} --router --node $ROUTER --tcpbuf $TCPBUF --net `h2ip $ROUTER` tcp || exit 1 -${LMC} --node $ROUTER --net `h2elan $ROUTER` elan|| exit 1 -${LMC} --node $ROUTER --route elan `h2elan $ROUTER` `h2elan $CLIENT_LO` `h2elan $CLIENT_HI` || exit 2 - -${LMC} --node $MDS --net `h2elan $MDS` elan || exit 1 -${LMC} --node $MDS --mds mds1 $TMP/mds1 100000 || exit 1 -${LMC} --lov lov1 mds1 65536 0 0 - -${LMC} --node client --mtpt /mnt/lustre mds1 lov1 - -for s in $SERVERS - do - # server node - ${LMC} --node $s --tcpbuf $TCPBUF --net $s tcp || exit 1 - # route to server - ${LMC} --node $ROUTER --route tcp `h2ip $ROUTER` $s || exit 2 - # the device on the server - ${LMC} --format --lov lov1 --node $s --ost bluearc || exit 3 -done diff --git a/lustre/tests/mdcreq.sh b/lustre/tests/mdcreq.sh deleted file mode 100644 index bd54c96..0000000 --- a/lustre/tests/mdcreq.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -SRCDIR="`dirname $0`" -. $SRCDIR/common.sh - -NETWORK=tcp -LOCALHOST=localhost -SERVER=localhost -PORT=988 -TMP=${TMP:-/tmp} - -setup_portals -setup_lustre - -MDSFS=ext2 -new_fs ${MDSFS} $TMP/mds 1000 -MDS=$LOOPDEV - -echo 0xffffffff > /proc/sys/portals/debug - -$OBDCTL < -#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, S_IFREG| 0444); - if (rc) { - printf("mkdir(%s) error: %s\n", - dirname, strerror(errno)); - break; - } - if ((i % 10000) == 0) - printf(" - created %d (time %ld)\n", i, time(0)); - } - return rc; -} diff --git a/lustre/tests/modules.cfg b/lustre/tests/modules.cfg deleted file mode 100755 index 10fb9a7..0000000 --- a/lustre/tests/modules.cfg +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -# Config file for running tests on a single host over loopback TCP -NETWORK=tcp diff --git a/lustre/tests/mount2.sh b/lustre/tests/mount2.sh deleted file mode 100644 index 6e5aa0b..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/lustre1 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/munlink.c b/lustre/tests/munlink.c deleted file mode 100755 index a3c18c5..0000000 --- a/lustre/tests/munlink.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char ** argv) -{ - int rc; - - if (argc < 2) { - printf("Usage %s filename\n", argv[0]); - return 1; - } - - rc = unlink(argv[1]); - if (rc) { - printf("unlink(%s) error: %s\n", argv[1], strerror(errno)); - } - return rc; -} diff --git a/lustre/tests/net-client.cfg b/lustre/tests/net-client.cfg deleted file mode 100644 index 7cd4a8d..0000000 --- a/lustre/tests/net-client.cfg +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# Config file for setting up a remote server with a real OST -NETWORK=tcp -LOCALHOST=dev5 -SERVER=dev4 -PORT=988 diff --git a/lustre/tests/net-local.cfg b/lustre/tests/net-local.cfg deleted file mode 100644 index 2ce3abe..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=988 diff --git a/lustre/tests/net-server.cfg b/lustre/tests/net-server.cfg deleted file mode 100644 index 8386525..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=988 diff --git a/lustre/tests/obddisk.cfg b/lustre/tests/obddisk.cfg deleted file mode 100644 index 22e6ef2..0000000 --- a/lustre/tests/obddisk.cfg +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# Config file for setting up an object storage target with obdfilter -OSTDEV=/dev/hda7 -OSTFS=ext2 -OSTTYPE=obdfilter -SETUP_OST=y diff --git a/lustre/tests/obdecho.cfg b/lustre/tests/obdecho.cfg deleted file mode 100644 index 2c2b40f..0000000 --- a/lustre/tests/obdecho.cfg +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -# Config file for setting up a test (echo) OST -OSTTYPE=obdecho -SETUP_OST=y diff --git a/lustre/tests/obdfilter.cfg b/lustre/tests/obdfilter.cfg deleted file mode 100644 index e9021c2..0000000 --- a/lustre/tests/obdfilter.cfg +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -# Config file for setting up an object storage target with obdfilter -OSTDEV=/tmp/ost -OSTSIZE=10000 -OSTFS=extN -OSTTYPE=obdfilter -SETUP_OST=y diff --git a/lustre/tests/openclose.c b/lustre/tests/openclose.c deleted file mode 100644 index cc4b06d..0000000 --- a/lustre/tests/openclose.c +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifndef O_DIRECT -# define O_DIRECT 040000 /* direct disk access hint */ -#endif - -int main(int argc, char *argv[]) -{ - char filename[1024]; - unsigned long count, i; - int thread = 0; - int threads = 0; - int rc = 0; - int fd, ioctl_flags = 0; - - if (argc < 3 || argc > 4) { - fprintf(stderr, "usage: %s [threads]\n", - argv[0]); - exit(1); - } - - count = strtoul(argv[2], NULL, 0); - if (argc == 4) - threads = strtoul(argv[3], NULL, 0); - - for (i = 1; i <= threads; i++) { - rc = fork(); - if (rc < 0) { - fprintf(stderr, "error: %s: #%ld - %s\n", argv[0], i, - strerror(rc = errno)); - break; - } else if (rc == 0) { - thread = i; - argv[2] = "--device"; - break; - } else - printf("%s: thread #%ld (PID %d) started\n", - argv[0], i, rc); - rc = 0; - } - - if (threads && thread == 0) { /* parent process */ - int live_threads = threads; - - while (live_threads > 0) { - int status; - pid_t ret; - - ret = waitpid(0, &status, 0); - if (ret == 0) { - continue; - } - - if (ret < 0) { - fprintf(stderr, "error: %s: wait - %s\n", - argv[0], strerror(errno)); - if (!rc) - rc = errno; - } else { - /* - * This is a hack. We _should_ be able to use - * WIFEXITED(status) to see if there was an - * error, but it appears to be broken and it - * always returns 1 (OK). See wait(2). - */ - int err = WEXITSTATUS(status); - if (err || WIFSIGNALED(status)) - fprintf(stderr, - "%s: PID %d had rc=%d\n", - argv[0], ret, err); - if (!rc) - rc = err; - - live_threads--; - } - } - } else { - if (threads) - sprintf(filename, "%s-%d", argv[1], thread); - else - strcpy(filename, argv[1]); - - fd = open(filename, O_RDWR|O_CREAT, 0644); - if (fd < 0) { - fprintf(stderr, "open(%s, O_CREAT): %s\n", filename, - strerror(errno)); - exit(errno); - } - if (close(fd) < 0) { - fprintf(stderr, "close(): %s\n", strerror(errno)); - rc = errno; - goto unlink; - } - - for (i = 0; i < count; i++) { - fd = open(filename, O_RDWR|O_LARGEFILE|O_DIRECT); - if (fd < 0) { - fprintf(stderr, "open(%s, O_RDWR): %s\n", - filename, strerror(errno)); - rc = errno; - break; - } - if (ioctl(fd, LL_IOC_SETFLAGS, &ioctl_flags) < 0) { - fprintf(stderr, "ioctl(): %s\n", - strerror(errno)); - rc = errno; - break; - } - if (close(fd) < 0) { - fprintf(stderr, "close(): %s\n", - strerror(errno)); - rc = errno; - break; - } - } - unlink: - if (unlink(filename) < 0) { - fprintf(stderr, "unlink(%s): %s\n", filename, - strerror(errno)); - rc = errno; - } - if (threads) - printf("Thread %d done: rc = %d\n", thread, rc); - else - printf("Done: rc = %d\n", rc); - } - return rc; -} diff --git a/lustre/tests/openme.c b/lustre/tests/openme.c deleted file mode 100644 index 9a1f3f3..0000000 --- a/lustre/tests/openme.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - int fd; - - if (argc != 2) { - printf("Usage openme \n"); - exit(1); - } - - fd = open(argv[1], O_RDONLY | O_CREAT, 0600); - if (fd == -1) { - printf("Error opening %s\n", argv[1]); - exit(1); - } - - sleep(10000000); - return 0; -} diff --git a/lustre/tests/openunlink.c b/lustre/tests/openunlink.c deleted file mode 100644 index 3d5904d..0000000 --- a/lustre/tests/openunlink.c +++ /dev/null @@ -1,132 +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 (normal) %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 (normal) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "closing\n"); - rc = close(fd); - if (rc) { - fprintf(stderr, "close (normal) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "opening again\n"); - fd = open(argv[1], O_RDWR); - if (fd == -1) { - fprintf(stderr, "open (unlink) %s\n", strerror(errno)); - exit(1); - } - -#if 0 - fprintf(stderr, "unlinking\n"); - rc = unlink(argv[1]); - if (rc) { - fprintf(stderr, "unlink %s\n", strerror(errno)); - exit(1); - } -#else - printf("unlink %s and press enter\n", argv[1]); - getc(stdin); -#endif - - fprintf(stderr, "reading\n"); - rc = read(fd, buf, strlen(T1) + 1); - if (rc != strlen(T1) + 1) { - fprintf(stderr, "read (unlink) %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 (unlink) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "seeking\n"); - rc = lseek(fd, 0, SEEK_SET); - if (rc) { - fprintf(stderr, "seek (after unlink trunc) %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 (after unlink trunc) %s (rc %d)\n", - strerror(errno), rc); - exit(1); - } - - fprintf(stderr, "seeking\n"); - rc = lseek(fd, 0, SEEK_SET); - if (rc) { - fprintf(stderr, "seek (before unlink 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 unlink rewrite) %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 rewrite\n"); - exit(1); - } - - fprintf(stderr, "closing again\n"); - rc = close(fd); - if (rc) { - fprintf(stderr, "close (unlink) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "SUCCESS - goto beer\n"); - return 0; -} diff --git a/lustre/tests/ostreq.sh b/lustre/tests/ostreq.sh deleted file mode 100644 index 2d600ca..0000000 --- a/lustre/tests/ostreq.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -SRCDIR="`dirname $0`/" -. $SRCDIR/common.sh - -SERVER=localhost -PORT=988 -TMP=${TMP:-/tmp} - -$ACCEPTOR $PORT - -$PTLCTL < /proc/sys/portals/debug -TGT=/mnt/lustre/client.txt -SRC=/usr/lib/dbench/client.txt -[ ! -e $TGT -a -e $SRC ] && echo "copying $SRC to $TGT" && cp $SRC $TGT -SRC=/usr/lib/dbench/client_plain.txt -[ ! -e $TGT -a -e $SRC ] && echo "copying $SRC to $TGT" && cp $SRC $TGT -cd /mnt/lustre -dbench -c client.txt $@ diff --git a/lustre/tests/runfailure-client-mds-recover.sh b/lustre/tests/runfailure-client-mds-recover.sh deleted file mode 100755 index 8ea79df..0000000 --- a/lustre/tests/runfailure-client-mds-recover.sh +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/sh -SRCDIR=. - -. common.sh - -reconnect () { - -$OBDCTL < /proc/sys/lustre/fail_loc -touch /mnt/lustre/foo & -ps axww | grep touch -echo "MDS dropped create request -- sleep 4 secs - watch for timeout" -sleep 7 -# reconnect -sleep 1 -echo "did things recover? check for file foo." -ls -l /mnt/lustre -echo "Test 1 done" - - -echo -echo "Test 2 test delay queue:" `date` "creating /mnt/lustre/foo" -echo -rm -rf /mnt/lustre/* -mkdir /mnt/lustre/a -echo 0x80000107 > /proc/sys/lustre/fail_loc -touch /mnt/lustre/foo & -ps axww | grep touch -echo "MDS dropped create request -- sleep 4 secs - watch for timeout" -sleep 4 -touch /mnt/lustre/a/f & -#reconnect -sleep 5 -echo "did things recover? check for file foo and a/f" -ls -l /mnt/lustre -ls -l /mnt/lustre/a -echo "Test 2 done" - -echo -echo "Test 3 dropped reply:" `date` "creating /mnt/lustre/foo2" -echo -rm -rf /mnt/lustre/* -echo 0x80000119 > /proc/sys/lustre/fail_loc -touch /mnt/lustre/foo2 & -ps axww | grep touch -echo "MDS dropped create request -- sleep 4 secs - watch for timeout" -sleep 4 -# reconnect -echo failure cleared -sleep 4 -echo "did things recover? check for file foo2" -ls -l /mnt/lustre -echo "Test 3 done" - - -echo -echo "Test 4: Multiple failures" -echo -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 -# reconnect -sleep 6 -echo "failure cleared" -echo "did things recover? Check for file bar" -ls -l /mnt/lustre/bar - -echo "Test 4 done" - - -echo -echo "Test 5: Continue writing during recovery:" `date` "creating and writing/mnt/lustre/foo" -echo -rm -rf /mnt/lustre/* -./openme /mnt/lustre/foo3 & -./writeme /mnt/lustre/iogoeson & -sleep 1 -ls -l /mnt/lustre -echo 0x80000107 > /proc/sys/lustre/fail_loc -mknod /mnt/lustre/dev c 10 240 & -echo "MDS dropped create request -- sleep 4 secs - watch for timeout" -sleep 6 -# reconnect -sleep 1 -echo "did things recover? check for file foo, bar, check log for reopen." -ls -l /mnt/lustre -echo "Test 5 done" diff --git a/lustre/tests/runfailure-mds b/lustre/tests/runfailure-mds deleted file mode 100755 index f2942c3..0000000 --- a/lustre/tests/runfailure-mds +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/sh - -SRCDIR="`dirname $0`" -. $SRCDIR/common.sh - -. $SRCDIR/llmount.sh - -MNT="setup_mount" - -test_fail() { - echo $1 > /proc/sys/lustre/fail_loc - shift - echo "Running '$*'" - $* - - echo "Cleaning up and restarting MDS" - umount /mnt/lustre || fail "unable to unmount" - $OBDCTL <<- EOF - name2dev MDSDEV - cleanup - detach - quit - EOF - - echo 0 > /proc/sys/lustre/fail_loc - - $OBDCTL <<- EOF - newdev - attach mds MDSDEV - setup ${MDS} ${MDSFS} - quit - EOF - $MNT -} - -#set -vx - -touch /mnt/lustre/foo -chmod a+x /mnt/lustre/foo -sync - -# OBD_FAIL_MDS_REINT_SETATTR_WRITE - MDS will discard data from setattr -test_fail 0x10a chmod 000 /mnt/lustre/foo -ls -l /mnt/lustre/foo -[ ! -x /mnt/lustre/foo ] && fail "/mnt/lustre/foo is not executable!" - -# OBD_FAIL_MDS_REINT_CREATE_WRITE - MDS will not create the file -test_fail 0x10c touch /mnt/lustre/bar -ls /mnt/lustre/bar -[ $? -eq 0 ] && fail "/mnt/lustre/bar was created!" - -# OBD_FAIL_MDS_REINT_UNLINK_WRITE - MDS will discard data from unlink -test_fail 0x10e rm /mnt/lustre/foo -ls /mnt/lustre/foo -[ $? -eq 1 ] && fail "/mnt/lustre/foo has been removed!" - -# OBD_FAIL_MDS_REINT_RENAME_WRITE - MDS will discard data from rename -test_fail 0x112 mv /mnt/lustre/foo /mnt/lustre/bar -ls /mnt/lustre/foo /mnt/lustre/bar -[ ! -f /mnt/lustre/foo -o -f /mnt/lustre/bar ] && \ - fail "/mnt/lustre/foo has been renamed to bar!" - -echo "Done." diff --git a/lustre/tests/runfailure-net b/lustre/tests/runfailure-net deleted file mode 100755 index ce5634b..0000000 --- a/lustre/tests/runfailure-net +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh - -fail() { - echo "ERROR: $1" 1>&2 - [ $2 ] && RC=$2 || RC=1 - exit $RC -} - -test_fail() { - oldtimeout=`cat /proc/sys/lustre/timeout` - echo $TIMEOUT > /proc/sys/lustre/timeout - echo $1 > /proc/sys/lustre/fail_loc - shift - $* & - sleep $TIMEOUT - sleep 2 # fudge - kill -9 $! - - echo $oldtimeout > /proc/sys/lustre/timeout - echo 0 > /proc/sys/lustre/fail_loc - umount -f /mnt/lustre || fail "cannot unmount /mnt/lustre" - mount -t lustre_lite -o "osc=$OSC,mdc=$MDC" none /mnt/lustre || \ - fail "cannot remount $OSC/$MDC on /mnt/lustre" -} - -set -vx - -LCTL=../utils/lctl -OSC=OSC_localhost_UUID -MDC=MDC_client1_UUID -TIMEOUT=5 # complete in finite time - -[ "`mount | grep /mnt/lustre`" ] || echo | sh llmount.sh || exit -1 - -# GETATTR_NET - ls will hang on the getattr -# test_fail 0x102 ls -l /mnt/lustre - -# READPAGE_NET - ls will hang reading in new pages (lost+found is not in cache) -test_fail 0x104 ls /mnt/lustre - -sleep 1 - -# REINT_NET - touch will hang on setattr -test_fail 0x107 touch /mnt/lustre - -# REINT_NET - touch will hang on create -test_fail 0x107 touch /mnt/lustre/tt - -# REINT_NET - mv will hang on rename -touch /mnt/lustre/foo -test_fail 0x107 mv /mnt/lustre/foo /mnt/lustre/bar - -# REINT_NET - rm will hang on unlink -touch /mnt/lustre/salmon -test_fail 0x107 rm /mnt/lustre/salmon - -# OPEN_NET - touch will hang on open -touch /mnt/lustre/foo -test_fail 0x113 cat /mnt/lustre/foo - -# CLOSE_NET - ls will hang on close -test_fail 0x115 ./testreq --close junk_file_handle - -echo 0 > /proc/sys/lustre/fail_loc - -echo "Done." diff --git a/lustre/tests/runfailure-ost b/lustre/tests/runfailure-ost deleted file mode 100755 index 0c68d5a..0000000 --- a/lustre/tests/runfailure-ost +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/sh - -SRCDIR="`dirname $0`" -. $SRCDIR/common.sh - -setup_opts "$@" - -set -vx - -test_fail() { - echo $1 > /proc/sys/lustre/fail_loc - shift - echo "Running '$*'" - $* & - sleep 1 - kill -9 $! - - echo 0 > /proc/sys/lustre/fail_loc - umount /mnt/lustre || fail "cannot unmount /mnt/lustre" - setup_mount || fail "cannot remount /mnt/lustre" -} - -[ "`mount | grep /mnt/lustre`" ] || . llsetup.sh "$@" || exit -1 - -# OBD_FAIL_OST_OPEN_NET: OST will discard open request packet -touch /mnt/lustre/foo -test_fail 0x208 cat /mnt/lustre/foo - -# OBD_FAIL_OST_CLOSE_NET: OST will discard close request packet -test_fail 0x209 cat /mnt/lustre/foo - -# OBD_FAIL_OST_CREATE_NET: OST will discard create request packet -test_fail 0x204 touch /mnt/lustre/bar - -# OBD_FAIL_OST_DESTROY_NET: OST will discard destroy request packet -test_fail 0x205 rm /mnt/lustre/foo - -# OBD_FAIL_OST_BRW_NET: OST will discard read request packet -echo foo >> /mnt/lustre/foo -test_fail 0x20a cat /mnt/lustre/foo - -# OBD_FAIL_OST_BRW_NET: OST will discard write request packet -test_fail 0x20a "echo bar >> /mnt/lustre/foo" - -# OBD_FAIL_OST_PUNCH_NET: OST will discard truncate request packet -test_fail 0x208 "echo bar > /mnt/lustre/foo" - -# OBD_FAIL_OST_STATFS_NET: OST will discard statfs request packet -test_fail 0x208 df /mnt/lustre - -echo "Done." diff --git a/lustre/tests/runiozone b/lustre/tests/runiozone deleted file mode 100755 index cf198ad..0000000 --- a/lustre/tests/runiozone +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -[ -z "$SIZE" ] && SIZE=5g -[ -z "$LOOPS" ] && LOOPS=9999 -[ -z "$VERIFY" ] && VERIFY="-+d" -[ -z "$ODIR" ] && ODIR="-I" -[ -z "$REC" ] && REC=64 -[ -z "$FILE" ] && FILE=/mnt/lustre/test.$$ -[ $1 ] && SIZE=$1 -COUNT=0 -rm -f endiozone -echo 0 > /proc/sys/portals/debug -while date; do - echo "Test #$COUNT" - iozone $VERIFY $ODIR -r $REC -i 0 -i 1 -f $FILE -s $SIZE 2>&1 || exit $? - COUNT=`expr $COUNT + 1` - [ -f endiozone -o $COUNT -ge $LOOPS ] && rm -f endiozone && exit 0 -done | tee /tmp/iozone.log diff --git a/lustre/tests/runregression-brw.sh b/lustre/tests/runregression-brw.sh deleted file mode 100644 index 702bd1f..0000000 --- a/lustre/tests/runregression-brw.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/bin/sh -export PATH=/sbin:/usr/sbin:$PATH - -SRCDIR="`dirname $0`/" -. $SRCDIR/common.sh - -COUNT=${COUNT:-1000000} -COUNT_10=`expr $COUNT / 10` -COUNT_100=`expr $COUNT / 100` - -ENDRUN=endrun-`hostname` - -ECHONAME="`$OBDCTL device_list 2> /dev/null | awk '/ echo_client / { print $4 }' | tail -1`" - -if [ -z "$ECHONAME" ]; then - echo "$0: needs an ECHO_CLIENT set up first" 1>&2 - exit 1 -fi - -cleanup () { - $OBDCTL --device \$$ECHONAME destroy $OID -} - -runthreads() { - THR=$1 - DO=$2 - CNT=$3 - V=$4 - PGS=$5 - - case $DO in - test_getattr) - RW= - ;; - test_brw_write) - DO=test_brw - RW=w - ;; - test_brw_read) - DO=test_brw - RW=r - ;; - esac - - $OBDCTL --threads $THR v \$$ECHONAME $DO $CNT $RW $V $PGS $OID || exit 1 - - if [ -e $ENDRUN ]; then - rm $ENDRUN - echo "exiting because $ENDRUN file was found" - cleanup - fi -} - -[ -z "$OID" ] && OID=`$OBDCTL --device \\$$ECHONAME create 1 | awk '/is object id/ { print $6 }'` -[ -z "$OID" ] && echo "error creating object" 1>&2 && exit 1 - -# TODO: obdctl needs to check on the progress of each forked thread -# (IPC SHM, sockets?) to see if it hangs. -while date; do - PG=1 - PGVW=16 - PGVR=16 - - # We use '--threads 1 X' instead of '--device X' so that - # obdctl can monitor the forked thread for progress (TODO). - debug_server_off - debug_client_off - runthreads 1 test_brw_write 1000 -30 $PG - runthreads 1 test_brw_read 1000 -30 $PG - - [ "$PGVW" ] && runthreads 1 test_brw_write 100 -30 $PGVW - [ "$PGVW" ] && runthreads 1 test_brw_read 1600 -30 $PG - [ "$PGVR" ] && runthreads 1 test_brw_read 100 -30 $PGVR - - runthreads 1 test_brw_write $COUNT -30 $PG - runthreads 1 test_brw_read $COUNT -30 $PG - - [ "$PGVW" ] && runthreads 1 test_brw_write $COUNT_10 -30 $PGVW - [ "$PGVR" ] && runthreads 1 test_brw_read $COUNT_10 -30 $PGVR - - runthreads 2 test_brw_write $COUNT -30 $PG - runthreads 2 test_brw_read $COUNT -30 $PG - - [ "$PGVW" ] && runthreads 2 test_brw_write $COUNT_10 -30 $PGVW - [ "$PGVR" ] && runthreads 2 test_brw_read $COUNT_10 -30 $PGVR - - runthreads 10 test_brw_write $COUNT_10 -30 $PG - runthreads 10 test_brw_read $COUNT_10 -30 $PG - - [ "$PGVW" ] && runthreads 10 test_brw_write $COUNT_100 -60 $PGVW - [ "$PGVR" ] && runthreads 10 test_brw_read $COUNT_100 -60 $PGVR - - runthreads 32 test_brw_write $COUNT_10 -30 $PG - runthreads 32 test_brw_read $COUNT_10 -30 $PG - - [ "$PGVW" ] && runthreads 32 test_brw_write $COUNT_100 -60 $PGVW - [ "$PGVR" ] && runthreads 32 test_brw_read $COUNT_100 -60 $PGVR - - runthreads 64 test_brw_write $COUNT_10 -30 $PG - runthreads 64 test_brw_read $COUNT_10 -30 $PG - - [ "$PGVW" ] && runthreads 64 test_brw_write $COUNT_100 -60 $PGVW - [ "$PGVR" ] && runthreads 64 test_brw_read $COUNT_100 -60 $PGVR - - runthreads 100 test_brw_write $COUNT_100 -60 $PG - runthreads 100 test_brw_read $COUNT_100 -60 $PG - - [ "$PGVW" ] && runthreads 100 test_brw_write $COUNT_100 -60 $PGVW - [ "$PGVR" ] && runthreads 100 test_brw_read $COUNT_100 -60 $PGVR -done - -cleanup diff --git a/lustre/tests/runregression-mds.sh b/lustre/tests/runregression-mds.sh deleted file mode 100755 index ecfe0d9..0000000 --- a/lustre/tests/runregression-mds.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/sh - -SRCDIR="`dirname $0`" - -ENDRUN=endrun-`hostname` - -fail() { - echo "ERROR: $1" 1>&2 - [ $2 ] && RC=$2 || RC=1 - exit $RC -} - -export PATH=/sbin:/usr/sbin:$SRCDIR:$PATH - -cleanup() { - trap 0 - $LCONF --cleanup $OPTS -} - -[ "$COUNT" ] || COUNT=1000 - -[ "$LCONF" ] || LCONF=$SRCDIR/../utils/lconf - -[ -z "$*" ] && fail "usage: $0 [--reformat] .xml" 1 - -OSCMT="`mount | awk '/ lustre_lite / { print $3 }' | tail -1`" -if [ -z "$OSCMT" ]; then - $LCONF $@ || exit 1 - trap cleanup 0 - OSCMT="`mount | awk '/ lustre_lite / { print $3 }' | tail -1`" - [ -z "$OSCMT" ] && fail "no lustre filesystem mounted" 1 -fi - -V="-10" -while [ "$1" ]; do - case $1 in - -v|--verbose) V="1";; - --reformat) : ;; - *) OPTS="$OPTS $1" ;; - esac - shift -done - -OSCTMP=`echo $OSCMT | tr "/" "."` -USED=`df | awk "/$OSCTMP/ { print \\$3 }" | tail -1` -USED=`expr $USED + 16` # Some space for the status file - -THREADS=1 -while [ $THREADS -lt 196 ]; do - echo "starting $THREADS threads at `date`" - [ $V -gt 0 ] || echo 0 > /proc/sys/portals/debug - $SRCDIR/createdestroy /mnt/lustre/file-$$ $COUNT $V $THREADS - $SRCDIR/openclose /mnt/lustre/file-$$ $COUNT $THREADS - THREADS=`expr $THREADS + 5` - $LCONF --cleanup $OPTS || fail 10 - $LCONF $OPTS || fail 11 -done - -rm -f $ENDRUN - -NOWUSED=`df | awk "/$OSCTMP/ { print \\$3 }" | tail -1` -if [ $NOWUSED -gt $USED ]; then - echo "Space not all freed: now ${NOWUSED}kB, was ${USED}kB." 1>&2 - echo "This is normal on BA OSTs, because of subdirectories." 1>&2 -fi - -cleanup diff --git a/lustre/tests/runregression-net.sh b/lustre/tests/runregression-net.sh deleted file mode 100644 index 288f847..0000000 --- a/lustre/tests/runregression-net.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/sh -export PATH=/sbin:/usr/sbin:$PATH - -SRCDIR="`dirname $0`/" -. $SRCDIR/common.sh - -COUNT=${COUNT:-1000000} -COUNT_10=`expr $COUNT / 10` -COUNT_100=`expr $COUNT / 100` -COUNT_1000=`expr $COUNT / 1000` - -ENDRUN=endrun-`hostname` - -ECHONAME="`$OBDCTL device_list 2> /dev/null | awk '/ echo_client / { print $4 }' | tail -1`" - -if [ -z "$ECHONAME" ]; then - echo "$0: needs an ECHO_CLIENT set up first" 1>&2 - exit 1 -fi - -runthreads() { - THR=$1 - DO=$2 - CNT=$3 - V=$4 - PGS=$5 - - case $DO in - test_getattr) - RW= - ;; - - test_brw_write) - DO=test_brw - RW=w - ;; - - test_brw_read) - DO=test_brw - RW=r - ;; - esac - - $OBDCTL --threads $THR v \$$ECHONAME $DO $CNT $RW $V $PGS $OID || exit 1 - - if [ -e endrun ]; then - rm endrun - echo "exiting because endrun file was found" - exit 0 - fi -} - -[ -z "$OID" ] && OID=`$OBDCTL --device \\$$ECHONAME create 1 | awk '/is object id/ { print $6 }'` -[ -z "$OID" ] && echo "error creating object" 1>&2 && exit 1 - -# 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_write test_brw_read; do - case $CMD in - test_getattr) - PG= - PGV= - ;; - test_brw_write) - PG=1 - PGV=16 - ;; - test_brw_read) - PG=1 - PGV=16 - ;; - esac - - # We use '--threads 1 X' instead of '--device X' so that - # obdctl can monitor the forked thread for progress (TODO). - runthreads 1 $CMD 1 1 $PG - runthreads 1 $CMD 100 1 $PG - - debug_server_off - debug_client_off - runthreads 1 $CMD $COUNT_100 -10 $PG - [ "$PGV" ] && runthreads 1 $CMD $COUNT_1000 -10 $PGV - - runthreads 1 $CMD $COUNT -30 $PG - [ "$PGV" ] && runthreads 1 $CMD $COUNT_10 -30 $PGV - - runthreads 2 $CMD $COUNT_100 -30 $PG - [ "$PGV" ] && runthreads 2 $CMD $COUNT_1000 -30 $PGV - - runthreads 2 $CMD $COUNT -30 $PG - [ "$PGV" ] && runthreads 2 $CMD $COUNT_10 -30 $PGV - - runthreads 10 $CMD $COUNT_10 -30 $PG - [ "$PGV" ] && runthreads 10 $CMD $COUNT_100 -30 $PGV - - runthreads 100 $CMD $COUNT_100 -30 $PG - [ "$PGV" ] && runthreads 100 $CMD $COUNT_1000 -30 $PGV -done - -$OBDCTL --device \$$ECHONAME destroy $OID diff --git a/lustre/tests/runslabinfo b/lustre/tests/runslabinfo deleted file mode 100755 index 48d6602..0000000 --- a/lustre/tests/runslabinfo +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -while sleep 1 ; do - egrep "ll_|ldlm|filp|dentry|inode|portals|size-[0-9]* " /proc/slabinfo - echo '-----------------------' -done diff --git a/lustre/tests/runtests b/lustre/tests/runtests deleted file mode 100755 index e068a01..0000000 --- a/lustre/tests/runtests +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/sh -# -# Script which does some basic tests to ensure we haven't regressed. -# Probably a good idea to run this before doing any checkins. -# In the future this can become more fancy, but it's OK for now. - -SRCDIR="`dirname $0`" -fail() { - echo "ERROR: $1" 1>&2 - [ $2 ] && RC=$2 || RC=1 - exit $RC -} - -export PATH=/sbin:/usr/sbin:$SRCDIR:$PATH - -ERROR= -SRC=/etc -[ "$COUNT" ] || COUNT=1000 - -[ "$LCONF" ] || LCONF=$SRCDIR/../utils/lconf - -[ "$MCREATE" ] || MCREATE=$SRCDIR/../tests/mcreate - -while [ "$1" ]; do - case $1 in - *.xml) export NAME=`echo $1 | sed "s/.xml//"` ;; - esac - shift -done - -OSCMT="`mount | awk '/ lustre_lite / { print $3 }' | tail -1`" -if [ -z "$OSCMT" ]; then - sh llmount.sh - OSCMT="`mount | awk '/ lustre_lite / { print $3 }' | tail -1`" - [ -z "$OSCMT" ] && fail "no lustre filesystem mounted" 1 - I_MOUNTED="yes" -fi - -OSCTMP=`echo $OSCMT | tr "/" "."` -USED=`df | awk "/$OSCTMP/ { print \\$3 }" | tail -1` -USED=`expr $USED + 16` # Some space for the status file - -# let's start slowly here... -echo "touching $OSCMT" -touch $OSCMT || fail "can't touch $OSCMT" 2 -HOSTS=$OSCMT/hosts.$$ - -# this will cause the following cp to trigger bug #620096 -echo "create an empty file $HOSTS" -$MCREATE $HOSTS - -echo "copying /etc/hosts to $HOSTS" -cp /etc/hosts $HOSTS || fail "can't cp /etc/hosts to $HOSTS" 3 -echo "comparing /etc/hosts and $HOSTS" -diff -u /etc/hosts $HOSTS || fail "$HOSTS different" 4 -echo "renaming $HOSTS to $HOSTS.ren" -mv $HOSTS $HOSTS.ren || fail "can't rename $HOSTS to $HOSTS.ren" 5 -echo "copying /etc/hosts to $HOSTS again" -cp /etc/hosts $HOSTS || fail "can't cp /etc/hosts to $HOSTS again" 6 -echo "truncating $HOSTS" -> $HOSTS || fail "can't truncate $HOSTS" 8 -echo "removing $HOSTS" -rm $HOSTS || fail "can't remove $HOSTS" 9 - -DST=$OSCMT/runtest.$$ -# let's start slowly here... -echo "creating $DST" -mkdir $DST || fail "can't mkdir $DST" 10 - -# ok, that hopefully worked, so let's do a little more, with files that -# haven't changed in the last day (hopefully they don't change during test) -FILES=`find $SRC -type f -mtime +1 -ctime +1 | head -$COUNT` -echo "copying files from $SRC to $DST$SRC" -tar cf - $FILES | tar xvf - -C $DST || fail "copying $SRC" 11 - -echo "comparing newly copied files" -for f in $FILES; do - [ $V ] && echo "verifying $DST/$f" - diff -q $f $DST/$f || ERROR=11 -done - -[ "$ERROR" ] && fail "old and new files are different" $ERROR - -sh llmountcleanup.sh || exit 19 -sh llrmount.sh || exit 20 - -echo "comparing previously copied files" -for f in $FILES; do - [ $V ] && echo "verifying $DST/$f" - diff -q $f $DST/$f || ERROR=22 -done - -[ "$ERROR" ] && fail "old and new files are different on second diff" $ERROR - -sh llmountcleanup.sh || exit 19 -sh llrmount.sh || exit 20 - -echo "renaming $HOSTS.ren to $HOSTS" -mv $HOSTS.ren $HOSTS || fail "can't rename $HOSTS.ren to $HOSTS" 32 -echo "truncating $HOSTS" -> $HOSTS || fail "can't truncate $HOSTS" 34 -echo "removing $HOSTS" -rm $HOSTS || fail "can't remove $HOSTS again" 36 -echo "removing $DST" -rm -r $V $DST || fail "can't remove $DST" 37 - -NOWUSED=`df | awk "/$OSCTMP/ { print \\$3 }" | tail -1` -if [ $NOWUSED -gt $USED ]; then - echo "Space not all freed: now ${NOWUSED}kB, was ${USED}kB." 1>&2 - echo "This is normal on BA OSTs, because of subdirectories." 1>&2 -fi - -if [ "$I_MOUNTED" = "yes" ]; then - sh llmountcleanup.sh || exit 29 -fi diff --git a/lustre/tests/runvmstat b/lustre/tests/runvmstat deleted file mode 100755 index 6bff5ce..0000000 --- a/lustre/tests/runvmstat +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -vmstat 1 | while read LINE ; do echo "`date +%H:%M:%S`: $LINE" ; done diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh deleted file mode 100644 index da72bda..0000000 --- a/lustre/tests/sanity.sh +++ /dev/null @@ -1,218 +0,0 @@ -#!/bin/bash - -export NAME=$NAME -clean() { - echo -n "cleanup..." - sh llmountcleanup.sh > /dev/null -} -CLEAN=clean -start() { - echo -n "mounting..." - sh llrmount.sh > /dev/null - echo -n "mounted" -} -START=start - -echo '== touch .../f ; rm .../f ======================== test 0' -touch /mnt/lustre/f -rm /mnt/lustre/f -$CLEAN -$START - -echo '== mkdir .../d1; mkdir .../d1/d2 ================= test 1' -mkdir /mnt/lustre/d1 -mkdir /mnt/lustre/d1/d2 -$CLEAN -$START - -echo '== rmdir .../d1/d2; rmdir .../d1 ================= test 1b' -rmdir /mnt/lustre/d1/d2 -rmdir /mnt/lustre/d1 -$CLEAN -$START - -echo '== mkdir .../d2; touch .../d2/f ================== test 2' -mkdir /mnt/lustre/d2 -touch /mnt/lustre/d2/f -$CLEAN -$START - -echo '== rm -r .../d2; touch .../d2/f ================== test 2b' -rm -r /mnt/lustre/d2 -$CLEAN -$START - -echo '== mkdir .../d3 ================================== test 3' -mkdir /mnt/lustre/d3 -$CLEAN -$START -echo '== touch .../d3/f ================================ test 3b' -touch /mnt/lustre/d3/f -$CLEAN -$START -echo '== rm -r .../d3 ================================== test 3c' -rm -r /mnt/lustre/d3 -$CLEAN -$START - -echo '== mkdir .../d4 ================================== test 4' -mkdir /mnt/lustre/d4 -$CLEAN -$START -echo '== mkdir .../d4/d2 =============================== test 4b' -mkdir /mnt/lustre/d4/d2 -$CLEAN -$START - -echo '== mkdir .../d5; mkdir .../d5/d2; chmod .../d5/d2 = test 5' -mkdir /mnt/lustre/d5 -mkdir /mnt/lustre/d5/d2 -chmod 0666 /mnt/lustre/d5/d2 -$CLEAN -$START - -echo '== touch .../f6; chmod .../f6 ==================== test 6' -touch /mnt/lustre/f6 -chmod 0666 /mnt/lustre/f6 -$CLEAN -$START - -echo '== mkdir .../d7; mcreate .../d7/f; chmod .../d7/f = test 7' -mkdir /mnt/lustre/d7 -./mcreate /mnt/lustre/d7/f -chmod 0666 /mnt/lustre/d7/f -$CLEAN -$START - -echo '== mkdir .../d8; touch .../d8/f; chmod .../d8/f == test 8' -mkdir /mnt/lustre/d8 -touch /mnt/lustre/d8/f -chmod 0666 /mnt/lustre/d8/f -$CLEAN -$START - - -echo '== mkdir .../d9; mkdir .../d9/d2; mkdir .../d9/d2/d3 == test 9' -mkdir /mnt/lustre/d9 -mkdir /mnt/lustre/d9/d2 -mkdir /mnt/lustre/d9/d2/d3 -$CLEAN -$START - - -echo '== mkdir .../d10; mkdir .../d10/d2; touch .../d10/d2/f = test 10' -mkdir /mnt/lustre/d10 -mkdir /mnt/lustre/d10/d2 -touch /mnt/lustre/d10/d2/f -$CLEAN -$START - -echo '=================================================== test 11' -mkdir /mnt/lustre/d11 -mkdir /mnt/lustre/d11/d2 -chmod 0666 /mnt/lustre/d11/d2 -chmod 0555 /mnt/lustre/d11/d2 -$CLEAN -$START - -echo '=================================================== test 12' -mkdir /mnt/lustre/d12 -touch /mnt/lustre/d12/f -chmod 0666 /mnt/lustre/d12/f -chmod 0555 /mnt/lustre/d12/f -$CLEAN -$START - -echo '=================================================== test 13' -mkdir /mnt/lustre/d13 -cp /etc/passwd /mnt/lustre/d13/f -> /mnt/lustre/d13/f -$CLEAN -$START - - -echo '=================================================== test 14' -mkdir /mnt/lustre/d14 -touch /mnt/lustre/d14/f -rm /mnt/lustre/d14/f -$CLEAN -$START - - -echo '=================================================== test 15' -mkdir /mnt/lustre/d15 -touch /mnt/lustre/d15/f -mv /mnt/lustre/d15/f /mnt/lustre/d15/f2 -$CLEAN -$START - -echo '=================================================== test 16' -mkdir /mnt/lustre/d16 -touch /mnt/lustre/d16/f -rm -rf /mnt/lustre/d16/f -$CLEAN -$START - -echo '== symlinks: create, remove (dangling and real) === test 17' -mkdir /mnt/lustre/d17 -touch /mnt/lustre/d17/f -ln -s /mnt/lustre/d17/f /mnt/lustre/d17/l-exist -ln -s no-such-file /mnt/lustre/d17/l-dangle -ls -l /mnt/lustre/d17 -rm -f /mnt/lustre/l-dangle -rm -f /mnt/lustre/l-exist -$CLEAN -$START - -echo '== touch /mnt/lustre/f ; ls /mnt/lustre ========== test 18' -touch /mnt/lustre/f -ls /mnt/lustre -$CLEAN -$START - -echo '== touch /mnt/lustre/f ; ls -l /mnt/lustre ======= test 19' -touch /mnt/lustre/f -ls -l /mnt/lustre -rm /mnt/lustre/f -$CLEAN -$START - -echo '== touch /mnt/lustre/f ; ls -l /mnt/lustre ======= test 20' -touch /mnt/lustre/f -rm /mnt/lustre/f -echo "1 done" -touch /mnt/lustre/f -rm /mnt/lustre/f -echo "2 done" -touch /mnt/lustre/f -rm /mnt/lustre/f -echo "3 done" -$CLEAN -$START - -echo '== write to dangling link ======================= test 21' -mkdir /mnt/lustre/d21 -ln -s dangle /mnt/lustre/d21/link -echo foo >> /mnt/lustre/d21/link -cat /mnt/lustre/d21/dangle -$CLEAN -$START - -# echo '== unpack tar archive as nonroot user =========== test 22' -echo '== please fix test 22' -# mkdir /mnt/lustre/d22 -# chown 4711 /mnt/lustre/d22 -# (./setuid 4711 ; tar cf - /etc/hosts /etc/sysconfig/network | tar xfC - /mnt/lustre/d22 ; ./setuid 0) -# ls -lR /mnt/lustre/d22/etc -# $CLEAN -# $START - -echo '== O_CREAT|O_EXCL in subdir ===================== test 23' -mkdir /mnt/lustre/d23 -./toexcl /mnt/lustre/d23/f23 -./toexcl /mnt/lustre/d23/f23 -$CLEAN -$START - -echo '======================= finished =======================' -exit diff --git a/lustre/tests/setuid.c b/lustre/tests/setuid.c deleted file mode 100644 index 04dba5e..0000000 --- a/lustre/tests/setuid.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char ** argv) -{ - int rc, fsuid; - - if (argc < 2) { - printf("Usage %s fsuid\n", argv[0]); - return 1; - } - - fsuid = strtoul(argv[2], NULL, 0); - rc = setfsuid(fsuid); - if (rc) { - printf("mknod(%s) error: %s\n", argv[1], strerror(errno)); - } - return rc; -} diff --git a/lustre/tests/snaprun.sh b/lustre/tests/snaprun.sh deleted file mode 100755 index ea77cfb..0000000 --- a/lustre/tests/snaprun.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# Utility script to test several features of a snapshot filesystem -# Assumes that snapshot has already been configured -# -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -OBDDIR="`dirname $0`/.." -. $OBDDIR/demos/config.sh - -qrun ls $MNTOBD -qrun chown bin.bin $MNTOBD -qrun ls -ld $MNTOBD -qrun ls -ld $MNTSNAP -qrun cp /etc/hosts $MNTOBD -qrun ls $MNTOBD -qrun ls $MNTSNAP - -# More complicated because we can't pass ">>" as an argument easily -echo -n "Run 'echo today >> $MNTOBD/hello' [Y/n]" ; read JUNK -case $JUNK in - n*|N*) echo "not run" ;; - *) plog log "echo today >> $MNTOBD/hello" - echo "today" >> $MNTOBD/hello ;; -esac - -qrun cat $MNTOBD/hello -qrun cat $MNTSNAP/hello -qrun cat $MNTOBD/link -qrun cat $MNTSNAP/link -qrun rm $MNTOBD/goodbye -qrun ls $MNTOBD -qrun ls $MNTSNAP -qrun cat $MNTSNAP/goodbye 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/tbox.sh b/lustre/tests/tbox.sh deleted file mode 100644 index 337e1b8..0000000 --- a/lustre/tests/tbox.sh +++ /dev/null @@ -1,116 +0,0 @@ -# tbox.sh - Shell functions to manage tinderbox build reporting -# Copyright (C) 2002 Cluster File Systems, Inc. -# Gord Eagle , 2002-08-22 - -HOSTNAME=`hostname` -PROGNAME=`echo "$0" | sed -e 's%^.*/%%'` -MAILPROG="${MAILPROG-mail}" - -TBOX_PHASE=build # or test -TBOX_STARTTIME=`date +%s` -TBOX_LOG="${TBOX_LOG-/tmp/tbox.$$.$TBOX_STARTTIME.log}" -TBOX_BUILDMAIL=tinderbox_builds@lustre.org -TBOX_BUILDNAME="${TBOX_BUILDNAME-$PROGNAME-$HOSTNAME}" - -# Send a status message to the list. -tbox_status() { - [ -n "$TBOX_BUILDNAME" -a -n "$TBOX_BUILDMAIL" ] || return 0 - [ "$#" -ge 4 ] || return 1 - if [ "$#" -gt 4 ]; then - log="$5" - echo >> $log - else - log= - fi - - TREE="$1" - SUBJECT="$2" - STATUS="$3" - TIMENOW="$4" - - echo "sending tinderbox mail to $TBOX_BUILDMAIL: $TREE $SUBJECT $STATUS" - - TMPFILE="/tmp/tinderbox.boilerplate.$$.$TIMENOW" - - cat > $TMPFILE <<-EOF - tinderbox: tree: $TREE - tinderbox: starttime: $TBOX_STARTTIME - tinderbox: timenow: $TIMENOW - tinderbox: builddate: $TBOX_STARTTIME - tinderbox: status: $STATUS - tinderbox: buildname: $TBOX_BUILDNAME - tinderbox: errorparser: unix - tinderbox: END - -EOF - - cat $TMPFILE $log | $MAILPROG -s "build $SUBJECT ($TBOX_BUILDNAME)" $TBOX_BUILDMAIL - rm -f $TMPFILE -} - -# Send out the failure or success message based on exit status. -tbox_exit() { - TREE="$1" - TAILPID="$2" - CODE=${3-$?} - if [ $CODE -eq 0 ]; then - SUBJECT=successful - STATUS=success - else - SUBJECT=failed - STATUS="${TBOX_PHASE}_failed" - fi - - # Send off the status message. - trap 0 - tbox_status "$TREE" "$SUBJECT" "$STATUS" - rm -f $TBOX_LOG - - # Wait for tail to display all output, then finish it. - sleep 1 - kill $TAILPID - exit $CODE -} - -# Run a subprogram, but stop it from sending its own tinderbox -# messages. -tbox_absorb_log() { - # This probably doesn't do what you think it does... it only prepends - # TBOX_LOG= to our arguments. - set TBOX_LOG= "$@" - - # Now evaluate the command. - eval "$@" -} - -# Start the log for a given tree. -tbox_start_log() { - TREE="$1" - - # Send status messages to stdout, stderr. - exec 6>&1 7>&2 - - [ -n "$TBOX_LOG" ] || return 0 - - # Initialize the output log file. - : > $TBOX_LOG - - # Send all our output to the log. - exec >>$TBOX_LOG 2>&1 - - # Monitor it on the old stdout. - tail -f $TBOX_LOG 1>&6 & - - # Allow tail to print our last output before exiting. - trap "tbox_exit \"$TREE\" $! 1" 1 2 10 15 - trap "tbox_exit \"$TREE\" $!" 0 -} - - -# Begin writing to the log and send out the initial status. -# tbox_start TREE -tbox_start() { - TREE="$1" - tbox_start_log "$TREE" - tbox_status "$TREE" starting building "$TBOX_STARTTIME" -} diff --git a/lustre/tests/tchmod.c b/lustre/tests/tchmod.c deleted file mode 100644 index 9fcb1ac..0000000 --- a/lustre/tests/tchmod.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - mode_t mode; - - if (argc != 3) { - printf("usage: %s mode name\n", argv[0]); - return 1; - } - - mode = strtoul(argv[1], NULL, 8); - return chmod(argv[2], mode); -} diff --git a/lustre/tests/test.c b/lustre/tests/test.c deleted file mode 100755 index d4c6bf7..0000000 --- a/lustre/tests/test.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2001 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LOOP_DEVICE "/dev/loop0" -#define OBD_DEVICE "/dev/obd" - -int main (int argc, char * argv[]) -{ - int fd, rc, err = -1; - struct stat stat_buf; - struct statfs stfs; - - - if (argc < 2) { - printf("syntax: %s command [argument]\n", argv[0]); - printf("Where command is one of \"setup\", \"create\", \"destroy\", or \"sync\".\n"); - exit(1); - } - if (stat(LOOP_DEVICE, &stat_buf)) { - printf("Couldn't stat(" LOOP_DEVICE ").\n"); - exit(1); - } - printf("Device: %u\n", (unsigned int) stat_buf.st_rdev); - - fd = open (OBD_DEVICE, O_RDONLY); - if (fd == -1) { - printf("Couldn't open " OBD_DEVICE ".\n"); - exit(1); - } - - if (!strcmp(argv[1], "setup")) { - rc = ioctl(fd, OBD_IOC_SETUP, &stat_buf.st_rdev); - fprintf(stderr, "rc = %d, errno = %d\n", rc, errno); - } else if (!strcmp(argv[1], "create")) { - int iter, i; - - if (argc < 3) { - printf("create requires a nonzero argument.\n"); - exit(1); - } - - iter = atoi(argv[2]); - if (iter < 1) { - printf("create requires a nonzero argument.\n"); - exit(1); - } - printf("creating %d objects...\n", iter); - - for (i = 0; i < iter; i++) { - if ((rc = ioctl(fd, OBD_IOC_CREATE, &err))) { - fprintf(stderr, "Error; aborting.\n"); - break; - } - if ((rc = ioctl(fd, OBD_IOC_DESTROY, &err))) { - fprintf(stderr, "Error; aborting.\n"); - break; - } - } - fprintf(stderr, "rc = %d, errno = %d, err = %d\n", - rc, errno, err); - } else if (!strcmp(argv[1], "sync")) { - rc = ioctl(fd, OBD_IOC_SYNC, &err); - fprintf(stderr, "rc = %d, errno = %d, err = %d\n", - rc, errno, err); - } else if (!strcmp(argv[1], "destroy")) { - int ino; - - if (argc < 3) { - printf("destroy requires a nonzero inode number.\n"); - exit(1); - } - - ino = atoi(argv[2]); - if (ino < 1) { - printf("destroy requires a nonzero inode number.\n"); - exit(1); - } - - rc = ioctl(fd, OBD_IOC_DESTROY, &ino); - fprintf(stderr, "rc = %d, errno = %d\n", rc, errno); - } else { - printf("Invalid command, run with no arguments for help.\n"); - } - close(fd); - - return 0; -} diff --git a/lustre/tests/test2.c b/lustre/tests/test2.c deleted file mode 100755 index fbbe6bb..0000000 --- a/lustre/tests/test2.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2001 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ - -#include -#include -#include -#include -#include -#include -#include - -/* Beware when setting FSROOT that I've not made any attempts to avoid buffer - * overruns below--this is a test program, it's a static buffer. */ -#define FSROOT "/mnt" -#define OBD_ITERATIONS 10000 - -int main (int argc, char * argv[]) -{ - int fd, rc, err = -1; - struct stat stat_buf; - - if (argc < 2) { - printf("syntax: %s command\n", argv[0]); - printf("Where command is one of \"setup\" or \"create\".\n"); - exit(1); - } - - if (!strcmp(argv[1], "setup")) { - printf("This is silly.\n"); - } else if (!strcmp(argv[1], "create")) { - int i, iter; - - if (argc < 3) { - printf("create requires a nonzero argument.\n"); - exit(1); - } - - iter = atoi(argv[2]); - - if (iter < 1) { - printf("create requires a nonzero argument.\n"); - exit(1); - } - printf("creating %d files...\n", iter); - - for (i = 0; i < iter; i++) { - fd = creat(FSROOT "/foo123", S_IRWXU); - close(fd); - unlink(FSROOT "/foo123"); - } - } else { - printf("Invalid command, run with no arguments for help.\n"); - } - - return 0; -} diff --git a/lustre/tests/test_brw.c b/lustre/tests/test_brw.c deleted file mode 100644 index 196f32c..0000000 --- a/lustre/tests/test_brw.c +++ /dev/null @@ -1,209 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -// not correctly in the headers yet!! -//#define O_DIRECT 0 -#ifndef O_DIRECT -#define O_DIRECT 040000 /* direct disk access hint */ -#endif - -#define BLOCKSIZE 4096 -#define CERROR(fmt, arg...) fprintf(stderr, fmt, ## arg) -#ifndef __u64 -#define __u64 long long -#define HTON__u64(v) (v) -#endif - -#ifndef LPU64 -#define LPU64 "%Lu" -#define LPX64 "%#Lx" -#endif - -#define READ 1 -#define WRITE 2 - -#define LPDS sizeof(__u64) -int page_debug_setup(void *addr, int len, __u64 off, __u64 id) -{ - off = HTON__u64(off); - id = HTON__u64(id); - memcpy(addr, (char *)&off, LPDS); - memcpy(addr + LPDS, (char *)&id, LPDS); - - addr += len - LPDS - LPDS; - memcpy(addr, (char *)&off, LPDS); - memcpy(addr + LPDS, (char *)&id, LPDS); - - return 0; -} - -int page_debug_check(char *who, void *addr, int size, __u64 off, __u64 id) -{ - __u64 ne_off; - int err = 0; - - ne_off = HTON__u64(off); - id = HTON__u64(id); - if (memcmp(addr, (char *)&ne_off, LPDS)) { - CERROR("%s: for offset "LPU64" off: "LPX64" != "LPX64"\n", - who, off, *(__u64 *)addr, ne_off); - err = -EINVAL; - } - if (memcmp(addr + LPDS, (char *)&id, LPDS)) { - CERROR("%s: for offset "LPU64" id: "LPX64" != "LPX64"\n", - who, off, *(__u64 *)(addr + LPDS), id); - err = -EINVAL; - } - - addr += size - LPDS - LPDS; - if (memcmp(addr, (char *)&ne_off, LPDS)) { - CERROR("%s: for offset "LPU64" end off: "LPX64" != "LPX64"\n", - who, off, *(__u64 *)addr, ne_off); - err = -EINVAL; - } - if (memcmp(addr + LPDS, (char *)&id, LPDS)) { - CERROR("%s: for offset "LPU64" end id: "LPX64" != "LPX64"\n", - who, off, *(__u64 *)(addr + LPDS), id); - err = -EINVAL; - } - - return err; -} -#undef LPDS - -void usage(char *prog) -{ - fprintf(stderr, - "usage: %s file count [[d]{r|w|rw} [pages_per_vec [objid]]]\n", - prog); - exit(1); -} - -int main(int argc, char **argv) -{ - int fd; - char *buf; - long long count, last, offset; - long pg_vec, len; - long long objid = 3; - int flags = 0; - int cmd = 0; - char *end; - int rc; - - if (argc < 3 || argc > 6) - usage(argv[0]); - - count = strtoull(argv[2], &end, 0); - if (*end) { - fprintf(stderr, "%s: invalid count '%s'\n", argv[0], argv[2]); - usage(argv[0]); - } - if (argc >= 4) { - if (strchr(argv[3], 'r')) { - cmd = READ; - flags = O_RDONLY; - } - if (strchr(argv[3], 'w')) { - cmd |= WRITE; - flags = O_RDWR | O_CREAT; - } - if (strchr(argv[3], 'd')) { - flags |= O_DIRECT; - } - if (!cmd) - usage(argv[0]); - } else { - cmd = READ | WRITE; - flags = O_RDWR | O_CREAT | O_DIRECT; - } - - if (argc >= 5) { - pg_vec = strtoul(argv[4], &end, 0); - if (*end) { - fprintf(stderr, "%s: invalid pages_per_vec '%s'\n", - argv[0], argv[4]); - usage(argv[0]); - } - } - len = pg_vec * BLOCKSIZE; - last = (long long)count * len; - - if (argc >= 6) { - objid = strtoull(argv[5], &end, 0); - if (*end) { - fprintf(stderr, "%s: invalid objid '%s'\n", - argv[0], argv[5]); - usage(argv[0]); - } - } - - printf("%s: %s on %s(objid "LPX64") for "LPU64"x%ld pages \n", - argv[0], flags & O_DIRECT ? "directio" : "i/o", - argv[1], objid, count, pg_vec); - - buf = mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0); - if (!buf) { - fprintf(stderr, "%s: no buffer memory %s\n", - argv[0], strerror(errno)); - return 2; - } - - fd = open(argv[1], flags | O_LARGEFILE); - if (fd == -1) { - fprintf(stderr, "%s: cannot open %s: %s\n", argv[0], - argv[1], strerror(errno)); - return 3; - } - - for (offset = 0; offset < last && cmd & WRITE; offset += len) { - int i; - - for (i = 0; i < len; i += BLOCKSIZE) - page_debug_setup(buf + i, BLOCKSIZE, offset + i, objid); - - rc = write(fd, buf, len); - - for (i = 0; i < len; i += BLOCKSIZE) { - if (page_debug_check("write", buf + i, BLOCKSIZE, - offset + i, objid)) - return 10; - } - - if (rc != len) { - fprintf(stderr, "%s: write error: %s, rc %d\n", - argv[0], strerror(errno), rc); - return 4; - } - } - - if (lseek(fd, 0, SEEK_SET) != 0) { - fprintf(stderr, "%s: cannot seek %s\n", - argv[0], strerror(errno)); - return 5; - } - - for (offset = 0; offset < last && cmd && READ; offset += len) { - int i; - - rc = read(fd, buf, len); - if (rc != len) { - fprintf(stderr, "%s: read error: %s, rc %d\n", - argv[0], strerror(errno), rc); - return 6; - } - - for (i = 0; i < len; i += BLOCKSIZE) { - if (page_debug_check("read", buf + i, BLOCKSIZE, - offset + i, objid)) - return 11; - } - } - - return 0; -} diff --git a/lustre/tests/testreq.c b/lustre/tests/testreq.c deleted file mode 100644 index a0ce1de..0000000 --- a/lustre/tests/testreq.c +++ /dev/null @@ -1,140 +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.sf.net/projects/lustre/ - * - * 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 -#include -#include -#include -#include -#include - -#define _GNU_SOURCE -#include -#undef _GNU_SOURCE - -#include - -static void usage(char *argv0, int status) -{ - printf( -"Usage: %s [OPTION...]\n\ -\n\ ---getattr \n\ ---setattr \n\ ---readpage \n\ ---open \n\ ---close \n\ ---create \n", argv0); - - exit(status); -} - -int main(int argc, char **argv) -{ - int fd = 0; - int rc = 0; - int c = 0; - long cmd = 0; - unsigned long arg; - char *short_opts = "h", *name = argv[0]; - static struct option long_opts[] = { -#define OPT_GETATTR -2 - {"getattr", no_argument, NULL, OPT_GETATTR}, -#define OPT_READPAGE -3 - {"readpage", no_argument, NULL, OPT_READPAGE}, -#define OPT_SETATTR -4 - {"setattr", no_argument, NULL, OPT_SETATTR}, -#define OPT_CREATE -5 - {"create", no_argument, NULL, OPT_CREATE}, -#define OPT_OPEN -6 - {"open", no_argument, NULL, OPT_OPEN}, -#define OPT_CLOSE -7 - {"close", required_argument, NULL, OPT_CLOSE}, -#define OPT_HELP 'h' - {"help", no_argument, NULL, OPT_HELP}, - {0} - }; - - do { - c = getopt_long(argc, argv, short_opts, long_opts, NULL); - - switch (c) { - case OPT_HELP: - usage(argv[0], 0); - break; - case OPT_GETATTR: - cmd = IOC_REQUEST_GETATTR; - name = "getattr"; - arg = 2; - break; - case OPT_SETATTR: - cmd = IOC_REQUEST_SETATTR; - name = "setattr"; - arg = 2; - break; - case OPT_READPAGE: - cmd = IOC_REQUEST_READPAGE; - name = "readpage"; - arg = 2; - break; - case OPT_CREATE: - cmd = IOC_REQUEST_CREATE; - name ="create"; - arg = 2; - break; - case OPT_OPEN: - cmd = IOC_REQUEST_OPEN; - name = "open"; - arg = 2; - break; - case OPT_CLOSE: - cmd = IOC_REQUEST_CLOSE; - name = "close"; - arg = strtoul(optarg, NULL, 0); - break; - case '?': - usage(argv[0], 1); - } - } while (c != -1); - - if (cmd == 0) - usage(argv[0], 1); - - fd = open("/dev/request", O_RDONLY); - if (fd == -1) { - fprintf(stderr, "error opening /dev/request: %s\n", - strerror(errno)); - exit(1); - } - - fprintf(stderr, "Executing %s test (arg=%lu)...\n", name, arg); - if (cmd == IOC_REQUEST_OPEN) { - rc = ioctl(fd, cmd, &arg); - printf("%lu\n", arg); - } else - rc = ioctl(fd, cmd, arg); - fprintf(stderr, "result code: %d\n", rc); - - return 0; -} diff --git a/lustre/tests/toexcl.c b/lustre/tests/toexcl.c deleted file mode 100644 index da13217..0000000 --- a/lustre/tests/toexcl.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - int rc; - - if (argc != 2) { - printf("usage: %s name\n", argv[0]); - return 1; - } - - rc = open(argv[1], O_CREAT|O_EXCL, 0644); - if (rc == -1) - printf("open failed: %s\n", strerror(errno)); - else - printf("open success.\n"); - return 0; -} diff --git a/lustre/tests/trivial.sh b/lustre/tests/trivial.sh deleted file mode 100755 index abfecf0..0000000 --- a/lustre/tests/trivial.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# Simple test of mount and unmount -sh llsetup.sh obdecho.cfg net-local.cfg client-echo.cfg || exit 1 -# FIXME: Scan logs for any unusual things (unbalanced allocations, errors) -sh llcleanup.sh obdecho.cfg net-local.cfg client-echo.cfg -OBD_LEAK=`dmesg | awk '/obd memory leaked/ { print $7 }'` -[ "$OBD_LEAK" != "0" ] && echo "OBD memory leak: $OBD_LEAK bytes" && ERR=1 -NAL_LEAK=`dmesg | awk '/NAL unloaded/ { print $7 }' -[ "$NAL_LEAK" != "0)" ] && echo "Portals memory leak: $NAL_LEAK" && ERR=1 -/sbin/lsmod | grep -q portals && "Portals module still loaded" && ERR=1 -exit $ERR diff --git a/lustre/tests/truncate.c b/lustre/tests/truncate.c deleted file mode 100644 index c49fb15..0000000 --- a/lustre/tests/truncate.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - unsigned long long off; - int err; - - if (argc != 3) { - printf("usage %s file bytes\n", argv[0]); - return 1; - } - - off = strtoull(argv[2], NULL, 0); - err = truncate64(argv[1], off); - if ( err ) - printf("Error truncating %s to %Ld: %s\n", argv[1], off, - strerror(errno)); - - return err; -} diff --git a/lustre/tests/uml.sh b/lustre/tests/uml.sh deleted file mode 100644 index 7d8da8f..0000000 --- a/lustre/tests/uml.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash - -config=${1-uml.xml} -LMC=${LMC-../utils/lmc} -TMP=${TMP:-/tmp} - -MDSDEV=$TMP/mds1 -MDSSIZE=50000 - -OSTDEV1=$TMP/ost1 -OSTDEV2=$TMP/ost2 -OSTSIZE=100000 - -# NOTE - You can't have different MDS/OST nodes and also have clients on the -# MDS/OST nodes without using --endlevel and --startlevel during lconf. -# You can put both MDS/OST on one node and client can be there too. -# CLIENTS is a space-separated list of client nodes. -# -# The rule is that both the MDS and the OST must be set up before any -# of the clients can be started, so plan accordingly. - -# Three separate systems -MDSNODE=uml1 -OSTNODE=uml2 -CLIENTS="uml3" - -# Single system with additional clients -#MDSNODE=uml1 -#OSTNODE=uml1 -#CLIENTS="$MDSNODE client" - -# Two systems with client on MDS, and additional clients (set up OST first) -#MDSNODE=uml1 -#OSTNODE=uml2 -#CLIENTS="$MDSNODE client" - -# Two systems with client on OST, and additional clients (set up MDS first) -#MDSNODE=uml1 -#OSTNODE=uml2 -#CLIENTS="$OSTNODE client" - -rm -f $config - -# create nodes -for NODE in $MDSNODE $OSTNODE $CLIENTS; do - eval [ \$$NODE ] && continue - ${LMC} -m $config --node $NODE --net $NODE tcp || exit 1 - eval "$NODE=done" -done - -# configure mds server -${LMC} -m $config --format --node $MDSNODE --mds mds1 $MDSDEV $MDSSIZE ||exit 10 - -# configure ost -${LMC} -m $config --lov lov1 mds1 65536 0 0 || exit 20 -${LMC} -m $config --node $OSTNODE --lov lov1 --ost $OSTDEV1 $OSTSIZE || exit 21 -${LMC} -m $config --node $OSTNODE --lov lov1 --ost $OSTDEV2 $OSTSIZE || exit 22 - -# create client config(s) -for NODE in $CLIENTS; do - ${LMC} -m $config --node $NODE --mtpt /mnt/lustre mds1 lov1 || exit 30 -done - 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/.cvsignore b/lustre/utils/.cvsignore deleted file mode 100644 index 7695706..0000000 --- a/lustre/utils/.cvsignore +++ /dev/null @@ -1,13 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -tags -TAGS -obdctl -lctl -lfind -lstripe diff --git a/lustre/utils/Makefile.am b/lustre/utils/Makefile.am deleted file mode 100644 index 6a5483d..0000000 --- a/lustre/utils/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -# Administration utilities Makefile -DEFS= - -CFLAGS:=-g -O2 -I$(top_srcdir)/utils -I$(PORTALS)/include -I$(srcdir)/../include -Wall -L$(PORTALSLIB) -KFLAGS:= -CPPFLAGS = $(HAVE_LIBREADLINE) -obdctl_LDADD := $(LIBREADLINE) -lctl_LDADD := $(LIBREADLINE) -lptlctl -sbin_PROGRAMS = lctl lfind lstripe obdctl -sbin_SCRIPTS = lconf lmc -obdctl_SOURCES = parser.c obdctl.c obd.c parser.h obdctl.h -lctl_SOURCES = parser.c obd.c lctl.c parser.h -lfind_SOURCES = lfind.c -lstripe_SOURCES = lstripe.c -lfind_CPPFLAGS = -D_XOPEN_SOURCE=500 -EXTRA_DIST = $(sbin_SCRIPTS) - -include $(top_srcdir)/Rules diff --git a/lustre/utils/ha_assist.sh b/lustre/utils/ha_assist.sh deleted file mode 100755 index 0f737f5..0000000 --- a/lustre/utils/ha_assist.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -echo primary `date` >> /tmp/halog - - diff --git a/lustre/utils/ha_assist2.sh b/lustre/utils/ha_assist2.sh deleted file mode 100755 index a07d8b5..0000000 --- a/lustre/utils/ha_assist2.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -set -vx -date -echo "ha assist checking for problems" -sleep 3 -if [ ! -e /tmp/halog ]; then - echo "no problems, exiting" - exit -fi - -echo "removing /tmp/halog" -rm /tmp/halog - -echo secondary start `date` -echo "- please supply a new mds" - -# invoke ldap client here - - -/usr/src/portals/linux/utils/ptlctl < -# 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 - - -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/linux/utils/')) - for d in syspath: - prog = os.path.join(d,cmd) - 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(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 - - -# ============================================================ -# 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) - - 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): - 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('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)) - 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) - 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('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) - 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 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') - 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) - self.add_module('lustre/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('lustre/mdc', 'mdc') - self.add_module('lustre/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 'No host entry found.' - 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): - base = os.path.dirname(cmd) - if os.access(base+"/Makefile", os.R_OK): - config.src_dir(base + "/../../") - -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 - 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') - - setupModulePath(sys.argv[0]) - 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/lctl.c b/lustre/utils/lctl.c deleted file mode 100644 index 2e6324c..0000000 --- a/lustre/utils/lctl.c +++ /dev/null @@ -1,239 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Peter J. Braam - * Author: Phil Schwan - * 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. - * - */ - - -#include -#include -#include -#include "obdctl.h" -#include "parser.h" - -static int jt_quit(int argc, char **argv) { - Parser_quit(argc, argv); - return 0; -} - -static int jt_noop(int argc, char **argv) { - return 0; -} - -static int jt_opt_ignore_errors(int argc, char **argv) { - Parser_ignore_errors(1); - return 0; -} - -command_t cmdlist[] = { - /* Metacommands */ - {"--device", jt_opt_device, 0, - "run after connecting to device \n" - "--device "}, - {"--threads", jt_opt_threads, 0, - "run separate instances of on device \n" - "--threads "}, - {"--ignore_errors", jt_opt_ignore_errors, 0, - "ignore errors that occur during script processing\n" - "--ignore_errors"}, - {"ignore_errors", jt_opt_ignore_errors, 0, - "ignore errors that occur during script processing\n" - "ignore_errors"}, - - /* Network configuration commands */ - {"==== network config ====", jt_noop, 0, "network config"}, - {"network", jt_ptl_network, 0, "commands that follow apply to net\n" - "usage: network "}, - {"connect", jt_ptl_connect, 0, "connect to a remote nid\n" - "usage: connect [[ ] | ]"}, - {"disconnect", jt_ptl_disconnect, 0, "disconnect from a remote nid\n" - "usage: disconnect "}, - {"mynid", jt_ptl_mynid, 0, "inform the socknal of the local nid. " - "The nid defaults to hostname for tcp networks and is automatically " - "setup for elan/myrinet networks.\n" - "usage: mynid [nid]"}, - {"add_uuid", jt_ptl_add_uuid, 0, "associate a UUID with a nid\n" - "usage: add_uuid "}, - {"close_uuid", jt_ptl_close_uuid, 0, "disconnect a UUID\n" - "usage: close_uuid )"}, - {"del_uuid", jt_ptl_del_uuid, 0, "delete a UUID association\n" - "usage: del_uuid "}, - {"add_route", jt_ptl_add_route, 0, - "add an entry to the routing table\n" - "usage: add_route [target]"}, - {"del_route", jt_ptl_del_route, 0, - "delete an entry from the routing table\n" - "usage: del_route "}, - {"route_list", jt_ptl_print_routes, 0, "print the routing table\n" - "usage: route_list"}, - {"recv_mem", jt_ptl_rxmem, 0, "set socket receive buffer size, " - "if size is omited the current size is reported.\n" - "usage: recv_mem [size]"}, - {"send_mem", jt_ptl_txmem, 0, "set socket send buffer size, " - "if size is omited the current size is reported.\n" - "usage: send_mem [size]"}, - {"nagle", jt_ptl_nagle, 0, "enable/disable nagle, omiting the " - "argument will cause the current nagle setting to be reported.\n" - "usage: nagle [on/off]"}, - - /* Device selection commands */ - {"=== device selection ===", jt_noop, 0, "device selection"}, - {"newdev", jt_obd_newdev, 0, "create a new device\n" - "usage: newdev"}, -#if 0 - {"uuid2dev", jt_obd_uuid2dev, 0, - "find device attached with and make it the current device\n" - "usage: uuid2dev "}, -#endif - {"name2dev", jt_obd_name2dev, 0, - "find device attached with and make it the current device\n" - "usage: name2dev "}, - {"device", jt_obd_device, 0, "set current device to \n" - "usage: device "}, - {"device_list", jt_obd_list, 0, "show all devices\n" - "usage: device_list"}, - {"lustre_build_version", jt_get_version, 0, - "print the build version of lustre\n" - "usage: lustre_build_version"}, - - /* Device configuration commands */ - {"==== device config =====", jt_noop, 0, "device config"}, - {"attach", jt_obd_attach, 0, - "set the type of the current device (with and )\n" - "usage: attach type [name [uuid]]"}, - {"setup", jt_obd_setup, 0, - "type specific device configuration information\n" - "usage: setup "}, - {"cleanup", jt_obd_cleanup, 0, "cleanup previously setup device\n" - "usage: cleanup"}, - {"detach", jt_obd_detach, 0, - "remove driver (and name and uuid) from current device\n" - "usage: detach"}, - {"lov_setconfig", jt_obd_lov_setconfig, 0, - "write lov configuration to an mds device\n" - "usage: lov_setconfig lov-uuid stripe-count stripe-size offset pattern UUID1 [UUID2 ...]"}, - {"lov_getconfig", jt_obd_lov_getconfig, 0, - "read lov configuration from an mds device\n" - "usage: lov_getconfig lov-uuid"}, - - /* Device operations */ - {"=== device operations ==", jt_noop, 0, "device operations"}, - {"probe", jt_obd_connect, 0, - "build a connection handle to a device. This command is used to " - "suspend configuration until lctl has ensured that the mds and osc " - "services are available. This is to avoid mount failures in a " - "rebooting cluster.\n" - "usage: probe [timeout]"}, - {"close", jt_obd_disconnect, 0, - "close the connection handle\n" - "usage: close"}, - {"getattr", jt_obd_getattr, 0, - "get attribute for OST object \n" - "usage: getattr "}, - {"setattr", jt_obd_setattr, 0, - "set mode attribute for OST object \n" - "usage: setattr "}, - {"create", jt_obd_create, 0, - "create OST objects (with )\n" - "usage: create [num [mode [verbose]]]"}, - {"destroy", jt_obd_destroy, 0, - "destroy OST object [num [verbose]]\n" - "usage: destroy objects, starting at objid "}, - {"test_getattr", jt_obd_test_getattr, 0, - "do getattrs (on OST object (objid+1 on each thread))\n" - "usage: test_getattr [verbose [[t]objid]]"}, - {"test_brw", jt_obd_test_brw, 0, - "do bulk read/writes ( per I/O, on OST object )\n" - "usage: test_brw [t] [write [verbose [npages [[t]objid]]]]"}, - {"test_ldlm", jt_obd_test_ldlm, 0, - "perform lock manager test\n" - "usage: test_ldlm"}, - {"ldlm_regress_start", jt_obd_ldlm_regress_start, 0, - "start lock manager stress test\n" - "usage: ldlm_regress_start [numthreads [refheld [numres [numext]]]]"}, - {"ldlm_regress_stop", jt_obd_ldlm_regress_stop, 0, - "stop lock manager stress test (no args)\n"}, - {"dump_ldlm", jt_obd_dump_ldlm, 0, - "dump all lock manager state (no args)"}, - {"lov_set_osc_active", jt_obd_lov_set_osc_active, 0, - "(de)activate an OSC in a LOV\n" - "usage: lov_set_osc_active <1|0 (active|inactive)>"}, - {"newconn", jt_obd_newconn, 0, "newconn [newuuid]"}, - {"failconn", jt_obd_failconn, 0, "failconn "}, - - /* Debug commands */ - {"======== debug =========", jt_noop, 0, "debug"}, - {"debug_kernel", jt_dbg_debug_kernel, 0, - "get debug buffer and dump to a file" - "usage: debug_kernel [file] [raw]"}, - {"debug_file", jt_dbg_debug_file, 0, - "read debug buffer from input and dump to output" - "usage: debug_file [output] [raw]"}, - {"clear", jt_dbg_clear_debug_buf, 0, "clear kernel debug buffer\n" - "usage: clear"}, - {"mark", jt_dbg_mark_debug_buf, 0,"insert marker text in kernel debug buffer\n" - "usage: mark "}, - {"filter", jt_dbg_filter, 0, "filter message type\n" - "usage: filter "}, - {"show", jt_dbg_show, 0, "show message type\n" - "usage: show "}, - {"debug_list", jt_dbg_list, 0, "list subsystem and debug types\n" - "usage: debug_list "}, - {"modules", jt_dbg_modules, 0, - "provide gdb-friendly module information\n" - "usage: modules "}, - {"panic", jt_dbg_panic, 0, "force the kernel to panic\n" - "usage: panic"}, - - /* User interface commands */ - {"======= control ========", jt_noop, 0, "control commands"}, - {"help", Parser_help, 0, "help"}, - {"exit", jt_quit, 0, "quit"}, - {"quit", jt_quit, 0, "quit"}, - { 0, 0, 0, NULL } -}; - - - -int main(int argc, char **argv) -{ - int rc; - - setlinebuf(stdout); - - ptl_initialize(argc, argv); - if (obd_initialize(argc, argv) < 0) - exit(2); - if (dbg_initialize(argc, argv) < 0) - exit(3); - - if (argc > 1) { - rc = Parser_execarg(argc - 1, argv + 1, cmdlist); - } else { - Parser_init("lctl > ", cmdlist); - rc = Parser_commands(); - } - - obd_cleanup(argc, argv); - return rc; -} - diff --git a/lustre/utils/lfind.c b/lustre/utils/lfind.c deleted file mode 100644 index d0b4c49..0000000 --- a/lustre/utils/lfind.c +++ /dev/null @@ -1,323 +0,0 @@ -#define _XOPEN_SOURCE 500 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define printk printf -#include -#include -#include - -#warning Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c -#define MAX_LOV_UUID_COUNT 1000 -#define OBD_NOT_FOUND ((__u32)-1) - -char * cmd; -struct option longOpts[] = { - {"help", 0, 0, 'h'}, - {"obd", 1, 0, 'o'}, - {"query", 0, 0, 'o'}, - {"verbose", 0, 0, 'v'}, - {0, 0, 0, 0} - }; -int query; -int verbose; -char * shortOpts = "ho:qv"; -char * usageMsg = "[ --obd | --query ] ..."; - -int max_ost_count = MAX_LOV_UUID_COUNT; -obd_uuid_t * obduuid; -__u32 obdcount; -__u32 obdindex; -char * buf; -int buflen; -struct obd_ioctl_data data; -struct lov_desc desc; -obd_uuid_t * uuids; -int uuidslen; -int cfglen; -struct lov_mds_md *lmm; -int lmmlen; - -void init(); -void usage(FILE *stream); -void errMsg(char *fmt, ...); -void processPath(char *path); -int processFile( - const char *path, - const struct stat *sp, - int flag, - struct FTW *ftwp - ); -__u32 getobdindex(const char *path); - -int -main (int argc, char **argv) { - int c; - - cmd = basename(argv[0]); - - while ((c = getopt_long(argc, argv, shortOpts, longOpts, NULL)) != -1) { - switch (c) { - case 'o': - if (obduuid) { - errMsg("obd '%s' already specified: '%s'.", - obduuid, optarg); - exit(1); - } - - obduuid = (obd_uuid_t *)optarg; - break; - case 'h': - usage(stdout); - exit(0); - case 'q': - query++; - break; - case 'v': - verbose++; - break; - case '?': - usage(stderr); - exit(1); - default: - errMsg("Internal error. Valid '%s' unrecognized.", - argv[optind - 1]); - usage(stderr); - exit(1); - } - } - - if (optind >= argc) { - usage(stderr); - exit(1); - } - - if (obduuid == NULL) - query++; - - init(); - - do { - processPath(argv[optind]); - } while (++optind < argc); - - exit (0); -} - -void -init() -{ - int datalen, desclen; - - datalen = size_round(sizeof(data)); - desclen = size_round(sizeof(desc)); - uuidslen = size_round(max_ost_count * sizeof(*uuids)); - cfglen = datalen + desclen + uuidslen; - lmmlen = lov_mds_md_size(max_ost_count); - if (cfglen > lmmlen) - buflen = cfglen; - else - buflen = lmmlen; - -#warning max ioctl buffer size currently hardcoded to 8192 - if (buflen > 8192) { - int nuuids, remaining, nluoinfos; - - buflen = 8192; - nuuids = (buflen - datalen - desclen) / sizeof(*uuids); - uuidslen = size_round(nuuids * sizeof(*uuids)); - remaining = nuuids * sizeof(*uuids); - if (uuidslen > remaining) - nuuids--; - nluoinfos = (buflen - sizeof(*lmm)) / sizeof(*lmm->lmm_objects); - if (nuuids > nluoinfos) - max_ost_count = nluoinfos; - else - max_ost_count = nuuids; - - cfglen = datalen + desclen + uuidslen; - lmmlen = lov_mds_md_size(max_ost_count); - } - - if ((buf = malloc(buflen)) == NULL) { - errMsg("Unable to allocate %d bytes of memory for ioctl's.", - buflen); - exit(1); - } - - lmm = (struct lov_mds_md *)buf; - uuids = (obd_uuid_t *)buf; -} - -void -usage(FILE *stream) -{ - fprintf(stream, "usage: %s %s\n", cmd, usageMsg); -} - -void -errMsg(char *fmt, ...) -{ - va_list args; - - fprintf(stderr, "%s: ", cmd); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - fprintf(stderr, "\n"); -} - -void -processPath(char *path) -{ - obdindex = OBD_NOT_FOUND; - nftw((const char *)path, processFile, 128, FTW_PHYS|FTW_MOUNT); -} - -int -processFile(const char *path, const struct stat *sp, int flag, struct FTW *ftwp) -{ - int fd; - int count; - int rc; - int i; - - if (flag != FTW_F) - return 0; - - if ((obdcount == 0) && (getobdindex(path) == OBD_NOT_FOUND)) { - /* terminate nftw walking this tree */ - return(1); - } - - if ((fd = open(path, O_RDONLY)) < 0) { - errMsg("open \"%.20s\" failed.", path); - perror("open"); - exit(1); - } - - memset((void *)buf, 0, buflen); - lmm->lmm_magic = LOV_MAGIC; - lmm->lmm_ost_count = max_ost_count; - - if ((rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE, (void *)lmm)) < 0) { - errMsg("LL_IOC_LOV_GETSTRIPE ioctl failed."); - perror("ioctl"); - exit(1); - } - - close(fd); - - if (query || verbose) - printf("\n%s:\n", path); - - if (verbose) { - printf("lmm_magic: 0x%x\n", lmm->lmm_magic); - printf("lmm_object_id: "LPX64"\n", lmm->lmm_object_id); - printf("lmm_stripe_offset: %d\n", lmm->lmm_stripe_offset); - printf("lmm_stripe_count: %d\n", lmm->lmm_stripe_count); - printf("lmm_ost_count: %d\n", lmm->lmm_ost_count); - printf("lmm_stripe_pattern: %d\n", lmm->lmm_stripe_pattern); - } - - count = lmm->lmm_ost_count; - - if (query || verbose) { - struct lov_object_id *loi; - __u64 oid; - - loi = lmm->lmm_objects; - - printf("obdidx\tobjid\n"); - - for (i = 0; i < count; i++, loi++) - if ((oid = loi->l_object_id)) - printf("%6d\t%5lld\n", i, (long long)oid); - - if (query) - return(0); - } - - if (lmm->lmm_objects[obdindex].l_object_id) - printf("%s\n", path); - - return(0); -} - -__u32 -getobdindex(const char *path) -{ - obd_uuid_t *uuidp; - int fd; - int rc; - int i; - - if ((fd = open(path, O_RDONLY)) < 0) { - errMsg("open \"%.20s\" failed.", path); - perror("open"); - exit(1); - } - - data.ioc_inllen1 = sizeof(desc); - data.ioc_inlbuf1 = (char *)&desc; - data.ioc_inllen2 = uuidslen; - data.ioc_inlbuf2 = (char *)uuids; - data.ioc_inllen3 = 0; - - memset(&desc, 0, sizeof(desc)); - desc.ld_tgt_count = max_ost_count; - - if (obd_ioctl_pack(&data, &buf, buflen)) { - errMsg("internal buffering error."); - exit(1); - } - - rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf); - if (rc) { - errMsg("OBD_IOC_LOV_GET_CONFIG ioctl failed: %d.", errno); - perror("ioctl"); - exit(1); - } - - if (obd_ioctl_unpack(&data, buf, buflen)) { - errMsg("Invalid reply from ioctl."); - exit(1); - } - - close(fd); - - obdcount = desc.ld_tgt_count; - - if (query) { - printf("OBDS:\n"); - for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) - printf("%4d: %s\n", i, (char *)uuidp); - - return(0); - } - - for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) { - rc = strncmp((const char *)obduuid, (const char *)uuidp, - sizeof(*uuidp)); - if (rc == 0) { - obdindex = i; - break; - } - } - - if (obdindex == OBD_NOT_FOUND) { - errMsg("obd UUID '%s' not found.", obduuid); - return(OBD_NOT_FOUND); - } - - return(0); -} diff --git a/lustre/utils/llanalyze b/lustre/utils/llanalyze deleted file mode 100644 index d2c9273..0000000 --- a/lustre/utils/llanalyze +++ /dev/null @@ -1,268 +0,0 @@ -#!/usr/bin/perl - -use Getopt::Long; -use Term::ANSIColor; - -GetOptions("pid=i" => \$pid, - "trace!" => \$trace, - "silent!" => \$silent, - "rpctrace!" => \$rpctrace, - "nodlm!" => \$nodlm, - "noclass!" => \$noclass, - "nonet!" => \$nonet); - -print "pid: $pid, nodlm $nodlm nonet $nonet trace $trace\n"; - - -$subsys->{UNDEFINED} = 0; -$subsys->{MDC} = 1; -$subsys->{MDS} = 2; -$subsys->{OSC} = 3; -$subsys->{OST} = 4; -$subsys->{CLASS} = 5; -$subsys->{OBDFS} = 6; -$subsys->{LLITE} = 7; -$subsys->{RPC} = 8; -$subsys->{EXT2OBD} = 9; -$subsys->{PORTALS} = 10; -$subsys->{SOCKNAL} = 11; -$subsys->{QSWNAL} = 12; -$subsys->{PINGER} = 13; -$subsys->{FILTER} = 14; -$subsys->{TRACE} = 15; # obdtrace, not to be confused with D_TRACE */ -$subsys->{ECHO} = 16; -$subsys->{LDLM} = 17; -$subsys->{LOV} = 18; -$subsys->{GMNAL} = 19; -$subsys->{PTLROUTER} = 20; - - -$masks->{TRACE} = 1 << 0; # /* ENTRY/EXIT markers */ -$masks->{INODE} = 1 << 1; # -$masks->{SUPER} = 1 << 2; # -$masks->{EXT2} = 1 << 3; # /* anything from ext2_debug */ -$masks->{MALLOC} = 1 << 4; # /* print malloc, free information */ -$masks->{CACHE} = 1 << 5; # /* cache-related items */ -$masks->{INFO} = 1 << 6; # /* general information */ -$masks->{IOCTL} = 1 << 7; # /* ioctl related information */ -$masks->{BLOCKS} = 1 << 8; # /* ext2 block allocation */ -$masks->{NET} = 1 << 9; # /* network communications */ -$masks->{WARNING} = 1 << 10; # -$masks->{BUFFS} = 1 << 11; # -$masks->{OTHER} = 1 << 12; # -$masks->{DENTRY} = 1 << 13; # -$masks->{PORTALS} = 1 << 14; # /* ENTRY/EXIT markers */ -$masks->{PAGE} = 1 << 15; # /* bulk page handling */ -$masks->{DLMTRACE} = 1 << 16; # -$masks->{ERROR} = 1 << 17; # /* CERROR} = ...) == CDEBUG} = D_ERROR, ...) */ -$masks->{EMERG} = 1 << 18; # /* CEMERG} = ...) == CDEBUG} = D_EMERG, ...) */ -$masks->{HA} = 1 << 19; # /* recovery and failover */ -$masks->{RPCTRACE} = 1 << 19; # /* recovery and failover */ - -sub extractpid -{ - $line = shift; -# print "$_\n"; - if ($line =~ m/\(\) ([0-9]*)\+[0-9]*\):/) { - return $1; - } - if ($line =~ m/\(\) ([0-9]*) | [0-9]*\+[0-9]*\):/) { - return $1; - } -} - -sub entering -{ - $_ = shift; - $entering = /Process entered/; -} - -sub leaving -{ - $_ = shift; - $entering = /Process leaving/; -} - -sub getsubsys -{ - my ($subsys, $mask) = split ":"; - return hex($subsys); -} - -sub getmask -{ - my ($subsys, $mask) = split ":"; - return hex($mask); -} - -sub setcolor -{ - my $linemask = shift; - if ($linemask == $masks->{TRACE}) { - print color("yellow on_black"); - } - if ($linemask == $masks->{DLMTRACE}) { - print color("magenta on_black"); - } - if ($linemask == $masks->{DLM}) { - print color("magenta on_black"); - } - if ($linemask == $masks->{DENTRY}) { - print color("red on_black"); - } -} - -sub study_lock -{ - $_ = shift; - my $rc; - - $rc = /completion callback handler START ns: (.*) lock: (.*) lrc: (.*) mode/; - if ($rc) { - $completion_callbacks{$1}->{$2} = $3; -# print color("white"); -# print "---CP CB START: $1 $2 $3\n"; -# print color("reset"); - } - $rc = /callback handler finished.* ns: (.*) lock: (.*) lrc: (.*) mode/; - if ($rc) { -# print color("white"); -# print "---CP CB END: $1 $2 $3 deleting $completion_callbacks{$1}->{$2}\n"; -# print color("reset"); - delete $completion_callbacks{$1}->{$2}; - } - - if ($rc) { - $rc = /client blocking AST callback handler START ns: (.*) lock: (.*) lrc: (.*) mode/; - $blocking_callbacks{$1}->{$2} = $3; -# print color("white"); -# print "---BL CB START: $1 $2\n"; -# print color("reset"); - } - $rc = /client blocking callback handler END ns: (.*) lock: (.*) lrc: (.*) mode/; - if ($rc) { -# print color("white"); -# print "---BL CB END: $1 $2 $3 deleting $blocking_callbacks{$1}->{$2}\n"; -# print color("reset"); - delete $blocking_callbacks{$1}->{$2}; - } - - $rc = /ldlm_lock_addref.*ns: (.*) lock: (.*) lrc: (.*) mode/; -# print color("white"); -# print "------>addref ns: $1 lock: $2 lrc: $3\n" if ($rc); -# print color("reset"); - $locks{$1}->{$2} = {$3} if ($rc); - $rc = /ldlm_lock_decref.*ns: (.*) lock: (.*) lrc: (.*) mode/; -# print color("white"); -# print "------>decref ns: $1 lock: $2 lrc: $3\n" if ($rc); -# print color("reset"); - $locks{$1}->{$2} = {$3} if ($rc); -} - -sub hanging_locks -{ - my $found; - my $ns; - - foreach (keys %completion_callbacks) { - $ns = $_; - $found = 0; - foreach (keys %{$completion_callbacks{$ns}}) { - if (!$found) { - print "Unfinished completions in ns $ns: \n"; - $found =1; - } - print " lock: $_ lrc: $completion_callbacks{$ns}->{$_}\n"; - } - } - foreach (keys %blocking_callbacks) { - $ns = $_; - $found = 0; - foreach (keys %{$blocking_callbacks{$ns}}) { - if (!$found) { - print "Unfinished blocking in ns $ns: \n"; - $found =1; - } - printf(" lock: $_ lrc: %s\n", $blocking_callbacks{$ns}->{$_}); - } - } - -} - -sub study_intent -{ - $_ = shift; - my $rc; - - $rc = /D_IT UP dentry (.*) fsdata/; - delete $it{$1} if ($rc); - $rc = /D_IT DOWN dentry (.*) fsdata/; - $it{$1} = "yes" if ($rc); -} - -sub unmatched_intents { - my $found; - foreach (keys %it) { - if (!$found) { - print "Unmatched intents: \n"; - $found =1; - } - print " $_\n"; - } -} - -while () { - $linepid = extractpid($_); - $linemask = getmask($_); - $linesubsys = getsubsys($_); - -# printf "---> mask %x subsys %x\n", $linemask, $linesubsys; - - if (leaving($_)) { - chop $prefix->{$linepid}; - chop $prefix->{$linepid}; - } - - if ($linemask == $masks->{DENTRY}) { - study_intent($_); - } - if ($linemask == $masks->{DLMTRACE}) { - study_lock($_); - } - - if ( !$pid || $linepid == $pid) { - next if ($rpctrace && $linemask != $masks->{RPCTRACE}); - next if ($trace && $linemask != $masks->{TRACE}); - - - next if ($nodlm && - ( $linesubsys == $subsys->{LDLM})); - next if ($noclass && - ( $linesubsys == $subsys->{CLASS})); - - next if ($nonet && - ( $linesubsys == $subsys->{RPC} || - $linesubsys == $subsys->{NET} || - $linesubsys == $subsys->{PORTALS} || - $linesubsys == $subsys->{SOCKNAL} || - $linesubsys == $subsys->{QSWNAL} || - $linesubsys == $subsys->{GMNAL})); - - -# printf "sub/mask: %s - %s\n", getsubsys($_), getmask($_); - if (!$silent) { - setcolor($linemask); - printf("%s%s", $prefix->{$linepid}, $_); - print color("reset"); - } - # last if $count++ > 100; - } - if (entering($_)) { - $prefix->{$linepid} .= ' '; - } -} - - -unmatched_intents(); -hanging_locks(); -# printf "argv %s pid %d\n", $ARGV[0], extractpid($ARGV[0]); diff --git a/lustre/utils/lmc b/lustre/utils/lmc deleted file mode 100755 index 3d7c7bf..0000000 --- a/lustre/utils/lmc +++ /dev/null @@ -1,850 +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. -# - -""" -lmc - lustre configurtion data manager - - Basic plan for lmc usage: -# create nodes -./lmc --output config.xml --node server --net server1 tcp -./lmc --merge config.xml --node client --net client1 tcp -./lmc --merge config.xml --node client --route gw lo [hi] -./lmc --merge config.xml --router --node gw1 --net gw1 tcp -./lmc --merge config.xml --node gw1 --net 1 elan - -./lmc --merge config.xml --route elan 1 1 100 -./lmc --merge config.xml --route tcp gw1 ba1 - - - -# configure server -./lmc --merge config.xml --node server --mds mds1 /tmp/mds1 50000 - -# create lov -./lmc --merge config.xml --lov lov1 mds1 65536 0 0 -./lmc --merge config.xml --node server --lov lov1 --ost /tmp/ost1 100000 -./lmc --merge config.xml --node server --lov lov1 --ost /tmp/ost2 100000 - -# create client config -./lmc --merge config.xml --node client --mtpt /mnt/lustre mds1 lov1 - -""" - -import sys, os, getopt, string -import xml.dom.minidom -from xml.dom.ext import PrettyPrint - - -DEFAULT_PORT = 988 # XXX What is the right default acceptor port to use? - -def usage(): - print """usage: lmc [--node --ost | --mtpt | --lov] args -Commands: ---node node_name - Node_name by itself it will create a new node. If the --router - option is used when creating a new node, then that node will also - be configured as a router. When used with other commands it - specifies the node to modify. - ---net hostname nettype [port, recv_buf, send_buf] - Nettype is either tcp, toe, elan, or gm. - Requires --node - ---route net gw lo [hi] - This command is used to create routes. NET is the - network type this route will be used on. The GW is an address of - one of the local interfaces. LO and HI represent a range of - addresses that can be reached through the gateway. If HI is not - set, then a route to the specific host in LO is created. - ---mds device [size] - Create a MDS using the device - Requires --node - ---lov lov_name [mds_name stripe_sz sub_stripe_count pattern] - Creates a logical volume - When used with other commands, it specifics the lov to modify - ---ost device [size] - Creates an OBD/OST/OSC configuration triplet for a new device. - When used on "host", the device will be initialized and the OST - will be enabled. On client nodes, the OSC will be avaiable. - Requires --node - Optional --obduuid Specifies the UUID used for the obd. - If --lov lov_name is used, this device is added to lov. - ---mtpt /mnt/point mds_name lov_name|osc_name - Creates a client mount point. - Requires --node - -Options: ---merge="xml file" Add the new objects to an existing file ---format Format the partitions if unformated - NB: The autoformat option has been disabled until a safe - method is implemented to determine if a block device has a - filesystem. ---reformat Reformat partitions (this should be an lconf arg, - I think) ---obdtype="obdtype" Specifiy obdtype: valid ones are obdecho and obdfilter. - This is only useful for the --ost command. - The device parameters are ignored for the obdecho type. -""" - sys.exit(1) - -def error(*args): - msg = string.join(map(str,args)) - print "Error: ", msg - sys.exit(1) - -def warning(*args): - msg = string.join(map(str,args)) - print "Warning: ", msg - -# -# manage names and uuids -# need to initialize this by walking tree to ensure -# no duplicate names or uuids are created. -# this are just place holders for now. -# consider changing this to be like OBD-dev-host -def new_name(base): - ctr = 2 - ret = base - while names.has_key(ret): - ret = "%s_%d" % (base, ctr) - ctr = 1 + ctr - names[ret] = 1 - return ret - -def new_uuid(name): - return "%s_UUID" % (name) - -ldlm_name = 'ldlm' -ldlm_uuid = 'ldlm_UUID' -def new_lustre(dom): - """Create a new empty lustre document""" - # adding ldlm here is a bit of a hack, but one is enough. - str = """ - - """ % (ldlm_name, ldlm_uuid) - return dom.parseString(str) - -names = {} -uuids = {} - -def init_names(doc): - """initialize auto-name generation tables""" - global names, uuids - # get all elements that contain a name attribute - for n in doc.childNodes: - if n.nodeType == n.ELEMENT_NODE: - if getName(n): - names[getName(n)] = 1 - uuids[getUUID(n)] = 1 - init_names(n) - -def get_format_flag(options): - if options.has_key('format'): - if options['format']: - return 'yes' - return 'no' - -############################################################ -# Build config objects using DOM -# -class GenConfig: - doc = None - dom = None - def __init__(self, doc): - self.doc = doc - - def ref(self, type, uuid): - """ generate <[type]_ref uuidref="[uuid]"/> """ - tag = "%s_ref" % (type) - ref = self.doc.createElement(tag) - ref.setAttribute("uuidref", uuid) - return ref - - def newService(self, tag, name, uuid): - """ create a new service elmement, which requires name and uuid attributes """ - new = self.doc.createElement(tag) - new.setAttribute("name", name); - new.setAttribute("uuid", uuid); - return new - - def addText(self, node, str): - txt = self.doc.createTextNode(str) - node.appendChild(txt) - - def addElement(self, node, tag, str=None): - """ create a new element and add it as a child to node. If str is passed, - a text node is created for the new element""" - new = self.doc.createElement(tag) - if str: - self.addText(new, str) - node.appendChild(new) - return new - - def network(self, name, uuid, hostname, net, port=0, tcpbuf=0): - """create node""" - network = self.newService("network", name, uuid) - network.setAttribute("type", net); - self.addElement(network, "server", hostname) - if port: - self.addElement(network, "port", "%d" %(port)) - if tcpbuf: - self.addElement(network, "send_mem", "%d" %(tcpbuf)) - self.addElement(network, "recv_mem", "%d" %(tcpbuf)) - - return network - - def route(self, net_type, gw, lo, hi): - """ create one entry for the route table """ - ref = self.doc.createElement('route') - ref.setAttribute("type", net_type) - ref.setAttribute("gw", gw) - ref.setAttribute("lo", lo) - if hi: - ref.setAttribute("hi", hi) - return ref - - def node(self, name, uuid): - """ create a host """ - node = self.newService("node", name, uuid) - self.addElement(node, 'profile') - return node - - def ldlm(self, name, uuid): - """ create a ldlm """ - ldlm = self.newService("ldlm", name, uuid) - return ldlm - - def obd(self, name, uuid, fs, obdtype, devname, format, dev_size=0): - obd = self.newService("obd", name, uuid) - obd.setAttribute('type', obdtype) - if fs: - self.addElement(obd, "fstype", fs) - if devname: - dev = self.addElement(obd, "device", devname) - if (dev_size): - dev.setAttribute("size", "%s" % (dev_size)) - self.addElement(obd, "autoformat", format) - return obd - - def osc(self, name, uuid, obd_uuid, net_uuid): - osc = self.newService("osc", name, uuid) - osc.appendChild(self.ref("ost", net_uuid)) - osc.appendChild(self.ref("obd", obd_uuid)) - return osc - - def ost(self, name, uuid, obd_uuid, net_uuid): - ost = self.newService("ost", name, uuid) - ost.appendChild(self.ref("network", net_uuid)) - ost.appendChild(self.ref("obd", obd_uuid)) - return ost - - def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_count, pattern): - lov = self.newService("lov", name, uuid) - lov.appendChild(self.ref("mds", mds_uuid)) - devs = self.addElement(lov, "devices" ) - devs.setAttribute("stripesize", stripe_sz) - devs.setAttribute("stripecount", stripe_count) - devs.setAttribute("pattern", pattern) - return lov - - def lovconfig(self, name, uuid, lov_uuid): - lovconfig = self.newService("lovconfig", name, uuid) - lovconfig.appendChild(self.ref("lov", lov_uuid)) - return lovconfig - - def mds(self, name, uuid, fs, devname, format, net_uuid, node_uuid, - failover_uuid = "", dev_size=0 ): - mds = self.newService("mds", name, uuid) - self.addElement(mds, "fstype", fs) - dev = self.addElement(mds, "device", devname) - if dev_size: - dev.setAttribute("size", "%s" % (dev_size)) - self.addElement(mds, "autoformat", format) - mds.appendChild(self.ref("network", net_uuid)) - mds.appendChild(self.ref("node", node_uuid)) - if failover_uuid: - mds.appendChild(self.ref("failover", failover_uuid)) - return mds - - def mountpoint(self, name, uuid, mds_uuid, osc_uuid, path): - mtpt = self.newService("mountpoint", name, uuid) - mtpt.appendChild(self.ref("mds", mds_uuid)) - mtpt.appendChild(self.ref("osc", osc_uuid)) - self.addElement(mtpt, "path", path) - return mtpt - - def echo_client(self, name, uuid, osc_uuid): - ec = self.newService("echo_client", name, uuid) - ec.appendChild(self.ref("osc", osc_uuid)) - return ec - -############################################################ -# Utilities to query a DOM tree -# Using this functions we can treat use config information -# directly as a database. -def getName(n): - return n.getAttribute('name') - -def getUUID(node): - return node.getAttribute('uuid') - - -def findByName(lustre, name, tag = ""): - for n in lustre.childNodes: - if n.nodeType == n.ELEMENT_NODE: - if tag and n.nodeName != tag: - continue - if getName(n) == name: - return n - else: - n = findByName(n, name) - if n: return n - return None - - -def lookup(node, uuid): - for n in 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 - - -def mds2node(lustre, mds_name): - """ Find the node a MDS is configured on """ - mds = findByName(lustre, mds_name, 'mds') - ref = mds.getElementsByTagName('node_ref') - if not ref: - error("mds2node:", "no node_ref found for", '"'+mds_name+'"') - node_uuid = ref[0].getAttribute('uuidref') - node = lookup(lustre, node_uuid) - if not node: - error('mds2node:', "no node found for :", '"'+mds_name+'"') - return node - - -def name2uuid(lustre, name, tag="", fatal=1): - ret = findByName(lustre, name, tag) - if not ret: - if fatal: - error('name2uuid:', '"'+name+'"', tag, 'element not found.') - else: - return "" - return getUUID(ret) - - -# XXX: assumes only one network element per node. will fix this -# as soon as support for routers is added -def get_net_uuid(lustre, node_name): - """ get a network uuid for a node_name """ - node = findByName(lustre, node_name, "node") - if not node: - error ('get_net_uuid:', '"'+node_name+'"', "node element not found.") - net = node.getElementsByTagName('network') - if net: - return getUUID(net[0]) - return None - - -def lov_add_osc(gen, lov, osc_uuid): - devs = lov.getElementsByTagName('devices') - if len(devs) == 1: - devs[0].appendChild(gen.ref("osc", osc_uuid)) - else: - error("No devices element found for LOV:", lov) - - -def node_add_profile(gen, node, ref, uuid): - ret = node.getElementsByTagName('profile') - if not ret: - error('node has no profile:', node) - ret[0].appendChild(gen.ref(ref, uuid)) - -def get_attr(dom_node, attr, default=""): - v = dom_node.getAttribute(attr) - if v: - return v - return default - -############################################################ -# Top level commands -# -def do_add_node(gen, lustre, options, node_name): - uuid = new_uuid(node_name) - node = gen.node(node_name, uuid) - node_add_profile(gen, node, 'ldlm', ldlm_uuid) - if options.has_key('router'): - node.setAttribute('router', '1') - lustre.appendChild(node) - return node - - -def add_node(gen, lustre, options, args): - """ create a node with a network config """ - if len(args) > 1: - usage() - - node_name = options['node'] - - ret = findByName(lustre, node_name, "node") - if ret: - print "Node:", node_name, "exists." - return - do_add_node(gen, lustre, options, node_name) - - -def add_net(gen, lustre, options, args): - """ create a node with a network config """ - if len(args) < 2: - usage() - - node_name = options['node'] - nid = args[0] - net_type = args[1] - port = 0 - tcpbuf = 0 - - if net_type in ('tcp', 'toe'): - if len(args) > 2: - port = int(args[2]) - else: - port = DEFAULT_PORT - if options.has_key('tcpbuf'): - tcpbuf = int(options['tcpbuf']) - elif net_type in ('elan', 'gm'): - port = 0 - else: - print "Unknown net_type: ", net_type - sys.exit(2) - - ret = findByName(lustre, node_name, "node") - if not ret: - node = do_add_node(gen, lustre, options, node_name) - else: - node = ret - net_name = new_name('NET_'+ node_name +'_'+ net_type) - net_uuid = new_uuid(net_name) - node.appendChild(gen.network(net_name, net_uuid, nid, net_type, port, tcpbuf)) - node_add_profile(gen, node, "network", net_uuid) - - -def add_route(gen, lustre, options, args): - """ create a node with a network config """ - if len(args) < 3: - usage() - - node_name = options['node'] - net_type= args[0] - gw = args[1] - lo = args[2] - hi = '' - - if len(args) > 3: - hi = args[3] - - node = findByName(lustre, node_name, "node") - if not node: - error (node_name, " not found.") - - netlist = node.getElementsByTagName('network') - net = netlist[0] - rlist = net.getElementsByTagName('route_tbl') - if len(rlist) > 0: - rtbl = rlist[0] - else: - rtbl = gen.addElement(net, 'route_tbl') - rtbl.appendChild(gen.route(net_type, gw, lo, hi)) - - -def add_mds(gen, lustre, options, args): - fstype = 'extN' - - if len(args) < 1: - usage() - - if options.has_key('node'): - node_name = options['node'] - else: - error("--mds requires a --node argument") - - if options.has_key('fstype'): - fstype = options['fstype'] - - mds_name = new_name(options['mds']) - if mds_name != options['mds']: - warning("name:", options['mds'], "already used. using:", mds_name) - devname = args[0] - if len(args) > 1: - size = args[1] - else: - size = 0 - - mds_uuid = new_uuid(mds_name) - - node_uuid = name2uuid(lustre, node_name, 'node') - - node = findByName(lustre, node_name, "node") - node_add_profile(gen, node, "mds", mds_uuid) - net_uuid = get_net_uuid(lustre, node_name) - if not net_uuid: - error("NODE: ", node_name, "not found") - - mds = gen.mds(mds_name, mds_uuid, fstype, devname, get_format_flag(options), - net_uuid, node_uuid, dev_size=size) - lustre.appendChild(mds) - - -def add_ost(gen, lustre, options, args): - lovname = '' - obdtype = 'obdfilter' - devname = '' - size = 0 - fstype = 'extN' - - if options.has_key('node'): - node_name = options['node'] - else: - error("--ost requires a --node argument") - - if options.has_key('lov'): - lovname = options['lov'] - - if options.has_key('obdtype'): - obdtype = options['obdtype'] - if options.has_key('fstype'): - fstype = options['fstype'] - if obdtype == 'obdecho': - fstype = '' - else: - if len(args) < 1: - usage() - devname = args[0] - if len(args) > 1: - size = args[1] - - obdname = new_name('OBD_'+ node_name) - oscname = new_name('OSC_'+ node_name) - ostname = new_name('OST_'+ node_name) - if options.has_key('obduuid'): - obd_uuid = options['obduuid'] - obd = lookup(lustre, obd_uuid) - if obd: - error("Duplicate OBD UUID:", obd_uuid) - else: - obd_uuid = new_uuid(obdname) - ost_uuid = new_uuid(ostname) - osc_uuid = new_uuid(oscname) - - net_uuid = get_net_uuid(lustre, node_name) - if not net_uuid: - error("NODE: ", node_name, "not found") - - obd = gen.obd(obdname, obd_uuid, fstype, obdtype, devname, get_format_flag(options), size) - ost = gen.ost(ostname, ost_uuid, obd_uuid, net_uuid) - osc = gen.osc(oscname, osc_uuid, obd_uuid, ost_uuid) - - if lovname: - lov = findByName(lustre, lovname, "lov") - if not lov: - error('add_ost:', '"'+lovname+'"', "lov element not found.") - lov_add_osc(gen, lov, osc_uuid) - - node = findByName(lustre, node_name, "node") - node_add_profile(gen, node, 'obd', obd_uuid) - node_add_profile(gen, node, 'ost', ost_uuid) - - lustre.appendChild(obd) - lustre.appendChild(osc) - lustre.appendChild(ost) - - -# this is generally only used by llecho.sh -def add_osc(gen, lustre, options, args): - """ add the osc to the profile for this node. """ - if len(args) < 1: - usage() - osc_name = args[0] - if options.has_key('node'): - node_name = options['node'] - else: - error("--osc requires a --node argument") - osc_uuid = name2uuid(lustre, osc_name) # either 'osc' or 'lov' - node = findByName(lustre, node_name, "node") - node_add_profile(gen, node, 'osc', osc_uuid) - - -#ditto -def add_echo_client(gen, lustre, options, args): - """ add an echo client to the profile for this node. """ - if len(args) < 1: - usage() - lov_name = args[0] - if options.has_key('node'): - node_name = options['node'] - else: - error("--echo_client requires a --node argument") - node = findByName(lustre, node_name, "node") - - echoname = new_name('ECHO_'+ node_name) - echo_uuid = new_uuid(echoname) - node_add_profile(gen, node, 'echo_client', echo_uuid) - - lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0) - if not lov_uuid: - lov_uuid = name2uuid(lustre, lov_name, tag='osc', fatal=1) - - echo = gen.echo_client(echoname, echo_uuid, lov_uuid) - lustre.appendChild(echo) - - -def add_lov(gen, lustre, options, args): - """ create a lov """ - if len(args) < 4: - usage() - - name = new_name(options['lov']) - if name != options['lov']: - warning("name:", options['lov'], "already used. using:", name) - - mds_name = args[0] - stripe_sz = args[1] - stripe_count = args[2] - pattern = args[3] - uuid = new_uuid(name) - - ret = findByName(lustre, name, "lov") - if ret: - error("LOV: ", name, " already exists.") - - mds_uuid = name2uuid(lustre, mds_name, 'mds') - lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_count, pattern) - lustre.appendChild(lov) - - # add an lovconfig entry to the mds profile - lovconfig_name = new_name('LVCFG_' + name) - lovconfig_uuid = new_uuid(lovconfig_name) - node = mds2node(lustre, mds_name) - node_add_profile(gen, node, "lovconfig", lovconfig_uuid) - lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid) - lustre.appendChild(lovconfig) - - - -def add_mtpt(gen, lustre, options, args): - """ create mtpt on a node """ - if len(args) < 3: - usage() - - if options.has_key('node'): - node_name = options['node'] - else: - error("--mtpt requires a --node argument") - - path = args[0] - mds_name = args[1] - lov_name = args[2] - - name = new_name('MNT_'+ node_name) - - ret = findByName(lustre, name, "mountpoint") - if ret: - error("MOUNTPOINT: ", name, " already exists.") - - mds_uuid = name2uuid(lustre, mds_name, tag='mds') - lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0) - if not lov_uuid: - lov_uuid = name2uuid(lustre, lov_name, tag='osc', fatal=1) - - uuid = new_uuid(name) - mtpt = gen.mountpoint(name, uuid, mds_uuid, lov_uuid, path) - node = findByName(lustre, node_name, "node") - if not node: - error('node:', node_name, "not found.") - node_add_profile(gen, node, "mountpoint", uuid) - lustre.appendChild(mtpt) - - -############################################################ -# Command line processing -# -def parse_cmdline(argv): - short_opts = "ho:i:m:" - long_opts = ["ost", "osc", "mtpt", "lov=", "node=", "mds=", "net", - "echo_client", "tcpbuf=", - "route", "router", "merge=", "format", "reformat", "output=", - "obdtype=", "fstype=", "obduuid=", "in=", "help", "batch="] - 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 == "--ost": - options['ost'] = 1 - if o == "--osc": - options['osc'] = 1 - if o == "--echo_client": - options['echo_client'] = 1 - if o == "--mds": - options['mds'] = a - if o == "--net": - options['net'] = 1 - if o == "--mtpt": - options['mtpt'] = 1 - if o == "--node": - options['node'] = a - if o == "--route": - options['route'] = 1 - if o == "--router": - options['router'] = 1 - if o == "--lov": - options['lov'] = a - - # Options for commands - if o == "--obdtype": - options['obdtype'] = a - if o == "--fstype": - options['fstype'] = a - if o == "--obduuid": - options['obduuid'] = a - if o == "--tcpbuf": - options['tcpbuf'] = a - - # 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 == "--format": - options['format'] = 1 - if o == "--reformat": - options['reformat'] = 1 - if o == "--batch": - options['batch'] = a - if o in ("--in" , "-i"): - options['in'] = a - - return options, args - - -# simple class for profiling -import time -class chrono: - def __init__(self): - self._start = 0 - def start(self): - self._stop = 0 - self._start = time.time() - def stop(self, msg=''): - self._stop = time.time() - if msg: - self.display(msg) - def dur(self): - return self._stop - self._start - def display(self, msg): - d = self.dur() - str = '%s: %g secs' % (msg, d) - print str - -############################################################ -# Main -# -def do_command(gen, lustre, options, args): - if options.has_key('ost'): - add_ost(gen, lustre, options, args) - elif options.has_key('osc'): - add_osc(gen, lustre, options, args) - elif options.has_key('echo_client'): - add_echo_client(gen, lustre, options, args) - elif options.has_key('mtpt'): - add_mtpt(gen, lustre, options, args) - elif options.has_key('mds'): - add_mds(gen, lustre, options, args) - elif options.has_key('net'): - add_net(gen, lustre, options, args) - elif options.has_key('lov'): - add_lov(gen, lustre, options, args) - elif options.has_key('route'): - add_route(gen, lustre, options, args) - elif options.has_key('node'): - add_node(gen, lustre, options, args) - else: - print "Missing command" - usage() - -def main(): - options, args = parse_cmdline(sys.argv[1:]) - outFile = '-' - - if options.has_key('merge'): - outFile = options['merge'] - if os.access(outFile, os.R_OK): - doc = xml.dom.minidom.parse(outFile) - else: - doc = new_lustre(xml.dom.minidom) - elif options.has_key('in'): - doc = xml.dom.minidom.parse(options['in']) - else: - doc = new_lustre(xml.dom.minidom) - - if options.has_key('output'): - outFile = options['output'] - - lustre = doc.documentElement - init_names(lustre) - if lustre.tagName != "lustre": - print "Existing config not valid." - sys.exit(1) - - gen = GenConfig(doc) - - if options.has_key('batch'): - fp = open(options['batch']) - batchCommands = fp.readlines() - fp.close() - for cmd in batchCommands: - options, args = parse_cmdline(string.split(cmd)) - do_command(gen, lustre, options, args) - else: - do_command(gen, lustre, options, args) - - if outFile == '-': - PrettyPrint(doc) - else: - PrettyPrint(doc, open(outFile,"w")) - -if __name__ == "__main__": - main() - - 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 2df183a..0000000 --- a/lustre/utils/lustre.dtd +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lustre/utils/mds-failover-sample b/lustre/utils/mds-failover-sample deleted file mode 100755 index f6269f4..0000000 --- a/lustre/utils/mds-failover-sample +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -MDS=NET_mds_tcp_UUID -MDSHOST=mds - -/r/src/lustre/utils/lctl < - * Author: Phil Schwan - * Author: Andreas Dilger - * 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. - * - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define printk printf - -#include -#include -#include -#include /* for IOC_LOV_SET_OSC_ACTIVE */ -#include /* for struct lov_stripe_md */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include /* needed for PAGE_SIZE - rread */ - -#define __KERNEL__ -#include -#undef __KERNEL__ - -#include "obdctl.h" -#include "parser.h" -#include - -#define SHMEM_STATS 1 -#if SHMEM_STATS -# include -# include - -# define MAX_SHMEM_COUNT 1024 -static long long *shared_counters; -static long long counter_snapshot[2][MAX_SHMEM_COUNT]; -struct timeval prev_time; -#endif - -int fd = -1; -uint64_t conn_addr = -1; -uint64_t conn_cookie; -char rawbuf[8192]; -char *buf = rawbuf; -int max = sizeof(rawbuf); - -static int thread; -static struct lov_stripe_md saved_lsm; -static char lsm_valid = 0; - -static int getfd(char *func); -static char *cmdname(char *func); - -#define IOCINIT(data) \ -do { \ - memset(&data, 0, sizeof(data)); \ - data.ioc_version = OBD_IOCTL_VERSION; \ - data.ioc_addr = conn_addr; \ - data.ioc_cookie = conn_cookie; \ - data.ioc_len = sizeof(data); \ - if (fd < 0) { \ - fprintf(stderr, "No device open, use device\n"); \ - return 1; \ - } \ -} while (0) - -#define IOC_PACK(func, data) \ -do { \ - if (obd_ioctl_pack(&data, &buf, max)) { \ - fprintf(stderr, "error: %s: invalid ioctl\n", \ - cmdname(func)); \ - return -2; \ - } \ -} while (0) - -#define IOC_UNPACK(func, data) \ -do { \ - if (obd_ioctl_unpack(&data, buf, max)) { \ - fprintf(stderr, "error: %s: invalid reply\n", \ - cmdname(func)); \ - return -2; \ - } \ -} while (0) - -char *obdo_print(struct obdo *obd) -{ - char buf[1024]; - - sprintf(buf, "id: "LPX64"\ngrp: "LPX64"\natime: "LPU64"\nmtime: "LPU64 - "\nctime: "LPU64"\nsize: "LPU64"\nblocks: "LPU64 - "\nblksize: %u\nmode: %o\nuid: %d\ngid: %d\nflags: %x\n" - "obdflags: %x\nnlink: %d,\nvalid %x\n", - obd->o_id, obd->o_gr, obd->o_atime, obd->o_mtime, obd->o_ctime, - obd->o_size, obd->o_blocks, obd->o_blksize, obd->o_mode, - obd->o_uid, obd->o_gid, obd->o_flags, obd->o_obdflags, - obd->o_nlink, obd->o_valid); - return strdup(buf); -} - - -#define BAD_VERBOSE (-999999999) - -#define N2D_OFF 0x100 /* So we can tell between error codes and devices */ - -static int do_name2dev(char *func, char *name) -{ - struct obd_ioctl_data data; - int rc; - - if (getfd(func)) - return -1; - - IOCINIT(data); - - data.ioc_inllen1 = strlen(name) + 1; - data.ioc_inlbuf1 = name; - - IOC_PACK(func, data); - rc = ioctl(fd, OBD_IOC_NAME2DEV, buf); - if (rc < 0) { - fprintf(stderr, "error: %s: %s - %s\n", cmdname(func), - name, strerror(rc = errno)); - return rc; - } - IOC_UNPACK(func, data); - - return data.ioc_dev + N2D_OFF; -} - -/* - * resolve a device name to a device number. - * supports a number or name. - * FIXME: support UUID - */ -static int parse_devname(char *func, char *name) -{ - int rc; - int ret = -1; - - if (!name) - return ret; - if (name[0] == '$') { - rc = do_name2dev(func, name + 1); - if (rc >= N2D_OFF) { - ret = rc - N2D_OFF; - printf("%s is device %d\n", name, ret); - } else { - fprintf(stderr, "error: %s: %s: %s\n", cmdname(func), - name, "device not found"); - } - } else - ret = strtoul(name, NULL, 0); - - return ret; -} - -static char *cmdname(char *func) -{ - static char buf[512]; - - if (thread) { - sprintf(buf, "%s-%d", func, thread); - return buf; - } - - return func; -} - -static int getfd(char *func) -{ - if (fd == -1) - fd = open("/dev/obd", O_RDWR); - if (fd == -1) { - fprintf(stderr, "error: %s: opening /dev/obd: %s\n" - "hint: lustre kernel modules may not be loaded.\n", - cmdname(func), strerror(errno)); - return -1; - } - return 0; -} - -#define difftime(a, b) \ - ((double)(a)->tv_sec - (b)->tv_sec + \ - ((double)((a)->tv_usec - (b)->tv_usec) / 1000000)) - -static int be_verbose(int verbose, struct timeval *next_time, - __u64 num, __u64 *next_num, int num_total) -{ - struct timeval now; - - if (!verbose) - return 0; - - if (next_time != NULL) - gettimeofday(&now, NULL); - - /* A positive verbosity means to print every X iterations */ - if (verbose > 0 && - (next_num == NULL || num >= *next_num || num >= num_total)) { - *next_num += verbose; - if (next_time) { - next_time->tv_sec = now.tv_sec - verbose; - next_time->tv_usec = now.tv_usec; - } - return 1; - } - - /* A negative verbosity means to print at most each X seconds */ - if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0){ - next_time->tv_sec = now.tv_sec - verbose; - next_time->tv_usec = now.tv_usec; - if (next_num) - *next_num = num; - return 1; - } - - return 0; -} - -static int get_verbose(char *func, const char *arg) -{ - int verbose; - char *end; - - if (!arg || arg[0] == 'v') - verbose = 1; - else if (arg[0] == 's' || arg[0] == 'q') - verbose = 0; - else { - verbose = (int)strtoul(arg, &end, 0); - if (*end) { - fprintf(stderr, "error: %s: bad verbose option '%s'\n", - cmdname(func), arg); - return BAD_VERBOSE; - } - } - - if (verbose < 0) - printf("Print status every %d seconds\n", -verbose); - else if (verbose == 1) - printf("Print status every operation\n"); - else if (verbose > 1) - printf("Print status every %d operations\n", verbose); - - return verbose; -} - -int do_disconnect(char *func, int verbose) -{ - int rc; - struct obd_ioctl_data data; - - if (conn_addr == -1) - return 0; - - IOCINIT(data); - - rc = ioctl(fd, OBD_IOC_DISCONNECT, &data); - if (rc < 0) { - fprintf(stderr, "error: %s: OPD_IOC_DISCONNECT %s\n", - cmdname(func),strerror(errno)); - } else { - if (verbose) - printf("%s: disconnected conn "LPX64"\n", cmdname(func), - conn_addr); - conn_addr = -1; - } - - return rc; -} - -#if SHMEM_STATS -static void shmem_setup(void) -{ - /* Create new segment */ - int shmid = shmget(IPC_PRIVATE, sizeof(counter_snapshot[0]), 0600); - - if (shmid == -1) { - fprintf(stderr, "Can't create shared memory counters: %s\n", - strerror(errno)); - return; - } - - /* Attatch to new segment */ - shared_counters = (long long *)shmat(shmid, NULL, 0); - - if (shared_counters == (long long *)(-1)) { - fprintf(stderr, "Can't attach shared memory counters: %s\n", - strerror(errno)); - shared_counters = NULL; - return; - } - - /* Mark segment as destroyed, so it will disappear when we exit. - * Forks will inherit attached segments, so we should be OK. - */ - if (shmctl(shmid, IPC_RMID, NULL) == -1) { - fprintf(stderr, "Can't destroy shared memory counters: %s\n", - strerror(errno)); - } -} - -static inline void shmem_reset(void) -{ - if (shared_counters == NULL) - return; - - memset(shared_counters, 0, sizeof(counter_snapshot[0])); - memset(counter_snapshot, 0, sizeof(counter_snapshot)); - gettimeofday(&prev_time, NULL); -} - -static inline void shmem_bump(void) -{ - if (shared_counters == NULL || thread <= 0 || thread > MAX_SHMEM_COUNT) - return; - - shared_counters[thread - 1]++; -} - -static void shmem_snap(int n) -{ - struct timeval this_time; - int non_zero = 0; - long long total = 0; - double secs; - int i; - - if (shared_counters == NULL || n > MAX_SHMEM_COUNT) - return; - - memcpy(counter_snapshot[1], counter_snapshot[0], - n * sizeof(counter_snapshot[0][0])); - memcpy(counter_snapshot[0], shared_counters, - n * sizeof(counter_snapshot[0][0])); - gettimeofday(&this_time, NULL); - - for (i = 0; i < n; i++) { - long long this_count = - counter_snapshot[0][i] - counter_snapshot[1][i]; - - if (this_count != 0) { - non_zero++; - total += this_count; - } - } - - secs = (this_time.tv_sec + this_time.tv_usec / 1000000.0) - - (prev_time.tv_sec + prev_time.tv_usec / 1000000.0); - - printf("%d/%d Total: %f/second\n", non_zero, n, total / secs); - - prev_time = this_time; -} - -#define SHMEM_SETUP() shmem_setup() -#define SHMEM_RESET() shmem_reset() -#define SHMEM_BUMP() shmem_bump() -#define SHMEM_SNAP(n) shmem_snap(n) -#else -#define SHMEM_SETUP() -#define SHMEM_RESET() -#define SHMEM_BUMP() -#define SHMEM_SNAP(n) -#endif - -extern command_t cmdlist[]; - -static int do_device(char *func, int dev) -{ - struct obd_ioctl_data data; - - memset(&data, 0, sizeof(data)); - - data.ioc_dev = dev; - - if (getfd(func)) - return -1; - - IOC_PACK(func, data); - return ioctl(fd, OBD_IOC_DEVICE, buf); -} - -int jt_obd_device(int argc, char **argv) -{ - int rc, dev; - do_disconnect(argv[0], 1); - - if (argc != 2) - return CMD_HELP; - - dev = parse_devname(argv[0], argv[1]); - if (dev < 0) - return -1; - - rc = do_device(argv[0], dev); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} - -int jt_obd_connect(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOCINIT(data); - - do_disconnect(argv[0], 1); - -#warning TODO: implement timeout per lctl usage for probe - if (argc != 1) - return CMD_HELP; - - rc = ioctl(fd, OBD_IOC_CONNECT, &data); - if (rc < 0) - fprintf(stderr, "error: %s: OBD_IOC_CONNECT %s\n", - cmdname(argv[0]), strerror(rc = errno)); - else { - conn_addr = data.ioc_addr; - conn_cookie = data.ioc_cookie; - } - return rc; -} - -int jt_obd_disconnect(int argc, char **argv) -{ - if (argc != 1) - return CMD_HELP; - - if (conn_addr == -1) - return 0; - - return do_disconnect(argv[0], 0); -} - -int jt_opt_device(int argc, char **argv) -{ - char *arg2[3]; - int ret; - int rc; - - if (argc < 3) - return CMD_HELP; - - rc = do_device("device", parse_devname(argv[0], argv[1])); - - if (!rc) { - arg2[0] = "connect"; - arg2[1] = NULL; - rc = jt_obd_connect(1, arg2); - } - - if (!rc) - rc = Parser_execarg(argc - 2, argv + 2, cmdlist); - - ret = do_disconnect(argv[0], 0); - if (!rc) - rc = ret; - - return rc; -} - -int jt_opt_threads(int argc, char **argv) -{ - __u64 threads, next_thread; - int verbose; - int rc = 0; - char *end; - int i; - - if (argc < 5) - return CMD_HELP; - - threads = strtoull(argv[1], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid page count '%s'\n", - cmdname(argv[0]), argv[1]); - return CMD_HELP; - } - - verbose = get_verbose(argv[0], argv[2]); - if (verbose == BAD_VERBOSE) - return CMD_HELP; - - if (verbose != 0) - printf("%s: starting "LPD64" threads on device %s running %s\n", - argv[0], threads, argv[3], argv[4]); - - SHMEM_RESET(); - - for (i = 1, next_thread = verbose; i <= threads; i++) { - rc = fork(); - if (rc < 0) { - fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i, - strerror(rc = errno)); - break; - } else if (rc == 0) { - thread = i; - argv[2] = "--device"; - return jt_opt_device(argc - 2, argv + 2); - } else if (be_verbose(verbose, NULL, i, &next_thread, threads)) - printf("%s: thread #%d (PID %d) started\n", - argv[0], i, rc); - rc = 0; - } - - if (!thread) { /* parent process */ - int live_threads = threads; - - while (live_threads > 0) { - int status; - pid_t ret; - - ret = waitpid(0, &status, verbose < 0 ? WNOHANG : 0); - if (ret == 0) { - if (verbose >= 0) - abort(); - - sleep(-verbose); - SHMEM_SNAP(threads); - continue; - } - - if (ret < 0) { - fprintf(stderr, "error: %s: wait - %s\n", - argv[0], strerror(errno)); - if (!rc) - rc = errno; - } else { - /* - * This is a hack. We _should_ be able to use - * WIFEXITED(status) to see if there was an - * error, but it appears to be broken and it - * always returns 1 (OK). See wait(2). - */ - int err = WEXITSTATUS(status); - if (err || WIFSIGNALED(status)) - fprintf(stderr, - "%s: PID %d had rc=%d\n", - argv[0], ret, err); - if (!rc) - rc = err; - - live_threads--; - } - } - } - - return rc; -} - -int jt_obd_detach(int argc, char **argv) -{ - struct obd_ioctl_data data; - char force = 'F'; - int rc; - - IOCINIT(data); - - if (argc != 1 && argc != 2) - return CMD_HELP; - - if (argc == 2) { - data.ioc_inllen1 = 1; - data.ioc_inlbuf1 = &force; - } - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_DETACH, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} - -int jt_obd_cleanup(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOCINIT(data); - - if (argc != 1) - return CMD_HELP; - - rc = ioctl(fd, OBD_IOC_CLEANUP, &data); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} - -int jt_obd_newdev(int argc, char **argv) -{ - int rc; - struct obd_ioctl_data data; - - if (getfd(argv[0])) - return -1; - - IOCINIT(data); - - if (argc != 1) - return CMD_HELP; - - rc = ioctl(fd, OBD_IOC_NEWDEV, &data); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - else { - printf("Current device set to %d\n", data.ioc_dev); - } - - return rc; -} - -int jt_get_version(int argc, char **argv) -{ - int rc; - char buf[8192]; - struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf; - - if (getfd(argv[0])) - return -1; - - memset(buf, 0, sizeof(buf)); - data->ioc_version = OBD_IOCTL_VERSION; - data->ioc_addr = conn_addr; - data->ioc_cookie = conn_addr; - data->ioc_len = sizeof(buf); - data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data)); - - if (argc != 1) - return CMD_HELP; - - rc = ioctl(fd, OBD_GET_VERSION, data); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - else { - printf("Lustre version: %s\n", data->ioc_bulk); - } - - printf("lctl version: %s\n",BUILD_VERSION); - return rc; -} - -int jt_obd_list(int argc, char **argv) -{ - int rc; - char buf[8192]; - struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf; - - if (getfd(argv[0])) - return -1; - - memset(buf, 0, sizeof(buf)); - data->ioc_version = OBD_IOCTL_VERSION; - data->ioc_addr = conn_addr; - data->ioc_cookie = conn_addr; - data->ioc_len = sizeof(buf); - data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data)); - - if (argc != 1) - return CMD_HELP; - - rc = ioctl(fd, OBD_IOC_LIST, data); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - else { - printf("%s", data->ioc_bulk); - } - - return rc; -} - -int jt_obd_attach(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOCINIT(data); - - if (argc != 2 && argc != 3 && argc != 4) - return CMD_HELP; - - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - if (argc >= 3) { - data.ioc_inllen2 = strlen(argv[2]) + 1; - data.ioc_inlbuf2 = argv[2]; - } - - if (argc == 4) { - data.ioc_inllen3 = strlen(argv[3]) + 1; - data.ioc_inlbuf3 = argv[3]; - } - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_ATTACH, buf); - if (rc < 0) - fprintf(stderr, "error: %s: OBD_IOC_ATTACH %s\n", - cmdname(argv[0]), strerror(rc = errno)); - else if (argc == 3) { - char name[1024]; - if (strlen(argv[2]) > 128) { - printf("Name too long to set environment\n"); - return -EINVAL; - } - snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]); - rc = setenv(name, argv[1], 1); - if (rc) { - printf("error setting env variable %s\n", name); - } - } - - return rc; -} - -int jt_obd_name2dev(int argc, char **argv) -{ - int rc; - - if (argc != 2) - return CMD_HELP; - - rc = do_name2dev(argv[0], argv[1]); - if (rc >= N2D_OFF) { - int dev = rc - N2D_OFF; - rc = do_device(argv[0], dev); - if (rc == 0) - printf("%d\n", dev); - } - return rc; -} - -int jt_obd_setup(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOCINIT(data); - - if (argc > 3) - return CMD_HELP; - - data.ioc_dev = -1; - if (argc > 1) { - data.ioc_dev = parse_devname(argv[0], argv[1]); - if (data.ioc_dev < 0) - return -1; - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - } - if (argc == 3) { - data.ioc_inllen2 = strlen(argv[2]) + 1; - data.ioc_inlbuf2 = argv[2]; - } - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_SETUP, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} - -/* The ioctl API has been extended to provide the LOV stripe metadata to the - * caller when applicable. This utility, however, only saves the LSM for the - * latest CREATE. */ -int jt_obd_create(int argc, char **argv) -{ - struct obd_ioctl_data data; - struct timeval next_time; - __u64 count = 1, next_count; - int verbose = 1, mode = 0100644, rc = 0, i; - char *end; - - IOCINIT(data); - if (argc < 2 || argc > 4) - return CMD_HELP; - - count = strtoull(argv[1], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid iteration count '%s'\n", - cmdname(argv[0]), argv[1]); - return CMD_HELP; - } - - if (argc > 2) { - mode = strtoul(argv[2], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid mode '%s'\n", - cmdname(argv[0]), argv[2]); - return CMD_HELP; - } - if (!(mode & S_IFMT)) - mode |= S_IFREG; - } - - if (argc > 3) { - verbose = get_verbose(argv[0], argv[3]); - if (verbose == BAD_VERBOSE) - return CMD_HELP; - } - - printf("%s: "LPD64" objects\n", cmdname(argv[0]), count); - gettimeofday(&next_time, NULL); - next_time.tv_sec -= verbose; - - for (i = 1, next_count = verbose; i <= count; i++) { - data.ioc_obdo1.o_mode = mode; - data.ioc_obdo1.o_id = i; - data.ioc_obdo1.o_uid = 0; - data.ioc_obdo1.o_gid = 0; - data.ioc_obdo1.o_valid = OBD_MD_FLTYPE | OBD_MD_FLMODE | - OBD_MD_FLID | OBD_MD_FLUID | OBD_MD_FLGID;; - - data.ioc_inllen1 = sizeof(saved_lsm); - data.ioc_inlbuf1 = (char *)&saved_lsm; - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_CREATE, buf); - IOC_UNPACK(argv[0], data); - fprintf(stderr, "lsm->lsm_o_id: "LPX64"\n", - saved_lsm.lsm_object_id); - SHMEM_BUMP(); - if (rc < 0) { - fprintf(stderr, "error: %s: #%d - %s\n", - cmdname(argv[0]), i, strerror(rc = errno)); - break; - } - if (!(data.ioc_obdo1.o_valid & OBD_MD_FLID)) { - fprintf(stderr, "error: %s: objid not valid #%d:%08x\n", - cmdname(argv[0]), i, data.ioc_obdo1.o_valid); - rc = EINVAL; - break; - } - - lsm_valid = 1; - - if (be_verbose(verbose, &next_time, i, &next_count, count)) - printf("%s: #%d is object id "LPX64"\n", - cmdname(argv[0]), i, data.ioc_obdo1.o_id); - } - return rc; -} - -int jt_obd_setattr(int argc, char **argv) -{ - struct obd_ioctl_data data; - char *end; - int rc; - - IOCINIT(data); - if (argc != 2) - return CMD_HELP; - - data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid objid '%s'\n", - cmdname(argv[0]), argv[1]); - return CMD_HELP; - } - data.ioc_obdo1.o_mode = S_IFREG | strtoul(argv[2], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid mode '%s'\n", - cmdname(argv[0]), argv[2]); - return CMD_HELP; - } - data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; - - if (lsm_valid == 1) { - data.ioc_inllen1 = sizeof(saved_lsm); - data.ioc_inlbuf1 = (char *)&saved_lsm; - } - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_SETATTR, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} - -int jt_obd_destroy(int argc, char **argv) -{ - struct obd_ioctl_data data; - struct timeval next_time; - __u64 count = 1, next_count; - int verbose = 1; - __u64 id; - char *end; - int rc = 0, i; - - IOCINIT(data); - if (argc < 2 || argc > 4) - return CMD_HELP; - - id = strtoull(argv[1], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid objid '%s'\n", - cmdname(argv[0]), argv[1]); - return CMD_HELP; - } - if (argc > 2) { - count = strtoull(argv[2], &end, 0); - if (*end) { - fprintf(stderr, - "error: %s: invalid iteration count '%s'\n", - cmdname(argv[0]), argv[2]); - return CMD_HELP; - } - } - - if (argc > 3) { - verbose = get_verbose(argv[0], argv[3]); - if (verbose == BAD_VERBOSE) - return CMD_HELP; - } - - printf("%s: "LPD64" objects\n", cmdname(argv[0]), count); - gettimeofday(&next_time, NULL); - next_time.tv_sec -= verbose; - - for (i = 1, next_count = verbose; i <= count; i++, id++) { - data.ioc_obdo1.o_id = id; - data.ioc_obdo1.o_mode = S_IFREG | 0644; - data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE; - - data.ioc_inllen1 = sizeof(saved_lsm); - data.ioc_inlbuf1 = (char *)&saved_lsm; - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_DESTROY, buf); - IOC_UNPACK(argv[0], data); - SHMEM_BUMP(); - if (rc < 0) { - fprintf(stderr, "error: %s: objid "LPX64": %s\n", - cmdname(argv[0]), id, strerror(rc = errno)); - break; - } - lsm_valid = 0; - - if (be_verbose(verbose, &next_time, i, &next_count, count)) - printf("%s: #%d is object id "LPX64"\n", - cmdname(argv[0]), i, id); - } - - return rc; -} - -int jt_obd_getattr(int argc, char **argv) -{ - struct obd_ioctl_data data; - char *end; - int rc; - - if (argc != 2) - return CMD_HELP; - - IOCINIT(data); - data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid objid '%s'\n", - cmdname(argv[0]), argv[1]); - return CMD_HELP; - } - /* to help obd filter */ - data.ioc_obdo1.o_mode = 0100644; - data.ioc_obdo1.o_valid = 0xffffffff; - printf("%s: object id "LPX64"\n", cmdname(argv[0]),data.ioc_obdo1.o_id); - - if (lsm_valid == 1) { - data.ioc_inllen1 = sizeof(saved_lsm); - data.ioc_inlbuf1 = (char *)&saved_lsm; - } - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_GETATTR, buf); - IOC_UNPACK(argv[0], data); - if (rc) { - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - } else { - printf("%s: object id "LPX64", mode %o\n", cmdname(argv[0]), - data.ioc_obdo1.o_id, data.ioc_obdo1.o_mode); - } - return rc; -} - -int jt_obd_test_getattr(int argc, char **argv) -{ - struct obd_ioctl_data data; - struct timeval start, next_time; - __u64 i, count, next_count; - int verbose = 1; - obd_id objid = 3; - char *end; - int rc = 0; - - if (argc < 2 && argc > 4) - return CMD_HELP; - - IOCINIT(data); - count = strtoull(argv[1], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid iteration count '%s'\n", - cmdname(argv[0]), argv[1]); - return CMD_HELP; - } - - if (argc >= 3) { - verbose = get_verbose(argv[0], argv[2]); - if (verbose == BAD_VERBOSE) - return CMD_HELP; - } - - if (argc >= 4) { - if (argv[3][0] == 't') { - objid = strtoull(argv[3] + 1, &end, 0); - if (thread) - objid += thread - 1; - } else - objid = strtoull(argv[3], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid objid '%s'\n", - cmdname(argv[0]), argv[3]); - return CMD_HELP; - } - } - - gettimeofday(&start, NULL); - next_time.tv_sec = start.tv_sec - verbose; - next_time.tv_usec = start.tv_usec; - if (verbose != 0) - printf("%s: getting "LPD64" attrs (objid "LPX64"): %s", - cmdname(argv[0]), count, objid, ctime(&start.tv_sec)); - - for (i = 1, next_count = verbose; i <= count; i++) { - data.ioc_obdo1.o_id = objid; - data.ioc_obdo1.o_mode = S_IFREG; - data.ioc_obdo1.o_valid = 0xffffffff; - rc = ioctl(fd, OBD_IOC_GETATTR, &data); - SHMEM_BUMP(); - if (rc < 0) { - fprintf(stderr, "error: %s: #"LPD64" - %d:%s\n", - cmdname(argv[0]), i, errno, strerror(rc = errno)); - break; - } else { - if (be_verbose - (verbose, &next_time, i, &next_count, count)) - printf("%s: got attr #"LPD64"\n", - cmdname(argv[0]), i); - } - } - - if (!rc) { - struct timeval end; - double diff; - - gettimeofday(&end, NULL); - - diff = difftime(&end, &start); - - --i; - if (verbose != 0) - printf("%s: "LPD64" attrs in %.4gs (%.4g attr/s): %s", - cmdname(argv[0]), i, diff, (double)i / diff, - ctime(&end.tv_sec)); - } - return rc; -} - -int jt_obd_test_brw(int argc, char **argv) -{ - struct obd_ioctl_data data; - struct timeval start, next_time; - int pages = 1; - __u64 count, next_count; - __u64 objid = 3; - int verbose = 1, write = 0, rw; - char *end; - int thr_offset = 0; - int i; - int len; - int rc = 0; - - if (argc < 2 || argc > 6) { - fprintf(stderr, "error: %s: bad number of arguments: %d\n", - cmdname(argv[0]), argc); - return CMD_HELP; - } - - /* make each thread write to a different offset */ - if (argv[1][0] == 't') { - count = strtoull(argv[1] + 1, &end, 0); - if (thread) - thr_offset = thread - 1; - } else - count = strtoull(argv[1], &end, 0); - - if (*end) { - fprintf(stderr, "error: %s: bad iteration count '%s'\n", - cmdname(argv[0]), argv[1]); - return CMD_HELP; - } - - if (argc >= 3) { - if (argv[2][0] == 'w' || argv[2][0] == '1') - write = 1; - else if (argv[2][0] == 'r' || argv[2][0] == '0') - write = 0; - } - - if (argc >= 4) { - verbose = get_verbose(argv[0], argv[3]); - if (verbose == BAD_VERBOSE) - return CMD_HELP; - } - - if (argc >= 5) { - pages = strtoul(argv[4], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: bad page count '%s'\n", - cmdname(argv[0]), argv[4]); - return CMD_HELP; - } - } - if (argc >= 6) { - if (argv[5][0] == 't') { - objid = strtoull(argv[5] + 1, &end, 0); - if (thread) - objid += thread - 1; - } else - objid = strtoull(argv[5], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: bad objid '%s'\n", - cmdname(argv[0]), argv[5]); - return CMD_HELP; - } - } - - len = pages * PAGE_SIZE; - - IOCINIT(data); - data.ioc_obdo1.o_id = objid; - data.ioc_obdo1.o_mode = S_IFREG; - data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; - data.ioc_count = len; - data.ioc_offset = thr_offset * len * count; - - if (lsm_valid == 1) { - data.ioc_inllen1 = sizeof(saved_lsm); - data.ioc_inlbuf1 = (char *)&saved_lsm; - } - - gettimeofday(&start, NULL); - next_time.tv_sec = start.tv_sec - verbose; - next_time.tv_usec = start.tv_usec; - - if (verbose != 0) - printf("%s: %s "LPU64"x%d pages (obj "LPX64", off "LPU64"): %s", - cmdname(argv[0]), write ? "writing" : "reading", count, - pages, objid, data.ioc_offset, ctime(&start.tv_sec)); - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_OPEN, buf); - IOC_UNPACK(argv[0], data); - if (rc) { - fprintf(stderr, "error: brw_open: %s\n", strerror(rc = errno)); - return rc; - } - - rw = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ; - for (i = 1, next_count = verbose; i <= count; i++) { - rc = ioctl(fd, rw, buf); - SHMEM_BUMP(); - if (rc) { - fprintf(stderr, "error: %s: #%d - %s on %s\n", - cmdname(argv[0]), i, strerror(rc = errno), - write ? "write" : "read"); - break; - } else if (be_verbose(verbose, &next_time,i, &next_count,count)) - printf("%s: %s number %dx%d\n", cmdname(argv[0]), - write ? "write" : "read", i, pages); - - data.ioc_offset += len; - } - - if (!rc) { - struct timeval end; - double diff; - - gettimeofday(&end, NULL); - - diff = difftime(&end, &start); - - --i; - if (verbose != 0) - printf("%s: %s %dx%d pages in %.4gs (%.4g pg/s): %s", - cmdname(argv[0]), write ? "wrote" : "read", - i, pages, diff, (double)i * pages / diff, - ctime(&end.tv_sec)); - } - rw = ioctl(fd, OBD_IOC_CLOSE, buf); - if (rw) { - fprintf(stderr, "error: brw_close: %s\n", strerror(rw = errno)); - if (!rc) - rc = rw; - } - - return rc; -} - -int jt_obd_lov_setconfig(int argc, char **argv) -{ - struct obd_ioctl_data data; - struct lov_desc desc; - obd_uuid_t *uuidarray, *ptr; - int rc, i; - char *end; - - IOCINIT(data); - - if (argc <= 6) - return CMD_HELP; - - if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) { - fprintf(stderr, - "error: %s: LOV uuid '%s' longer than %zd characters\n", - cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1); - return -EINVAL; - } - - memset(&desc, 0, sizeof(desc)); - strncpy(desc.ld_uuid, argv[1], sizeof(desc.ld_uuid) - 1); - desc.ld_tgt_count = argc - 6; - desc.ld_default_stripe_count = strtoul(argv[2], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: bad default stripe count '%s'\n", - cmdname(argv[0]), argv[2]); - return CMD_HELP; - } - if (desc.ld_default_stripe_count > desc.ld_tgt_count) { - fprintf(stderr, - "error: %s: default stripe count %u > OST count %u\n", - cmdname(argv[0]), desc.ld_default_stripe_count, - desc.ld_tgt_count); - return -EINVAL; - } - - desc.ld_default_stripe_size = strtoull(argv[3], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: bad default stripe size '%s'\n", - cmdname(argv[0]), argv[3]); - return CMD_HELP; - } - if (desc.ld_default_stripe_size < 4096) { - fprintf(stderr, - "error: %s: default stripe size "LPU64" too small\n", - cmdname(argv[0]), desc.ld_default_stripe_size); - return -EINVAL; - } else if ((long)desc.ld_default_stripe_size < - desc.ld_default_stripe_size) { - fprintf(stderr, - "error: %s: default stripe size "LPU64" too large\n", - cmdname(argv[0]), desc.ld_default_stripe_size); - return -EINVAL; - } - desc.ld_default_stripe_offset = strtoull(argv[4], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: bad default stripe offset '%s'\n", - cmdname(argv[0]), argv[4]); - return CMD_HELP; - } - desc.ld_pattern = strtoul(argv[5], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: bad stripe pattern '%s'\n", - cmdname(argv[0]), argv[5]); - return CMD_HELP; - } - - /* NOTE: it is possible to overwrite the default striping parameters, - * but EXTREME care must be taken when saving the OST UUID list. - * It must be EXACTLY the same, or have only additions at the - * end of the list, or only overwrite individual OST entries - * that are restored from backups of the previous OST. - */ - uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray)); - if (!uuidarray) { - fprintf(stderr, "error: %s: no memory for %d UUIDs\n", - cmdname(argv[0]), desc.ld_tgt_count); - rc = -ENOMEM; - goto out; - } - for (i = 6, ptr = uuidarray; i < argc; i++, ptr++) { - if (strlen(argv[i]) >= sizeof(*ptr)) { - fprintf(stderr, "error: %s: arg %d (%s) too long\n", - cmdname(argv[0]), i, argv[i]); - rc = -EINVAL; - goto out; - } - strcpy((char *)ptr, argv[i]); - } - - data.ioc_inllen1 = sizeof(desc); - data.ioc_inlbuf1 = (char *)&desc; - data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray); - data.ioc_inlbuf2 = (char *)uuidarray; - - if (obd_ioctl_pack(&data, &buf, max)) { - fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); - rc = -EINVAL; - goto out; - } - rc = ioctl(fd, OBD_IOC_LOV_SET_CONFIG, buf); - if (rc) - fprintf(stderr, "error: %s: ioctl error: %s\n", - cmdname(argv[0]), strerror(rc = errno)); -out: - free(uuidarray); - return rc; -} - -#define DEF_UUID_ARRAY_LEN (8192 / 40) - -int jt_obd_lov_getconfig(int argc, char **argv) -{ - struct obd_ioctl_data data; - struct lov_desc desc; - obd_uuid_t *uuidarray; - int rc; - - IOCINIT(data); - - if (argc != 2) - return CMD_HELP; - - if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) { - fprintf(stderr, - "error: %s: LOV uuid '%s' longer than %zd characters\n", - cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1); - return -EINVAL; - } - - memset(&desc, 0, sizeof(desc)); - strncpy(desc.ld_uuid, argv[1], sizeof(desc.ld_uuid) - 1); - desc.ld_tgt_count = DEF_UUID_ARRAY_LEN; -repeat: - uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray)); - if (!uuidarray) { - fprintf(stderr, "error: %s: no memory for %d uuid's\n", - cmdname(argv[0]), desc.ld_tgt_count); - return -ENOMEM; - } - - data.ioc_inllen1 = sizeof(desc); - data.ioc_inlbuf1 = (char *)&desc; - data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray); - data.ioc_inlbuf2 = (char *)uuidarray; - - if (obd_ioctl_pack(&data, &buf, max)) { - fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); - rc = -EINVAL; - goto out; - } - rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf); - if (rc == -ENOSPC) { - free(uuidarray); - goto repeat; - } else if (rc) { - fprintf(stderr, "error: %s: ioctl error: %s\n", - cmdname(argv[0]), strerror(rc = errno)); - } else { - obd_uuid_t *ptr; - int i; - - if (obd_ioctl_unpack(&data, buf, max)) { - fprintf(stderr, "error: %s: invalid reply\n", - cmdname(argv[0])); - rc = -EINVAL; - goto out; - } - printf("default_stripe_count: %u\n", - desc.ld_default_stripe_count); - printf("default_stripe_size: "LPU64"\n", - desc.ld_default_stripe_size); - printf("default_stripe_offset: "LPU64"\n", - desc.ld_default_stripe_offset); - printf("default_stripe_pattern: %u\n", desc.ld_pattern); - printf("obd_count: %u\n", desc.ld_tgt_count); - for (i = 0, ptr = uuidarray; i < desc.ld_tgt_count; i++, ptr++) - printf("%u: %s\n", i, (char *)ptr); - } -out: - free(uuidarray); - return rc; -} - -int jt_obd_test_ldlm(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOCINIT(data); - if (argc != 1) - return CMD_HELP; - - rc = ioctl(fd, IOC_LDLM_TEST, &data); - if (rc) - fprintf(stderr, "error: %s: test failed: %s\n", - cmdname(argv[0]), strerror(rc = errno)); - return rc; -} - -int jt_obd_dump_ldlm(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOCINIT(data); - if (argc != 1) - return CMD_HELP; - - rc = ioctl(fd, IOC_LDLM_DUMP, &data); - if (rc) - fprintf(stderr, "error: %s failed: %s\n", - cmdname(argv[0]), strerror(rc = errno)); - return rc; -} - -int jt_obd_ldlm_regress_start(int argc, char **argv) -{ - int rc; - struct obd_ioctl_data data; - char argstring[200]; - int i, count = sizeof(argstring) - 1; - - IOCINIT(data); - if (argc > 5) - return CMD_HELP; - - argstring[0] = '\0'; - for (i = 1; i < argc; i++) { - strncat(argstring, " ", count); - count--; - strncat(argstring, argv[i], count); - count -= strlen(argv[i]); - } - - if (strlen(argstring)) { - data.ioc_inlbuf1 = argstring; - data.ioc_inllen1 = strlen(argstring) + 1; - } - - IOC_PACK(argv[0], data); - rc = ioctl(fd, IOC_LDLM_REGRESS_START, buf); - if (rc) - fprintf(stderr, "error: %s: test failed: %s\n", - cmdname(argv[0]), strerror(rc = errno)); - - return rc; -} - -int jt_obd_ldlm_regress_stop(int argc, char **argv) -{ - int rc; - struct obd_ioctl_data data; - IOCINIT(data); - - if (argc != 1) - return CMD_HELP; - - rc = ioctl(fd, IOC_LDLM_REGRESS_STOP, &data); - - if (rc) - fprintf(stderr, "error: %s: test failed: %s\n", - cmdname(argv[0]), strerror(rc = errno)); - return rc; -} - -int jt_obd_lov_set_osc_active(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOCINIT(data); - if (argc != 3) - return CMD_HELP; - - data.ioc_inlbuf1 = argv[1]; - data.ioc_inllen1 = strlen(argv[1]) + 1; - - /* reuse offset for 'active' */ - data.ioc_offset = atoi(argv[2]); - - IOC_PACK(argv[0], data); - rc = ioctl(fd, IOC_LOV_SET_OSC_ACTIVE, buf); - if (rc) - fprintf(stderr, "error: %s: failed: %s\n", - cmdname(argv[0]), strerror(rc = errno)); - - return rc; -} - -int jt_obd_newconn(int argc, char **argv) -{ - int rc; - struct obd_ioctl_data data; - - IOCINIT(data); - if (argc < 2 || argc > 3) - return CMD_HELP; - - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - - if (argc == 3) { - data.ioc_inllen2 = strlen(argv[2]) + 1; - data.ioc_inlbuf2 = argv[2]; - } - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_RECOVD_NEWCONN, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} - -int jt_obd_failconn(int argc, char **argv) -{ - int rc; - struct obd_ioctl_data data; - - IOCINIT(data); - if (argc < 2) - return CMD_HELP; - - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_RECOVD_FAILCONN, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} - -static void signal_server(int sig) -{ - if (sig == SIGINT) { - do_disconnect("sigint", 1); - exit(1); - } else - fprintf(stderr, "%s: got signal %d\n", cmdname("sigint"), sig); -} - -int obd_initialize(int argc, char **argv) -{ - SHMEM_SETUP(); - return 0; -} - - -void obd_cleanup(int argc, char **argv) -{ - struct sigaction sigact; - - sigact.sa_handler = signal_server; - sigfillset(&sigact.sa_mask); - sigact.sa_flags = SA_RESTART; - sigaction(SIGINT, &sigact, NULL); - - do_disconnect(argv[0], 1); -} diff --git a/lustre/utils/obdctl.c b/lustre/utils/obdctl.c deleted file mode 100644 index 860b908..0000000 --- a/lustre/utils/obdctl.c +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Peter J. Braam - * Author: Phil Schwan - * - * 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 "obdctl.h" -#include "parser.h" - -/* the functions that were in here are now in obd.c */ - -static int jt_quit(int argc, char **argv) -{ - int rc = 0; - Parser_quit(argc, argv); - - return rc; -} - -command_t cmdlist[] = { - /* Metacommands */ - {"--device", jt_opt_device, 0, "--device "}, - {"--threads", jt_opt_threads, 0, - "--threads "}, - - /* Device configuration commands */ - {"lov_setconfig", jt_obd_lov_setconfig, 0, "configure lov data on MDS " - "[usage: lovconfig lov-uuid stripecount, stripesize, pattern, UUID1, [UUID2, ...]"}, - {"list", jt_obd_list, 0, "list the devices (no args)"}, - {"newdev", jt_obd_newdev, 0, "set device to a new unused obd (no args)"}, - {"device", jt_obd_device, 0, "set current device (args device_no name)"}, - {"name2dev", jt_obd_name2dev, 0, - "set device by name [usage: name2dev devname]"}, - {"attach", jt_obd_attach, 0, "name the type of device (args: type data"}, - {"setup", jt_obd_setup, 0, "setup device (args: [data]"}, - {"detach", jt_obd_detach, 0, "detach the current device (arg: )"}, - {"cleanup", jt_obd_cleanup, 0, "cleanup the current device (arg: )"}, - - /* Session commands */ - {"connect", jt_obd_connect, 0, "connect - get a connection to device"}, - {"disconnect", jt_obd_disconnect, 0, - "disconnect - break connection to device"}, - - /* Session operations */ - {"create", jt_obd_create, 0, "create [mode [verbose]]"}, - {"destroy", jt_obd_destroy, 0, "destroy [count [verbose]]"}, - {"getattr", jt_obd_getattr, 0, "getattr "}, - {"setattr", jt_obd_setattr, 0, "setattr "}, - {"newconn", jt_obd_newconn, 0, "newconn [newuuid]"}, - {"test_getattr", jt_obd_test_getattr, 0, "test_getattr [verbose [[t]objid]]"}, - {"test_brw", jt_obd_test_brw, 0, "test_brw [t] [write [verbose [pages [[t]objid]]]]"}, - {"test_ldlm", jt_obd_test_ldlm, 0, "test lock manager (no args)"}, - {"dump_ldlm", jt_obd_dump_ldlm, 0, "dump all lock manager state (no args)"}, - - /* User interface commands */ - {"help", Parser_help, 0, "help"}, - {"exit", jt_quit, 0, "quit"}, - {"quit", jt_quit, 0, "quit"}, - {0, 0, 0, NULL} -}; - - -int main(int argc, char **argv) -{ - int rc; - - setlinebuf(stdout); - - if (obd_initialize(argc, argv) < 0) - exit(1); - - if (argc > 1) { - rc = Parser_execarg(argc - 1, argv + 1, cmdlist); - } else { - Parser_init("obdctl > ", cmdlist); - rc = Parser_commands(); - } - - obd_cleanup(argc, argv); - return rc; -} diff --git a/lustre/utils/obdctl.h b/lustre/utils/obdctl.h deleted file mode 100644 index 01ece92..0000000 --- a/lustre/utils/obdctl.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * Author: Peter J. Braam - * Author: Phil Schwan - * 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. - * - */ -#ifndef _OBDCTL_H_ -#define _OBDCTL_H_ - -int do_disconnect(char *func, int verbose); -int obd_initialize(int argc, char **argv); -void obd_cleanup(int argc, char **argv); - -int jt_opt_device(int argc, char **argv); -int jt_opt_threads(int argc, char **argv); - -int jt_obd_device(int argc, char **argv); -int jt_obd_connect(int argc, char **argv); -int jt_obd_disconnect(int argc, char **argv); -int jt_obd_detach(int argc, char **argv); -int jt_obd_cleanup(int argc, char **argv); -int jt_obd_newdev(int argc, char **argv); -int jt_obd_list(int argc, char **argv); -int jt_obd_attach(int argc, char **argv); -int jt_obd_name2dev(int argc, char **argv); -int jt_obd_setup(int argc, char **argv); -int jt_obd_create(int argc, char **argv); -int jt_obd_setattr(int argc, char **argv); -int jt_obd_destroy(int argc, char **argv); -int jt_obd_getattr(int argc, char **argv); -int jt_obd_test_getattr(int argc, char **argv); -int jt_obd_test_brw(int argc, char **argv); -int jt_obd_lov_setconfig(int argc, char **argv); -int jt_obd_lov_getconfig(int argc, char **argv); -int jt_obd_test_ldlm(int argc, char **argv); -int jt_obd_ldlm_regress_start(int argc, char **argv); -int jt_obd_ldlm_regress_stop(int argc, char **argv); -int jt_obd_dump_ldlm(int argc, char **argv); -int jt_obd_lov_set_osc_active(int argc, char **argv); -int jt_obd_newconn(int argc, char **argv); -int jt_obd_failconn(int argc, char **argv); -int jt_get_version(int argc, char **argv); - -#endif diff --git a/lustre/utils/parser.c b/lustre/utils/parser.c deleted file mode 100644 index 0e5a9f0..0000000 --- a/lustre/utils/parser.c +++ /dev/null @@ -1,722 +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.sf.net/projects/lustre/ - * - * 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 -#include -#include -#include -#include -#include - -#ifdef HAVE_LIBREADLINE -#define READLINE_LIBRARY -#include - -//extern char **completion_matches __P((char *, rl_compentry_func_t *)); -extern void using_history(void); -extern void stifle_history(int); -extern void add_history(char *); -#endif - -#include "parser.h" - -static command_t * top_level; /* Top level of commands, initialized by - * InitParser */ -static char * parser_prompt = NULL;/* Parser prompt, set by InitParser */ -static int done; /* Set to 1 if user types exit or quit */ -static int ignore_errors; /* Normally, the parser will quit when - an error occurs in non-interacive - mode. Setting this to non-zero will - force it to keep buggering on. */ - - -/* static functions */ -static char *skipwhitespace(char *s); -static char *skiptowhitespace(char *s); -static command_t *find_cmd(char *name, command_t cmds[], char **next); -static int process(char *s, char **next, command_t *lookup, command_t **result, - char **prev); -static void print_commands(char *str, command_t *table); - -static char * skipwhitespace(char * s) -{ - char * t; - int len; - - len = (int)strlen(s); - for (t = s; t <= s + len && isspace(*t); t++); - return(t); -} - - -static char * skiptowhitespace(char * s) -{ - char * t; - - for (t = s; *t && !isspace(*t); t++); - return(t); -} - -static int line2args(char *line, char **argv, int maxargs) -{ - char *arg; - int i = 0; - - arg = strtok(line, " \t"); - if ( arg ) { - argv[i] = arg; - i++; - } else - return 0; - - while( (arg = strtok(NULL, " \t")) && (i <= maxargs)) { - argv[i] = arg; - i++; - } - return i; -} - -/* find a command -- return it if unique otherwise print alternatives */ -static command_t *Parser_findargcmd(char *name, command_t cmds[]) -{ - command_t *cmd; - - for (cmd = cmds; cmd->pc_name; cmd++) { - if (strcmp(name, cmd->pc_name) == 0) - return cmd; - } - return NULL; -} - -void Parser_ignore_errors(int ignore) -{ - ignore_errors = ignore; -} - -int Parser_execarg(int argc, char **argv, command_t cmds[]) -{ - command_t *cmd; - - cmd = Parser_findargcmd(argv[0], cmds); - if ( cmd ) { - return (cmd->pc_func)(argc, argv); - } else { - printf("Try interactive use without arguments or use one of:\n"); - for (cmd = cmds; cmd->pc_name; cmd++) - printf("\"%s\"\n", cmd->pc_name); - printf("as argument.\n"); - } - return -1; -} - -/* returns the command_t * (NULL if not found) corresponding to a - _partial_ match with the first token in name. It sets *next to - point to the following token. Does not modify *name. */ -static command_t * find_cmd(char * name, command_t cmds[], char ** next) -{ - int i, len; - - if (!cmds || !name ) - return NULL; - - /* This sets name to point to the first non-white space character, - and next to the first whitespace after name, len to the length: do - this with strtok*/ - name = skipwhitespace(name); - *next = skiptowhitespace(name); - len = *next - name; - if (len == 0) - return NULL; - - for (i = 0; cmds[i].pc_name; i++) { - if (strncasecmp(name, cmds[i].pc_name, len) == 0) { - *next = skipwhitespace(*next); - return(&cmds[i]); - } - } - return NULL; -} - -/* Recursively process a command line string s and find the command - corresponding to it. This can be ambiguous, full, incomplete, - non-existent. */ -static int process(char *s, char ** next, command_t *lookup, - command_t **result, char **prev) -{ - *result = find_cmd(s, lookup, next); - *prev = s; - - /* non existent */ - if ( ! *result ) - return CMD_NONE; - - /* found entry: is it ambigous, i.e. not exact command name and - more than one command in the list matches. Note that find_cmd - points to the first ambiguous entry */ - if ( strncasecmp(s, (*result)->pc_name, strlen((*result)->pc_name)) && - find_cmd(s, (*result) + 1, next)) - return CMD_AMBIG; - - /* found a unique command: component or full? */ - if ( (*result)->pc_func ) { - return CMD_COMPLETE; - } else { - if ( *next == '\0' ) { - return CMD_INCOMPLETE; - } else { - return process(*next, next, (*result)->pc_sub_cmd, result, prev); - } - } -} - -#ifdef HAVE_LIBREADLINE -static command_t * match_tbl; /* Command completion against this table */ -static char * command_generator(const char * text, int state) -{ - static int index, - len; - char *name; - - /* Do we have a match table? */ - if (!match_tbl) - return NULL; - - /* If this is the first time called on this word, state is 0 */ - if (!state) { - index = 0; - len = (int)strlen(text); - } - - /* Return next name in the command list that paritally matches test */ - while ( (name = (match_tbl + index)->pc_name) ) { - index++; - - if (strncasecmp(name, text, len) == 0) { - return(strdup(name)); - } - } - - /* No more matches */ - return NULL; -} - -/* probably called by readline */ -static char **command_completion(char * text, int start, int end) -{ - command_t * table; - char * pos; - - match_tbl = top_level; - for (table = find_cmd(rl_line_buffer, match_tbl, &pos); - table; - table = find_cmd(pos, match_tbl, &pos)) { - - if (*(pos - 1) == ' ') match_tbl = table->pc_sub_cmd; - } - - return(completion_matches(text, command_generator)); -} -#endif - -/* take a string and execute the function or print help */ -int execute_line(char * line) -{ - command_t *cmd, *ambig; - char *prev; - char *next, *tmp; - char *argv[MAXARGS]; - int i; - int rc = 0; - - switch( process(line, &next, top_level, &cmd, &prev) ) { - case CMD_AMBIG: - fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line); - while( (ambig = find_cmd(prev, cmd, &tmp)) ) { - fprintf(stderr, "%s ", ambig->pc_name); - cmd = ambig + 1; - } - fprintf(stderr, "\n"); - break; - case CMD_NONE: - fprintf(stderr, "No such command, type help\n"); - break; - case CMD_INCOMPLETE: - fprintf(stderr, - "'%s' incomplete command. Use '%s x' where x is one of:\n", - line, line); - fprintf(stderr, "\t"); - for (i = 0; cmd->pc_sub_cmd[i].pc_name; i++) { - fprintf(stderr, "%s ", cmd->pc_sub_cmd[i].pc_name); - } - fprintf(stderr, "\n"); - break; - case CMD_COMPLETE: - i = line2args(line, argv, MAXARGS); - rc = (cmd->pc_func)(i, argv); - - if (rc == CMD_HELP) - fprintf(stderr, "%s\n", cmd->pc_help); - - break; - } - - return rc; -} - -int -noop_fn () -{ - return (0); -} - -/* just in case you're ever in an airplane and discover you - forgot to install readline-dev. :) */ -int init_input() -{ - int interactive = isatty (fileno (stdin)); - -#ifdef HAVE_LIBREADLINE - using_history(); - stifle_history(HISTORY); - - if (!interactive) - { - rl_prep_term_function = (rl_vintfunc_t *)noop_fn; - rl_deprep_term_function = (rl_voidfunc_t *)noop_fn; - } - - rl_attempted_completion_function = (CPPFunction *)command_completion; - rl_completion_entry_function = (void *)command_generator; -#endif - return interactive; -} - -#ifndef HAVE_LIBREADLINE -#define add_history(s) -char * readline(char * prompt) -{ - char line[2048]; - int n = 0; - if (prompt) - printf ("%s", prompt); - if (fgets(line, sizeof(line), stdin) == NULL) - return (NULL); - n = strlen(line); - if (n && line[n-1] == '\n') - line[n-1] = '\0'; - return strdup(line); -} -#endif - -/* this is the command execution machine */ -int Parser_commands(void) -{ - char *line, *s; - int rc = 0, save_error = 0; - int interactive; - - interactive = init_input(); - - while(!done) { - line = readline(interactive ? parser_prompt : NULL); - - if (!line) break; - - s = skipwhitespace(line); - - if (*s) { - add_history(s); - rc = execute_line(s); - } - /* stop on error if not-interactive */ - if (rc != 0 && !interactive) { - if (save_error == 0) - save_error = rc; - if (!ignore_errors) - done = 1; - } - - free(line); - } - if (save_error) - rc = save_error; - return rc; -} - - -/* sets the parser prompt */ -void Parser_init(char * prompt, command_t * cmds) -{ - done = 0; - top_level = cmds; - if (parser_prompt) free(parser_prompt); - parser_prompt = strdup(prompt); -} - -/* frees the parser prompt */ -void Parser_exit(int argc, char *argv[]) -{ - done = 1; - free(parser_prompt); - parser_prompt = NULL; -} - -/* convert a string to an integer */ -int Parser_int(char *s, int *val) -{ - int ret; - - if (*s != '0') - ret = sscanf(s, "%d", val); - else if (*(s+1) != 'x') - ret = sscanf(s, "%o", val); - else { - s++; - ret = sscanf(++s, "%x", val); - } - - return(ret); -} - - -void Parser_qhelp(int argc, char *argv[]) { - - printf("Available commands are:\n"); - - print_commands(NULL, top_level); - printf("For more help type: help command-name\n"); -} - -int Parser_help(int argc, char **argv) -{ - char line[1024]; - char *next, *prev, *tmp; - command_t *result, *ambig; - int i; - - if ( argc == 1 ) { - Parser_qhelp(argc, argv); - return 0; - } - - line[0]='\0'; - for ( i = 1 ; i < argc ; i++ ) { - strcat(line, argv[i]); - } - - switch ( process(line, &next, top_level, &result, &prev) ) { - case CMD_COMPLETE: - fprintf(stderr, "%s: %s\n",line, result->pc_help); - break; - case CMD_NONE: - fprintf(stderr, "%s: Unknown command.\n", line); - break; - case CMD_INCOMPLETE: - fprintf(stderr, - "'%s' incomplete command. Use '%s x' where x is one of:\n", - line, line); - fprintf(stderr, "\t"); - for (i = 0; result->pc_sub_cmd[i].pc_name; i++) { - fprintf(stderr, "%s ", result->pc_sub_cmd[i].pc_name); - } - fprintf(stderr, "\n"); - break; - case CMD_AMBIG: - fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line); - while( (ambig = find_cmd(prev, result, &tmp)) ) { - fprintf(stderr, "%s ", ambig->pc_name); - result = ambig + 1; - } - fprintf(stderr, "\n"); - break; - } - return 0; -} - - -void Parser_printhelp(char *cmd) -{ - char *argv[] = { "help", cmd }; - Parser_help(2, argv); -} - - -/************************************************************************* - * COMMANDS * - *************************************************************************/ - - -static void print_commands(char * str, command_t * table) { - command_t * cmds; - char buf[80]; - - for (cmds = table; cmds->pc_name; cmds++) { - if (cmds->pc_func) { - if (str) printf("\t%s %s\n", str, cmds->pc_name); - else printf("\t%s\n", cmds->pc_name); - } - if (cmds->pc_sub_cmd) { - if (str) { - sprintf(buf, "%s %s", str, cmds->pc_name); - print_commands(buf, cmds->pc_sub_cmd); - } else { - print_commands(cmds->pc_name, cmds->pc_sub_cmd); - } - } - } -} - -char *Parser_getstr(const char *prompt, const char *deft, char *res, - size_t len) -{ - char *line = NULL; - int size = strlen(prompt) + strlen(deft) + 8; - char *theprompt; - theprompt = malloc(size); - assert(theprompt); - - sprintf(theprompt, "%s [%s]: ", prompt, deft); - - line = readline(theprompt); - free(theprompt); - - if ( line == NULL || *line == '\0' ) { - strncpy(res, deft, len); - } else { - strncpy(res, line, len); - } - - if ( line ) { - free(line); - return res; - } else { - return NULL; - } -} - -/* get integer from prompt, loop forever to get it */ -int Parser_getint(const char *prompt, long min, long max, long deft, int base) -{ - int rc; - long result; - char *line; - int size = strlen(prompt) + 40; - char *theprompt = malloc(size); - assert(theprompt); - sprintf(theprompt,"%s [%ld, (0x%lx)]: ", prompt, deft, deft); - - fflush(stdout); - - do { - line = NULL; - line = readline(theprompt); - if ( !line ) { - fprintf(stdout, "Please enter an integer.\n"); - fflush(stdout); - continue; - } - if ( *line == '\0' ) { - free(line); - result = deft; - break; - } - rc = Parser_arg2int(line, &result, base); - free(line); - if ( rc != 0 ) { - fprintf(stdout, "Invalid string.\n"); - fflush(stdout); - } else if ( result > max || result < min ) { - fprintf(stdout, "Error: response must lie between %ld and %ld.\n", - min, max); - fflush(stdout); - } else { - break; - } - } while ( 1 ) ; - - if (theprompt) - free(theprompt); - return result; - -} - -/* get boolean (starting with YyNn; loop forever */ -int Parser_getbool(const char *prompt, int deft) -{ - int result = 0; - char *line; - int size = strlen(prompt) + 8; - char *theprompt = malloc(size); - assert(theprompt); - - fflush(stdout); - - if ( deft != 0 && deft != 1 ) { - fprintf(stderr, "Error: Parser_getbool given bad default (%d).\n", - deft); - assert ( 0 ); - } - sprintf(theprompt, "%s [%s]: ", prompt, (deft==0)? "N" : "Y"); - - do { - line = NULL; - line = readline(theprompt); - if ( line == NULL ) { - result = deft; - break; - } - if ( *line == '\0' ) { - result = deft; - break; - } - if ( *line == 'y' || *line == 'Y' ) { - result = 1; - break; - } - if ( *line == 'n' || *line == 'N' ) { - result = 0; - break; - } - if ( line ) - free(line); - fprintf(stdout, "Invalid string. Must start with yY or nN\n"); - fflush(stdout); - } while ( 1 ); - - if ( line ) - free(line); - if ( theprompt ) - free(theprompt); - return result; -} - -/* parse int out of a string or prompt for it */ -long Parser_intarg(const char *inp, const char *prompt, int deft, - int min, int max, int base) -{ - long result; - int rc; - - rc = Parser_arg2int(inp, &result, base); - - if ( rc == 0 ) { - return result; - } else { - return Parser_getint(prompt, deft, min, max, base); - } -} - -/* parse int out of a string or prompt for it */ -char *Parser_strarg(char *inp, const char *prompt, const char *deft, - char *answer, int len) -{ - if ( inp == NULL || *inp == '\0' ) { - return Parser_getstr(prompt, deft, answer, len); - } else - return inp; -} - -/* change a string into a number: return 0 on success. No invalid characters - allowed. The processing of base and validity follows strtol(3)*/ -int Parser_arg2int(const char *inp, long *result, int base) -{ - char *endptr; - - if ( (base !=0) && (base < 2 || base > 36) ) - return 1; - - *result = strtol(inp, &endptr, base); - - if ( *inp != '\0' && *endptr == '\0' ) - return 0; - else - return 1; -} - -/* Convert human readable size string to and int; "1k" -> 1000 */ -int Parser_size (int *sizep, char *str) { - int size; - char mod[32]; - - switch (sscanf (str, "%d%1[gGmMkK]", &size, mod)) { - default: - return (-1); - - case 1: - *sizep = size; - return (0); - - case 2: - switch (*mod) { - case 'g': - case 'G': - *sizep = size << 30; - return (0); - - case 'm': - case 'M': - *sizep = size << 20; - return (0); - - case 'k': - case 'K': - *sizep = size << 10; - return (0); - - default: - *sizep = size; - return (0); - } - } -} - -/* Convert a string boolean to an int; "enable" -> 1 */ -int Parser_bool (int *b, char *str) { - if (!strcasecmp (str, "no") || - !strcasecmp (str, "n") || - !strcasecmp (str, "off") || - !strcasecmp (str, "disable")) - { - *b = 0; - return (0); - } - - if (!strcasecmp (str, "yes") || - !strcasecmp (str, "y") || - !strcasecmp (str, "on") || - !strcasecmp (str, "enable")) - { - *b = 1; - return (0); - } - - return (-1); -} - -int Parser_quit(int argc, char **argv) -{ - argc = argc; - argv = argv; - done = 1; - return 0; -} diff --git a/lustre/utils/parser.h b/lustre/utils/parser.h deleted file mode 100644 index 5aece60..0000000 --- a/lustre/utils/parser.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef _PARSER_H_ -#define _PARSER_H_ - -#define HISTORY 100 /* Don't let history grow unbounded */ -#define MAXARGS 100 - -#define CMD_COMPLETE 0 -#define CMD_INCOMPLETE 1 -#define CMD_NONE 2 -#define CMD_AMBIG 3 -#define CMD_HELP 4 - -typedef struct parser_cmd { - char *pc_name; - int (* pc_func)(int, char **); - struct parser_cmd * pc_sub_cmd; - char *pc_help; -} command_t; - -typedef struct argcmd { - char *ac_name; - int (*ac_func)(int, char **); - char *ac_help; -} argcmd_t; - -typedef struct network { - char *type; - char *server; - int port; -} network_t; - -int Parser_quit(int argc, char **argv); -void Parser_init(char *, command_t *); /* Set prompt and load command list */ -int Parser_commands(void); /* Start the command parser */ -void Parser_qhelp(int, char **); /* Quick help routine */ -int Parser_help(int, char **); /* Detailed help routine */ -void Parser_ignore_errors(int ignore); /* Set the ignore errors flag */ -void Parser_printhelp(char *); /* Detailed help routine */ -void Parser_exit(int, char **); /* Shuts down command parser */ -int Parser_execarg(int argc, char **argv, command_t cmds[]); -int execute_line(char * line); - -/* Converts a string to an integer */ -int Parser_int(char *, int *); - -/* Prompts for a string, with default values and a maximum length */ -char *Parser_getstr(const char *prompt, const char *deft, char *res, - size_t len); - -/* Prompts for an integer, with minimum, maximum and default values and base */ -int Parser_getint(const char *prompt, long min, long max, long deft, - int base); - -/* Prompts for a yes/no, with default */ -int Parser_getbool(const char *prompt, int deft); - -/* Extracts an integer from a string, or prompts if it cannot get one */ -long Parser_intarg(const char *inp, const char *prompt, int deft, - int min, int max, int base); - -/* Extracts a word from the input, or propmts if it cannot get one */ -char *Parser_strarg(char *inp, const char *prompt, const char *deft, - char *answer, int len); - -/* Extracts an integer from a string with a base */ -int Parser_arg2int(const char *inp, long *result, int base); - -/* Convert human readable size string to and int; "1k" -> 1000 */ -int Parser_size(int *sizep, char *str); - -/* Convert a string boolean to an int; "enable" -> 1 */ -int Parser_bool(int *b, char *str); - -#endif -- 1.8.3.1